lafcadio 0.9.0 → 0.9.1

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.
@@ -3,97 +3,84 @@ require 'lafcadio/util'
3
3
 
4
4
  module Lafcadio
5
5
  class MockDbBridge #:nodoc:
6
- attr_reader :last_pk_id_inserted, :retrievals_by_type, :query_count
6
+ attr_reader :last_pk_id_inserted
7
7
 
8
8
  def initialize
9
9
  @objects = {}
10
- @retrievals_by_type = Hash.new 0
11
- @query_count = Hash.new( 0 )
12
10
  @next_pk_ids = {}
11
+ @queries = []
12
+ end
13
+
14
+ def all( domain_class )
15
+ @objects[domain_class] ? @objects[domain_class].values : []
16
+ end
17
+
18
+ def select_dobjs(query)
19
+ @queries << query
20
+ domain_class = query.domain_class
21
+ objects = []
22
+ all( domain_class ).each { |dbObj|
23
+ objects << dbObj if query.dobj_satisfies?( dbObj )
24
+ }
25
+ query.order_and_limit_collection objects
13
26
  end
14
27
 
15
28
  def commit(db_object)
16
29
  if db_object.pk_id and !db_object.pk_id.is_a?( Integer )
17
30
  raise ArgumentError
18
31
  end
19
- objects_by_domain_class = get_objects_by_domain_class(
20
- db_object.domain_class
21
- )
32
+ objects_by_domain_class = objects_by_domain_class db_object.domain_class
22
33
  if db_object.delete
23
34
  objects_by_domain_class.delete( db_object.pk_id )
24
35
  else
25
- object_pk_id = get_pk_id_before_committing( db_object )
36
+ object_pk_id = pre_commit_pk_id( db_object )
26
37
  objects_by_domain_class[object_pk_id] = db_object
27
38
  end
28
39
  end
29
-
30
- def _get_all( domain_class )
31
- @retrievals_by_type[domain_class] = @retrievals_by_type[domain_class] + 1
32
- @objects[domain_class] ? @objects[domain_class].values : []
40
+
41
+ def group_query( query )
42
+ query.collect objects_by_domain_class( query.domain_class ).values
33
43
  end
34
44
 
35
- def get_collection_by_query(query)
36
- @query_count[query.to_sql] += 1
37
- objects = []
38
- _get_all( query.domain_class ).each { |dbObj|
39
- if query.condition
40
- objects << dbObj if query.condition.object_meets(dbObj)
41
- else
42
- objects << dbObj
43
- end
44
- }
45
- if ( order_by = query.order_by )
46
- objects = objects.sort_by { |dobj|
47
- if order_by.is_a?( Array )
48
- order_by.map { |field_name| dobj.send( field_name ) }
49
- else
50
- dobj.send( order_by )
51
- end
52
- }
53
- objects.reverse! if query.order_by_order == Query::DESC
54
- else
55
- objects = objects.sort_by { |dobj| dobj.pk_id }
56
- end
57
- if (range = query.limit)
58
- objects = objects[range]
59
- end
60
- objects
45
+ def next_pk_id( domain_class )
46
+ dobjs = objects_by_domain_class( domain_class ).values
47
+ dobjs.inject( 0 ) { |memo, obj| memo > obj.pk_id ? memo : obj.pk_id } + 1
61
48
  end
62
-
63
- def get_pk_id_before_committing( db_object )
64
- if db_object.pk_id
65
- db_object.pk_id
66
- else
67
- if ( next_pk_id = @next_pk_ids[db_object.domain_class] )
68
- @last_pk_id_inserted = next_pk_id
69
- @next_pk_ids[db_object.domain_class] = nil
70
- next_pk_id
71
- else
72
- maxpk_id = 0
73
- pk_ids = get_objects_by_domain_class( db_object.domain_class ).keys
74
- pk_ids.each { |pk_id|
75
- maxpk_id = pk_id if pk_id > maxpk_id
76
- }
77
- @last_pk_id_inserted = maxpk_id + 1
78
- @last_pk_id_inserted
79
- end
80
- end
49
+
50
+ def objects_by_domain_class( domain_class )
51
+ @objects[domain_class] = {} unless @objects[domain_class]
52
+ @objects[domain_class]
81
53
  end
