lafcadio 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/lafcadio.rb +1 -1
- data/lib/lafcadio.rb~ +1 -1
- data/lib/lafcadio/domain.rb +363 -255
- data/lib/lafcadio/domain.rb~ +201 -230
- data/lib/lafcadio/mock.rb +64 -70
- data/lib/lafcadio/mock.rb~ +48 -49
- data/lib/lafcadio/objectField.rb +137 -127
- data/lib/lafcadio/objectField.rb~ +7 -7
- data/lib/lafcadio/objectStore.rb +560 -586
- data/lib/lafcadio/objectStore.rb~ +495 -536
- data/lib/lafcadio/query.rb +320 -213
- data/lib/lafcadio/query.rb~ +129 -131
- data/lib/lafcadio/schema.rb +10 -14
- data/lib/lafcadio/schema.rb~ +1 -1
- data/lib/lafcadio/test.rb +174 -75
- data/lib/lafcadio/test.rb~ +191 -0
- data/lib/lafcadio/util.rb +1 -32
- data/lib/lafcadio/util.rb~ +1 -6
- metadata +2 -2
data/lib/lafcadio/query.rb~
CHANGED
@@ -110,11 +110,11 @@ module Lafcadio
|
|
110
110
|
@domain_class, @opts = domain_class, opts
|
111
111
|
( @condition, @order_by, @limit ) = [ nil, nil, nil ]
|
112
112
|
if pk_id_or_condition
|
113
|
-
if pk_id_or_condition.
|
113
|
+
if pk_id_or_condition.is_a?( Condition )
|
114
114
|
@condition = pk_id_or_condition
|
115
115
|
else
|
116
116
|
@condition = Query::Equals.new(
|
117
|
-
|
117
|
+
:pk_id, pk_id_or_condition, domain_class
|
118
118
|
)
|
119
119
|
end
|
120
120
|
end
|
@@ -133,52 +133,50 @@ module Lafcadio
|
|
133
133
|
|
134
134
|
def compound( comp_type, action )
|
135
135
|
rquery = Query.infer( @domain_class ) { |dobj| action.call( dobj ) }
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
Query::CompoundCondition.new(
|
137
|
+
@condition, rquery.condition, comp_type
|
138
|
+
).query
|
139
139
|
end
|
140
140
|
|
141
|
-
def
|
141
|
+
def dobj_satisfies?( dobj )
|
142
|
+
@condition.nil? or @condition.dobj_satisfies?( dobj )
|
143
|
+
end
|
144
|
+
|
145
|
+
def eql?( other ); other.is_a?( Query ) && other.to_sql == to_sql; end
|
142
146
|
|
143
147
|
def fields; @opts[:group_functions] == [:count] ? 'count(*)' : '*'; end
|
144
148
|
|
145
149
|
def hash; to_sql.hash; end
|
146
150
|
|
151
|
+
def implies?( other_query )
|
152
|
+
if other_query == self
|
153
|
+
true
|
154
|
+
elsif @domain_class == other_query.domain_class
|
155
|
+
if other_query.condition.nil? and !self.condition.nil?
|
156
|
+
true
|
157
|
+
else
|
158
|
+
self.condition and self.condition.implies?( other_query.condition )
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
147
163
|
def limit_clause
|
148
164
|
"limit #{ @limit.begin }, #{ @limit.end - @limit.begin + 1 }" if @limit
|
149
165
|
end
|
150
166
|
|
151
|
-
def object_meets( dobj ); @condition.object_meets( dobj ); end
|
152
|
-
|
153
167
|
def or( &action ); compound( CompoundCondition::OR, action ); end
|
154
168
|
|
155
169
|
def order_clause
|
156
170
|
if @order_by
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
}.join( ', ' )
|
161
|
-
else
|
162
|
-
field_str = @domain_class.get_field( @order_by ).db_field_name
|
163
|
-
end
|
171
|
+
field_str = @order_by.map { |f_name|
|
172
|
+
@domain_class.field( f_name.to_s ).db_field_name
|
173
|
+
}.join( ', ' )
|
164
174
|
clause = "order by #{ field_str } "
|
165
175
|
clause += @order_by_order == ASC ? 'asc' : 'desc'
|
166
176
|
clause
|
167
177
|
end
|
168
178
|
end
|
169
179
|
|
170
|
-
def implies?( other_query )
|
171
|
-
if other_query == self
|
172
|
-
true
|
173
|
-
elsif @domain_class == other_query.domain_class
|
174
|
-
if other_query.condition.nil? and !self.condition.nil?
|
175
|
-
true
|
176
|
-
else
|
177
|
-
self.condition and self.condition.implies?( other_query.condition )
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
|
182
180
|
def result_row( row )
|
183
181
|
if @opts[:group_functions] == [:count]
|
184
182
|
{ :count => row.first }
|
@@ -219,7 +217,7 @@ module Lafcadio
|
|
219
217
|
where_clauses << @condition.to_sql if @condition
|
220
218
|
end
|
221
219
|
}
|
222
|
-
where_clauses.
|
220
|
+
!where_clauses.empty? ? 'where ' + where_clauses.join( ' and ' ) : nil
|
223
221
|
end
|
224
222
|
|
225
223
|
class Condition #:nodoc:
|
@@ -230,19 +228,20 @@ module Lafcadio
|
|
230
228
|
attr_reader :domain_class
|
231
229
|
|
232
230
|
def initialize(fieldName, searchTerm, domain_class)
|
233
|
-
@fieldName =
|
234
|
-
|
235
|
-
unless @searchTerm.
|
231
|
+
@fieldName, @searchTerm, @domain_class =
|
232
|
+
fieldName, searchTerm, domain_class
|
233
|
+
unless @searchTerm.is_a?( self.class.search_term_type )
|
236
234
|
raise "Incorrect searchTerm type #{ searchTerm.class }"
|
237
235
|
end
|
238
|
-
@domain_class
|
239
|
-
|
240
|
-
unless @domain_class <= DomainObject
|
241
|
-
raise "Incorrect object type #{ @domain_class.to_s }"
|
242
|
-
end
|
236
|
+
if @domain_class and !( @domain_class < DomainObject )
|
237
|
+
raise "Incorrect object type #{ @domain_class.to_s }"
|
243
238
|
end
|
244
239
|
end
|
245
240
|
|
241
|
+
def |( other_cond ); Query.Or( self, other_cond ); end
|
242
|
+
|
243
|
+
def &( other_cond ); Query.And( self, other_cond ); end
|
244
|
+
|
246
245
|
def implies?( other_condition )
|
247
246
|
self.eql?( other_condition ) or (
|
248
247
|
other_condition.respond_to?( :implied_by? ) and
|
@@ -250,22 +249,28 @@ module Lafcadio
|
|
250
249
|
)
|
251
250
|
end
|
252
251
|
|
253
|
-
def db_field_name;
|
252
|
+
def db_field_name; field.db_column; end
|
254
253
|
|
255
254
|
def eql?( other_cond )
|
256
255
|
other_cond.is_a?( Condition ) and other_cond.to_sql == to_sql
|
257
256
|
end
|
258
257
|
|
259
|
-
def
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
258
|
+
def field
|
259
|
+
f = @domain_class.field @fieldName.to_s
|
260
|
+
f or raise(
|
261
|
+
MissingError,
|
262
|
+
"Couldn't find field \"#{ @fieldName }\" in " + @domain_class.name +
|
263
|
+
" domain class",
|
264
|
+
caller
|
265
|
+
)
|
265
266
|
end
|
267
|
+
|
268
|
+
def not; Query::Not.new( self ); end
|
266
269
|
|
267
270
|
def primary_key_field?; 'pk_id' == @fieldName; end
|
268
271
|
|
272
|
+
def query; Query.new( @domain_class, self ); end
|
273
|
+
|
269
274
|
def to_condition; self; end
|
270
275
|
end
|
271
276
|
|
@@ -294,17 +299,7 @@ module Lafcadio
|
|
294
299
|
@compareType = compareType
|
295
300
|
end
|
296
301
|
|
297
|
-
def
|
298
|
-
if ( get_field.kind_of?( DomainObjectField ) &&
|
299
|
-
!@searchTerm.respond_to?( :pk_id ) )
|
300
|
-
search_val = @searchTerm.to_s
|
301
|
-
else
|
302
|
-
search_val = get_field.value_for_sql( @searchTerm ).to_s
|
303
|
-
end
|
304
|
-
"#{ db_field_name } #{ @@comparators[@compareType] } " + search_val
|
305
|
-
end
|
306
|
-
|
307
|
-
def object_meets(anObj)
|
302
|
+
def dobj_satisfies?(anObj)
|
308
303
|
value = anObj.send @fieldName
|
309
304
|
value = value.pk_id if value.class <= DomainObject
|
310
305
|
if value
|
@@ -313,6 +308,16 @@ module Lafcadio
|
|
313
308
|
false
|
314
309
|
end
|
315
310
|
end
|
311
|
+
|
312
|
+
def to_sql
|
313
|
+
if ( field.kind_of?( DomainObjectField ) &&
|
314
|
+
!@searchTerm.respond_to?( :pk_id ) )
|
315
|
+
search_val = @searchTerm.to_s
|
316
|
+
else
|
317
|
+
search_val = field.value_for_sql( @searchTerm ).to_s
|
318
|
+
end
|
319
|
+
"#{ db_field_name } #{ @@comparators[@compareType] } #{ search_val }"
|
320
|
+
end
|
316
321
|
end
|
317
322
|
|
318
323
|
class CompoundCondition < Condition #:nodoc:
|
@@ -320,7 +325,7 @@ module Lafcadio
|
|
320
325
|
OR = 2
|
321
326
|
|
322
327
|
def initialize( *args )
|
323
|
-
if( [ AND, OR ].
|
328
|
+
if( [ AND, OR ].include?( args.last ) )
|
324
329
|
@compound_type = args.last
|
325
330
|
args.pop
|
326
331
|
else
|
@@ -332,6 +337,18 @@ module Lafcadio
|
|
332
337
|
@domain_class = @conditions[0].domain_class
|
333
338
|
end
|
334
339
|
|
340
|
+
def dobj_satisfies?(anObj)
|
341
|
+
if @compound_type == AND
|
342
|
+
@conditions.inject( true ) { |result, cond|
|
343
|
+
result && cond.dobj_satisfies?( anObj )
|
344
|
+
}
|
345
|
+
else
|
346
|
+
@conditions.inject( false ) { |result, cond|
|
347
|
+
result || cond.dobj_satisfies?( anObj )
|
348
|
+
}
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
335
352
|
def implied_by?( other_condition )
|
336
353
|
@compound_type == OR && @conditions.any? { |cond|
|
337
354
|
cond.implies?( other_condition )
|
@@ -341,27 +358,15 @@ module Lafcadio
|
|
341
358
|
def implies?( other_condition )
|
342
359
|
super( other_condition ) or (
|
343
360
|
@compound_type == AND and @conditions.any? { |cond|
|
344
|
-
cond.implies?
|
361
|
+
cond.implies? other_condition
|
345
362
|
}
|
346
363
|
) or (
|
347
364
|
@compound_type == OR and @conditions.all? { |cond|
|
348
|
-
cond.implies?
|
365
|
+
cond.implies? other_condition
|
349
366
|
}
|
350
367
|
)
|
351
368
|
end
|
352
369
|
|
353
|
-
def object_meets(anObj)
|
354
|
-
if @compound_type == AND
|
355
|
-
@conditions.inject( true ) { |result, cond|
|
356
|
-
result && cond.object_meets( anObj )
|
357
|
-
}
|
358
|
-
else
|
359
|
-
@conditions.inject( false ) { |result, cond|
|
360
|
-
result || cond.object_meets( anObj )
|
361
|
-
}
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
370
|
def to_sql
|
366
371
|
booleanString = @compound_type == AND ? 'and' : 'or'
|
367
372
|
subSqlStrings = @conditions.collect { |cond| cond.to_sql }
|
@@ -382,10 +387,9 @@ module Lafcadio
|
|
382
387
|
|
383
388
|
def method_missing( methId, *args )
|
384
389
|
fieldName = methId.id2name
|
385
|
-
|
386
|
-
classField = self.domain_class.get_field( fieldName )
|
390
|
+
if ( classField = self.domain_class.field( fieldName ) )
|
387
391
|
ObjectFieldImpostor.new( self, classField )
|
388
|
-
|
392
|
+
else
|
389
393
|
super( methId, *args )
|
390
394
|
end
|
391
395
|
end
|
@@ -406,10 +410,18 @@ module Lafcadio
|
|
406
410
|
end
|
407
411
|
|
408
412
|
class Equals < Condition #:nodoc:
|
413
|
+
def dobj_satisfies?(anObj)
|
414
|
+
if @searchTerm.is_a?( ObjectField )
|
415
|
+
compare_value = anObj.send @searchTerm.name
|
416
|
+
else
|
417
|
+
compare_value = @searchTerm
|
418
|
+
end
|
419
|
+
compare_value == anObj.send( @fieldName )
|
420
|
+
end
|
421
|
+
|
409
422
|
def r_val_string
|
410
|
-
|
411
|
-
|
412
|
-
@searchTerm.db_table_and_field_name
|
423
|
+
if @searchTerm.is_a?( ObjectField )
|
424
|
+
@searchTerm.db_column
|
413
425
|
else
|
414
426
|
begin
|
415
427
|
field.value_for_sql( @searchTerm ).to_s
|
@@ -424,38 +436,22 @@ module Lafcadio
|
|
424
436
|
end
|
425
437
|
end
|
426
438
|
|
427
|
-
def object_meets(anObj)
|
428
|
-
if @searchTerm.class <= ObjectField
|
429
|
-
compare_value = anObj.send( @searchTerm.name )
|
430
|
-
else
|
431
|
-
compare_value = @searchTerm
|
432
|
-
end
|
433
|
-
compare_value == anObj.send( @fieldName )
|
434
|
-
end
|
435
|
-
|
436
439
|
def to_sql
|
437
440
|
sql = "#{ db_field_name } "
|
438
|
-
|
439
|
-
sql += "= " + r_val_string
|
440
|
-
else
|
441
|
-
sql += "is null"
|
442
|
-
end
|
441
|
+
sql += ( !@searchTerm.nil? ? "= #{ r_val_string }" : "is null" )
|
443
442
|
sql
|
444
443
|
end
|
445
444
|
end
|
446
445
|
|
447
446
|
class In < Condition #:nodoc:
|
448
|
-
def self.search_term_type
|
449
|
-
Array
|
450
|
-
end
|
447
|
+
def self.search_term_type; Array; end
|
451
448
|
|
452
|
-
def
|
453
|
-
|
454
|
-
@searchTerm.index(value) != nil
|
449
|
+
def dobj_satisfies?(anObj)
|
450
|
+
@searchTerm.include?( anObj.send( @fieldName ) )
|
455
451
|
end
|
456
452
|
|
457
453
|
def to_sql
|
458
|
-
if
|
454
|
+
if field.is_a?( StringField )
|
459
455
|
quoted = @searchTerm.map do |str| "'#{ str }'"; end
|
460
456
|
end_clause = quoted.join ', '
|
461
457
|
else
|
@@ -467,12 +463,15 @@ module Lafcadio
|
|
467
463
|
|
468
464
|
class Include < CompoundCondition
|
469
465
|
def initialize( field_name, search_term, domain_class )
|
470
|
-
begin_cond = Like.new(
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
466
|
+
begin_cond = Like.new(
|
467
|
+
field_name, search_term + ',', domain_class, Like::POST_ONLY
|
468
|
+
)
|
469
|
+
mid_cond = Like.new(
|
470
|
+
field_name, ',' + search_term + ',', domain_class
|
471
|
+
)
|
472
|
+
end_cond = Like.new(
|
473
|
+
field_name, ',' + search_term, domain_class, Like::PRE_ONLY
|
474
|
+
)
|
476
475
|
only_cond = Equals.new( field_name, search_term, domain_class )
|
477
476
|
super( begin_cond, mid_cond, end_cond, only_cond, OR )
|
478
477
|
end
|
@@ -489,7 +488,7 @@ module Lafcadio
|
|
489
488
|
end
|
490
489
|
|
491
490
|
def execute
|
492
|
-
impostor = DomainObjectImpostor.impostor
|
491
|
+
impostor = DomainObjectImpostor.impostor @domain_class
|
493
492
|
condition = @action.call( impostor ).to_condition
|
494
493
|
query = Query.new( @domain_class, condition )
|
495
494
|
query.order_by = @order_by
|
@@ -504,12 +503,23 @@ module Lafcadio
|
|
504
503
|
POST_ONLY = 3
|
505
504
|
|
506
505
|
def initialize(
|
507
|
-
|
506
|
+
fieldName, searchTerm, domain_class, matchType = PRE_AND_POST
|
507
|
+
)
|
508
508
|
super fieldName, searchTerm, domain_class
|
509
509
|
@matchType = matchType
|
510
510
|
end
|
511
511
|
|
512
|
-
def
|
512
|
+
def dobj_satisfies?(anObj)
|
513
|
+
value = anObj.send @fieldName
|
514
|
+
value = value.pk_id.to_s if value.respond_to?( :pk_id )
|
515
|
+
if value.is_a?( Array )
|
516
|
+
value.include? @searchTerm
|
517
|
+
else
|
518
|
+
!regexp.match( value ).nil?
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
def regexp
|
513
523
|
if @matchType == PRE_AND_POST
|
514
524
|
Regexp.new( @searchTerm, Regexp::IGNORECASE )
|
515
525
|
elsif @matchType == PRE_ONLY
|
@@ -519,18 +529,6 @@ module Lafcadio
|
|
519
529
|
end
|
520
530
|
end
|
521
531
|
|
522
|
-
def object_meets(anObj)
|
523
|
-
value = anObj.send @fieldName
|
524
|
-
if value.class <= DomainObject || value.class == DomainObjectProxy
|
525
|
-
value = value.pk_id.to_s
|
526
|
-
end
|
527
|
-
if value.class <= Array
|
528
|
-
(value.index(@searchTerm) != nil)
|
529
|
-
else
|
530
|
-
get_regexp.match(value) != nil
|
531
|
-
end
|
532
|
-
end
|
533
|
-
|
534
532
|
def to_sql
|
535
533
|
withWildcards = @searchTerm
|
536
534
|
if @matchType == PRE_AND_POST
|
@@ -553,15 +551,15 @@ module Lafcadio
|
|
553
551
|
end
|
554
552
|
|
555
553
|
def collect( coll )
|
556
|
-
max = coll.inject(
|
557
|
-
a_value = d_obj.send
|
558
|
-
(
|
554
|
+
max = coll.inject( coll.first ) { |max, d_obj|
|
555
|
+
a_value = d_obj.send @field_name
|
556
|
+
( a_value > max ) ? a_value : max
|
559
557
|
}
|
560
558
|
[ result_row( [max] ) ]
|
561
559
|
end
|
562
560
|
|
563
561
|
def fields
|
564
|
-
"max(#{ @domain_class.
|
562
|
+
"max(#{ @domain_class.field( @field_name ).db_field_name })"
|
565
563
|
end
|
566
564
|
|
567
565
|
def result_row( row ); { :max => row.first }; end
|
@@ -572,8 +570,8 @@ module Lafcadio
|
|
572
570
|
@unCondition = unCondition
|
573
571
|
end
|
574
572
|
|
575
|
-
def
|
576
|
-
!@unCondition.
|
573
|
+
def dobj_satisfies?(obj)
|
574
|
+
!@unCondition.dobj_satisfies?(obj)
|
577
575
|
end
|
578
576
|
|
579
577
|
def domain_class; @unCondition.domain_class; end
|
@@ -594,25 +592,25 @@ module Lafcadio
|
|
594
592
|
|
595
593
|
attr_reader :class_field
|
596
594
|
|
597
|
-
def initialize( domainObjectImpostor,
|
595
|
+
def initialize( domainObjectImpostor, class_field )
|
598
596
|
@domainObjectImpostor = domainObjectImpostor
|
599
|
-
|
600
|
-
|
601
|
-
else
|
602
|
-
@class_field = class_field_or_name
|
603
|
-
@field_name = class_field_or_name.name
|
604
|
-
end
|
597
|
+
@class_field = class_field
|
598
|
+
@field_name = class_field.name
|
605
599
|
end
|
606
600
|
|
607
601
|
def method_missing( methId, *args )
|
608
602
|
methodName = methId.id2name
|
609
|
-
if
|
603
|
+
if self.class.comparators.keys.include?( methodName )
|
610
604
|
register_compare_condition( methodName, *args )
|
611
605
|
else
|
612
606
|
super( methId, *args )
|
613
607
|
end
|
614
608
|
end
|
615
609
|
|
610
|
+
def |( condition ); Query.Or( to_condition, condition ); end
|
611
|
+
|
612
|
+
def &( condition ); Query.And( to_condition, condition ); end
|
613
|
+
|
616
614
|
def register_compare_condition( compareStr, searchTerm)
|
617
615
|
compareVal = ObjectFieldImpostor.comparators[compareStr]
|
618
616
|
Compare.new( @field_name, searchTerm,
|