lafcadio 0.7.3 → 0.7.4
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/lafcadio.rb +1 -2
- data/lib/lafcadio.rb~ +1 -2
- data/lib/lafcadio/dateTime.rb~ +3 -3
- data/lib/lafcadio/depend.rb +5 -1
- data/lib/lafcadio/depend.rb~ +8 -0
- data/lib/lafcadio/domain.rb +92 -27
- data/lib/lafcadio/domain.rb~ +103 -27
- data/lib/lafcadio/mock.rb +28 -13
- data/lib/lafcadio/mock.rb~ +8 -4
- data/lib/lafcadio/objectField.rb +103 -103
- data/lib/lafcadio/objectField.rb~ +102 -99
- data/lib/lafcadio/objectStore.rb +11 -15
- data/lib/lafcadio/objectStore.rb~ +12 -14
- data/lib/lafcadio/query.rb +42 -16
- data/lib/lafcadio/query.rb~ +44 -23
- data/lib/lafcadio/schema.rb +4 -4
- data/lib/lafcadio/schema.rb~ +56 -0
- data/lib/lafcadio/test.rb +1 -1
- data/lib/lafcadio/test.rb~ +6 -1
- data/lib/lafcadio/util.rb +14 -297
- data/lib/lafcadio/util.rb~ +25 -210
- metadata +48 -6
- data/lib/lafcadio/dateTime.rb +0 -93
data/lib/lafcadio/objectStore.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'dbi'
|
2
|
+
require 'lafcadio/depend'
|
2
3
|
require 'lafcadio/domain'
|
3
4
|
require 'lafcadio/query'
|
4
5
|
require 'lafcadio/util'
|
@@ -11,9 +12,10 @@ module Lafcadio
|
|
11
12
|
|
12
13
|
attr_reader :commit_type, :db_object
|
13
14
|
|
14
|
-
def initialize(db_object, dbBridge)
|
15
|
+
def initialize(db_object, dbBridge, cache)
|
15
16
|
@db_object = db_object
|
16
17
|
@dbBridge = dbBridge
|
18
|
+
@cache = cache
|
17
19
|
@objectStore = ObjectStore.get_object_store
|
18
20
|
@commit_type = nil
|
19
21
|
end
|
@@ -28,6 +30,7 @@ module Lafcadio
|
|
28
30
|
unless @db_object.pk_id
|
29
31
|
@db_object.pk_id = @dbBridge.last_pk_id_inserted
|
30
32
|
end
|
33
|
+
@cache.update_after_commit self
|
31
34
|
@db_object.post_commit_trigger
|
32
35
|
end
|
33
36
|
|
@@ -129,12 +132,8 @@ module Lafcadio
|
|
129
132
|
|
130
133
|
def group_query( query )
|
131
134
|
execute_select( query.to_sql )[0].collect { |val|
|
132
|
-
|
133
|
-
|
134
|
-
a_field.value_from_sql( val )
|
135
|
-
else
|
136
|
-
val.to_i
|
137
|
-
end
|
135
|
+
a_field = query.domain_class.get_field( query.field_name )
|
136
|
+
a_field.value_from_sql( val )
|
138
137
|
}
|
139
138
|
end
|
140
139
|
|
@@ -153,7 +152,7 @@ module Lafcadio
|
|
153
152
|
end
|
154
153
|
end
|
155
154
|
|
156
|
-
class DbConnection < ContextualService
|
155
|
+
class DbConnection < ContextualService::Service
|
157
156
|
@@connectionClass = DBI
|
158
157
|
@@db_name = nil
|
159
158
|
@@dbh = nil
|
@@ -206,7 +205,7 @@ module Lafcadio
|
|
206
205
|
end
|
207
206
|
|
208
207
|
# The DomainObjectProxy is used when retrieving domain objects that are
|
209
|
-
# linked to other domain objects with
|
208
|
+
# linked to other domain objects with DomainObjectFields. In terms of +domain_class+
|
210
209
|
# and
|
211
210
|
# +pk_id+, a DomainObjectProxy instance looks to the outside world like the
|
212
211
|
# domain object it's supposed to represent. It only retrieves its domain
|
@@ -405,7 +404,7 @@ module Lafcadio
|
|
405
404
|
# Domain classes can be set to fire triggers either before or after commits.
|
406
405
|
# Since these triggers are executed in Ruby, they're easy to test. See
|
407
406
|
# DomainObject#pre_commit_trigger and DomainObject#post_commit_trigger for more.
|
408
|
-
class ObjectStore < ContextualService
|
407
|
+
class ObjectStore < ContextualService::Service
|
409
408
|
def self.set_db_name(dbName) #:nodoc:
|
410
409
|
DbConnection.set_db_name dbName
|
411
410
|
end
|
@@ -546,9 +545,8 @@ module Lafcadio
|
|
546
545
|
end
|
547
546
|
|
548
547
|
def commit( db_object )
|
549
|
-
committer = Committer.new db_object, @dbBridge
|
548
|
+
committer = Committer.new db_object, @dbBridge, self
|
550
549
|
committer.execute
|
551
|
-
update_after_commit( committer )
|
552
550
|
end
|
553
551
|
|
554
552
|
# Flushes a domain object.
|
@@ -704,9 +702,7 @@ module Lafcadio
|
|
704
702
|
begin
|
705
703
|
dispatch_get_singular
|
706
704
|
rescue CouldntMatchDomainClassError
|
707
|
-
domain_class_name =
|
708
|
-
camel_case_method_name_after_get
|
709
|
-
)
|
705
|
+
domain_class_name = camel_case_method_name_after_get.singular
|
710
706
|
begin
|
711
707
|
@domain_class =
|
712
708
|
DomainObject.get_domain_class_from_string( domain_class_name )
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'dbi'
|
2
|
+
require 'lafcadio/depend'
|
2
3
|
require 'lafcadio/domain'
|
3
4
|
require 'lafcadio/query'
|
4
5
|
require 'lafcadio/util'
|
@@ -11,9 +12,10 @@ module Lafcadio
|
|
11
12
|
|
12
13
|
attr_reader :commit_type, :db_object
|
13
14
|
|
14
|
-
def initialize(db_object, dbBridge)
|
15
|
+
def initialize(db_object, dbBridge, cache)
|
15
16
|
@db_object = db_object
|
16
17
|
@dbBridge = dbBridge
|
18
|
+
@cache = cache
|
17
19
|
@objectStore = ObjectStore.get_object_store
|
18
20
|
@commit_type = nil
|
19
21
|
end
|
@@ -28,6 +30,7 @@ module Lafcadio
|
|
28
30
|
unless @db_object.pk_id
|
29
31
|
@db_object.pk_id = @dbBridge.last_pk_id_inserted
|
30
32
|
end
|
33
|
+
@cache.update_after_commit self
|
31
34
|
@db_object.post_commit_trigger
|
32
35
|
end
|
33
36
|
|
@@ -129,12 +132,8 @@ module Lafcadio
|
|
129
132
|
|
130
133
|
def group_query( query )
|
131
134
|
execute_select( query.to_sql )[0].collect { |val|
|
132
|
-
|
133
|
-
|
134
|
-
a_field.value_from_sql( val )
|
135
|
-
else
|
136
|
-
val.to_i
|
137
|
-
end
|
135
|
+
a_field = query.domain_class.get_field( query.field_name )
|
136
|
+
a_field.value_from_sql( val )
|
138
137
|
}
|
139
138
|
end
|
140
139
|
|
@@ -206,7 +205,7 @@ module Lafcadio
|
|
206
205
|
end
|
207
206
|
|
208
207
|
# The DomainObjectProxy is used when retrieving domain objects that are
|
209
|
-
# linked to other domain objects with
|
208
|
+
# linked to other domain objects with DomainObjectFields. In terms of +domain_class+
|
210
209
|
# and
|
211
210
|
# +pk_id+, a DomainObjectProxy instance looks to the outside world like the
|
212
211
|
# domain object it's supposed to represent. It only retrieves its domain
|
@@ -450,7 +449,9 @@ module Lafcadio
|
|
450
449
|
domain_class = DomainObject.get_domain_class_from_string(
|
451
450
|
domain_class_name
|
452
451
|
)
|
453
|
-
|
452
|
+
unless fieldName
|
453
|
+
fieldName = domain_class.get_link_field( searchTerm.domain_class ).name
|
454
|
+
end
|
454
455
|
get_subset( Query::Equals.new( fieldName, searchTerm, domain_class ) )
|
455
456
|
end
|
456
457
|
|
@@ -544,9 +545,8 @@ module Lafcadio
|
|
544
545
|
end
|
545
546
|
|
546
547
|
def commit( db_object )
|
547
|
-
committer = Committer.new db_object, @dbBridge
|
548
|
+
committer = Committer.new db_object, @dbBridge, self
|
548
549
|
committer.execute
|
549
|
-
update_after_commit( committer )
|
550
550
|
end
|
551
551
|
|
552
552
|
# Flushes a domain object.
|
@@ -702,9 +702,7 @@ module Lafcadio
|
|
702
702
|
begin
|
703
703
|
dispatch_get_singular
|
704
704
|
rescue CouldntMatchDomainClassError
|
705
|
-
domain_class_name =
|
706
|
-
camel_case_method_name_after_get
|
707
|
-
)
|
705
|
+
domain_class_name = camel_case_method_name_after_get.singular
|
708
706
|
begin
|
709
707
|
@domain_class =
|
710
708
|
DomainObject.get_domain_class_from_string( domain_class_name )
|
data/lib/lafcadio/query.rb
CHANGED
@@ -274,7 +274,7 @@ module Lafcadio
|
|
274
274
|
end
|
275
275
|
|
276
276
|
def to_sql
|
277
|
-
if ( get_field.kind_of?(
|
277
|
+
if ( get_field.kind_of?( DomainObjectField ) &&
|
278
278
|
!@searchTerm.respond_to?( :pk_id ) )
|
279
279
|
search_val = @searchTerm.to_s
|
280
280
|
else
|
@@ -348,21 +348,39 @@ module Lafcadio
|
|
348
348
|
end
|
349
349
|
end
|
350
350
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
def initialize( domain_class )
|
355
|
-
@domain_class = domain_class
|
356
|
-
end
|
351
|
+
module DomainObjectImpostor #:nodoc:
|
352
|
+
@@impostor_classes = {}
|
357
353
|
|
358
|
-
def
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
354
|
+
def self.impostor( domain_class )
|
355
|
+
unless @@impostor_classes[domain_class]
|
356
|
+
i_class = Class.new
|
357
|
+
i_class.module_eval <<-CLASS_DEF
|
358
|
+
attr_reader :domain_class
|
359
|
+
|
360
|
+
def initialize; @domain_class = #{ domain_class.name }; end
|
361
|
+
|
362
|
+
def method_missing( methId, *args )
|
363
|
+
fieldName = methId.id2name
|
364
|
+
begin
|
365
|
+
classField = self.domain_class.get_field( fieldName )
|
366
|
+
ObjectFieldImpostor.new( self, classField )
|
367
|
+
rescue MissingError
|
368
|
+
super( methId, *args )
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
#{ domain_class.name }.class_fields.each do |class_field|
|
373
|
+
begin
|
374
|
+
undef_method class_field.name.to_sym
|
375
|
+
rescue NameError
|
376
|
+
# not defined globally or in an included Module, skip it
|
377
|
+
end
|
378
|
+
end
|
379
|
+
CLASS_DEF
|
380
|
+
@@impostor_classes[domain_class] = i_class
|
365
381
|
end
|
382
|
+
i_class = @@impostor_classes[domain_class]
|
383
|
+
i_class.new
|
366
384
|
end
|
367
385
|
end
|
368
386
|
|
@@ -416,7 +434,13 @@ module Lafcadio
|
|
416
434
|
end
|
417
435
|
|
418
436
|
def to_sql
|
419
|
-
|
437
|
+
if get_field.is_a?( StringField )
|
438
|
+
quoted = @searchTerm.map do |str| "'#{ str }'"; end
|
439
|
+
end_clause = quoted.join ', '
|
440
|
+
else
|
441
|
+
end_clause = @searchTerm.join ', '
|
442
|
+
end
|
443
|
+
"#{ db_field_name } in (#{ end_clause })"
|
420
444
|
end
|
421
445
|
end
|
422
446
|
|
@@ -439,7 +463,7 @@ module Lafcadio
|
|
439
463
|
end
|
440
464
|
|
441
465
|
def execute
|
442
|
-
impostor = DomainObjectImpostor.
|
466
|
+
impostor = DomainObjectImpostor.impostor( @domain_class )
|
443
467
|
condition = @action.call( impostor ).to_condition
|
444
468
|
query = Query.new( @domain_class, condition )
|
445
469
|
end
|
@@ -613,6 +637,8 @@ module Lafcadio
|
|
613
637
|
@domainObjectImpostor.domain_class )
|
614
638
|
end
|
615
639
|
|
640
|
+
def nil?; equals( nil ); end
|
641
|
+
|
616
642
|
def to_condition
|
617
643
|
if @class_field.instance_of?( BooleanField )
|
618
644
|
Query::Equals.new( @field_name, true,
|
data/lib/lafcadio/query.rb~
CHANGED
@@ -274,7 +274,7 @@ module Lafcadio
|
|
274
274
|
end
|
275
275
|
|
276
276
|
def to_sql
|
277
|
-
if ( get_field.kind_of?(
|
277
|
+
if ( get_field.kind_of?( DomainObjectField ) &&
|
278
278
|
!@searchTerm.respond_to?( :pk_id ) )
|
279
279
|
search_val = @searchTerm.to_s
|
280
280
|
else
|
@@ -298,17 +298,19 @@ module Lafcadio
|
|
298
298
|
AND = 1
|
299
299
|
OR = 2
|
300
300
|
|
301
|
-
def initialize(*
|
302
|
-
if( [ AND, OR ].index(
|
303
|
-
@compound_type =
|
304
|
-
|
301
|
+
def initialize( *args )
|
302
|
+
if( [ AND, OR ].index( args.last) )
|
303
|
+
@compound_type = args.last
|
304
|
+
args.pop
|
305
305
|
else
|
306
306
|
@compound_type = AND
|
307
307
|
end
|
308
|
-
@conditions =
|
309
|
-
|
308
|
+
@conditions = args.map { |arg|
|
309
|
+
arg.respond_to?( :to_condition ) ? arg.to_condition : arg
|
310
|
+
}
|
311
|
+
@domain_class = @conditions[0].domain_class
|
310
312
|
end
|
311
|
-
|
313
|
+
|
312
314
|
def implied_by?( other_condition )
|
313
315
|
@compound_type == OR && @conditions.any? { |cond|
|
314
316
|
cond.implies?( other_condition )
|
@@ -346,21 +348,32 @@ module Lafcadio
|
|
346
348
|
end
|
347
349
|
end
|
348
350
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
def initialize( domain_class )
|
353
|
-
@domain_class = domain_class
|
354
|
-
end
|
351
|
+
module DomainObjectImpostor #:nodoc:
|
352
|
+
@@impostor_classes = {}
|
355
353
|
|
356
|
-
def
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
354
|
+
def self.impostor( domain_class )
|
355
|
+
unless @@impostor_classes[domain_class]
|
356
|
+
i_class = Class.new
|
357
|
+
i_class.module_eval {
|
358
|
+
attr_reader :domain_class
|
359
|
+
|
360
|
+
def initialize; @domain_class = domain_class; end
|
361
|
+
|
362
|
+
def method_missing( methId, *args )
|
363
|
+
fieldName = methId.id2name
|
364
|
+
begin
|
365
|
+
classField = @@domain_class.get_field( fieldName )
|
366
|
+
ObjectFieldImpostor.new( self, classField )
|
367
|
+
rescue MissingError
|
368
|
+
super( methId, *args )
|
369
|
+
end
|
370
|
+
end
|
371
|
+
}
|
372
|
+
@@impostor_classes[domain_class] = i_class
|
363
373
|
end
|
374
|
+
i_class = @@impostor_classes[domain_class]
|
375
|
+
puts i_class.new.domain_class.name
|
376
|
+
i_class.new
|
364
377
|
end
|
365
378
|
end
|
366
379
|
|
@@ -414,7 +427,13 @@ module Lafcadio
|
|
414
427
|
end
|
415
428
|
|
416
429
|
def to_sql
|
417
|
-
|
430
|
+
if get_field.is_a?( StringField )
|
431
|
+
quoted = @searchTerm.map do |str| "'#{ str }'"; end
|
432
|
+
end_clause = quoted.join ', '
|
433
|
+
else
|
434
|
+
end_clause = @searchTerm.join ', '
|
435
|
+
end
|
436
|
+
"#{ db_field_name } in (#{ end_clause })"
|
418
437
|
end
|
419
438
|
end
|
420
439
|
|
@@ -437,7 +456,7 @@ module Lafcadio
|
|
437
456
|
end
|
438
457
|
|
439
458
|
def execute
|
440
|
-
impostor = DomainObjectImpostor.
|
459
|
+
impostor = DomainObjectImpostor.impostor( @domain_class )
|
441
460
|
condition = @action.call( impostor ).to_condition
|
442
461
|
query = Query.new( @domain_class, condition )
|
443
462
|
end
|
@@ -611,6 +630,8 @@ module Lafcadio
|
|
611
630
|
@domainObjectImpostor.domain_class )
|
612
631
|
end
|
613
632
|
|
633
|
+
def nil?; equals( nil ); end
|
634
|
+
|
614
635
|
def to_condition
|
615
636
|
if @class_field.instance_of?( BooleanField )
|
616
637
|
Query::Equals.new( @field_name, true,
|
data/lib/lafcadio/schema.rb
CHANGED
@@ -3,7 +3,7 @@ require 'lafcadio/objectField'
|
|
3
3
|
module Lafcadio
|
4
4
|
class CreateTableStatement #:nodoc:
|
5
5
|
@@simple_field_clauses = {
|
6
|
-
|
6
|
+
FloatField => 'float', DateField => 'date', BooleanField => 'bool',
|
7
7
|
TimeStampField => 'timestamp', DateTimeField => 'datetime'
|
8
8
|
}
|
9
9
|
|
@@ -42,11 +42,11 @@ module Lafcadio
|
|
42
42
|
"'#{ enumValue }'"
|
43
43
|
}
|
44
44
|
"enum( #{ singleQuotedValues.join( ', ' ) } )"
|
45
|
-
elsif ( field.class <=
|
45
|
+
elsif ( field.class <= StringField || field.class <= TextListField )
|
46
46
|
'varchar(255)'
|
47
|
-
elsif ( field.class <=
|
47
|
+
elsif ( field.class <= DomainObjectField || field.class <= IntegerField )
|
48
48
|
'int'
|
49
|
-
elsif ( field.class <=
|
49
|
+
elsif ( field.class <= FloatField )
|
50
50
|
'float(10, 2)'
|
51
51
|
elsif ( field.class <= BlobField )
|
52
52
|
'blob'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'lafcadio/objectField'
|
2
|
+
|
3
|
+
module Lafcadio
|
4
|
+
class CreateTableStatement #:nodoc:
|
5
|
+
@@simple_field_clauses = {
|
6
|
+
FloatField => 'float', DateField => 'date', BooleanField => 'bool',
|
7
|
+
TimeStampField => 'timestamp', TimeField => 'datetime'
|
8
|
+
}
|
9
|
+
|
10
|
+
def initialize( domain_class )
|
11
|
+
@domain_class = domain_class
|
12
|
+
end
|
13
|
+
|
14
|
+
def definition_terms( field )
|
15
|
+
definitionTerms = []
|
16
|
+
definitionTerms << field.db_field_name
|
17
|
+
definitionTerms << type_clause( field )
|
18
|
+
definitionTerms << 'not null' if field.not_null
|
19
|
+
definitionTerms.join( ' ' )
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_sql
|
23
|
+
createDefinitions = []
|
24
|
+
createDefinitions << "#{ @domain_class.sql_primary_key_name } " +
|
25
|
+
"int not null auto_increment"
|
26
|
+
createDefinitions << "primary key (#{ @domain_class.sql_primary_key_name })"
|
27
|
+
@domain_class.class_fields.each { |field|
|
28
|
+
createDefinitions << definition_terms( field )
|
29
|
+
}
|
30
|
+
<<-SQL
|
31
|
+
create table #{ @domain_class.table_name } (
|
32
|
+
#{ createDefinitions.join(",\n ") }
|
33
|
+
);
|
34
|
+
SQL
|
35
|
+
end
|
36
|
+
|
37
|
+
def type_clause( field )
|
38
|
+
if ( type_clause = @@simple_field_clauses[field.class] )
|
39
|
+
type_clause
|
40
|
+
elsif ( field.class <= EnumField )
|
41
|
+
singleQuotedValues = field.enums.keys.collect! { |enumValue|
|
42
|
+
"'#{ enumValue }'"
|
43
|
+
}
|
44
|
+
"enum( #{ singleQuotedValues.join( ', ' ) } )"
|
45
|
+
elsif ( field.class <= StringField || field.class <= TextListField )
|
46
|
+
'varchar(255)'
|
47
|
+
elsif ( field.class <= DomainObjectField || field.class <= IntegerField )
|
48
|
+
'int'
|
49
|
+
elsif ( field.class <= FloatField )
|
50
|
+
'float(10, 2)'
|
51
|
+
elsif ( field.class <= BlobField )
|
52
|
+
'blob'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|