lafcadio 0.8.3 → 0.9.0
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/dateTime.rb~ +93 -0
- data/lib/lafcadio/depend.rb~ +8 -0
- data/lib/lafcadio/domain.rb +127 -120
- data/lib/lafcadio/domain.rb~ +48 -40
- data/lib/lafcadio/mock.rb +9 -12
- data/lib/lafcadio/mock.rb~ +110 -0
- data/lib/lafcadio/objectField.rb +6 -6
- data/lib/lafcadio/objectField.rb~ +564 -0
- data/lib/lafcadio/objectStore.rb +45 -24
- data/lib/lafcadio/objectStore.rb.~1.64.~ +766 -0
- data/lib/lafcadio/objectStore.rb~ +57 -26
- data/lib/lafcadio/query.rb +57 -22
- data/lib/lafcadio/query.rb~ +48 -17
- data/lib/lafcadio/schema.rb~ +56 -0
- data/lib/lafcadio/test.rb +218 -0
- data/lib/lafcadio/test.rb~ +25 -0
- data/lib/lafcadio/test/testconfig.dat~ +13 -0
- data/lib/lafcadio/util.rb +3 -2
- data/lib/lafcadio/util.rb~ +104 -0
- metadata +111 -97
@@ -76,18 +76,18 @@ module Lafcadio
|
|
76
76
|
end
|
77
77
|
|
78
78
|
class DbBridge #:nodoc:
|
79
|
-
@@dbh = nil
|
80
79
|
@@last_pk_id_inserted = nil
|
81
80
|
|
82
81
|
def self._load(aString)
|
83
|
-
aString =~ /
|
84
|
-
|
82
|
+
aString =~ /db_conn:/
|
83
|
+
db_conn_str = $'
|
85
84
|
begin
|
86
|
-
|
85
|
+
db_conn = Marshal.load db_conn_str
|
87
86
|
rescue TypeError
|
88
|
-
|
87
|
+
db_conn = nil
|
89
88
|
end
|
90
|
-
|
89
|
+
DbConnection.set_db_connection db_conn
|
90
|
+
new
|
91
91
|
end
|
92
92
|
|
93
93
|
def initialize
|
@@ -131,10 +131,7 @@ module Lafcadio
|
|
131
131
|
end
|
132
132
|
|
133
133
|
def group_query( query )
|
134
|
-
execute_select( query.to_sql )
|
135
|
-
a_field = query.domain_class.get_field( query.field_name )
|
136
|
-
a_field.value_from_sql( val )
|
137
|
-
}
|
134
|
+
execute_select( query.to_sql ).map { |row| query.result_row( row ) }
|
138
135
|
end
|
139
136
|
|
140
137
|
def last_pk_id_inserted; @@last_pk_id_inserted; end
|
@@ -150,6 +147,34 @@ module Lafcadio
|
|
150
147
|
sqllog.info sql
|
151
148
|
end
|
152
149
|
end
|
150
|
+
|
151
|
+
def transaction( action )
|
152
|
+
tr = Transaction.new @db_conn
|
153
|
+
tr.commit
|
154
|
+
begin
|
155
|
+
action.call tr
|
156
|
+
tr.commit
|
157
|
+
rescue RollbackError
|
158
|
+
# rollback handled by Transaction
|
159
|
+
rescue
|
160
|
+
err_to_raise = $!
|
161
|
+
tr.rollback false
|
162
|
+
raise err_to_raise
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Transaction
|
167
|
+
def initialize( db_conn ); @db_conn = db_conn; end
|
168
|
+
|
169
|
+
def commit; @db_conn.commit; end
|
170
|
+
|
171
|
+
def rollback( raise_error = true )
|
172
|
+
@db_conn.rollback
|
173
|
+
raise RollbackError if raise_error
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
class RollbackError < StandardError; end
|
153
178
|
end
|
154
179
|
|
155
180
|
class DbConnection < ContextualService::Service
|
@@ -186,6 +211,8 @@ module Lafcadio
|
|
186
211
|
end
|
187
212
|
@@dbh = @@connectionClass.connect( dbAndHost, config['dbuser'],
|
188
213
|
config['dbpassword'] )
|
214
|
+
@@dbh['AutoCommit'] = false
|
215
|
+
@@dbh
|
189
216
|
end
|
190
217
|
|
191
218
|
def method_missing( symbol, *args )
|
@@ -280,7 +307,7 @@ module Lafcadio
|
|
280
307
|
value = @obj.send(field.name)
|
281
308
|
unless field.db_will_automatically_write
|
282
309
|
nameValues << field.name_for_sql
|
283
|
-
nameValues <<
|
310
|
+
nameValues <<(field.value_for_sql(value))
|
284
311
|
end
|
285
312
|
if field.bind_write?
|
286
313
|
@bind_values << value
|
@@ -486,7 +513,8 @@ module Lafcadio
|
|
486
513
|
# ObjectStore#get_max( Invoice, "rate" )
|
487
514
|
# will return the highest rate for all invoices.
|
488
515
|
def get_max( domain_class, field_name = 'pk_id' )
|
489
|
-
|
516
|
+
qry = Query::Max.new( domain_class, field_name )
|
517
|
+
@dbBridge.group_query( qry ).only[:max]
|
490
518
|
end
|
491
519
|
|
492
520
|
# Retrieves a collection of domain objects by +pk_id+.
|
@@ -527,6 +555,8 @@ module Lafcadio
|
|
527
555
|
def mock? #:nodoc:
|
528
556
|
false
|
529
557
|
end
|
558
|
+
|
559
|
+
def query( query ); @dbBridge.group_query( query ); end
|
530
560
|
|
531
561
|
def respond_to?( symbol, include_private = false )
|
532
562
|
begin
|
@@ -536,6 +566,8 @@ module Lafcadio
|
|
536
566
|
end
|
537
567
|
end
|
538
568
|
|
569
|
+
def transaction( &action ); @dbBridge.transaction( action ); end
|
570
|
+
|
539
571
|
class Cache #:nodoc:
|
540
572
|
def initialize( dbBridge )
|
541
573
|
@dbBridge = dbBridge
|
@@ -582,21 +614,11 @@ module Lafcadio
|
|
582
614
|
query.implies?( other_query )
|
583
615
|
}
|
584
616
|
if pk_ids
|
585
|
-
|
617
|
+
@collections_by_query[query] = ( pk_ids.collect { |pk_id|
|
586
618
|
get( query.domain_class, pk_id )
|
587
619
|
} ).select { |dobj| query.object_meets( dobj ) }.collect { |dobj|
|
588
620
|
dobj.pk_id
|
589
621
|
}
|
590
|
-
collection = collection[query.limit] if query.limit
|
591
|
-
if ( order_by = query.order_by )
|
592
|
-
collection = collection.sort_by { |pk_id|
|
593
|
-
get( query.domain_class, pk_id ).send( order_by )
|
594
|
-
}
|
595
|
-
collection.reverse! if query.order_by_order == Query::DESC
|
596
|
-
else
|
597
|
-
collection = collection.sort
|
598
|
-
end
|
599
|
-
@collections_by_query[query] = collection
|
600
622
|
elsif @collections_by_query.values
|
601
623
|
newObjects = @dbBridge.get_collection_by_query(query)
|
602
624
|
newObjects.each { |dbObj| save dbObj }
|
@@ -747,18 +769,23 @@ module Lafcadio
|
|
747
769
|
end
|
748
770
|
end
|
749
771
|
|
750
|
-
class SqlValueConverter #:nodoc:
|
772
|
+
class SqlValueConverter < Hash #:nodoc:
|
751
773
|
attr_reader :domain_class, :row_hash
|
752
774
|
|
753
775
|
def initialize( domain_class, row_hash )
|
776
|
+
super()
|
754
777
|
@domain_class = domain_class
|
755
|
-
|
778
|
+
row_hash.each do |key, value| self[key] = value; end
|
756
779
|
end
|
757
780
|
|
758
781
|
def []( key )
|
782
|
+
puts key.inspect
|
759
783
|
begin
|
760
784
|
field = @domain_class.get_field( key )
|
761
|
-
|
785
|
+
sql_value = super field.db_field_name
|
786
|
+
puts sql_value.inspect
|
787
|
+
val = field.value_from_sql sql_value
|
788
|
+
puts val.inspect
|
762
789
|
if field.instance_of?( PrimaryKeyField ) && val.nil?
|
763
790
|
raise FieldMatchError, error_msg, caller
|
764
791
|
else
|
@@ -768,6 +795,10 @@ module Lafcadio
|
|
768
795
|
nil
|
769
796
|
end
|
770
797
|
end
|
798
|
+
|
799
|
+
def each( &action )
|
800
|
+
super do |k, v| puts "#{ k } #{ v }"; action.call( k, self[k] ); end
|
801
|
+
end
|
771
802
|
|
772
803
|
def error_msg
|
773
804
|
"The field \"" + @domain_class.sql_primary_key_name +
|
data/lib/lafcadio/query.rb
CHANGED
@@ -90,10 +90,8 @@ module Lafcadio
|
|
90
90
|
class Query
|
91
91
|
def self.And( *conditions ); CompoundCondition.new( *conditions ); end
|
92
92
|
|
93
|
-
def self.infer(
|
94
|
-
inferrer = Query::Inferrer.new(
|
95
|
-
action.call( obj )
|
96
|
-
}
|
93
|
+
def self.infer( *args, &action )
|
94
|
+
inferrer = Query::Inferrer.new( *args ) { |obj| action.call( obj ) }
|
97
95
|
inferrer.execute
|
98
96
|
end
|
99
97
|
|
@@ -108,15 +106,16 @@ module Lafcadio
|
|
108
106
|
attr_reader :domain_class, :condition
|
109
107
|
attr_accessor :order_by, :order_by_order, :limit
|
110
108
|
|
111
|
-
def initialize(domain_class,
|
112
|
-
@domain_class = domain_class
|
109
|
+
def initialize(domain_class, pk_id_or_condition = nil, opts = {} )
|
110
|
+
@domain_class, @opts = domain_class, opts
|
113
111
|
( @condition, @order_by, @limit ) = [ nil, nil, nil ]
|
114
|
-
if
|
115
|
-
if
|
116
|
-
@condition =
|
112
|
+
if pk_id_or_condition
|
113
|
+
if pk_id_or_condition.class <= Condition
|
114
|
+
@condition = pk_id_or_condition
|
117
115
|
else
|
118
|
-
@condition = Query::Equals.new(
|
119
|
-
|
116
|
+
@condition = Query::Equals.new(
|
117
|
+
'pk_id', pk_id_or_condition, domain_class
|
118
|
+
)
|
120
119
|
end
|
121
120
|
end
|
122
121
|
@order_by_order = ASC
|
@@ -124,20 +123,24 @@ module Lafcadio
|
|
124
123
|
|
125
124
|
def and( &action ); compound( CompoundCondition::AND, action ); end
|
126
125
|
|
126
|
+
def collect( coll )
|
127
|
+
if @opts[:group_functions] == [:count]
|
128
|
+
[ result_row( [coll.size] ) ]
|
129
|
+
else
|
130
|
+
raise
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
127
134
|
def compound( comp_type, action )
|
128
135
|
rquery = Query.infer( @domain_class ) { |dobj| action.call( dobj ) }
|
129
136
|
comp_cond = Query::CompoundCondition.new( @condition, rquery.condition,
|
130
137
|
comp_type )
|
131
|
-
|
132
|
-
[ :order_by, :order_by_order, :limit ].each do |attr|
|
133
|
-
q.send( attr.to_s + '=', self.send( attr ) )
|
134
|
-
end
|
135
|
-
q
|
138
|
+
comp_cond.query
|
136
139
|
end
|
137
140
|
|
138
141
|
def eql?( other ); other.class <= Query && other.to_sql == to_sql; end
|
139
142
|
|
140
|
-
def fields; '*'; end
|
143
|
+
def fields; @opts[:group_functions] == [:count] ? 'count(*)' : '*'; end
|
141
144
|
|
142
145
|
def hash; to_sql.hash; end
|
143
146
|
|
@@ -151,8 +154,14 @@ module Lafcadio
|
|
151
154
|
|
152
155
|
def order_clause
|
153
156
|
if @order_by
|
154
|
-
|
155
|
-
|
157
|
+
if @order_by.is_a? Array
|
158
|
+
field_str = @order_by.map { |f_name|
|
159
|
+
@domain_class.get_field( f_name.to_s ).db_field_name
|
160
|
+
}.join( ', ' )
|
161
|
+
else
|
162
|
+
field_str = @domain_class.get_field( @order_by ).db_field_name
|
163
|
+
end
|
164
|
+
clause = "order by #{ field_str } "
|
156
165
|
clause += @order_by_order == ASC ? 'asc' : 'desc'
|
157
166
|
clause
|
158
167
|
end
|
@@ -169,6 +178,14 @@ module Lafcadio
|
|
169
178
|
end
|
170
179
|
end
|
171
180
|
end
|
181
|
+
|
182
|
+
def result_row( row )
|
183
|
+
if @opts[:group_functions] == [:count]
|
184
|
+
{ :count => row.first }
|
185
|
+
else
|
186
|
+
raise
|
187
|
+
end
|
188
|
+
end
|
172
189
|
|
173
190
|
def sql_primary_key_field(domain_class)
|
174
191
|
"#{ domain_class.table_name }.#{ domain_class.sql_primary_key_name }"
|
@@ -226,6 +243,10 @@ module Lafcadio
|
|
226
243
|
end
|
227
244
|
end
|
228
245
|
|
246
|
+
def |( other_cond ); Query.Or( self, other_cond ); end
|
247
|
+
|
248
|
+
def &( other_cond ); Query.And( self, other_cond ); end
|
249
|
+
|
229
250
|
def implies?( other_condition )
|
230
251
|
self.eql?( other_condition ) or (
|
231
252
|
other_condition.respond_to?( :implied_by? ) and
|
@@ -462,14 +483,22 @@ module Lafcadio
|
|
462
483
|
end
|
463
484
|
|
464
485
|
class Inferrer #:nodoc:
|
465
|
-
def initialize(
|
466
|
-
@domain_class =
|
486
|
+
def initialize( *args, &action )
|
487
|
+
@domain_class = args.first; @action = action
|
488
|
+
unless args.size == 1
|
489
|
+
h = args.last
|
490
|
+
@order_by = h[:order_by]
|
491
|
+
@order_by_order = h[:order_by_order]
|
492
|
+
end
|
467
493
|
end
|
468
494
|
|
469
495
|
def execute
|
470
496
|
impostor = DomainObjectImpostor.impostor( @domain_class )
|
471
497
|
condition = @action.call( impostor ).to_condition
|
472
498
|
query = Query.new( @domain_class, condition )
|
499
|
+
query.order_by = @order_by
|
500
|
+
query.order_by_order = @order_by_order
|
501
|
+
query
|
473
502
|
end
|
474
503
|
end
|
475
504
|
|
@@ -532,12 +561,14 @@ module Lafcadio
|
|
532
561
|
a_value = d_obj.send( @field_name )
|
533
562
|
( max.nil? || a_value > max ) ? a_value : max
|
534
563
|
}
|
535
|
-
[ max ]
|
564
|
+
[ result_row( [max] ) ]
|
536
565
|
end
|
537
566
|
|
538
567
|
def fields
|
539
568
|
"max(#{ @domain_class.get_field( @field_name ).db_field_name })"
|
540
569
|
end
|
570
|
+
|
571
|
+
def result_row( row ); { :max => row.first }; end
|
541
572
|
end
|
542
573
|
|
543
574
|
class Not < Condition #:nodoc:
|
@@ -586,6 +617,10 @@ module Lafcadio
|
|
586
617
|
end
|
587
618
|
end
|
588
619
|
|
620
|
+
def |( condition ); Query.Or( to_condition, condition ); end
|
621
|
+
|
622
|
+
def &( condition ); Query.And( to_condition, condition ); end
|
623
|
+
|
589
624
|
def register_compare_condition( compareStr, searchTerm)
|
590
625
|
compareVal = ObjectFieldImpostor.comparators[compareStr]
|
591
626
|
Compare.new( @field_name, searchTerm,
|
data/lib/lafcadio/query.rb~
CHANGED
@@ -90,10 +90,8 @@ module Lafcadio
|
|
90
90
|
class Query
|
91
91
|
def self.And( *conditions ); CompoundCondition.new( *conditions ); end
|
92
92
|
|
93
|
-
def self.infer(
|
94
|
-
inferrer = Query::Inferrer.new(
|
95
|
-
action.call( obj )
|
96
|
-
}
|
93
|
+
def self.infer( *args, &action )
|
94
|
+
inferrer = Query::Inferrer.new( *args ) { |obj| action.call( obj ) }
|
97
95
|
inferrer.execute
|
98
96
|
end
|
99
97
|
|
@@ -108,15 +106,16 @@ module Lafcadio
|
|
108
106
|
attr_reader :domain_class, :condition
|
109
107
|
attr_accessor :order_by, :order_by_order, :limit
|
110
108
|
|
111
|
-
def initialize(domain_class,
|
112
|
-
@domain_class = domain_class
|
109
|
+
def initialize(domain_class, pk_id_or_condition = nil, opts = {} )
|
110
|
+
@domain_class, @opts = domain_class, opts
|
113
111
|
( @condition, @order_by, @limit ) = [ nil, nil, nil ]
|
114
|
-
if
|
115
|
-
if
|
116
|
-
@condition =
|
112
|
+
if pk_id_or_condition
|
113
|
+
if pk_id_or_condition.class <= Condition
|
114
|
+
@condition = pk_id_or_condition
|
117
115
|
else
|
118
|
-
@condition = Query::Equals.new(
|
119
|
-
|
116
|
+
@condition = Query::Equals.new(
|
117
|
+
'pk_id', pk_id_or_condition, domain_class
|
118
|
+
)
|
120
119
|
end
|
121
120
|
end
|
122
121
|
@order_by_order = ASC
|
@@ -124,6 +123,14 @@ module Lafcadio
|
|
124
123
|
|
125
124
|
def and( &action ); compound( CompoundCondition::AND, action ); end
|
126
125
|
|
126
|
+
def collect( coll )
|
127
|
+
if @opts[:group_functions] == [:count]
|
128
|
+
[ result_row( [coll.size] ) ]
|
129
|
+
else
|
130
|
+
raise
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
127
134
|
def compound( comp_type, action )
|
128
135
|
rquery = Query.infer( @domain_class ) { |dobj| action.call( dobj ) }
|
129
136
|
comp_cond = Query::CompoundCondition.new( @condition, rquery.condition,
|
@@ -133,7 +140,7 @@ module Lafcadio
|
|
133
140
|
|
134
141
|
def eql?( other ); other.class <= Query && other.to_sql == to_sql; end
|
135
142
|
|
136
|
-
def fields; '*'; end
|
143
|
+
def fields; @opts[:group_functions] == [:count] ? 'count(*)' : '*'; end
|
137
144
|
|
138
145
|
def hash; to_sql.hash; end
|
139
146
|
|
@@ -147,8 +154,14 @@ module Lafcadio
|
|
147
154
|
|
148
155
|
def order_clause
|
149
156
|
if @order_by
|
150
|
-
|
151
|
-
|
157
|
+
if @order_by.is_a? Array
|
158
|
+
field_str = @order_by.map { |f_name|
|
159
|
+
@domain_class.get_field( f_name.to_s ).db_field_name
|
160
|
+
}.join( ', ' )
|
161
|
+
else
|
162
|
+
field_str = @domain_class.get_field( @order_by ).db_field_name
|
163
|
+
end
|
164
|
+
clause = "order by #{ field_str } "
|
152
165
|
clause += @order_by_order == ASC ? 'asc' : 'desc'
|
153
166
|
clause
|
154
167
|
end
|
@@ -165,6 +178,14 @@ module Lafcadio
|
|
165
178
|
end
|
166
179
|
end
|
167
180
|
end
|
181
|
+
|
182
|
+
def result_row( row )
|
183
|
+
if @opts[:group_functions] == [:count]
|
184
|
+
{ :count => row.first }
|
185
|
+
else
|
186
|
+
raise
|
187
|
+
end
|
188
|
+
end
|
168
189
|
|
169
190
|
def sql_primary_key_field(domain_class)
|
170
191
|
"#{ domain_class.table_name }.#{ domain_class.sql_primary_key_name }"
|
@@ -458,14 +479,22 @@ module Lafcadio
|
|
458
479
|
end
|
459
480
|
|
460
481
|
class Inferrer #:nodoc:
|
461
|
-
def initialize(
|
462
|
-
@domain_class =
|
482
|
+
def initialize( *args, &action )
|
483
|
+
@domain_class = args.first; @action = action
|
484
|
+
unless args.size == 1
|
485
|
+
h = args.last
|
486
|
+
@order_by = h[:order_by]
|
487
|
+
@order_by_order = h[:order_by_order]
|
488
|
+
end
|
463
489
|
end
|
464
490
|
|
465
491
|
def execute
|
466
492
|
impostor = DomainObjectImpostor.impostor( @domain_class )
|
467
493
|
condition = @action.call( impostor ).to_condition
|
468
494
|
query = Query.new( @domain_class, condition )
|
495
|
+
query.order_by = @order_by
|
496
|
+
query.order_by_order = @order_by_order
|
497
|
+
query
|
469
498
|
end
|
470
499
|
end
|
471
500
|
|
@@ -528,12 +557,14 @@ module Lafcadio
|
|
528
557
|
a_value = d_obj.send( @field_name )
|
529
558
|
( max.nil? || a_value > max ) ? a_value : max
|
530
559
|
}
|
531
|
-
[ max ]
|
560
|
+
[ result_row( [max] ) ]
|
532
561
|
end
|
533
562
|
|
534
563
|
def fields
|
535
564
|
"max(#{ @domain_class.get_field( @field_name ).db_field_name })"
|
536
565
|
end
|
566
|
+
|
567
|
+
def result_row( row ); { :max => row.first }; end
|
537
568
|
end
|
538
569
|
|
539
570
|
class Not < Condition #:nodoc:
|