Class: Rufus::Tokyo::TableQuery

Inherits:
Object
  • Object
show all
Includes:
QueryConstants
Defined in:
lib/rufus/tokyo/cabinet/table.rb

Overview

A query on a Tokyo Cabinet table db

Constant Summary

Constants included from QueryConstants

QueryConstants::DIRECTIONS, QueryConstants::OPERATORS, QueryConstants::TDBQCNEGATE, QueryConstants::TDBQCNOIDX

Instance Method Summary collapse

Constructor Details

#initialize(table) ⇒ TableQuery

Creates a query for a given Rufus::Tokyo::Table

Queries are usually created via the #query (#prepare_query #do_query) of the Table instance.

Methods of interest here are :

* #add (or #add_condition)
* #order_by
* #limit

also

* #pk_only
* #no_pk

620
621
622
623
624
625
626
# File 'lib/rufus/tokyo/cabinet/table.rb', line 620

def initialize (table)

  @table   = table
  @query   = @table.lib.qry_new(@table.pointer)
  @opts    = {}
  @has_run = false
end

Instance Method Details

#add(colname, operator, val, affirmative = true, no_index = false) ⇒ Object Also known as: add_condition

Adds a condition

table.query { |q|
  q.add 'name', :equals, 'Oppenheimer'
  q.add 'age', :numgt, 35
}

Understood 'operators' :

:streq # string equality
:eq
:eql
:equals

:strinc # string include
:inc # string include
:includes # string include

:strbw # string begins with
:bw
:starts_with
:strew # string ends with
:ew
:ends_with

:strand # string which include all the tokens in the given exp
:and

:stror # string which include at least one of the tokens
:or

:stroreq # string which is equal to at least one token

:strorrx # string which matches the given regex
:regex
:matches

# numbers...

:numeq # equal
:numequals
:numgt # greater than
:gt
:numge # greater or equal
:ge
:gte
:numlt # greater or equal
:lt
:numle # greater or equal
:le
:lte
:numbt # a number between two tokens in the given exp
:bt
:between

:numoreq # number which is equal to at least one token

:ftsph # full-text phrase search
:ftsphrase
:phrase
:ftsand # full-text AND
:ftsor # full-text OR
:ftsex # full-text with 'compound' expression

706
707
708
709
710
711
712
713
714
715
# File 'lib/rufus/tokyo/cabinet/table.rb', line 706

def add (colname, operator, val, affirmative=true, no_index=false)

  colname = colname.to_s
  val = val.to_s

  op = operator.is_a?(Fixnum) ? operator : OPERATORS[operator]
  op = op | TDBQCNEGATE unless affirmative
  op = op | TDBQCNOIDX if no_index
  lib.qry_addcond(@query, colname, op, val)
end

#countObject

Gets the count of records returned by this query.

Note : the 'real' impl is only available since TokyoCabinet 1.4.12.


833
834
835
836
837
838
839
840
841
# File 'lib/rufus/tokyo/cabinet/table.rb', line 833

def count

  #if lib.respond_to?(:qry_count)
  run.free unless @has_run
  lib.qry_count(@query)
  #else
  #  @last_resultset ? @last_resultset.size : 0
  #end
end

#deleteObject

Runs this query AND let all the matching records get deleted.


824
825
826
827
# File 'lib/rufus/tokyo/cabinet/table.rb', line 824

def delete

  lib.qry_searchout(@query) || raise_error
end

#freeObject Also known as: close, destroy

Frees this data structure


845
846
847
848
849
# File 'lib/rufus/tokyo/cabinet/table.rb', line 845

def free

  lib.qry_del(@query)
  @query = nil
end

#libObject

Returns the FFI lib the table uses.


630
631
632
633
# File 'lib/rufus/tokyo/cabinet/table.rb', line 630

def lib

  @table.lib
end

#limit(i, offset = -1)) ⇒ Object

Sets the max number of records to return for this query.

(If you're using TC >= 1.4.10 the optional 'offset' (skip) parameter is accepted)


723
724
725
726
727
728
# File 'lib/rufus/tokyo/cabinet/table.rb', line 723

def limit (i, offset=-1)

  lib.respond_to?(:qry_setlimit) ?
    lib.qry_setlimit(@query, i, offset) :
    lib.qry_setmax(@query, i)
end

#no_pk(on = true) ⇒ Object

When set to true, the :pk (primary key) is not inserted in the record (hashes) returned


757
758
759
760
# File 'lib/rufus/tokyo/cabinet/table.rb', line 757

def no_pk (on=true)

  @opts[:no_pk] = on
end

#order_by(colname, direction = :strasc) ⇒ Object

Sets the sort order for the result of the query

The 'direction' may be :

:strasc # string ascending
:strdesc
:asc # string ascending
:desc
:numasc # number ascending
:numdesc

741
742
743
744
# File 'lib/rufus/tokyo/cabinet/table.rb', line 741

def order_by (colname, direction=:strasc)

  lib.qry_setorder(@query, colname.to_s, DIRECTIONS[direction])
end

#pk_only(on = true) ⇒ Object

When set to true, only the primary keys of the matching records will be returned.


749
750
751
752
# File 'lib/rufus/tokyo/cabinet/table.rb', line 749

def pk_only (on=true)

  @opts[:pk_only] = on
end

#pointerObject

Returns the underlying pointer.


637
638
639
640
# File 'lib/rufus/tokyo/cabinet/table.rb', line 637

def pointer

  @query
end

#process(&block) ⇒ Object

Process each record using the supplied block, which will be passed two parameters, the primary key and the value hash.

The block passed to this method accepts two parameters : the [String] primary key and a Hash of the values for the record.

The return value of the passed block does matter. Three different values are expected :stop, :delete or a Hash instance.

:stop will make the iteration stop, further matching records will not be passed to the block

:delete will let Tokyo Cabinet delete the record just seen.

a Hash is passed to let TC update the values for the record just seen.

Passing an array is possible : [ :stop, { 'name' => 'Toto' } ] will update the record just seen to a unique column 'name' and will stop the iteration. Likewise, returning [ :stop, :delete ] will work as well.

(by Matthew King)


784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
# File 'lib/rufus/tokyo/cabinet/table.rb', line 784

def process (&block)

  callback = lambda do |pk, pklen, map, opt_param|

    key = pk.read_string(pklen)
    val = Rufus::Tokyo::Map.new(map).to_h

    r = block.call(key, val)
    r = [ r ] unless r.is_a?(Array)

    if updated_value = r.find { |e| e.is_a?(Hash) }
      Rufus::Tokyo::Map.new(map).merge!(updated_value)
    end

    r.inject(0) { |i, v|
      case v
      when :stop then i = i | 1 << 24
      when :delete then i = i | 2
      when Hash then i = i | 1
      end
      i
    }
  end

  lib.qry_proc(@query, callback, nil)

  self
end

#runObject

Runs this query (returns a TableResultSet instance)


815
816
817
818
819
820
# File 'lib/rufus/tokyo/cabinet/table.rb', line 815

def run

  @has_run = true
  #@last_resultset =
  TableResultSet.new(@table, lib.qry_search(@query), @opts)
end