82
-
83
- def get_objects_by_domain_class( domain_class )
84
- objects_by_domain_class = @objects[domain_class]
85
- unless objects_by_domain_class
86
- objects_by_domain_class = {}
87
- @objects[domain_class] = objects_by_domain_class
54
+
55
+ def pre_commit_pk_id( domain_object )
56
+ @next_pk_ids = {} unless @next_pk_ids
57
+ if (next_pk_id = @next_pk_ids[domain_object.domain_class])
58
+ @next_pk_ids[domain_object.domain_class] = nil
59
+ @last_pk_id_inserted = next_pk_id
60
+ elsif domain_object.pk_id
61
+ domain_object.pk_id
62
+ elsif ( next_pk_id = @next_pk_ids[domain_object.domain_class] )
63
+ @last_pk_id_inserted = next_pk_id
64
+ @next_pk_ids[domain_object.domain_class] = nil
65
+ next_pk_id
66
+ else
67
+ pk_ids = objects_by_domain_class( domain_object.domain_class ).keys
68
+ @last_pk_id_inserted = pk_ids.max ? pk_ids.max + 1 : 1
88
69
  end
89
- objects_by_domain_class
90
70
  end
91
71
 
92
- def group_query( query )
93
- query.collect( get_objects_by_domain_class( query.domain_class ).values )
72
+ def queries( domain_class = nil )
73
+ @queries.select { |qry|
74
+ domain_class ? qry.domain_class == domain_class : true
75
+ }
76
+ end
77
+
78
+ def query_count( sql )
79
+ @queries.select { |qry| qry.to_sql == sql }.size
94
80
  end
95
81
 
96
82
  def set_next_pk_id( domain_class, npi )
83
+ @next_pk_ids = {} unless @next_pk_ids
97
84
  @next_pk_ids[ domain_class ] = npi
98
85
  end
99
86
  end
@@ -101,14 +88,21 @@ module Lafcadio
101
88
  # Externally, the MockObjectStore looks and acts exactly like the ObjectStore,
102
89
  # but stores all its data in memory. This makes it very useful for unit
103
90
  # testing, and in fact LafcadioTestCase#setup creates a new instance of
104
- # MockObjectStore for each test case.
91
+ # MockObjectStore for each test case. For example:
92
+ #
93
+ # class SomeTestCase < Test::Unit::TestCase
94
+ # def setup
95
+ # @mock_object_store = Lafcadio::MockObjectStore.new
96
+ # Lafcadio::ObjectStore.set_object_store @mock_object_store
97
+ # end
98
+ # end
105
99
  class MockObjectStore < ObjectStore
106
- public_class_method :new
107
-
108
- def initialize # :nodoc:
109
- super( MockDbBridge.new )
100
+ def self.db_bridge #:nodoc:
101
+ MockDbBridge.new
110
102
  end
111
103
 
104
+ public_class_method :new
105
+
112
106
  def mock? # :nodoc:
113
107
  true
114
108
  end
@@ -3,58 +3,67 @@ require 'lafcadio/util'
3
3
 
4
4
  module Lafcadio
5
5
  class MockDbBridge #:nodoc:
6
- attr_reader :last_pk_id_inserted, :retrievals_by_type, :query_count
6
+ attr_reader :last_pk_id_inserted
7
7
 
8
8
  def initialize
9
9
  @objects = {}
10
- @retrievals_by_type = Hash.new 0
11
- @query_count = Hash.new( 0 )
12
10
  @next_pk_ids = {}
11
+ @queries = []
12
+ end
13
+
14
+ def all( domain_class )
15
+ @objects[domain_class] ? @objects[domain_class].values : []
16
+ end
17
+
18
+ def select_dobjs(query)
19
+ @queries << query
20
+ domain_class = query.domain_class
21
+ objects = []
22
+ all( domain_class ).each { |dbObj|
23
+ objects << dbObj if query.dobj_satisfies?( dbObj )
24
+ }
25
+ objects = order_collection( objects, query )
26
+ if (range = query.limit); objects = objects[range]; end
27
+ objects
13
28
  end
14
29
 
15
30
  def commit(db_object)
16
31
  if db_object.pk_id and !db_object.pk_id.is_a?( Integer )
17
32
  raise ArgumentError
18
33
  end
19
- objects_by_domain_class = get_objects_by_domain_class(
20
- db_object.domain_class
21
- )
34
+ objects_by_domain_class = objects_by_domain_class db_object.domain_class
22
35
  if db_object.delete
23
36
  objects_by_domain_class.delete( db_object.pk_id )
24
37
  else
