lafcadio 0.7.3 → 0.7.4

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.
@@ -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
- if query.field_name != query.domain_class.sql_primary_key_name
133
- a_field = query.domain_class.get_field( query.field_name )
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 LinkFields. In terms of +domain_class+
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 = English.singular(
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
- if query.field_name != query.domain_class.sql_primary_key_name
133
- a_field = query.domain_class.get_field( query.field_name )
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 LinkFields. In terms of +domain_class+
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
- fieldName = get_field_name( searchTerm ) unless fieldName
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 = English.singular(
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 )
@@ -274,7 +274,7 @@ module Lafcadio
274
274
  end
275
275
 
276
276
  def to_sql
277
- if ( get_field.kind_of?( LinkField ) &&
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
- class DomainObjectImpostor #:nodoc:
352
- attr_reader :domain_class
353
-
354
- def initialize( domain_class )
355
- @domain_class = domain_class
356
- end
351
+ module DomainObjectImpostor #:nodoc:
352
+ @@impostor_classes = {}
357
353
 
358
- def method_missing( methId, *args )
359
- fieldName = methId.id2name
360
- begin
361
- classField = @domain_class.get_field( fieldName )
362
- ObjectFieldImpostor.new( self, classField )
363
- rescue MissingError
364
- super( methId, *args )
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
- "#{ db_field_name } in (#{ @searchTerm.join(', ') })"
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.new( @domain_class )
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,
@@ -274,7 +274,7 @@ module Lafcadio
274
274
  end
275
275
 
276
276
  def to_sql
277
- if ( get_field.kind_of?( LinkField ) &&
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(*conditions)
302
- if( [ AND, OR ].index(conditions.last) )
303
- @compound_type = conditions.last
304
- conditions.pop
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 = conditions
309
- @domain_class = conditions[0].domain_class
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
- class DomainObjectImpostor #:nodoc:
350
- attr_reader :domain_class
351
-
352
- def initialize( domain_class )
353
- @domain_class = domain_class
354
- end
351
+ module DomainObjectImpostor #:nodoc:
352
+ @@impostor_classes = {}
355
353
 
356
- def method_missing( methId, *args )
357
- fieldName = methId.id2name
358
- begin
359
- classField = @domain_class.get_field( fieldName )
360
- ObjectFieldImpostor.new( self, classField )
361
- rescue MissingError
362
- super( methId, *args )
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
- "#{ db_field_name } in (#{ @searchTerm.join(', ') })"
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.new( @domain_class )
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,
@@ -3,7 +3,7 @@ require 'lafcadio/objectField'
3
3
  module Lafcadio
4
4
  class CreateTableStatement #:nodoc:
5
5
  @@simple_field_clauses = {
6
- DecimalField => 'float', DateField => 'date', BooleanField => 'bool',
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 <= TextField || field.class <= TextListField )
45
+ elsif ( field.class <= StringField || field.class <= TextListField )
46
46
  'varchar(255)'
47
- elsif ( field.class <= LinkField || field.class <= IntegerField )
47
+ elsif ( field.class <= DomainObjectField || field.class <= IntegerField )
48
48
  'int'
49
- elsif ( field.class <= DecimalField )
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