Module: Rufus::Edo::TableCore

Includes:
Tokyo::HashMethods, Tokyo::Transactions
Included in:
NetTyrantTable, Table
Defined in:
lib/rufus/edo/tabcore.rb

Overview

Methods common to the two table classes (cabinet + ntyrant) found in Rufus::Edo

Constant Summary collapse

INDEX_TYPES =
{
  :lexical => 0,
  :decimal => 1,
  :token => 2,
  :qgram => 3,
  :opt => 9998,
  :optimized => 9998,
  :void => 9999,
  :remove => 9999,
  :keep => 1 << 24
}

Instance Attribute Summary

Attributes included from Tokyo::HashMethods

#default_proc

Instance Method Summary collapse

Methods included from Tokyo::Transactions

#abort, #transaction

Methods included from Tokyo::HashMethods

#[], #default, #default=, #each, #merge, #merge!, #to_a, #to_h, #values

Instance Method Details

#[]=(pk, h_or_a) ⇒ Object

Inserts a record in the table db

table['pk0'] = [ 'name', 'fred', 'age', '45' ]
table['pk1'] = { 'name' => 'jeff', 'age' => '46' }

Accepts both a hash or an array (expects the array to be of the form [ key, value, key, value, … ] else it will raise an ArgumentError)

Raises an error in case of failure.



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/rufus/edo/tabcore.rb', line 107

def []= (pk, h_or_a)

  pk = pk.to_s

  m = h_or_a.is_a?(Hash) ? h_or_a : Hash[*h_or_a]
  m = Rufus::Tokyo.h_or_a_to_s(m)

  #verify_value(m)

  @db.put(pk, m) || raise_error
end

#clearObject

Removes all records in this table database

Raises an error if something went wrong



141
142
143
144
# File 'lib/rufus/edo/tabcore.rb', line 141

def clear

  @db.vanish || raise_error
end

#closeObject

Closes the table (and frees the datastructure allocated for it), raises an exception in case of failure.



45
46
47
# File 'lib/rufus/edo/tabcore.rb', line 45

def close
  @db.close || raise_error
end

#delete(k) ⇒ Object

Removes an entry in the table

(might raise an error if the delete itself failed, but returns nil if there was no entry for the given key)

Raises an error if something went wrong



126
127
128
129
130
131
132
133
134
135
# File 'lib/rufus/edo/tabcore.rb', line 126

def delete (k)

  k = k.to_s

  val = @db[k]
  return nil unless val

  @db.out(k) || raise_error
  val
end

#delete_keys_with_prefix(prefix) ⇒ Object

Deletes all the entries whose key begin with the given prefix.



181
182
183
184
185
186
187
188
189
# File 'lib/rufus/edo/tabcore.rb', line 181

def delete_keys_with_prefix (prefix)

  if @db.respond_to?(:misc)
    @db.misc('outlist', @db.fwmkeys(prefix, -1))
  else
    ks = @db.fwmkeys(prefix, -1) # -1 for no limit
    ks.each { |k| self.delete(k) }
  end
end

#difference(*queries) ⇒ Object

Returns the difference of the listed queries

r = table.intersection(
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'es'
  },
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'li'
  }
)

will return a hash { primary_key => record } of the values matching the first query OR the second but not both.

If the last element element passed to this method is the value ‘false’, the return value will the array of matching primary keys.



338
339
340
341
# File 'lib/rufus/edo/tabcore.rb', line 338

def difference (*queries)

  search(:difference, *queries)
end

#generate_unique_idObject Also known as: genuid

Generates a unique id (in the context of this Table instance)



51
52
53
# File 'lib/rufus/edo/tabcore.rb', line 51

def generate_unique_id
  @db.genuid
end

#intersection(*queries) ⇒ Object

Returns the intersection of the listed queries

r = table.intersection(
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'es'
  },
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'li'
  }
)

will return a hash { primary_key => record } of the values matching the first query AND the second.

If the last element element passed to this method is the value ‘false’, the return value will the array of matching primary keys.



316
317
318
319
# File 'lib/rufus/edo/tabcore.rb', line 316

def intersection (*queries)

  search(:intersection, *queries)
end

#keys(options = {}) ⇒ Object

Returns an array of all the primary keys in the table

With no options given, this method will return all the keys (strings) in a Ruby array.

:prefix --> returns only the keys who match a given string prefix

:limit --> returns a limited number of keys


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/rufus/edo/tabcore.rb', line 155

def keys (options={})

  if pref = options[:prefix]

    @db.fwmkeys(pref, options[:limit] || -1)

  else

    limit = options[:limit] || -1
    limit = nil if limit < 1

    @db.iterinit

    l = []

    while (k = @db.iternext)
      break if limit and l.size >= limit
      l << k
    end

    l
  end
end

#lget(keys) ⇒ Object Also known as: mget

Returns a hash { key => record } of all the records matching the given keys.



194
195
196
197
198
199
200
201
202
203
# File 'lib/rufus/edo/tabcore.rb', line 194