25
- object_pk_id = get_pk_id_before_committing( db_object )
38
+ object_pk_id = pre_commit_pk_id( db_object )
26
39
  objects_by_domain_class[object_pk_id] = db_object
27
40
  end
28
41
  end
29
-
30
- def _get_all( domain_class )
31
- @retrievals_by_type[domain_class] = @retrievals_by_type[domain_class] + 1
32
- @objects[domain_class] ? @objects[domain_class].values : []
42
+
43
+ def group_query( query )
44
+ query.collect objects_by_domain_class( query.domain_class ).values
33
45
  end
34
46
 
35
- def get_collection_by_query(query)
36
- @query_count[query.to_sql] += 1
37
- objects = []
38
- _get_all( query.domain_class ).each { |dbObj|
39
- if query.condition
40
- objects << dbObj if query.condition.object_meets(dbObj)
47
+ def objects_by_domain_class( domain_class )
48
+ @objects[domain_class] = {} unless @objects[domain_class]
49
+ @objects[domain_class]
50
+ end
51
+
52
+ def order_collection( objects, query )
53
+ objects = objects.sort_by { |dobj|
54
+ if ( order_by = query.order_by ).nil?
55
+ dobj.pk_id
56
+ elsif order_by.is_a?( Array )
57
+ order_by.map { |field_name| dobj.send( field_name ) }
41
58
  else
42
- objects << dbObj
59
+ dobj.send order_by
43
60
  end
44
61
  }
45
- if ( order_by = query.order_by )
46
- objects = objects.sort_by { |dobj| dobj.send( order_by ) }
47
- objects.reverse! if query.order_by_order == Query::DESC
48
- else
49
- objects = objects.sort_by { |dobj| dobj.pk_id }
50
- end
51
- if (range = query.limit)
52
- objects = objects[range]
53
- end
62
+ objects.reverse! if query.order_by_order == Query::DESC
54
63
  objects
55
64
  end
56
65
 
57
- def get_pk_id_before_committing( db_object )
66
+ def pre_commit_pk_id( db_object )
58
67
  if db_object.pk_id
59
68
  db_object.pk_id
60
69
  else
@@ -63,28 +72,20 @@ module Lafcadio
63
72
  @next_pk_ids[db_object.domain_class] = nil
64
73
  next_pk_id
65
74
  else
66
- maxpk_id = 0
67
- pk_ids = get_objects_by_domain_class( db_object.domain_class ).keys
68
- pk_ids.each { |pk_id|
69
- maxpk_id = pk_id if pk_id > maxpk_id
70
- }
71
- @last_pk_id_inserted = maxpk_id + 1
72
- @last_pk_id_inserted
75
+ pk_ids = objects_by_domain_class( db_object.domain_class ).keys
76
+ @last_pk_id_inserted = pk_ids.max ? pk_ids.max + 1 : 1
73
77
  end
74
78
  end
75
79
  end
76
80
 
77
- def get_objects_by_domain_class( domain_class )
78
- objects_by_domain_class = @objects[domain_class]
79
- unless objects_by_domain_class
80
- objects_by_domain_class = {}
81
- @objects[domain_class] = objects_by_domain_class
82
- end
83
- objects_by_domain_class
81
+ def queries( domain_class = nil )
82
+ @queries.select { |qry|
83
+ domain_class ? qry.domain_class == domain_class : true
84
+ }
84
85
  end
85
-
86
- def group_query( query )
87
- query.collect( get_objects_by_domain_class( query.domain_class ).values )
86
+
87
+ def query_count( sql )
88
+ @queries.select { |qry| qry.to_sql == sql }.size
88
89
  end
89
90
 
90
91
  def set_next_pk_id( domain_class, npi )
@@ -97,12 +98,10 @@ module Lafcadio
97
98
  # testing, and in fact LafcadioTestCase#setup creates a new instance of
98
99
  # MockObjectStore for each test case.
99
100
  class MockObjectStore < ObjectStore
101
+ def self.db_bridge; MockDbBridge.new; end
102
+
100
103
  public_class_method :new
101
104
 
102
- def initialize # :nodoc:
103
- super( MockDbBridge.new )
104
- end
105
-
106
105
  def mock? # :nodoc:
107
106
  true
108
107
  end
@@ -4,14 +4,28 @@ require 'lafcadio/util'
4
4
 
5
5
  module Lafcadio
6
6
  # ObjectField is the abstract base class of any field for domain objects.
7
+ # Fields can be added to a domain class using DomainObject.string,
8
+ # DomainObject.integer, etc.
9
+ #
10
+ # class User < Lafcadio::DomainObject
11
+ # string 'fname'
12
+ # date 'birthday'
13
+ # end
14
+ #
15
+ # All fields accept the following arguments in hashes:
16
+ # [not_nil] This is +true+ by default. Set it to +false+ to avoid
17
+ # checking for nil values in tests.
18
+ # [db_field_name] By default, fields are assumed to have the same name in
19
+ # the database, but you can override this assumption using
20
+ # +db_field_name+.
21
+ #
22
+ # class User < Lafcadio::DomainObject
23
+ # string 'fname', { 'not_nil' => false }
24
+ # date 'birthday', { 'db_field_name' => 'bday' }
25
+ # end
7
26
  class ObjectField
8
- include Comparable
9
-
10
- attr_reader :name, :domain_class
11
- attr_accessor :not_null, :db_field_name
12
-
13
- def self.instantiate_from_xml( domain_class, fieldElt ) #:nodoc:
14
- parameters = instantiation_parameters( fieldElt )
27
+ def self.create_from_xml( domain_class, fieldElt ) #:nodoc:
28
+ parameters = creation_parameters( fieldElt )
15
29
  create_with_args( domain_class, parameters )
16
30
  end
17
31
 
@@ -23,7 +37,7 @@ module Lafcadio
23
37
  instance
24
38
  end
25
39
 
26
- def self.instantiation_parameters( fieldElt ) #:nodoc:
40
+ def self.creation_parameters( fieldElt ) #:nodoc:
27
41
  parameters = {}
28
42
  parameters['name'] = fieldElt.attributes['name']
29
43
  parameters['db_field_name'] = fieldElt.attributes['db_field_name']
@@ -34,13 +48,18 @@ module Lafcadio
34
48
  Object
35
49
  end
36
50
 
37
- # [domain_class] The domain class that this object field belongs to.
51
+ include Comparable
52
+
53
+ attr_reader :domain_class, :name
54
+ attr_accessor :db_field_name, :not_nil
55
+
56
+ # [domain_class] The domain class that this field belongs to.
38
57
  # [name] The name of this field.
39
58
  def initialize( domain_class, name )
40
59
  @domain_class = domain_class
41
60
  @name = name
42
61
  @db_field_name = name
43
- @not_null = true
62
+ @not_nil = true
44
63
  end
45
64
 
46
65
  def <=>(other)
@@ -51,23 +70,18 @@ module Lafcadio
51
70
  end
52
71
  end
53
72
 
54
- def bind_write?; false; end #:nodoc:
73
+ def bind_write? #:nodoc:
74
+ false
75
+ end
55
76
 
56
- def db_table_and_field_name
77
+ def db_column #:nodoc:
57
78
  "#{ domain_class.table_name }.#{ db_field_name }"
58
79
  end
59
80
 
60
- def db_will_automatically_write #:nodoc:
81
+ def db_will_automatically_write? #:nodoc:
61
82
  false
62
83
  end
63
84
 
64
- # Returns the name that this field is referenced by in the MySQL table. By
65
- # default this is the same as the name; to override it, set
66
- # ObjectField#db_field_name.
67
- def name_for_sql
68
- db_field_name
69
- end
70
-
71
85
  def prev_value(pk_id) #:nodoc:
72
86
  prevObject = ObjectStore.get_object_store.get( @domain_class, pk_id )
73
87
  prevObject.send(name)
@@ -85,17 +99,17 @@ module Lafcadio
85
99
  end
86
100
 
87
101
  def verify(value, pk_id) #:nodoc:
88
- if value.nil? && not_null
102
+ if value.nil? && not_nil
89
103
  raise(
90
104
  FieldValueError,
91
105
  "#{ self.domain_class.name }##{ name } can not be nil.",
92
106
  caller
93
107
  )
94
108
  end
95
- verify_non_nil( value, pk_id ) if value
109
+ verify_non_nil_value( value, pk_id ) if value
96
110
  end
97
111
 
98
- def verify_non_nil( value, pk_id )
112
+ def verify_non_nil_value( value, pk_id ) #:nodoc:
99
113
  value_type = self.class.value_type
100
114
  unless value.class <= value_type
101
115
  raise(
@@ -115,7 +129,7 @@ module Lafcadio
115
129
 
116
130
  # A StringField is expected to contain a string value.
117
131
  class StringField < ObjectField
118
- def value_for_sql(value) #:nodoc:
132
+ def value_for_sql(value)
119
133
  if value
120
134
  value = value.gsub(/(\\?')/) { |m| m.length == 1 ? "''" : m }
121
135
  value = value.gsub(/\\/) { '\\\\' }
@@ -128,7 +142,7 @@ module Lafcadio
128
142
 
129
143
  # IntegerField represents an integer.
130
144
  class IntegerField < ObjectField
131
- def value_from_sql(string) #:nodoc:
145
+ def value_from_sql(string)
132
146
  value = super
133
147
  value ? value.to_i : nil
134
148
  end
@@ -137,46 +151,42 @@ module Lafcadio
137
151
  # BlobField stores a string value and expects to store its value in a BLOB
138
152
  # field in the database.
139
153
  class BlobField < ObjectField
140
- attr_accessor :size
141
-
142
- def self.value_type; String; end
154
+ def self.value_type #:nodoc:
155
+ String
156
+ end
143
157
 
144
158
  def bind_write?; true; end #:nodoc:
145
159
 
146
- def value_for_sql(value); "?"; end #:nodoc:
160
+ def value_for_sql(value); "?"; end
147
161
  end
148
162
 
149
163
  # BooleanField represents a boolean value. By default, it assumes that the
150
- # table field represents True and False with the integers 1 and 0. There are
151
- # two different ways to change this default.
164
+ # table field represents +true+ and +false+ with the integers 1 and 0. There
165
+ # are two different ways to change this default.
152
166
  #
153
167
  # First, BooleanField includes a few enumerated defaults. Currently there are
154
168
  # only
155
169
  # * BooleanField::ENUMS_ONE_ZERO (the default, uses integers 1 and 0)
156
170
  # * BooleanField::ENUMS_CAPITAL_YES_NO (uses characters 'Y' and 'N')
157
- # In the XML class definition, this field would look like
158
- # <field name="field_name" class="BooleanField"
159
- # enum_type="ENUMS_CAPITAL_YES_NO"/>
160
- # If you're defining a field in Ruby, simply set BooleanField#enum_type to one
161
- # of the values.
162
- #
163
- # For more fine-grained specification you can pass specific values in. Use
164
- # this format for the XML class definition:
165
- # <field name="field_name" class="BooleanField">
166
- # <enums>
167
- # <enum key="true">yin</enum>
168
- # <enum key="false">tang</enum>
169
- # </enums>
170
- # </field>
171
- # If you're defining the field in Ruby, set BooleanField#enums to a hash.
172
- # myBooleanField.enums = { true => 'yin', false => 'yang' }
171
+ # In a class definition, this would look like
172
+ # class User < Lafcadio::DomainObject
173
+ # boolean 'administrator',
174
+ # { 'enum_type' => Lafcadio::BooleanField::ENUMS_CAPITAL_YES_NO }
175
+ # end
173
176
  #
177
+ # For more fine-grained specification you can pass a hash with the keys
178
+ # +true+ and +false+ using the argument +enums+.
179
+ # class User < Lafcadio::DomainObject
180
+ # boolean 'administrator',
181
+ # { 'enums' => { true => 'yin', false => 'yang' } }
182
+ # end
174
183
  # +enums+ takes precedence over +enum_type+.
175
184
  class BooleanField < ObjectField
176
185
  ENUMS_ONE_ZERO = 0
177
186
  ENUMS_CAPITAL_YES_NO = 1
178
187
 
179
- attr_accessor :enum_type, :enums
188
+ attr_accessor :enum_type
189
+ attr_writer :enums
180
190
 
181
191
  def initialize( domain_class, name )
182
192
  super( domain_class, name )
@@ -184,15 +194,11 @@ module Lafcadio
184
194
  @enums = nil
185
195
  end
186
196
 
187
- def false_enum # :nodoc:
188
- get_enums[false]
189
- end
190
-
191
- def get_enums( value = nil ) # :nodoc:
197
+ def enums( value = nil ) # :nodoc:
192
198
  if @enums
193
199
  @enums
194
200
  elsif @enum_type == ENUMS_ONE_ZERO
195
- if value.class == String
201
+ if value.is_a?( String )
196
202
  { true => '1', false => '0' }
197
203
  else
198
204
  { true => 1, false => 0 }
@@ -204,24 +210,24 @@ module Lafcadio
204
210
  end
205
211
  end
206
212
 
207
- def text_enum_type # :nodoc:
213
+ def false_enum # :nodoc:
214
+ enums[false]
215
+ end
216
+
217
+ def text_enum_type? # :nodoc:
208
218
  @enums ? @enums[true].class == String : @enum_type == ENUMS_CAPITAL_YES_NO
209
219
  end
210
220
 
211
221
  def true_enum( value = nil ) # :nodoc:
212
- get_enums( value )[true]
222
+ enums( value )[true]
213
223
  end
214
224
 
215
225
  def value_for_sql(value) # :nodoc:
216
- if value
217
- vfs = true_enum
218
- else
219
- vfs = false_enum
220
- end
221
- text_enum_type ? "'#{vfs}'" : vfs
226
+ vfs = value ? true_enum : false_enum
227
+ text_enum_type? ? "'#{ vfs }'" : vfs
222
228
  end
223
229
 
224
- def value_from_sql(value, lookupLink = true) # :nodoc:
230
+ def value_from_sql( value ) # :nodoc:
225
231
  value == true_enum( value )
226
232
  end
227
233
  end
@@ -240,7 +246,7 @@ module Lafcadio
240
246
  value ? "'#{value.to_s}'" : 'null'
241
247
  end
242
248
 
243
- def value_from_sql(dbiDate, lookupLink = true) # :nodoc:
249
+ def value_from_sql( dbiDate ) # :nodoc:
244
250
  begin
245
251
  dbiDate ? dbiDate.to_date : nil
246
252
  rescue ArgumentError
@@ -265,16 +271,41 @@ module Lafcadio
265
271
  end
266
272
  end
267
273
 
268
- def value_from_sql(dbi_value, lookupLink = true) # :nodoc:
274
+ def value_from_sql( dbi_value ) # :nodoc:
269
275
  dbi_value ? dbi_value.to_time : nil
270
276
  end
271
277
  end
272
278
 
273
- # A DomainObjectField is used to link from one domain class to another.
279
+ # A DomainObjectField is used to link from one domain class to another. To
280
+ # add such an association in a class definition, call
281
+ # DomainObject.domain_object:
282
+ # class Invoice < Lafcadio::DomainObject
283
+ # domain_object Client
284
+ # end
285
+ # By default, the field name is assumed to be the same as the class name,
286
+ # only lower-cased and camel-case.
287
+ # class LineItem < Lafcadio::DomainObject
288
+ # domain_object Product # field name 'product'
289
+ # domain_object CatalogOrder # field name 'catalog_order'
290
+ # end
291
+ # The field name can be explicitly set as the 2nd argument of
292
+ # DomainObject.domain_object.
293
+ # class Message < Lafcadio::DomainObject
294
+ # domain_object User, 'sender'
295
+ # domain_object User, 'recipient'
296
+ # end
297
+ # Setting +delete_cascade+ to true means that if the domain object being
298
+ # associated to is deleted, this domain object will also be deleted.
299
+ # class Invoice < Lafcadio::DomainObject
300
+ # domain_object Client, 'client', { 'delete_cascade' => true }
301
+ # end
302
+ # cli = Client.new( 'name' => 'big company' ).commit
303
+ # inv = Invoice.new( 'client' => cli ).commit
304
+ # cli.delete!
305
+ # inv_prime = Invoice[inv.pk_id] # => will raise DomainObjectNotFoundError
274
306
  class DomainObjectField < ObjectField
275
- def self.auto_name( linked_type )
276
- linked_type.name =~ /::/
277
- ( $' || linked_type.name ).camel_case_to_underscore
307
+ def self.auto_name( linked_type ) #:nodoc:
308
+ linked_type.basename.camel_case_to_underscore
278
309
  end
279
310
 
280
311
  def self.create_with_args( domain_class, parameters ) #:nodoc:
@@ -290,51 +321,46 @@ module Lafcadio
290
321
  instance
291
322
  end
292
323
 
293
- def self.instantiation_parameters( fieldElt ) #:nodoc:
324
+ def self.creation_parameters( fieldElt ) #:nodoc:
294
325
  parameters = super( fieldElt )
295
326
  linked_typeStr = fieldElt.attributes['linked_type']
296
- linked_type = DomainObject.get_domain_class_from_string( linked_typeStr )
297
- parameters['linked_type'] = linked_type
298
- parameters['delete_cascade'] = fieldElt.attributes['delete_cascade'] == 'y'
327
+ parameters['linked_type'] = Class.by_name linked_typeStr
328
+ parameters['delete_cascade'] =
329
+ ( fieldElt.attributes['delete_cascade'] == 'y' )
299
330
  parameters
300
331
  end
301
332
 
302
333
  attr_reader :linked_type
303
334
  attr_accessor :delete_cascade
304
335
 
305
- # [domain_class] The domain class that this field belongs to.
306
- # [linked_type] The domain class that this field points to.
307
- # [name] The name of this field.
308
- # [delete_cascade] If this is true, deleting the domain object that is
309
- # linked to will cause this domain object to be deleted
310
- # as well.
311
336
  def initialize( domain_class, linked_type, name = nil,
312
- delete_cascade = false )
337
+ delete_cascade = false ) #:nodoc:
313
338
  name = self.class.auto_name( linked_type ) unless name
314
339
  super( domain_class, name )
315
340
  ( @linked_type, @delete_cascade ) = linked_type, delete_cascade
316
341
  end
317
342
 
318
- def value_from_sql(string) #:nodoc:
319
- string != nil ? DomainObjectProxy.new(@linked_type, string.to_i) : nil
320
- end
321
-
322
343
  def value_for_sql(value) #:nodoc:
323
- if !value
344
+ if value.nil?
324
345
  "null"
325
346
  elsif value.pk_id
326
347
  value.pk_id
327
348
  else
328
- raise( DomainObjectInitError, "Can't commit #{name} without pk_id",
329
- caller )
349
+ raise(
350
+ DomainObjectInitError, "Can't commit #{name} without pk_id", caller
351
+ )
330
352
  end
331
353
  end
332
354
 
333
- def verify_non_nil(value, pk_id) #:nodoc:
355
+ def value_from_sql(string) #:nodoc:
356
+ string ? DomainObjectProxy.new(@linked_type, string.to_i) : nil
357
+ end
358
+
359
+ def verify_non_nil_value(value, pk_id) #:nodoc:
334
360
  super
335
361
  if @linked_type != @domain_class && pk_id
336
362
  subsetDomainObjectField = @linked_type.class_fields.find { |field|
337
- field.class == SubsetDomainObjectField && field.subset_field == @name
363
+ field.is_a?( SubsetDomainObjectField ) && field.subset_field == @name
338
364
  }
339
365
  if subsetDomainObjectField
340
366
  verify_subset_link_field( subsetDomainObjectField, pk_id )
@@ -342,11 +368,10 @@ module Lafcadio
342
368
  end
343
369
  end
344
370
 
345
- def verify_subset_link_field( subsetDomainObjectField, pk_id )
371
+ def verify_subset_link_field( subsetDomainObjectField, pk_id ) #:nodoc:
346
372
  begin
347
- prevObj = ObjectStore.get_object_store.get( domain_class, pk_id )
348
- prevObjLinkedTo = prevObj.send(name)
349
- possiblyMyObj = prevObjLinkedTo.send(subsetDomainObjectField.name)
373
+ prevObjLinkedTo = domain_class[pk_id].send(name)
374
+ possiblyMyObj = prevObjLinkedTo.send subsetDomainObjectField.name
350
375
  if possiblyMyObj && possiblyMyObj.pk_id == pk_id
351
376
  cantChangeMsg = "You can't change that."
352
377
  raise FieldValueError, cantChangeMsg, caller
@@ -369,7 +394,7 @@ module Lafcadio
369
394
  super( domain_class, name )
370
395
  end
371
396
 
372
- def verify_non_nil(value, pk_id) #:nodoc:
397
+ def verify_non_nil_value(value, pk_id) #:nodoc:
373
398
  super(value, pk_id)
374
399
  if !EmailField.valid_address(value)
375
400
  raise(
@@ -382,24 +407,17 @@ module Lafcadio
382
407
  end
383
408
 
384
409
  # EnumField represents an enumerated field that can only be set to one of a
385
- # set range of string values. To set the enumeration in the class definition
386
- # XML, use the following format:
387
- # <field name="flavor" class="EnumField">
388
- # <enums>
389
- # <enum>Vanilla</enum>
390
- # <enum>Chocolate</enum>
391
- # <enum>Lychee</enum>
392
- # </enums>
393
- # </field>
394
- # If you're defining the field in Ruby, you can simply pass in an array of
395
- # enums as the +enums+ argument.
396
- #
410
+ # set range of string values. To set the enumeration in the class definition,
411
+ # pass in an Array of values as +enums+.
412
+ # class IceCream < Lafcadio::DomainObject
413
+ # enum 'flavor', { 'enums' => %w( Vanilla Chocolate Lychee ) }
414
+ # end
397
415
  class EnumField < StringField
398
416
  def self.create_with_args( domain_class, parameters ) #:nodoc:
399
417
  self.new( domain_class, parameters['name'], parameters['enums'] )
400
418
  end
401
419
 
402
- def self.enum_queue_hash( fieldElt )
420
+ def self.enum_queue_hash( fieldElt ) #:nodoc:
403
421
  enumValues = []
404
422
  fieldElt.elements.each( 'enums/enum' ) { |enumElt|
405
423
  enumValues << enumElt.attributes['key']
@@ -408,7 +426,7 @@ module Lafcadio
408
426
  QueueHash.new( *enumValues )
409
427
  end
410
428
 
411
- def self.instantiation_parameters( fieldElt ) #:nodoc:
429
+ def self.creation_parameters( fieldElt ) #:nodoc:
412
430
  parameters = super( fieldElt )
413
431
  if fieldElt.elements['enums'][1].attributes['key']
414
432
  parameters['enums'] = enum_queue_hash( fieldElt )
@@ -423,11 +441,7 @@ module Lafcadio
423
441
 
424
442
  attr_reader :enums
425
443
 
426
- # [domain_class] The domain class that this field belongs to.
427
- # [name] The name of this domain class.
428
- # [enums] An array of Strings representing the possible choices for
429
- # this field.
430
- def initialize( domain_class, name, enums )
444
+ def initialize( domain_class, name, enums ) #:nodoc:
431
445
  super( domain_class, name )
432
446
  if enums.class == Array
433
447
  @enums = QueueHash.new_from_array enums
@@ -437,10 +451,10 @@ module Lafcadio
437
451
  end
438
452
 
439
453
  def value_for_sql(value) #:nodoc:
440
- value != '' ?(super(value)) : 'null'
454
+ value != '' ? (super(value)) : 'null'
441
455
  end
442
456
 
443
- def verify_non_nil( value, pk_id ) #:nodoc:
457
+ def verify_non_nil_value( value, pk_id ) #:nodoc:
444
458
  super
445
459
  if @enums[value].nil?
446
460
  key_str = '[ ' +
@@ -457,10 +471,6 @@ module Lafcadio
457
471
 
458
472
  # FloatField represents a decimal value.
459
473
  class FloatField < ObjectField
460
- def self.create_with_args( domain_class, parameters ) #:nodoc:
461
- self.new( domain_class, parameters['name'] )
462
- end
463
-
464
474
  def self.value_type #:nodoc:
465
475
  Numeric
466
476
  end
@@ -487,16 +497,16 @@ module Lafcadio
487
497
  end
488
498
  end
489
499
 
490
- class PrimaryKeyField < IntegerField
500
+ class PrimaryKeyField < IntegerField #:nodoc:
491
501
  def initialize( domain_class )
492
502
  super( domain_class, 'pk_id' )
493
- @not_null = false
503
+ @not_nil = false
494
504
  end
495
505
  end
496
506
 
497
- # A StateField is a specialized subclass of EnumField; its possible values are
498
- # any of the 50 states of the United States, stored as each state's two-letter
499
- # postal code.
507
+ # A StateField is a specialized subclass of EnumField; its possible value
508
+ # are any of the 50 states of the United States, stored as each state's
509
+ # two-letter postal code.
500
510
  class StateField < EnumField
501
511
  def initialize( domain_class, name = "state" )
502
512
  super( domain_class, name, USCommerce::UsStates.states )
@@ -509,7 +519,7 @@ module Lafcadio
509
519
  parameters['subset_field'], parameters['name'] )
510
520
  end
511
521
 
512
- def self.instantiation_parameters( fieldElt )
522
+ def self.creation_parameters( fieldElt )
513
523
  parameters = super( fieldElt )
514
524
  parameters['subset_field'] = fieldElt.attributes['subset_field']
515
525
  parameters
@@ -554,10 +564,10 @@ module Lafcadio
554
564
  class TimeStampField < DateTimeField #:nodoc:
555
565
  def initialize( domain_class, name = 'timeStamp' )
556
566
  super( domain_class, name )
557
- @not_null = false
567
+ @not_nil = false
558
568
  end
559
569
 
560
- def db_will_automatically_write
570
+ def db_will_automatically_write?
561
571
  true
562
572
  end
563
573
  end