Class: Arel::Visitors::Datastore::QString

Inherits:
Object
  • Object
show all
Defined in:
lib/arel/visitors/datastore.rb

Constant Summary collapse

TypeCast =
{
  :primary_key => lambda{|k,v| AppEngine::Datastore::Key.from_path( k, v.to_i ) },
  :integer     => lambda{|k,i| i.to_i },
  :datetime    => lambda{|k,t| t.is_a?(Time)? t : Time.parse(t.to_s) },
  :date        => lambda{|k,t| t.is_a?(Date)? t : Date.parse(t.to_s) },
  :float       => lambda{|k,f| f.to_f },
  :text        => lambda{|k,t| AppEngine::Datastore::Text.new(t) },
  :binary      => lambda{|k,t| AppEngine::Datastore::Blob.new(t) }
}
InScan =
/'((\\.|[^'])*)'|(\d+)/
RExpr =
Regexp.union( /(in)/i,
/\(\s*(('((\\.|[^'])*)'|\d+)(\s*,\s*('((\\.|[^'])*)'|\d+))*)\s*\)/,
/"((\\.|[^"])*)"/,
/'((\\.|[^'])*)'/,
/([\w\.]+)/,
/([^\w\s\.'"]+)/ )
Optr =
{ "=" => :== }
ExOptr =
["(",")"]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(conn, kind, options = {}) ⇒ QString

Returns a new instance of QString.



16
17
18
19
20
21
# File 'lib/arel/visitors/datastore.rb', line 16

def initialize( conn, kind, options = {} )
  @connection = conn
  @kind = kind
  @q = AppEngine::Datastore::Query.new( kind )
  @options = options
end

Instance Attribute Details

#connectionObject (readonly)

Returns the value of attribute connection.



14
15
16
# File 'lib/arel/visitors/datastore.rb', line 14

def connection
  @connection
end

#kindObject (readonly)

Returns the value of attribute kind.



11
12
13
# File 'lib/arel/visitors/datastore.rb', line 11

def kind
  @kind
end

#optionsObject (readonly)

Returns the value of attribute options.



13
14
15
# File 'lib/arel/visitors/datastore.rb', line 13

def options
  @options
end

#qObject (readonly)

Returns the value of attribute q.



12
13
14
# File 'lib/arel/visitors/datastore.rb', line 12

def q
  @q
end

Instance Method Details

#apply_filter(key, opt, value) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/arel/visitors/datastore.rb', line 66

def apply_filter( key, opt, value )
  key, opt = key.to_sym, opt.to_sym
  column = @connection.columns(kind).find{|c| c.name == key.to_s }
  opt = :in      if value.is_a? Array
  type_cast_proc = TypeCast[ column.primary ? :primary_key : column.type ]
  if opt == :in or opt == :IN
    value = value.scan(InScan).collect{|d| d.find{|i| i}}   if value.is_a? String
    value.collect!{|v| type_cast_proc.call(kind,v) }        if type_cast_proc
    options[:empty], value = true, [ "EMPTY" ]              if value.empty?
  else
    value = type_cast_proc.call( kind, value ) if type_cast_proc
  end
  key = :__key__ if column.primary
  q.filter( key, opt, value )
end

#orders(ords) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
# File 'lib/arel/visitors/datastore.rb', line 103

def orders( ords )
  ords.each{|o|
    if( o.is_a? String )
      key, dir, notuse = o.split
    else
      key, dir = o.expr, o.direction
    end
    q.sort( key, dir )
  }
  self
end

#parese_expression_string(query) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
# File 'lib/arel/visitors/datastore.rb', line 91

def parese_expression_string( query )
  datas = query.scan( RExpr ).collect{|a| a.find{|i| i } }
  datas.delete_if{|d| ExOptr.include?(d) }
  while( datas.size >= 3 )
    key = datas.shift.sub(/^[^.]*\./,'').to_sym
    opt = datas.shift
    val = datas.shift
    concat_opt = datas.shift
    apply_filter( key, Optr[opt] || opt.to_sym, val )
  end
end

#projections(projs) ⇒ Object



32
33
34
35
36
37
38
39
# File 'lib/arel/visitors/datastore.rb', line 32

def projections( projs )
  projs.each{|p|
    if( p.is_a? Arel::Nodes::Count )
      options[:count] = true
    end
  }
  self
end

#to_sObject Also known as: inspect



23
24
25
26
27
28
# File 'lib/arel/visitors/datastore.rb', line 23

def to_s
  out = q.inspect 
  out += " OFFSET #{options[:offset]} " if options[:offset]  
  out += " LIMIT  #{options[:limit]} "  if options[:limit]  
  out
end

#wheres(conditions) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/arel/visitors/datastore.rb', line 41

def wheres( conditions )
  conditions.each{|w|
    w_expr  = w.expr rescue w
    if( w_expr.class != Arel::Nodes::SqlLiteral )
      key     = w_expr.left.name
      val     = w_expr.right
      opt     = w_expr.operator
      apply_filter( key, opt, val )
    else
      parese_expression_string( w_expr.to_s )
    end
  }
  self
end