lafcadio 0.9.2 → 0.9.3
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/bin/lafcadio_schema +28 -26
- data/lib/lafcadio.rb +3 -3
- data/lib/lafcadio.rb~ +1 -1
- data/lib/lafcadio/domain.rb +29 -35
- data/lib/lafcadio/domain.rb~ +35 -42
- data/lib/lafcadio/mock.rb +37 -15
- data/lib/lafcadio/mock.rb~ +59 -36
- data/lib/lafcadio/objectField.rb +31 -20
- data/lib/lafcadio/objectField.rb~ +163 -142
- data/lib/lafcadio/objectStore.rb +125 -58
- data/lib/lafcadio/objectStore.rb~ +242 -177
- data/lib/lafcadio/query.rb +98 -95
- data/lib/lafcadio/query.rb~ +96 -95
- data/lib/lafcadio/schema.rb +4 -4
- data/lib/lafcadio/schema.rb~ +13 -17
- data/lib/lafcadio/test.rb +33 -7
- data/lib/lafcadio/test.rb~ +146 -20
- data/lib/lafcadio/util.rb +27 -11
- data/lib/lafcadio/util.rb~ +27 -43
- metadata +3 -7
- data/lib/lafcadio/dateTime.rb~ +0 -93
- data/lib/lafcadio/depend.rb~ +0 -8
- data/lib/lafcadio/objectStore.rb.~1.64.~ +0 -766
- data/lib/lafcadio/test/testconfig.dat~ +0 -13
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
|
-
BooleanField => 'bool',
|
6
|
+
BooleanField => 'bool', BinaryField => 'blob', DateField => 'date',
|
7
7
|
DomainObjectField => 'int', FloatField => 'float',
|
8
8
|
DateTimeField => 'datetime', IntegerField => 'int',
|
9
9
|
StringField => 'varchar(255)', TextListField => 'varchar(255)',
|
@@ -32,9 +32,9 @@ module Lafcadio
|
|
32
32
|
createDefinitions << definition_terms( field )
|
33
33
|
}
|
34
34
|
<<-SQL
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
create table #{ @domain_class.table_name } (
|
36
|
+
#{ createDefinitions.join(",\n ") }
|
37
|
+
);
|
38
38
|
SQL
|
39
39
|
end
|
40
40
|
|
data/lib/lafcadio/schema.rb~
CHANGED
@@ -3,8 +3,11 @@ require 'lafcadio/objectField'
|
|
3
3
|
module Lafcadio
|
4
4
|
class CreateTableStatement #:nodoc:
|
5
5
|
@@simple_field_clauses = {
|
6
|
-
|
7
|
-
|
6
|
+
BooleanField => 'bool', BlobField => 'blob', DateField => 'date',
|
7
|
+
DomainObjectField => 'int', FloatField => 'float',
|
8
|
+
DateTimeField => 'datetime', IntegerField => 'int',
|
9
|
+
StringField => 'varchar(255)', TextListField => 'varchar(255)',
|
10
|
+
TimeStampField => 'timestamp'
|
8
11
|
}
|
9
12
|
|
10
13
|
def initialize( domain_class )
|
@@ -15,22 +18,23 @@ module Lafcadio
|
|
15
18
|
definitionTerms = []
|
16
19
|
definitionTerms << field.db_field_name
|
17
20
|
definitionTerms << type_clause( field )
|
18
|
-
definitionTerms << 'not null' if field.
|
21
|
+
definitionTerms << 'not null' if field.not_nil
|
19
22
|
definitionTerms.join( ' ' )
|
20
23
|
end
|
21
24
|
|
22
25
|
def to_sql
|
23
26
|
createDefinitions = []
|
24
|
-
createDefinitions <<
|
25
|
-
|
26
|
-
createDefinitions <<
|
27
|
+
createDefinitions <<
|
28
|
+
"#{ @domain_class.sql_primary_key_name } int not null auto_increment"
|
29
|
+
createDefinitions <<
|
30
|
+
"primary key (#{ @domain_class.sql_primary_key_name })"
|
27
31
|
@domain_class.class_fields.each { |field|
|
28
32
|
createDefinitions << definition_terms( field )
|
29
33
|
}
|
30
34
|
<<-SQL
|
31
|
-
|
32
|
-
|
33
|
-
|
35
|
+
create table #{ @domain_class.table_name } (
|
36
|
+
#{ createDefinitions.join(",\n ") }
|
37
|
+
);
|
34
38
|
SQL
|
35
39
|
end
|
36
40
|
|
@@ -42,14 +46,6 @@ module Lafcadio
|
|
42
46
|
"'#{ enumValue }'"
|
43
47
|
}
|
44
48
|
"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
49
|
end
|
54
50
|
end
|
55
51
|
end
|
data/lib/lafcadio/test.rb
CHANGED
@@ -48,9 +48,35 @@ module Lafcadio
|
|
48
48
|
Time.now
|
49
49
|
end
|
50
50
|
|
51
|
-
module
|
52
|
-
|
53
|
-
|
51
|
+
# A convenience module for test-cases of Lafcadio-dependent applications.
|
52
|
+
# Include this module in a test-case, and you automatically get the
|
53
|
+
# class-level method <tt>setup_mock_dobjs</tt>. This calls
|
54
|
+
# DomainObject.default_mock, and assigns the result to an instance variable
|
55
|
+
# named after the domain class. Note that if your test case also defines a
|
56
|
+
# <tt>setup</tt>, you should make sure to call <tt>super</tt> in that setup
|
57
|
+
# method to make <tt>setup_mock_dobjs</tt> work.
|
58
|
+
#
|
59
|
+
# class User < Lafcadio::DomainObject
|
60
|
+
# strings :fname, :lname, :email
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# class TestSendMessage < Test::Unit::TestCase
|
64
|
+
# include Lafcadio::DomainMock
|
65
|
+
# setup_mock_dobjs User
|
66
|
+
# def test_send_to_self
|
67
|
+
# SendMessage.new( 'sender' => @user, 'recipient' => @user )
|
68
|
+
# assert_equal( 1, Message.all.size )
|
69
|
+
# end
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# <tt>setup_mock_dobjs</tt> can handle plural domain classes:
|
73
|
+
#
|
74
|
+
# setup_mock_dobjs User, Message
|
75
|
+
#
|
76
|
+
# It can also handle assignments to different instance variables:
|
77
|
+
#
|
78
|
+
# setup_mock_dobjs User, '@sender'
|
79
|
+
module DomainMock
|
54
80
|
def self.included( includer )
|
55
81
|
def includer.setup_mock_dobjs( *domain_classes_or_symbol_names )
|
56
82
|
domain_classes = DomainClassSymbolMapper.new
|
@@ -158,7 +184,7 @@ module Lafcadio
|
|
158
184
|
# <tt>lafcadio/test.rb</tt>.
|
159
185
|
#
|
160
186
|
# class User < Lafcadio::DomainObject
|
161
|
-
#
|
187
|
+
# strings :fname, :lname, :email
|
162
188
|
# end
|
163
189
|
# u1 = User.custom_mock
|
164
190
|
# u1.fname # => 'test text'
|
@@ -225,7 +251,7 @@ module Lafcadio
|
|
225
251
|
# <tt>lafcadio/test.rb</tt>.
|
226
252
|
#
|
227
253
|
# class User < Lafcadio::DomainObject
|
228
|
-
#
|
254
|
+
# strings :fname, :lname, :email
|
229
255
|
# end
|
230
256
|
# u1 = User.default_mock
|
231
257
|
# u1.fname # => 'test text'
|
@@ -269,7 +295,7 @@ module Lafcadio
|
|
269
295
|
# <tt>lafcadio/test.rb</tt>.
|
270
296
|
#
|
271
297
|
# class User < Lafcadio::DomainObject
|
272
|
-
#
|
298
|
+
# strings :fname, :lname, :email
|
273
299
|
# end
|
274
300
|
# User.mock_value :fname, 'Bill'
|
275
301
|
# User.mock_value :lname, 'Smith'
|
@@ -289,7 +315,7 @@ module Lafcadio
|
|
289
315
|
# <tt>lafcadio/test.rb</tt>.
|
290
316
|
#
|
291
317
|
# class User < Lafcadio::DomainObject
|
292
|
-
#
|
318
|
+
# strings :fname, :lname, :email
|
293
319
|
# end
|
294
320
|
# User.mock_values { :fname => 'Bill', :lname => 'Smith' }
|
295
321
|
# u1 = User.default_mock
|
data/lib/lafcadio/test.rb~
CHANGED
@@ -21,17 +21,34 @@ class LafcadioTestCase < Test::Unit::TestCase
|
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
# Asserts that for each key-value pair in +att_values+, sending the key to
|
25
|
+
# +object+ will return the value.
|
26
|
+
# u = User.new( 'fname' => 'Francis', 'lname' => 'Hwang' )
|
27
|
+
# assert_attributes( u, { 'fname' => 'Francis', 'lname' => 'Hwang' } )
|
28
|
+
def assert_attributes( object, att_values )
|
29
|
+
att_values.each { |method, expected|
|
30
|
+
assert_equal( expected, object.send( method ), method.to_s )
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
def default_test #:nodoc:
|
35
|
+
end
|
25
36
|
end
|
26
37
|
|
27
38
|
module Lafcadio
|
28
|
-
def BooleanField.mock_value
|
39
|
+
def BooleanField.mock_value #:nodoc:
|
40
|
+
true
|
41
|
+
end
|
29
42
|
|
30
|
-
def DateField.mock_value
|
43
|
+
def DateField.mock_value #:nodoc:
|
44
|
+
Date.today
|
45
|
+
end
|
31
46
|
|
32
|
-
def DateTimeField.mock_value
|
47
|
+
def DateTimeField.mock_value #:nodoc:
|
48
|
+
Time.now
|
49
|
+
end
|
33
50
|
|
34
|
-
module DomainMock
|
51
|
+
module DomainMock #:nodoc:
|
35
52
|
Version = '0.1.0'
|
36
53
|
|
37
54
|
def self.included( includer )
|
@@ -83,7 +100,7 @@ module Lafcadio
|
|
83
100
|
self.class.setup_procs.each { |proc| proc.call( self ) }
|
84
101
|
end
|
85
102
|
|
86
|
-
class DomainClassSymbolMapper < Hash
|
103
|
+
class DomainClassSymbolMapper < Hash #:nodoc:
|
87
104
|
def initialize; @last_domain_class = nil; end
|
88
105
|
|
89
106
|
def default_symbol_name( domain_class )
|
@@ -120,7 +137,7 @@ module Lafcadio
|
|
120
137
|
hash[a_class] = default_args
|
121
138
|
}
|
122
139
|
|
123
|
-
def self.commit_mock( args, caller = nil )
|
140
|
+
def self.commit_mock( args, caller = nil ) #:nodoc:
|
124
141
|
dobj = self.new( args )
|
125
142
|
link_fields = all_fields.select { |field| field.is_a? DomainObjectField }
|
126
143
|
link_fields.each do |field|
|
@@ -131,16 +148,62 @@ module Lafcadio
|
|
131
148
|
dobj
|
132
149
|
end
|
133
150
|
|
151
|
+
# Commits and returns a custom mock object of the given domain class. All
|
152
|
+
# the field values are set to defaults, except for the fields passed in
|
153
|
+
# through +custom_args+. This mock object will have a +pk_id+ greater than
|
154
|
+
# 1, and each successive call to DomainObject.custom_mock will return an
|
155
|
+
# object with a unique +pk_id+.
|
156
|
+
#
|
157
|
+
# This class method is only visible if you include
|
158
|
+
# <tt>lafcadio/test.rb</tt>.
|
159
|
+
#
|
160
|
+
# class User < Lafcadio::DomainObject
|
161
|
+
# string :fname, :lname, :email
|
162
|
+
# end
|
163
|
+
# u1 = User.custom_mock
|
164
|
+
# u1.fname # => 'test text'
|
165
|
+
# u1.lname # => 'test text'
|
166
|
+
# u1.email # => 'test text'
|
167
|
+
# u1.pk_id # => probably 2, guaranteed to be greater than 1
|
168
|
+
# u2 = User.custom_mock( 'fname' => 'Francis', 'lname' => 'Hwang' )
|
169
|
+
# u2.fname # => 'Francis'
|
170
|
+
# u2.lname # => 'Hwang'
|
171
|
+
# u2.email # => 'test text'
|
172
|
+
# u2.pk_id # => probably 3, guaranteed to not be u1.pk_id and to be
|
173
|
+
# # greater than 1
|
134
174
|
def self.custom_mock( custom_args = nil )
|
135
175
|
dobj_args = default_args
|
136
176
|
object_store = ObjectStore.get_object_store
|
137
|
-
dbb = object_store.
|
177
|
+
dbb = object_store.db_bridge
|
138
178
|
dbb.set_next_pk_id( self, 2 ) if dbb.next_pk_id( self ) == 1
|
139
179
|
dobj_args['pk_id'] = nil
|
140
|
-
|
180
|
+
if custom_args.is_a? Hash
|
181
|
+
custom_args.each do |k, v| dobj_args[k.to_s] = v; end
|
182
|
+
end
|
141
183
|
commit_mock( dobj_args )
|
142
184
|
end
|
143
185
|
|
186
|
+
# Returns a hash of default arguments for mock instances of this domain
|
187
|
+
# class. DomainObject.default_mock uses exactly these arguments to create
|
188
|
+
# the default mock for a given domain class, and DomainObject.custom_mock
|
189
|
+
# overrides some of the field arguments based on its custom arguments.
|
190
|
+
#
|
191
|
+
# By default this will retrieve simple values based on the field type:
|
192
|
+
# * BooleanField: +true+
|
193
|
+
# * DateField: Date.today
|
194
|
+
# * DateTimeField: Time.now
|
195
|
+
# * DomainObjectField: The instance of the domain class with +pk_id+ 1
|
196
|
+
# * EmailField: "john.doe@email.com"
|
197
|
+
# * FloatField: 0.0
|
198
|
+
# * IntegerField: 1
|
199
|
+
# * StringField: "test text"
|
200
|
+
# * TextListField: [ 'a', 'b', 'c' ]
|
201
|
+
#
|
202
|
+
# You can override this method, if you like. However, it will probably be
|
203
|
+
# simpler just to call DomainObject.mock_value.
|
204
|
+
#
|
205
|
+
# This class method is only visible if you include
|
206
|
+
# <tt>lafcadio/test.rb</tt>.
|
144
207
|
def self.default_args
|
145
208
|
default_args = {}
|
146
209
|
@@default_arg_directives[self].each do |name, value_or_proc|
|
@@ -153,13 +216,29 @@ module Lafcadio
|
|
153
216
|
default_args
|
154
217
|
end
|
155
218
|
|
219
|
+
# Commits and returns a mock object of the given domain class. All
|
220
|
+
# the field values are set to defaults. This mock object will have a
|
221
|
+
# +pk_id+ of 1. Successive calls to DomainObject.default_mock will always
|
222
|
+
# return the same mock object.
|
223
|
+
#
|
224
|
+
# This class method is only visible if you include
|
225
|
+
# <tt>lafcadio/test.rb</tt>.
|
226
|
+
#
|
227
|
+
# class User < Lafcadio::DomainObject
|
228
|
+
# string :fname, :lname, :email
|
229
|
+
# end
|
230
|
+
# u1 = User.default_mock
|
231
|
+
# u1.fname # => 'test text'
|
232
|
+
# u1.lname # => 'test text'
|
233
|
+
# u1.email # => 'test text'
|
234
|
+
# u1.pk_id # => 1
|
156
235
|
def self.default_mock( calling_class = nil )
|
157
236
|
if @@default_mock_available[self]
|
158
237
|
begin
|
159
238
|
dobj = ObjectStore.get_object_store.get( self, 1 )
|
160
239
|
dobj
|
161
240
|
rescue DomainObjectNotFoundError
|
162
|
-
dbb = ObjectStore.get_object_store.
|
241
|
+
dbb = ObjectStore.get_object_store.db_bridge
|
163
242
|
dbb.set_next_pk_id( self, 1 ) if dbb.next_pk_id( self ) > 1
|
164
243
|
commit_mock( default_args, calling_class )
|
165
244
|
end
|
@@ -168,11 +247,11 @@ module Lafcadio
|
|
168
247
|
end
|
169
248
|
end
|
170
249
|
|
171
|
-
def self.default_mock_available( is_avail )
|
250
|
+
def self.default_mock_available( is_avail ) #:nodoc:
|
172
251
|
@@default_mock_available[self] = is_avail
|
173
252
|
end
|
174
253
|
|
175
|
-
def self.maybe_call_default_mock( field, caller )
|
254
|
+
def self.maybe_call_default_mock( field, caller ) #:nodoc:
|
176
255
|
linked_type = field.linked_type
|
177
256
|
begin
|
178
257
|
ObjectStore.get_object_store.get( linked_type, 1 )
|
@@ -183,34 +262,81 @@ module Lafcadio
|
|
183
262
|
end
|
184
263
|
end
|
185
264
|
|
265
|
+
# Sets the mock value for the given field. These mock values are used in
|
266
|
+
# DomainObject.default_mock and DomainObject.custom_mock
|
267
|
+
#
|
268
|
+
# This class method is only visible if you include
|
269
|
+
# <tt>lafcadio/test.rb</tt>.
|
270
|
+
#
|
271
|
+
# class User < Lafcadio::DomainObject
|
272
|
+
# string :fname, :lname, :email
|
273
|
+
# end
|
274
|
+
# User.mock_value :fname, 'Bill'
|
275
|
+
# User.mock_value :lname, 'Smith'
|
276
|
+
# u1 = User.default_mock
|
277
|
+
# u1.fname # => 'Bill'
|
278
|
+
# u1.lname # => 'Smith'
|
279
|
+
# u1.email # => 'test text'
|
280
|
+
# u1.pk_id # => 1
|
186
281
|
def self.mock_value( field_sym, value )
|
187
282
|
@@default_arg_directives[self][field_sym.id2name] = value
|
188
283
|
end
|
189
284
|
|
285
|
+
# Sets the mock value for the fields in +hash+. These mock values are used
|
286
|
+
# in DomainObject.default_mock and DomainObject.custom_mock
|
287
|
+
#
|
288
|
+
# This class method is only visible if you include
|
289
|
+
# <tt>lafcadio/test.rb</tt>.
|
290
|
+
#
|
291
|
+
# class User < Lafcadio::DomainObject
|
292
|
+
# string :fname, :lname, :email
|
293
|
+
# end
|
294
|
+
# User.mock_values { :fname => 'Bill', :lname => 'Smith' }
|
295
|
+
# u1 = User.default_mock
|
296
|
+
# u1.fname # => 'Bill'
|
297
|
+
# u1.lname # => 'Smith'
|
298
|
+
# u1.email # => 'test text'
|
299
|
+
# u1.pk_id # => 1
|
190
300
|
def self.mock_values( hash )
|
191
301
|
hash.each do |field_sym, value| mock_value( field_sym, value ); end
|
192
302
|
end
|
193
303
|
end
|
194
304
|
|
195
305
|
class DomainObjectField < ObjectField
|
196
|
-
def default_mock_value
|
306
|
+
def default_mock_value #:nodoc:
|
307
|
+
DomainObjectProxy.new( linked_type, 1 )
|
308
|
+
end
|
197
309
|
end
|
198
310
|
|
199
|
-
def EmailField.mock_value
|
311
|
+
def EmailField.mock_value #:nodoc:
|
312
|
+
'john.doe@email.com'
|
313
|
+
end
|
200
314
|
|
201
|
-
def FloatField.mock_value
|
315
|
+
def FloatField.mock_value #:nodoc:
|
316
|
+
0.0
|
317
|
+
end
|
202
318
|
|
203
|
-
def IntegerField.mock_value
|
319
|
+
def IntegerField.mock_value #:nodoc:
|
320
|
+
1
|
321
|
+
end
|
204
322
|
|
205
323
|
class ObjectField
|
206
324
|
attr_writer :mock_value
|
207
325
|
|
208
|
-
def default_mock_value
|
326
|
+
def default_mock_value #:nodoc:
|
327
|
+
self.class.mock_value
|
328
|
+
end
|
209
329
|
end
|
210
330
|
|
211
|
-
def PrimaryKeyField.mock_value
|
331
|
+
def PrimaryKeyField.mock_value #:nodoc:
|
332
|
+
nil
|
333
|
+
end
|
212
334
|
|
213
|
-
def StringField.mock_value
|
335
|
+
def StringField.mock_value #:nodoc:
|
336
|
+
'test text'
|
337
|
+
end
|
214
338
|
|
215
|
-
def TextListField.mock_value
|
339
|
+
def TextListField.mock_value #:nodoc:
|
340
|
+
%w( a b c )
|
341
|
+
end
|
216
342
|
end
|
data/lib/lafcadio/util.rb
CHANGED
@@ -13,24 +13,40 @@ module Lafcadio
|
|
13
13
|
# dbpassword:password
|
14
14
|
# dbname:lafcadio_test
|
15
15
|
# dbhost:localhost
|
16
|
+
# dbtype:Mysql ("Mysql" is the default; select "Pg" for Postgres)
|
16
17
|
class LafcadioConfig < Hash
|
17
|
-
@@
|
18
|
-
@@
|
19
|
-
|
20
|
-
def self.set_filename(filename); @@filename = filename; end
|
18
|
+
@@value_hash = {}
|
19
|
+
@@instances = []
|
21
20
|
|
22
|
-
def self.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
21
|
+
def self.[]=( k, v )
|
22
|
+
@@value_hash[k] = v
|
23
|
+
@@instances.each do |instance| instance[k] = v; end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.new
|
27
|
+
inst = super
|
28
|
+
@@instances << inst
|
29
|
+
inst
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.set_filename(filename)
|
33
|
+
@@value_hash = {}
|
34
|
+
if filename
|
35
|
+
File.new( filename ).each_line { |line|
|
29
36
|
line.chomp =~ /^(.*?):(.*)$/
|
30
37
|
self[$1] = $2
|
31
38
|
}
|
32
39
|
end
|
33
40
|
end
|
41
|
+
|
42
|
+
def self.set_values( value_hash )
|
43
|
+
@@value_hash = ( value_hash.nil? ? {} : value_hash )
|
44
|
+
ObjectStore.db_type = @@value_hash['dbtype'] if @@value_hash['dbtype']
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize
|
48
|
+
@@value_hash.each { |key, value| self[key] = value }
|
49
|
+
end
|
34
50
|
end
|
35
51
|
|
36
52
|
class MissingError < RuntimeError; end
|