lafcadio 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/lafcadio.rb +1 -1
- data/lib/lafcadio.rb~ +1 -1
- data/lib/lafcadio/domain.rb +9 -8
- data/lib/lafcadio/domain.rb~ +221 -84
- data/lib/lafcadio/query.rb +1 -1
- data/lib/lafcadio/query.rb~ +211 -94
- metadata +106 -111
data/lib/lafcadio/query.rb
CHANGED
@@ -108,7 +108,7 @@
|
|
108
108
|
# }
|
109
109
|
# # => "select * from invoices where (hours = 40 or rate = 50 or client = 99)"
|
110
110
|
# Note that both compound operators can be nested:
|
111
|
-
# invoices =
|
111
|
+
# invoices = Invoice.get { |inv|
|
112
112
|
# inv.hours.equals( 40 ) &
|
113
113
|
# ( inv.rate.equals( 50 ) | inv.client.equals( client99 ) )
|
114
114
|
# }
|
data/lib/lafcadio/query.rb~
CHANGED
@@ -1,19 +1,46 @@
|
|
1
1
|
# = Overview
|
2
2
|
# By passing a block to ObjectStore, you can write complex, ad-hoc queries in
|
3
|
-
# Ruby. This involves a few more keystrokes than writing raw SQL, but also
|
4
|
-
# it easier to change queries at runtime, and these queries can also be
|
5
|
-
# tested against the MockObjectStore.
|
6
|
-
# big_invoices =
|
7
|
-
# # => "select * from invoices where rate > 50"
|
3
|
+
# Ruby. This involves a few more keystrokes than writing raw SQL, but also
|
4
|
+
# makes it easier to change queries at runtime, and these queries can also be
|
5
|
+
# fully tested against the MockObjectStore.
|
6
|
+
# big_invoices = Invoice.get { |inv| inv.rate.gt( 50 ) }
|
7
|
+
# # => runs "select * from invoices where rate > 50"
|
8
8
|
# This a full-fledged block, so you can pass in values from the calling context.
|
9
9
|
# date = Date.new( 2004, 1, 1 )
|
10
|
-
# recent_invoices =
|
11
|
-
# # => "select * from invoices where date > '2004-01-01'"
|
10
|
+
# recent_invoices = Invoice.get { |inv| inv.date.gt( date ) }
|
11
|
+
# # => runs "select * from invoices where date > '2004-01-01'"
|
12
|
+
#
|
13
|
+
# = Building and accessing queries
|
14
|
+
# To build a query and run it immediately, call DomainObject.get and pass it a
|
15
|
+
# block:
|
16
|
+
# hwangs = User.get { |u| u.lname.equals( 'Hwang' ) }
|
17
|
+
# You can also call ObjectStore#[ plural domain class ] with a block:
|
18
|
+
# hwangs = ObjectStore.get_object_store.users { |u|
|
19
|
+
# u.lname.equals( 'Hwang' )
|
20
|
+
# }
|
21
|
+
# If you want more fine-grained control over a query, first create it with
|
22
|
+
# Query.infer and then build it, using ObjectStore#query to run it.
|
23
|
+
# qry = Query.infer( User ) { |u| u.lname.equals( 'Hwang' ) }
|
24
|
+
# qry.to_sql # => "select * from users where users.lname = 'Hwang'"
|
25
|
+
# qry = qry.and { |u| u.fname.equals( 'Francis' ) }
|
26
|
+
# qry.to_sql # => "select * from users where (users.lname = 'Hwang' and
|
27
|
+
# users.fname = 'Francis')"
|
28
|
+
# qry.limit = 0..5
|
29
|
+
# qry.to_sql # => "select * from users where (users.lname = 'Hwang' and
|
30
|
+
# users.fname = 'Francis') limit 0, 6"
|
31
|
+
# Using Query.infer, you can also set order_by and order_by_order clauses:
|
32
|
+
# qry = Query.infer(
|
33
|
+
# SKU,
|
34
|
+
# :order_by => [ :standardPrice, :salePrice ],
|
35
|
+
# :order_by_order => Query::DESC
|
36
|
+
# ) { |s| s.sku.nil? }
|
37
|
+
# qry.to_sql # => "select * from skus where skus.sku is null order by
|
38
|
+
# standardPrice, salePrice desc"
|
12
39
|
#
|
13
|
-
# = Query operators
|
40
|
+
# = Query inference operators
|
14
41
|
# You can compare fields either to simple values, or to other fields in the same
|
15
42
|
# table.
|
16
|
-
# paid_immediately =
|
43
|
+
# paid_immediately = Invoice.get { |inv|
|
17
44
|
# inv.date.equals( inv.paid )
|
18
45
|
# }
|
19
46
|
# # => "select * from invoices where date = paid"
|
@@ -21,81 +48,121 @@
|
|
21
48
|
# == Numerical comparisons: +lt+, +lte+, +gte+, +gt+
|
22
49
|
# +lt+, +lte+, +gte+, and +gt+ stand for "less than", "less than or equal",
|
23
50
|
# "greater than or equal", and "greater than", respectively.
|
24
|
-
# tiny_invoices =
|
51
|
+
# tiny_invoices = Invoice.get { |inv| inv.rate.lte( 25 ) }
|
25
52
|
# # => "select * from invoices where rate <= 25"
|
26
53
|
# These comparators work on fields that contain numbers, dates, and even
|
27
54
|
# references to other domain objects.
|
28
|
-
# for_1st_ten_clients =
|
55
|
+
# for_1st_ten_clients = Invoice.get { |inv|
|
29
56
|
# inv.client.lte( 10 )
|
30
57
|
# }
|
31
58
|
# # => "select * from invoices where client <= 10"
|
59
|
+
# client10 = Client[10]
|
60
|
+
# for_1st_ten_clients = Invoice.get { |inv|
|
61
|
+
# inv.client.lte( client10 )
|
62
|
+
# }
|
63
|
+
# # => "select * from invoices where client <= 10"
|
32
64
|
#
|
33
65
|
# == Equality: +equals+
|
34
|
-
# full_week_invs =
|
66
|
+
# full_week_invs = Invoice.get { |inv| inv.hours.equals( 40 ) }
|
35
67
|
# # => "select * from invoices where hours = 40"
|
36
68
|
# If you're comparing to a domain object you should pass in the object itself.
|
37
|
-
# client =
|
38
|
-
# invoices =
|
69
|
+
# client = Client[99]
|
70
|
+
# invoices = Invoice.get { |inv| inv.client.equals( client ) }
|
39
71
|
# # => "select * from invoices where client = 99"
|
72
|
+
# If you're comparing to a boolean value you don't need to use
|
73
|
+
# <tt>equals( true )</tt>.
|
74
|
+
# administrators = User.get { |u| u.administrator.equals( true ) }
|
75
|
+
# administrators = User.get { |u| u.administrator } # both forms work
|
76
|
+
# Matching for +nil+ can use <tt>nil?</tt>
|
77
|
+
# no_email = User.get { |u| u.email.nil? }
|
40
78
|
#
|
41
|
-
# == Inclusion: +in+
|
42
|
-
#
|
79
|
+
# == Inclusion: +in+ and <tt>include?</tt>
|
80
|
+
# Any field can be matched via +in+:
|
81
|
+
# first_three_invs = Invoice.get { |inv| inv.pk_id.in( 1, 2, 3 ) }
|
43
82
|
# # => "select * from invoices where pk_id in ( 1, 2, 3 )"
|
83
|
+
# A TextListField can be matched via <tt>include?</tt>
|
84
|
+
# aim_users = User.get { |u| u.im_methods.include?( 'aim' ) }
|
85
|
+
# # => "select * from users where user.im_methods like 'aim,%' or
|
86
|
+
# user.im_methods like '%,aim,%' or user.im_methods like '%,aim' or
|
87
|
+
# user.im_methods = 'aim'"
|
44
88
|
#
|
45
89
|
# == Text comparison: +like+
|
46
|
-
# fname_starts_with_a =
|
47
|
-
# user.fname.like( /^a/ )
|
48
|
-
# }
|
90
|
+
# fname_starts_with_a = User.get { |user| user.fname.like( /^a/ ) }
|
49
91
|
# # => "select * from users where fname like 'a%'"
|
50
|
-
# fname_ends_with_a =
|
51
|
-
# user.fname.like( /a$/ )
|
52
|
-
# }
|
92
|
+
# fname_ends_with_a = User.get { |user| user.fname.like( /a$/ ) }
|
53
93
|
# # => "select * from users where fname like '%a'"
|
54
|
-
# fname_contains_a =
|
55
|
-
# user.fname.like( /a/ )
|
56
|
-
# }
|
94
|
+
# fname_contains_a = User.get { |user| user.fname.like( /a/ ) }
|
57
95
|
# # => "select * from users where fname like '%a%'"
|
58
96
|
# Please note that although we're using the Regexp operators here, these aren't
|
59
97
|
# full-fledged regexps. Only ^ and $ work for this.
|
60
98
|
#
|
61
|
-
# == Compound conditions: <tt
|
62
|
-
# invoices =
|
63
|
-
#
|
99
|
+
# == Compound conditions: <tt>&</tt> and <tt>|</tt>
|
100
|
+
# invoices = Invoice.get { |inv|
|
101
|
+
# inv.hours.equals( 40 ) & inv.rate.equals( 50 )
|
64
102
|
# }
|
65
103
|
# # => "select * from invoices where (hours = 40 and rate = 50)"
|
66
|
-
# client99 =
|
67
|
-
# invoices =
|
68
|
-
#
|
69
|
-
#
|
70
|
-
# inv.client.equals( client99 ) )
|
104
|
+
# client99 = Client[99]
|
105
|
+
# invoices = Invoice.get { |inv|
|
106
|
+
# inv.hours.equals( 40 ) | inv.rate.equals( 50 ) |
|
107
|
+
# inv.client.equals( client99 )
|
71
108
|
# }
|
72
109
|
# # => "select * from invoices where (hours = 40 or rate = 50 or client = 99)"
|
73
|
-
# Note that both compound operators can
|
74
|
-
# be nested:
|
110
|
+
# Note that both compound operators can be nested:
|
75
111
|
# invoices = object_store.getInvoices { |inv|
|
76
|
-
#
|
77
|
-
#
|
78
|
-
# inv.client.equals( client99 ) ) )
|
112
|
+
# inv.hours.equals( 40 ) &
|
113
|
+
# ( inv.rate.equals( 50 ) | inv.client.equals( client99 ) )
|
79
114
|
# }
|
80
115
|
# # => "select * from invoices where (hours = 40 and
|
81
116
|
# # (rate = 50 or client = 99))"
|
82
117
|
#
|
83
118
|
# == Negation: +not+
|
84
|
-
# invoices =
|
119
|
+
# invoices = Invoice.get { |inv| inv.rate.equals( 50 ).not }
|
85
120
|
# # => "select * from invoices where rate != 50"
|
121
|
+
# This can be used directly against boolean and nil comparisons, too.
|
122
|
+
# not_administrators = User.get { |u| u.administrator.not }
|
123
|
+
# # => "select * from users where administrator != 1"
|
124
|
+
# has_email = User.get { |u| u.email.nil?.not }
|
125
|
+
# # => "select * from users where email is not null"
|
126
|
+
#
|
127
|
+
# = Query caching via subset matching
|
128
|
+
# Lafcadio caches every query, and optimizes based on a simple subset
|
129
|
+
# calculation. For example, if you run these statements:
|
130
|
+
# User.get { |u| u.lname.equals( 'Smith' ) }
|
131
|
+
# User.get { |u| u.lname.equals( 'Smith' ) & u.fname.like( /John/ ) }
|
132
|
+
# User.get { |u| u.lname.equals( 'Smith' ) & u.email.like( /hotmail/ ) }
|
133
|
+
# Lafcadio can tell that the 2nd and 3rd queries are subsets of the first. So
|
134
|
+
# these three statements will result in one database call, for the first
|
135
|
+
# statement: The 2nd and 3rd statements will be handled entirely in Ruby. The
|
136
|
+
# result is less database calls with no extra work for the programmer.
|
86
137
|
|
87
138
|
require 'delegate'
|
88
139
|
|
89
140
|
module Lafcadio
|
90
141
|
class Query
|
91
|
-
def self.And( *conditions )
|
142
|
+
def self.And( *conditions ) #:nodoc:
|
143
|
+
CompoundCondition.new( *conditions )
|
144
|
+
end
|
92
145
|
|
146
|
+
# Infers a query from a block. The first required argument is the domain
|
147
|
+
# class. Other optional arguments should be passed in hash form:
|
148
|
+
# [:order_by] An array of fields to order the results by.
|
149
|
+
# [:order_by_order] Possible values are Query::ASC or Query::DESC. Defaults
|
150
|
+
# to Query::DESC.
|
151
|
+
# qry = Query.infer( User ) { |u| u.lname.equals( 'Hwang' ) }
|
152
|
+
# qry.to_sql # => "select * from users where users.lname = 'Hwang'"
|
153
|
+
# qry = Query.infer(
|
154
|
+
# SKU,
|
155
|
+
# :order_by => [ :standardPrice, :salePrice ],
|
156
|
+
# :order_by_order => Query::DESC
|
157
|
+
# ) { |s| s.sku.nil? }
|
158
|
+
# qry.to_sql # => "select * from skus where skus.sku is null order by
|
159
|
+
# standardPrice, salePrice desc"
|
93
160
|
def self.infer( *args, &action )
|
94
161
|
inferrer = Query::Inferrer.new( *args ) { |obj| action.call( obj ) }
|
95
162
|
inferrer.execute
|
96
163
|
end
|
97
164
|
|
98
|
-
def self.Or( *conditions )
|
165
|
+
def self.Or( *conditions ) #:nodoc:
|
99
166
|
conditions << CompoundCondition::OR
|
100
167
|
CompoundCondition.new( *conditions)
|
101
168
|
end
|
@@ -103,10 +170,10 @@ module Lafcadio
|
|
103
170
|
ASC = 1
|
104
171
|
DESC = 2
|
105
172
|
|
106
|
-
attr_reader :domain_class, :condition
|
107
|
-
attr_accessor :order_by, :order_by_order
|
173
|
+
attr_reader :domain_class, :condition, :limit
|
174
|
+
attr_accessor :order_by, :order_by_order
|
108
175
|
|
109
|
-
def initialize(domain_class, pk_id_or_condition = nil, opts = {} )
|
176
|
+
def initialize(domain_class, pk_id_or_condition = nil, opts = {} ) #:nodoc:
|
110
177
|
@domain_class, @opts = domain_class, opts
|
111
178
|
( @condition, @order_by, @limit ) = [ nil, nil, nil ]
|
112
179
|
if pk_id_or_condition
|
@@ -121,9 +188,16 @@ module Lafcadio
|
|
121
188
|
@order_by_order = ASC
|
122
189
|
end
|
123
190
|
|
191
|
+
# Returns a new query representing the condition of the current query and
|
192
|
+
# the new inferred query.
|
193
|
+
# qry = Query.infer( User ) { |u| u.lname.equals( 'Hwang' ) }
|
194
|
+
# qry.to_sql # => "select * from users where users.lname = 'Hwang'"
|
195
|
+
# qry = qry.and { |u| u.fname.equals( 'Francis' ) }
|
196
|
+
# qry.to_sql # => "select * from users where (users.lname = 'Hwang' and
|
197
|
+
# users.fname = 'Francis')"
|
124
198
|
def and( &action ); compound( CompoundCondition::AND, action ); end
|
125
199
|
|
126
|
-
def collect( coll )
|
200
|
+
def collect( coll ) #:nodoc:
|
127
201
|
if @opts[:group_functions] == [:count]
|
128
202
|
[ result_row( [coll.size] ) ]
|
129
203
|
else
|
@@ -131,24 +205,34 @@ module Lafcadio
|
|
131
205
|
end
|
132
206
|
end
|
133
207
|
|
134
|
-
def compound( comp_type, action )
|
208
|
+
def compound( comp_type, action ) #:nodoc:
|
135
209
|
rquery = Query.infer( @domain_class ) { |dobj| action.call( dobj ) }
|
136
|
-
Query::CompoundCondition.new(
|
210
|
+
q = Query::CompoundCondition.new(
|
137
211
|
@condition, rquery.condition, comp_type
|
138
212
|
).query
|
213
|
+
[ :order_by, :order_by_order, :limit ].each do |attr|
|
214
|
+
q.send( attr.to_s + '=', self.send( attr ) )
|
215
|
+
end
|
216
|
+
q
|
139
217
|
end
|
140
218
|
|
141
|
-
def dobj_satisfies?( dobj )
|
219
|
+
def dobj_satisfies?( dobj ) #:nodoc:
|
142
220
|
@condition.nil? or @condition.dobj_satisfies?( dobj )
|
143
221
|
end
|
144
222
|
|
145
|
-
def eql?( other )
|
223
|
+
def eql?( other ) #:nodoc:
|
224
|
+
other.is_a?( Query ) && other.to_sql == to_sql
|
225
|
+
end
|
146
226
|
|
147
|
-
def fields
|
227
|
+
def fields #:nodoc:
|
228
|
+
@opts[:group_functions] == [:count] ? 'count(*)' : '*'
|
229
|
+
end
|
148
230
|
|
149
|
-
def hash
|
231
|
+
def hash #:nodoc:
|
232
|
+
to_sql.hash
|
233
|
+
end
|
150
234
|
|
151
|
-
def implies?( other_query )
|
235
|
+
def implies?( other_query ) #:nodoc:
|
152
236
|
if other_query == self
|
153
237
|
true
|
154
238
|
elsif @domain_class == other_query.domain_class
|
@@ -160,13 +244,24 @@ module Lafcadio
|
|
160
244
|
end
|
161
245
|
end
|
162
246
|
|
163
|
-
def
|
247
|
+
def limit=( limit )
|
248
|
+
@limit = limit.is_a?( Fixnum ) ? 0..limit-1 : limit
|
249
|
+
end
|
250
|
+
|
251
|
+
def limit_clause #:nodoc:
|
164
252
|
"limit #{ @limit.begin }, #{ @limit.end - @limit.begin + 1 }" if @limit
|
165
253
|
end
|
166
254
|
|
255
|
+
# Returns a new query representing the condition of the current query and
|
256
|
+
# the new inferred query.
|
257
|
+
# qry = Query.infer( User ) { |u| u.lname.equals( 'Hwang' ) }
|
258
|
+
# qry.to_sql # => "select * from users where users.lname = 'Hwang'"
|
259
|
+
# qry = qry.or { |u| u.fname.equals( 'Francis' ) }
|
260
|
+
# qry.to_sql # => "select * from users where (users.lname = 'Hwang' or
|
261
|
+
# users.fname = 'Francis')"
|
167
262
|
def or( &action ); compound( CompoundCondition::OR, action ); end
|
168
263
|
|
169
|
-
def order_clause
|
264
|
+
def order_clause #:nodoc:
|
170
265
|
if @order_by
|
171
266
|
field_str = @order_by.map { |f_name|
|
172
267
|
@domain_class.field( f_name.to_s ).db_field_name
|
@@ -177,7 +272,22 @@ module Lafcadio
|
|
177
272
|
end
|
178
273
|
end
|
179
274
|
|
180
|
-
def
|
275
|
+
def order_and_limit_collection( objects )
|
276
|
+
objects = objects.sort_by { |dobj|
|
277
|
+
if order_by.nil?
|
278
|
+
dobj.pk_id
|
279
|
+
elsif order_by.is_a?( Array )
|
280
|
+
order_by.map { |field_name| dobj.send( field_name ) }
|
281
|
+
else
|
282
|
+
dobj.send order_by
|
283
|
+
end
|
284
|
+
}
|
285
|
+
objects.reverse! if order_by_order == Query::DESC
|
286
|
+
objects = objects[limit] if limit
|
287
|
+
objects
|
288
|
+
end
|
289
|
+
|
290
|
+
def result_row( row ) #:nodoc:
|
181
291
|
if @opts[:group_functions] == [:count]
|
182
292
|
{ :count => row.first }
|
183
293
|
else
|
@@ -185,11 +295,11 @@ module Lafcadio
|
|
185
295
|
end
|
186
296
|
end
|
187
297
|
|
188
|
-
def sql_primary_key_field(domain_class)
|
298
|
+
def sql_primary_key_field(domain_class) #:nodoc:
|
189
299
|
"#{ domain_class.table_name }.#{ domain_class.sql_primary_key_name }"
|
190
300
|
end
|
191
301
|
|
192
|
-
def tables
|
302
|
+
def tables #:nodoc:
|
193
303
|
concrete_classes = domain_class.self_and_concrete_superclasses.reverse
|
194
304
|
table_names = concrete_classes.collect { |domain_class|
|
195
305
|
domain_class.table_name
|
@@ -205,7 +315,7 @@ module Lafcadio
|
|
205
315
|
clauses.join ' '
|
206
316
|
end
|
207
317
|
|
208
|
-
def where_clause
|
318
|
+
def where_clause #:nodoc:
|
209
319
|
concrete_classes = domain_class.self_and_concrete_superclasses.reverse
|
210
320
|
where_clauses = []
|
211
321
|
concrete_classes.each_with_index { |domain_class, i|
|
@@ -461,7 +571,7 @@ module Lafcadio
|
|
461
571
|
end
|
462
572
|
end
|
463
573
|
|
464
|
-
class Include < CompoundCondition
|
574
|
+
class Include < CompoundCondition #:nodoc:
|
465
575
|
def initialize( field_name, search_term, domain_class )
|
466
576
|
begin_cond = Like.new(
|
467
577
|
field_name, search_term + ',', domain_class, Like::POST_ONLY
|
@@ -483,7 +593,8 @@ module Lafcadio
|
|
483
593
|
unless args.size == 1
|
484
594
|
h = args.last
|
485
595
|
@order_by = h[:order_by]
|
486
|
-
@order_by_order = h[:order_by_order]
|
596
|
+
@order_by_order = ( h[:order_by_order] or ASC )
|
597
|
+
@limit = h[:limit]
|
487
598
|
end
|
488
599
|
end
|
489
600
|
|
@@ -493,6 +604,7 @@ module Lafcadio
|
|
493
604
|
query = Query.new( @domain_class, condition )
|
494
605
|
query.order_by = @order_by
|
495
606
|
query.order_by_order = @order_by_order
|
607
|
+
query.limit = @limit
|
496
608
|
query
|
497
609
|
end
|
498
610
|
end
|
@@ -505,8 +617,12 @@ module Lafcadio
|
|
505
617
|
def initialize(
|
506
618
|
fieldName, searchTerm, domain_class, matchType = PRE_AND_POST
|
507
619
|
)
|
620
|
+
if searchTerm.is_a? Regexp
|
621
|
+
searchTerm = process_regexp searchTerm
|
622
|
+
else
|
623
|
+
@matchType = matchType
|
624
|
+
end
|
508
625
|
super fieldName, searchTerm, domain_class
|
509
|
-
@matchType = matchType
|
510
626
|
end
|
511
627
|
|
512
628
|
def dobj_satisfies?(anObj)
|
@@ -518,6 +634,19 @@ module Lafcadio
|
|
518
634
|
!regexp.match( value ).nil?
|
519
635
|
end
|
520
636
|
end
|
637
|
+
|
638
|
+
def process_regexp( searchTerm )
|
639
|
+
if searchTerm.source =~ /^\^(.*)/
|
640
|
+
@matchType = Query::Like::POST_ONLY
|
641
|
+
$1
|
642
|
+
elsif searchTerm.source =~ /(.*)\$$/
|
643
|
+
@matchType = Query::Like::PRE_ONLY
|
644
|
+
$1
|
645
|
+
else
|
646
|
+
@matchType = Query::Like::PRE_AND_POST
|
647
|
+
searchTerm.source
|
648
|
+
end
|
649
|
+
end
|
521
650
|
|
522
651
|
def regexp
|
523
652
|
if @matchType == PRE_AND_POST
|
@@ -551,9 +680,9 @@ module Lafcadio
|
|
551
680
|
end
|
552
681
|
|
553
682
|
def collect( coll )
|
554
|
-
max = coll.inject(
|
683
|
+
max = coll.inject( nil ) { |max, d_obj|
|
555
684
|
a_value = d_obj.send @field_name
|
556
|
-
( a_value > max ) ? a_value : max
|
685
|
+
( max.nil? || a_value > max ) ? a_value : max
|
557
686
|
}
|
558
687
|
[ result_row( [max] ) ]
|
559
688
|
end
|
@@ -598,32 +727,34 @@ module Lafcadio
|
|
598
727
|
@field_name = class_field.name
|
599
728
|
end
|
600
729
|
|
730
|
+
def &( condition ); Query.And( to_condition, condition ); end
|
731
|
+
|
732
|
+
def |( condition ); Query.Or( to_condition, condition ); end
|
733
|
+
|
601
734
|
def method_missing( methId, *args )
|
602
735
|
methodName = methId.id2name
|
603
736
|
if self.class.comparators.keys.include?( methodName )
|
604
|
-
|
737
|
+
compare_condition( methodName, *args )
|
605
738
|
else
|
606
|
-
super
|
739
|
+
super
|
607
740
|
end
|
608
741
|
end
|
609
742
|
|
610
|
-
def
|
611
|
-
|
612
|
-
def &( condition ); Query.And( to_condition, condition ); end
|
613
|
-
|
614
|
-
def register_compare_condition( compareStr, searchTerm)
|
743
|
+
def compare_condition( compareStr, searchTerm)
|
615
744
|
compareVal = ObjectFieldImpostor.comparators[compareStr]
|
616
|
-
Compare.new( @field_name, searchTerm,
|
617
|
-
@domainObjectImpostor.domain_class, compareVal )
|
745
|
+
Compare.new( @field_name, searchTerm, domain_class, compareVal )
|
618
746
|
end
|
619
747
|
|
748
|
+
def domain_class; @domainObjectImpostor.domain_class; end
|
749
|
+
|
620
750
|
def equals( searchTerm )
|
621
|
-
Equals.new(
|
622
|
-
|
751
|
+
Equals.new(
|
752
|
+
@field_name, field_or_field_name( searchTerm ), domain_class
|
753
|
+
)
|
623
754
|
end
|
624
755
|
|
625
756
|
def field_or_field_name( search_term )
|
626
|
-
if search_term.
|
757
|
+
if search_term.is_a? ObjectFieldImpostor
|
627
758
|
search_term.class_field
|
628
759
|
else
|
629
760
|
search_term
|
@@ -631,9 +762,8 @@ module Lafcadio
|
|
631
762
|
end
|
632
763
|
|
633
764
|
def include?( search_term )
|
634
|
-
if @class_field.
|
635
|
-
Include.new( @field_name, search_term,
|
636
|
-
@domainObjectImpostor.domain_class )
|
765
|
+
if @class_field.is_a?( TextListField )
|
766
|
+
Include.new( @field_name, search_term, domain_class )
|
637
767
|
else
|
638
768
|
raise ArgumentError
|
639
769
|
end
|
@@ -641,18 +771,7 @@ module Lafcadio
|
|
641
771
|
|
642
772
|
def like( regexp )
|
643
773
|
if regexp.is_a?( Regexp )
|
644
|
-
|
645
|
-
searchTerm = $1
|
646
|
-
matchType = Query::Like::POST_ONLY
|
647
|
-
elsif regexp.source =~ /(.*)\$$/
|
648
|
-
searchTerm = $1
|
649
|
-
matchType = Query::Like::PRE_ONLY
|
650
|
-
else
|
651
|
-
searchTerm = regexp.source
|
652
|
-
matchType = Query::Like::PRE_AND_POST
|
653
|
-
end
|
654
|
-
Query::Like.new( @field_name, searchTerm,
|
655
|
-
@domainObjectImpostor.domain_class, matchType )
|
774
|
+
Query::Like.new( @field_name, regexp, domain_class )
|
656
775
|
else
|
657
776
|
raise(
|
658
777
|
ArgumentError, "#{ @field_name }#like needs to receive a Regexp",
|
@@ -662,16 +781,14 @@ module Lafcadio
|
|
662
781
|
end
|
663
782
|
|
664
783
|
def in( *searchTerms )
|
665
|
-
Query::In.new( @field_name, searchTerms,
|
666
|
-
@domainObjectImpostor.domain_class )
|
784
|
+
Query::In.new( @field_name, searchTerms, domain_class )
|
667
785
|
end
|
668
786
|
|
669
787
|
def nil?; equals( nil ); end
|
670
788
|
|
671
789
|
def to_condition
|
672
790
|
if @class_field.instance_of?( BooleanField )
|
673
|
-
Query::Equals.new( @field_name, true,
|
674
|
-
@domainObjectImpostor.domain_class )
|
791
|
+
Query::Equals.new( @field_name, true, domain_class )
|
675
792
|
else
|
676
793
|
raise
|
677
794
|
end
|