def lget (keys)

  keys = Rufus::Tokyo::h_or_a_to_s(keys)

  if @db.respond_to?(:mget)
    @db.mget(keys)
  else
    keys.inject({}) { |h, k| v = self[k]; h[k] = v if v; h }
  end
end

#originalObject

Returns the underlying ‘native’ Ruby object (of the class devised by Hirabayashi-san)



272
273
274
275
# File 'lib/rufus/edo/tabcore.rb', line 272

def original

  @db
end

#prepare_query(&block) ⇒ Object

Prepares a query instance (block is optional)



216
217
218
219
220
221
222
# File 'lib/rufus/edo/tabcore.rb', line 216

def prepare_query (&block)

  q = TableQuery.new(table_query_class, self)
  block.call(q) if block

  q
end

#query(&block) ⇒ Object

Prepares and runs a query, returns an array of hashes (all Ruby) (takes care of freeing the query and the result set structures)



227
228
229
230
# File 'lib/rufus/edo/tabcore.rb', line 227

def query (&block)

  prepare_query(&block).run
end

#query_delete(&block) ⇒ Object

Prepares, runs AND delete all the matching records.



234
235
236
237
# File 'lib/rufus/edo/tabcore.rb', line 234

def query_delete (&block)

  prepare_query(&block).delete
end

#search(type, *queries) ⇒ Object

A #search a la ruby-tokyotyrant (github.com/actsasflinn/ruby-tokyotyrant/tree)

r = table.search(
  :intersection,
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'es'
  },
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'li'
  }
)

Accepts the symbols :union, :intersection, :difference or :diff as first parameter.

If the last element element passed to this method is the value ‘false’, the return value will the array of matching primary keys.

Raises:

  • (ArgumentError)


362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/rufus/edo/tabcore.rb', line 362

def search (type, *queries)

  run_query = true
  run_query = queries.pop if queries.last == false

  raise(
    ArgumentError.new("pass at least one prepared query")
  ) if queries.size < 1

  t = META_TYPES[type]

  raise(
    ArgumentError.new("no search type #{type.inspect}")
  ) unless t

  q = queries.shift.original
  qs = queries.collect { |qq| qq.original }

  pks = q.metasearch(qs, META_TYPES[type])

  run_query ? lget(pks) : pks
end

#set_index(column_name, *types) ⇒ Object

Sets an index on a column of the table.

Types maybe be :lexical or :decimal.

Recently (TC 1.4.26 and 1.4.27) inverted indexes have been added, they are :token and :qgram. There is an :opt index as well.

Sorry couldn’t find any good doc about those inverted indexes apart from :

http://alpha.mixi.co.jp/blog/?p=1147
http://www.excite-webtl.jp/world/english/web/?wb_url=http%3A%2F%2Falpha.mixi.co.jp%2Fblog%2F%3Fp%3D1147&wb_lp=JAEN&wb_dis=2&wb_submit=+%96%7C+%96%F3+

Use :keep to “add” and :remove (or :void) to “remove” an index.

If column_name is :pk or “”, the index will be set on the primary key.

Returns true in case of success.



87
88
89
90
91
92
93
94
# File 'lib/rufus/edo/tabcore.rb', line 87

def set_index (column_name, *types)

  column_name = column_name == :pk ? '' : column_name.to_s

  i = types.inject(0) { |i, t| i = i | INDEX_TYPES[t]; i }

  @db.setindex(column_name, i) || raise_error
end

#sizeObject

Returns the number of records in this table db



209
210
211
212
# File 'lib/rufus/edo/tabcore.rb', line 209

def size

  @db.rnum
end

#tranabortObject

Warning : this method is low-level, you probably only need to use #transaction and a block.

Direct call for ‘transaction abort’.



264
265
266
267
# File 'lib/rufus/edo/tabcore.rb', line 264

def tranabort

  @db.tranabort || raise_error
end

#tranbeginObject

Warning : this method is low-level, you probably only need to use #transaction and a block.

Direct call for ‘transaction begin’.



244
245
246
247
# File 'lib/rufus/edo/tabcore.rb', line 244

def tranbegin

  @db.tranbegin || raise_error
end

#trancommitObject

Warning : this method is low-level, you probably only need to use #transaction and a block.

Direct call for ‘transaction commit’.



254
255
256
257
# File 'lib/rufus/edo/tabcore.rb', line 254

def trancommit

  @db.trancommit || raise_error
end

#union(*queries) ⇒ Object

Returns the union of the listed queries

r = table.union(
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'es'
  },
  @t.prepare_query { |q|
    q.add 'lang', :includes, 'li'
  }
)

will return a hash { primary_key => record } of the values matching the first query OR the second.

If the last element element passed to this method is the value ‘false’, the return value will the array of matching primary keys.



294
295
296
297
# File 'lib/rufus/edo/tabcore.rb', line 294

def union (*queries)

  search(:union, *queries)
end