lafcadio 0.7.3 → 0.7.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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