lafcadio 0.9.0 → 0.9.1
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 +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,
|