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 (table + 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

Class Method Summary collapse

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

Class Method Details

.included(target) ⇒ Object

Add the open() method to all Table type classes.



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

def self.included(target)
  target.extend(Rufus::Tokyo::Openable)
end

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.



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/rufus/edo/tabcore.rb', line 113

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



147
148
149
150
# File 'lib/rufus/edo/tabcore.rb', line 147

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.



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

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



132
133
134
135
136
137
138
139
140
141
# File 'lib/rufus/edo/tabcore.rb', line 132

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.



170
171
172
173
# File 'lib/rufus/edo/tabcore.rb', line 170

def delete_keys_with_prefix (prefix)

  query_delete { |q| q.add('', :strbw, prefix) }
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.



331
332
333
334
# File 'lib/rufus/edo/tabcore.rb', line 331

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)



57
58
59
# File 'lib/rufus/edo/tabcore.rb', line 57

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.



309
310
311
312
# File 'lib/rufus/edo/tabcore.rb', line 309

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


161
162
163
164
165
166
# File 'lib/rufus/edo/tabcore.rb', line 161

def keys (options={})

  pref = options.fetch(:prefix, "")

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

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

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



178
179
180
181
182
183
184
185
186
187
# File 'lib/rufus/edo/tabcore.rb', line 178

def lget (*keys)

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

  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)



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

def original

  @db
end

#prepare_query(&block) ⇒ Object

Prepares a query instance (block is optional)



200
201
202
203
204
205
206
# File 'lib/rufus/edo/tabcore.rb', line 200

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)



211
212
213
214
# File 'lib/rufus/edo/tabcore.rb', line 211

def query (&block)

  prepare_query(&block).run
end

#query_count(&block) ⇒ Object

Prepares, runs AND counts all the matching records.



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

def query_count (&block)

  prepare_query { |q|
    q.pk_only  # improve efficiency, since we have to do the query
  }.count
end

#query_delete(&block) ⇒ Object

Prepares, runs AND delete all the matching records.



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

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)


355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
# File 'lib/rufus/edo/tabcore.rb', line 355

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.



93
94
95
96
97
98
99
100
# File 'lib/rufus/edo/tabcore.rb', line 93

def set_index (column_name, *types)

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

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

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

#sizeObject

Returns the number of records in this table db



193
194
195
196
# File 'lib/rufus/edo/tabcore.rb', line 193

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'.



257
258
259
260
# File 'lib/rufus/edo/tabcore.rb', line 257

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'.



237
238
239
240
# File 'lib/rufus/edo/tabcore.rb', line 237

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'.



247
248
249
250
# File 'lib/rufus/edo/tabcore.rb', line 247

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.



287
288
289
290
# File 'lib/rufus/edo/tabcore.rb', line 287

def union (*queries)

  search(:union, *queries)
end