sdb_dal 0.0.4 → 0.0.5
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/sdb_dal/domain_object.rb +475 -422
- data/lib/sdb_dal/lazy_loading_text.rb +2 -0
- data/lib/sdb_dal/memory_repository.rb +54 -23
- data/lib/sdb_dal/repository.rb +356 -305
- data/lib/sdb_dal/repository_factory.rb +4 -3
- data/lib/sdb_dal/s3.rb +69 -57
- data/lib/sdb_dal/sdb_monkey_patch.rb +47 -0
- data/lib/sdb_dal/storage.rb +8 -4
- metadata +4 -3
@@ -6,76 +6,94 @@ require File.dirname(__FILE__) +"/index_description.rb"
|
|
6
6
|
require File.dirname(__FILE__) +"/lazy_loading_text.rb"
|
7
7
|
require File.dirname(__FILE__) +"/repository_factory.rb"
|
8
8
|
module SdbDal
|
9
|
-
class DomainObject
|
9
|
+
class DomainObject
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
@attribute_values[attribute_name]=value
|
11
|
+
@@items_to_commit=nil
|
12
|
+
@@transaction_depth=0
|
13
|
+
attr_accessor :sdb_key
|
14
|
+
def initialize(options={})
|
15
|
+
@attribute_values=HashWithIndifferentAccess.new
|
16
|
+
|
17
|
+
self.class.attribute_descriptions.each do |attribute_name,description|
|
18
|
+
value=options[attribute_name]
|
19
|
+
value=value || options[attribute_name.intern]
|
20
|
+
if !description.is_collection && value.respond_to?(:flatten) && value.length==1
|
21
|
+
value=value[0]
|
22
|
+
end
|
23
|
+
@attribute_values[attribute_name]=value
|
24
|
+
|
26
25
|
end
|
26
|
+
@accessor_cache={}
|
27
|
+
@repository=options[:repository]
|
27
28
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
29
|
+
|
30
|
+
|
31
|
+
def self.primary_key_attribute_names
|
32
|
+
return @primary_key_attribute_names
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def id
|
37
|
+
return @attribute_values[:id] if self.class.attribute_descriptions[:id]
|
38
|
+
return base.id
|
39
|
+
end
|
40
|
+
def set_map(keys,values)
|
41
|
+
(0..keys.length-1).each do |i|
|
42
|
+
key=keys[i]
|
43
|
+
value=values[i]
|
44
|
+
@attribute_values[key]=value
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
def self.index_names
|
52
|
+
[]
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.index(name,columns,options={})
|
56
|
+
return if self.index_descriptions[name]
|
57
|
+
$columns_xxx=columns
|
58
|
+
class_eval <<-GETTERDONE
|
59
|
+
|
60
|
+
@@index_descriptions||={}
|
61
|
+
unless @@index_descriptions.has_key?(:#{name})
|
62
|
+
@@index_names||=[]
|
63
|
+
@@index_names<<:#{name}
|
46
64
|
|
47
65
|
def self.index_names
|
48
66
|
@@index_names
|
49
67
|
end
|
50
68
|
|
51
|
-
attribute_description=SdbDal::DomainAttributeDescription.new(name,:string,{})
|
52
|
-
@@index_descriptions[name]=SdbDal::IndexDescription.new(name
|
53
|
-
|
54
|
-
|
69
|
+
attribute_description=SdbDal::DomainAttributeDescription.new(:#{name},:string,{})
|
70
|
+
@@index_descriptions[:#{name}]=SdbDal::IndexDescription.new(:#{name},$columns_xxx)
|
71
|
+
end
|
72
|
+
GETTERDONE
|
55
73
|
|
56
|
-
|
57
|
-
|
74
|
+
getter_params=[]
|
75
|
+
finder_code=""
|
58
76
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
77
|
+
params=[]
|
78
|
+
columns.each do |column|
|
79
|
+
if column.respond_to?(:transform)
|
80
|
+
finder_code<<"h[:#{column.name}]=#{column.name.to_s.downcase}\n"
|
81
|
+
getter_params<<"@attribute_values[:#{column.source_column}]"
|
64
82
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
83
|
+
params<<"#{column.name.to_s.downcase}"
|
84
|
+
else
|
85
|
+
finder_code<<"h[:#{column}]=#{column.to_s.downcase}\n"
|
86
|
+
getter_params<<"@attribute_values[:#{column}]"
|
87
|
+
params<<"#{column.to_s.downcase}"
|
70
88
|
|
71
|
-
|
89
|
+
end
|
72
90
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
91
|
+
end
|
92
|
+
find_scope=":all"
|
93
|
+
if options[:unique]
|
94
|
+
find_scope=":first"
|
95
|
+
end
|
96
|
+
class_eval <<-GETTERDONE
|
79
97
|
def #{name}
|
80
98
|
return self.class.calculate_#{name}(#{getter_params.join(",")})
|
81
99
|
end
|
@@ -93,21 +111,25 @@ class DomainObject
|
|
93
111
|
options[:index_value]=self.calculate_#{name}(#{params.join(",")})
|
94
112
|
find(#{find_scope},options)
|
95
113
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
114
|
+
GETTERDONE
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
@@index_descriptions ||={}
|
119
|
+
|
120
|
+
def self.index_descriptions
|
100
121
|
@@index_descriptions || {}
|
101
122
|
end
|
102
|
-
|
103
|
-
|
123
|
+
|
124
|
+
def self.data_attribute(name,type,options={})
|
125
|
+
class_eval <<-GETTERDONE
|
104
126
|
@@attribute_descriptions||=HashWithIndifferentAccess.new
|
105
127
|
|
106
128
|
@@non_clob_attribute_names||=[]
|
107
129
|
@@clob_attribute_names||=[]
|
108
130
|
@@on_destroy_blocks||=[]
|
109
131
|
def self.on_destroy_blocks
|
110
|
-
@@on_destroy_blocks
|
132
|
+
@@on_destroy_blocks || []
|
111
133
|
end
|
112
134
|
def self.attribute_descriptions
|
113
135
|
@@attribute_descriptions
|
@@ -127,37 +149,39 @@ class DomainObject
|
|
127
149
|
return true
|
128
150
|
end
|
129
151
|
end
|
130
|
-
|
131
|
-
|
152
|
+
GETTERDONE
|
153
|
+
return if self.attribute_descriptions.has_key?(name)
|
132
154
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
155
|
+
attribute_description=DomainAttributeDescription.new(name,type,options)
|
156
|
+
self.attribute_descriptions[name] = attribute_description
|
157
|
+
@primary_key_attribute_names||=[]
|
158
|
+
if attribute_description.is_primary_key
|
159
|
+
@primary_key_attribute_names<<name
|
160
|
+
pk_code="[:#{@primary_key_attribute_names.join(",:")}]"
|
161
|
+
class_eval <<-GETTERDONE
|
162
|
+
def self.primary_key_attribute_names
|
163
|
+
#{pk_code}
|
139
164
|
end
|
140
165
|
def self.exists?(primary_key)
|
141
166
|
return self.find(primary_key)!=nil
|
142
167
|
end
|
143
168
|
|
144
|
-
|
145
|
-
end
|
146
|
-
if !attribute_description.is_primary_key
|
147
|
-
if attribute_description.value_type==:clob
|
148
|
-
clob_attribute_names<<attribute_description.name
|
149
|
-
else
|
150
|
-
non_clob_attribute_names<<attribute_description.name
|
169
|
+
GETTERDONE
|
151
170
|
end
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
171
|
+
if attribute_description.value_type==:clob
|
172
|
+
clob_attribute_names<<attribute_description.name
|
173
|
+
else
|
174
|
+
non_clob_attribute_names<<attribute_description.name
|
175
|
+
end
|
176
|
+
|
177
|
+
scope=":all"
|
178
|
+
if(options[:unique] && options[:unique]==true)
|
179
|
+
scope=":first"
|
180
|
+
end
|
181
|
+
if type==:reference_set
|
158
182
|
|
159
183
|
|
160
|
-
|
184
|
+
class_eval <<-GETTERDONE
|
161
185
|
def #{attribute_description.name}
|
162
186
|
result=@attribute_values[:#{attribute_description.name}] || []
|
163
187
|
result=result.sort_by{|item|item.index}
|
@@ -177,10 +201,10 @@ class DomainObject
|
|
177
201
|
end
|
178
202
|
end
|
179
203
|
|
180
|
-
|
204
|
+
GETTERDONE
|
181
205
|
|
182
|
-
|
183
|
-
|
206
|
+
elsif type==:clob
|
207
|
+
class_eval <<-GETTERDONE
|
184
208
|
|
185
209
|
def #{attribute_description.name}
|
186
210
|
if @attribute_values[:#{attribute_description.name}]!= nil &&
|
@@ -191,17 +215,17 @@ class DomainObject
|
|
191
215
|
end
|
192
216
|
end
|
193
217
|
|
194
|
-
|
195
|
-
|
218
|
+
GETTERDONE
|
219
|
+
else
|
196
220
|
|
197
|
-
|
221
|
+
class_eval <<-GETTERDONE
|
198
222
|
def #{attribute_description.name}
|
199
223
|
return @attribute_values[:#{attribute_description.name}]
|
200
224
|
end
|
201
225
|
|
202
|
-
|
203
|
-
|
204
|
-
|
226
|
+
GETTERDONE
|
227
|
+
end
|
228
|
+
class_eval <<-GETTERDONE
|
205
229
|
|
206
230
|
def #{attribute_description.name}=(xvalue)
|
207
231
|
@attribute_values[:#{attribute_description.name}] =xvalue
|
@@ -214,45 +238,50 @@ class DomainObject
|
|
214
238
|
options[:params]={:#{attribute_description.name}=>#{attribute_description.name.to_s.downcase}}
|
215
239
|
find(#{scope},options)
|
216
240
|
end
|
217
|
-
|
218
|
-
|
241
|
+
GETTERDONE
|
242
|
+
end
|
219
243
|
|
220
|
-
|
244
|
+
def self.belongs_to(domain_class,foreign_key_attribute=nil,accesser_attribute_name=nil,options={})
|
221
245
|
|
222
|
-
|
223
|
-
|
246
|
+
foreign_key_attribute ||= "#{domain_class.to_s.downcase}_id".to_sym
|
247
|
+
accesser_attribute_name ||=domain_class.to_s.downcase
|
224
248
|
|
225
|
-
|
249
|
+
class_eval <<-GETTERDONE
|
226
250
|
def #{accesser_attribute_name}
|
227
251
|
#{domain_class}.find(self.#{foreign_key_attribute})
|
228
252
|
end
|
229
253
|
|
230
|
-
|
231
|
-
end
|
232
|
-
def self.many_to_many(domain_class,
|
233
|
-
through_class,
|
234
|
-
reflecting_key_attribute=nil,
|
235
|
-
foriegn_key_attribute=nil,
|
236
|
-
accesser_attribute_name=nil,
|
237
|
-
options={})
|
238
|
-
reflecting_key_attribute ||= (self.name+"_"+primary_key_attribute_name.to_s).downcase.to_sym
|
239
|
-
accesser_attribute_name ||=domain_class.to_s.downcase+'s'
|
240
|
-
order=""
|
241
|
-
if options[:order_by]
|
242
|
-
if options[:order]
|
243
|
-
order="result=DomainObject.sort_result(result,:#{options[:order_by]},:#{options[:order]})"
|
244
|
-
else
|
245
|
-
order="result=DomainObject.sort_result(result,:#{options[:order_by]},:ascending)"
|
246
|
-
end
|
254
|
+
GETTERDONE
|
247
255
|
end
|
256
|
+
def self.many_to_many(domain_class,
|
257
|
+
through_class,
|
258
|
+
reflecting_key_attributes=nil,
|
259
|
+
foriegn_key_attribute=nil,
|
260
|
+
accesser_attribute_name=nil,
|
261
|
+
options={})
|
262
|
+
reflecting_key_attributes ||= primary_key_attribute_names.map{|x|self.name+"_"+x.to_s}
|
263
|
+
reflecting_key_attributes =arrayify(reflecting_key_attributes)
|
264
|
+
reflecting_array_code="[:"+reflecting_key_attributes.join(",:")+"]"
|
265
|
+
|
266
|
+
accesser_attribute_name ||=domain_class.to_s.downcase+'s'
|
267
|
+
order=""
|
268
|
+
if options[:order_by]
|
269
|
+
if options[:order]
|
270
|
+
order="result=DomainObject.sort_result(result,:#{options[:order_by]},:#{options[:order]})"
|
271
|
+
else
|
272
|
+
order="result=DomainObject.sort_result(result,:#{options[:order_by]},:ascending)"
|
273
|
+
end
|
274
|
+
end
|
248
275
|
|
249
276
|
|
250
|
-
|
251
|
-
|
252
|
-
|
277
|
+
foriegn_key_attributes=options[:foriegn_key_attribute] || "#{domain_class.to_s.downcase}_id".to_sym
|
278
|
+
foriegn_key_attributes=arrayify(foriegn_key_attributes)
|
279
|
+
fkey_array_code="[:"+foriegn_key_attributes.join(",:")+"]"
|
280
|
+
class_eval <<-XXDONE
|
281
|
+
|
253
282
|
def #{accesser_attribute_name}
|
254
283
|
#unless @accessor_cache.has_key? :#{accesser_attribute_name}
|
255
|
-
|
284
|
+
through_results= #{through_class}.find(:all,:map=>{:keys=>#{reflecting_array_code},:values=>DomainObject.arrayify(self.primary_key)})
|
256
285
|
result=[]
|
257
286
|
through_results.each do |through_result|
|
258
287
|
item= #{domain_class}.find(through_result.#{foriegn_key_attribute})
|
@@ -268,378 +297,402 @@ class DomainObject
|
|
268
297
|
end
|
269
298
|
def connect_#{domain_class.to_s.downcase}(#{domain_class.to_s.downcase})
|
270
299
|
connector=#{through_class}.new
|
271
|
-
connector
|
272
|
-
connector
|
300
|
+
connector.set_map(#{fkey_array_code},DomainObject.arrayify(#{domain_class.to_s.downcase}.primary_key))
|
301
|
+
connector.set_map(#{reflecting_array_code},DomainObject.arrayify(self.primary_key))
|
273
302
|
connector.save
|
274
303
|
end
|
275
|
-
|
304
|
+
XXDONE
|
276
305
|
|
277
306
|
|
278
|
-
end
|
279
|
-
def DomainObject.transaction
|
280
|
-
@@items_to_commit||=[]
|
281
|
-
@@transaction_depth+=1
|
282
|
-
begin
|
283
|
-
yield
|
284
|
-
rescue # catch all
|
285
|
-
raise $! # rethrow
|
286
|
-
ensure
|
287
|
-
@@transaction_depth-=1
|
288
|
-
|
289
307
|
end
|
308
|
+
|
309
|
+
|
310
|
+
def DomainObject.transaction
|
311
|
+
@@items_to_commit||=[]
|
312
|
+
@@transaction_depth+=1
|
313
|
+
begin
|
314
|
+
yield
|
315
|
+
rescue # catch all
|
316
|
+
raise $! # rethrow
|
317
|
+
ensure
|
318
|
+
@@transaction_depth-=1
|
319
|
+
|
320
|
+
end
|
290
321
|
|
291
322
|
|
292
|
-
|
323
|
+
if @@transaction_depth==0
|
293
324
|
|
294
|
-
|
295
|
-
|
325
|
+
@@items_to_commit.uniq.each do |item |
|
326
|
+
item.save!
|
327
|
+
end
|
328
|
+
@@items_to_commit=[]
|
296
329
|
end
|
297
|
-
@@items_to_commit=[]
|
298
|
-
end
|
299
330
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
331
|
+
end
|
332
|
+
def DomainObject.sort_result(results,sort_by,order=:ascending)
|
333
|
+
non_null_results=[]
|
334
|
+
null_results=[]
|
335
|
+
results.each { |i|
|
336
|
+
sorter_value=i.get_attribute(sort_by)
|
337
|
+
if sorter_value
|
338
|
+
non_null_results<<i
|
339
|
+
else
|
340
|
+
null_results<<i
|
341
|
+
end
|
342
|
+
}
|
343
|
+
sorted_results=non_null_results.sort{ |a,b|
|
313
344
|
a_val= a.get_sortable_attribute(sort_by)
|
314
345
|
b_val= b.get_sortable_attribute(sort_by)
|
315
346
|
|
316
|
-
|
317
|
-
|
347
|
+
a_val <=> b_val
|
348
|
+
}
|
318
349
|
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
end
|
334
|
-
def self.has_many(domain_class,
|
335
|
-
reflecting_key_attribute=nil,
|
336
|
-
accesser_attribute_name=nil,
|
337
|
-
options={})
|
338
|
-
|
339
|
-
reflecting_key_attribute ||= (self.name+"_"+primary_key_attribute_name.to_s).downcase.to_sym
|
340
|
-
accesser_attribute_name ||=domain_class.to_s.downcase+'s'
|
341
|
-
order=""
|
342
|
-
if options[:order_by]
|
343
|
-
order=",:order_by=>:#{options[:order_by]}"
|
344
|
-
end
|
345
|
-
if options[:order]
|
346
|
-
order<<",:order=>:#{options[:order]}"
|
350
|
+
if order!=:ascending
|
351
|
+
sorted_results.reverse!
|
352
|
+
end
|
353
|
+
sorted_results.concat( null_results)
|
354
|
+
sorted_results
|
355
|
+
end
|
356
|
+
def get_sortable_attribute(attr_name)
|
357
|
+
a_val= self.get_attribute(attr_name)
|
358
|
+
return 0 unless a_val
|
359
|
+
if a_val.class== Time
|
360
|
+
return a_val.to_f
|
361
|
+
else
|
362
|
+
return a_val
|
363
|
+
end
|
347
364
|
end
|
365
|
+
def self.has_many(domain_class,
|
366
|
+
reflecting_key_attributes=nil,
|
367
|
+
accesser_attribute_name=nil,
|
368
|
+
options={})
|
369
|
+
reflecting_key_attributes ||= primary_key_attribute_names.map{|x|self.name.downcase+"_"+x.to_s}
|
370
|
+
reflecting_key_attributes =arrayify(reflecting_key_attributes)
|
371
|
+
reflecting_array_code="[:"+reflecting_key_attributes.join(",:")+"]"
|
372
|
+
|
373
|
+
accesser_attribute_name ||=domain_class.to_s.downcase+'s'
|
374
|
+
order=""
|
375
|
+
if options[:order_by]
|
376
|
+
order=",:order_by=>:#{options[:order_by]}"
|
377
|
+
end
|
378
|
+
if options[:order]
|
379
|
+
order<<",:order=>:#{options[:order]}"
|
380
|
+
end
|
348
381
|
|
349
|
-
|
382
|
+
if options[:dependent]
|
350
383
|
|
351
|
-
|
384
|
+
class_eval <<-XXDONE
|
352
385
|
|
353
386
|
on_destroy_blocks<<"#{accesser_attribute_name}.each{|item|item.destroy}"
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
class_eval <<-XXDONE
|
387
|
+
XXDONE
|
388
|
+
end
|
389
|
+
# if options[:tracking]
|
390
|
+
# #add add_xxx method
|
391
|
+
# #add to list of tracker attributes
|
392
|
+
#
|
393
|
+
# class_eval <<-XXDONE
|
394
|
+
#
|
395
|
+
# @@attribute_descriptions[ :#{accesser_attribute_name}_tracker]=TrackerDescription.new(:#{accesser_attribute_name}_tracker,:#{domain_class},:#{reflecting_key_attribute})
|
396
|
+
# # def #{accesser_attribute_name} # find_tracked_list(:#{accesser_attribute_name}_tracker,#{domain_class},:#{reflecting_key_attribute})
|
397
|
+
# # end
|
398
|
+
# def add_to_#{accesser_attribute_name}(item)
|
399
|
+
# # item.save!
|
400
|
+
# add_to_tracked_list(:#{accesser_attribute_name}_tracker,#{domain_class.to_s},:#{reflecting_key_attribute},item.primary_key)
|
401
|
+
# item.set_attribute(:#{reflecting_key_attribute},self.primary_key)
|
402
|
+
#
|
403
|
+
#
|
404
|
+
# # end
|
405
|
+
# XXDONE
|
406
|
+
# else
|
407
|
+
class_eval <<-XXDONE
|
376
408
|
def #{accesser_attribute_name}
|
377
409
|
if !@accessor_cache.has_key? :#{accesser_attribute_name}
|
378
|
-
|
410
|
+
result= #{domain_class}.find(:all,:map=>{:keys=>#{reflecting_array_code},:values=>DomainObject::arrayify(self.primary_key)}#{order})
|
411
|
+
@accessor_cache[:#{accesser_attribute_name}]=result || []
|
379
412
|
end
|
380
|
-
return @accessor_cache[:#{accesser_attribute_name}]
|
413
|
+
return @accessor_cache[:#{accesser_attribute_name}]
|
381
414
|
end
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
@attribute_values[ self.class.primary_key_attribute_name]
|
394
|
-
end
|
395
|
-
def primary_key=(value)
|
396
|
-
@attribute_values[ self.class.primary_key_attribute_name]=value
|
397
|
-
end
|
398
|
-
def method_missing(method_symbol, *arguments) #:nodoc:
|
399
|
-
method_name = method_symbol.to_s
|
415
|
+
XXDONE
|
416
|
+
# end
|
417
|
+
end
|
418
|
+
def self.AttributeDescription(name)
|
419
|
+
return attribute_descriptions[name]
|
420
|
+
end
|
421
|
+
def self.ColumnDescription(name)
|
422
|
+
return column_descriptions[name]
|
423
|
+
end
|
424
|
+
def primary_key
|
400
425
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
426
|
+
result=[]
|
427
|
+
self.class.primary_key_attribute_names.each do |key_part|
|
428
|
+
result<<@attribute_values[key_part ]
|
429
|
+
end
|
430
|
+
return result[0] if result.length==1
|
431
|
+
return result
|
432
|
+
end
|
433
|
+
def primary_key=(value)
|
434
|
+
key=DomainObject::arrayify(value)
|
435
|
+
self.class.primary_key_attribute_names.each do |key_part|
|
436
|
+
|
437
|
+
@attribute_values[ key_part]=key.shift
|
438
|
+
end
|
439
|
+
end
|
440
|
+
def method_missing(method_symbol, *arguments) #:nodoc:
|
441
|
+
method_name = method_symbol.to_s
|
442
|
+
|
443
|
+
case method_name.last
|
444
|
+
when "="
|
445
|
+
if @attribute_values.has_key?(method_name.first(-1))
|
446
|
+
@attribute_values[method_name.first(-1)] = arguments.first
|
447
|
+
else
|
448
|
+
super
|
449
|
+
end
|
450
|
+
when "?"
|
451
|
+
@attribute_values[method_name.first(-1)]
|
405
452
|
else
|
406
|
-
super
|
453
|
+
@attribute_values.has_key?(method_name) ? @attribute_values[method_name] : super
|
407
454
|
end
|
408
|
-
when "?"
|
409
|
-
@attribute_values[method_name.first(-1)]
|
410
|
-
else
|
411
|
-
@attribute_values.has_key?(method_name) ? @attribute_values[method_name] : super
|
412
455
|
end
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
self.class.index_names.each do |name|
|
456
|
+
def index_values
|
457
|
+
result={}
|
458
|
+
self.class.index_names.each do |name|
|
417
459
|
|
418
|
-
|
460
|
+
result[name]= self.send("#{name}")
|
419
461
|
|
462
|
+
end
|
463
|
+
result
|
420
464
|
end
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
result= "<#{self.class.table_name}>"
|
431
|
-
attributes.each do |key,value|
|
465
|
+
def set_attribute(name,value)
|
466
|
+
@attribute_values[name]=value
|
467
|
+
end
|
468
|
+
def get_attribute(name)
|
469
|
+
@attribute_values[name]
|
470
|
+
end
|
471
|
+
def to_xml
|
472
|
+
result= "<#{self.class.table_name}>"
|
473
|
+
attributes.each do |key,value|
|
432
474
|
if value.respond_to?(:flatten)
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
475
|
+
result<<"<#{key}>"
|
476
|
+
value.each do |sub_value|
|
477
|
+
result<<"<value>#{h sub_value.to_s}</value>"
|
478
|
+
end
|
479
|
+
result<<"</#{key}>"
|
438
480
|
else
|
439
481
|
result<<"<#{key}>#{h value.to_s}</#{key}>"
|
440
482
|
end
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
end
|
445
|
-
def destroy(options={})
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
483
|
+
end
|
484
|
+
result<< "</#{self.class.table_name}>"
|
485
|
+
result
|
486
|
+
end
|
487
|
+
def destroy(options={})
|
488
|
+
if self.class.on_destroy_blocks
|
489
|
+
self.class.on_destroy_blocks.each do |block|
|
490
|
+
instance_eval <<-XXDONE
|
491
|
+
#{block}
|
492
|
+
|
493
|
+
XXDONE
|
494
|
+
|
495
|
+
end
|
496
|
+
end
|
497
|
+
if self.primary_key
|
498
|
+
self.repository(options).destroy(self.table_name,self.primary_key)
|
499
|
+
end
|
455
500
|
end
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
501
|
+
def attributes
|
502
|
+
result={}
|
503
|
+
# #todo refactor to avoid this copy
|
504
|
+
self.class.attribute_descriptions.values.each do |description|
|
505
|
+
if !description.is_clob || is_dirty(description.name)
|
506
|
+
result[description.name]=@attribute_values[description.name]
|
507
|
+
end
|
463
508
|
end
|
509
|
+
return result
|
464
510
|
end
|
465
|
-
return result
|
466
|
-
end
|
467
511
|
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
512
|
+
def find_tracked_list(tracking_attribute,other_class,reflecting_attribute)
|
513
|
+
# #if the attribute has no value do a query
|
514
|
+
list=@attribute_values[tracking_attribute]
|
515
|
+
if !list
|
516
|
+
list=other_class.query_ids(:params=>{reflecting_attribute=>self.primary_key})
|
517
|
+
@attribute_values[tracking_attribute]=list
|
518
|
+
self.save!
|
519
|
+
end
|
476
520
|
|
477
|
-
|
521
|
+
return other_class.find_list(list)
|
478
522
|
|
479
|
-
|
523
|
+
end
|
480
524
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
525
|
+
def add_to_tracked_list(tracking_attribute,other_class,reflecting_attribute,value)
|
526
|
+
list=@attribute_values[tracking_attribute]
|
527
|
+
if !list
|
528
|
+
list=other_class.query_ids(:params=>{reflecting_attribute=>self.primary_key})
|
485
529
|
|
486
|
-
|
487
|
-
|
488
|
-
|
530
|
+
end
|
531
|
+
list<<value
|
532
|
+
@attribute_values[tracking_attribute]=list.uniq
|
489
533
|
|
490
|
-
end
|
491
|
-
def save!(options={})
|
492
|
-
save(options)
|
493
|
-
end
|
494
|
-
def save(options={})
|
495
|
-
if !self.primary_key
|
496
|
-
self.primary_key= UUID.generate.to_s
|
497
534
|
end
|
535
|
+
def save!(options={})
|
536
|
+
save(options)
|
537
|
+
end
|
538
|
+
def save(options={})
|
539
|
+
if !self.primary_key
|
540
|
+
self.primary_key= UUID.generate.to_s
|
541
|
+
end
|
498
542
|
|
499
|
-
|
500
|
-
|
501
|
-
|
543
|
+
if @@transaction_depth>0
|
544
|
+
# #we are in a transaction. wait to commit
|
545
|
+
@@items_to_commit<<self
|
502
546
|
|
503
|
-
|
504
|
-
|
505
|
-
|
547
|
+
else
|
548
|
+
temp_accessor_cache=@accessor_cache
|
549
|
+
@accessor_cache=nil
|
506
550
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
551
|
+
# $service.put_attributes(class_object.table_name,item.send(name_column),attributes,true)
|
552
|
+
attributes={}
|
553
|
+
# #todo refactor to avoid this copy
|
554
|
+
self.class.attribute_descriptions.values.each do |description|
|
555
|
+
if !description.is_clob || is_dirty(description.name)
|
556
|
+
value=@attribute_values[description.name]
|
557
|
+
attributes[description]=value
|
558
|
+
end
|
515
559
|
|
516
560
|
|
517
561
|
|
518
|
-
|
519
|
-
|
562
|
+
end
|
563
|
+
self.index_values.each do |name,value|
|
520
564
|
|
521
|
-
|
522
|
-
|
565
|
+
attributes[self.class.index_descriptions[name]]=value
|
566
|
+
end
|
523
567
|
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
end
|
529
|
-
def table_name
|
530
|
-
return self.class.table_name
|
531
|
-
end
|
532
|
-
def DomainObject.table_name
|
533
|
-
return self.name
|
534
|
-
end
|
535
|
-
# def find
|
536
|
-
#
|
537
|
-
# attributes=repository.find(self.class.name,self.primary_key,@@non_clob_attribute_names,@@clob_attribute_names)
|
538
|
-
# attributes.each do |key,value|
|
539
|
-
# @attribute_values[key]=value
|
540
|
-
# end
|
541
|
-
# end
|
542
|
-
def repository(options=nil)
|
568
|
+
self.repository(options).save(self.table_name,self.primary_key,attributes,self.class.index_descriptions)
|
569
|
+
@accessor_cache=temp_accessor_cache
|
570
|
+
end
|
543
571
|
|
544
|
-
if options and options.has_key?(:repository)
|
545
|
-
return options[:repository]
|
546
572
|
end
|
547
|
-
|
548
|
-
return
|
573
|
+
def table_name
|
574
|
+
return self.class.table_name
|
549
575
|
end
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
576
|
+
def DomainObject.table_name
|
577
|
+
return self.name
|
578
|
+
end
|
579
|
+
# def find
|
580
|
+
#
|
581
|
+
# attributes=repository.find(self.class.name,self.primary_key,@@non_clob_attribute_names,@@clob_attribute_names)
|
582
|
+
# attributes.each do |key,value|
|
583
|
+
# @attribute_values[key]=value
|
584
|
+
# end
|
585
|
+
# end
|
586
|
+
def repository(options=nil)
|
555
587
|
|
556
|
-
if options.has_key?(:repository)
|
588
|
+
if options and options.has_key?(:repository)
|
557
589
|
return options[:repository]
|
558
590
|
end
|
591
|
+
if @repository
|
592
|
+
return @repository
|
593
|
+
end
|
594
|
+
|
595
|
+
return self.class.repository
|
596
|
+
end
|
597
|
+
class << self
|
598
|
+
def repository(options={})
|
599
|
+
|
600
|
+
if options.has_key?(:repository)
|
601
|
+
return options[:repository]
|
602
|
+
end
|
559
603
|
|
560
|
-
|
604
|
+
$repository ||= RepositoryFactory.instance(options)
|
561
605
|
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
606
|
+
return $repository
|
607
|
+
end
|
608
|
+
def find(*arguments)
|
609
|
+
scope = arguments.slice!(0)
|
610
|
+
options = arguments.slice!(0) || {}
|
567
611
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
612
|
+
case scope
|
613
|
+
when :all then return find_every(options)
|
614
|
+
when :first then return find_one(options)
|
615
|
+
else return find_single(scope, options)
|
616
|
+
end
|
572
617
|
end
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
def find_every(options)
|
618
|
+
def find_one(options)
|
619
|
+
options[:limit]=1
|
620
|
+
find_every(options).first
|
621
|
+
end
|
622
|
+
def find_every(options)
|
579
623
|
|
580
|
-
|
581
|
-
|
582
|
-
|
624
|
+
results=[]
|
625
|
+
untyped_results=self.repository.query(self.table_name,attribute_descriptions,options)
|
626
|
+
untyped_results.each do |item_attributes|
|
583
627
|
|
584
|
-
|
585
|
-
|
586
|
-
|
628
|
+
results<<istantiate(item_attributes,self.repository(options))
|
629
|
+
end
|
630
|
+
return results
|
587
631
|
|
588
|
-
end
|
589
|
-
def find_list(primary_keys,options={})
|
590
|
-
result=[]
|
591
|
-
primary_keys.each do |key|
|
592
|
-
item=find_single(key,options)
|
593
|
-
result<<item if item
|
594
632
|
end
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
633
|
+
def find_list(primary_keys,options={})
|
634
|
+
result=[]
|
635
|
+
primary_keys.each do |key|
|
636
|
+
item=find_single(key,options)
|
637
|
+
result<<item if item
|
638
|
+
end
|
639
|
+
return result
|
640
|
+
end
|
641
|
+
def query_ids(options={})
|
642
|
+
self.repository.query_ids(self.table_name,attribute_descriptions,options)
|
643
|
+
end
|
644
|
+
def istantiate(sdb_attributes,repository)
|
645
|
+
this_result=new(sdb_attributes||{})
|
646
|
+
get_clob_proc=nil
|
647
|
+
clob_attribute_names.each do |clob_attribute_name|
|
648
|
+
get_clob_proc= proc {
|
649
|
+
repository.get_clob(self.table_name,this_result.primary_key,clob_attribute_name)
|
650
|
+
}
|
607
651
|
|
608
|
-
|
652
|
+
this_result.set_attribute(clob_attribute_name, LazyLoadingText.new(get_clob_proc))
|
653
|
+
end
|
654
|
+
this_result
|
609
655
|
end
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
656
|
+
def arrayify(x)
|
657
|
+
unless x.is_a?(Array)
|
658
|
+
x=[x]
|
659
|
+
end
|
660
|
+
return x
|
661
|
+
|
662
|
+
end
|
663
|
+
def find_single(id, options)
|
664
|
+
return nil if id==nil
|
665
|
+
id=arrayify(id)
|
666
|
+
attributes=self.repository(options).find_one(self.table_name,id,attribute_descriptions)
|
667
|
+
if attributes && attributes.length>0
|
668
|
+
@primary_key_attribute_names.each do |key_name|
|
669
|
+
attributes[key_name]=id.shift
|
670
|
+
end
|
671
|
+
attributes[:repository]=self.repository(options)
|
672
|
+
return istantiate(attributes,self.repository(options))
|
673
|
+
end
|
674
|
+
return nil
|
675
|
+
end
|
676
|
+
def find_recent_with_exponential_expansion(time_column,how_many,options={})
|
677
|
+
found=[]
|
678
|
+
tries=0
|
679
|
+
timespan=options[:timespan_hint] || 60*60*4
|
627
680
|
|
628
|
-
|
681
|
+
params = options[:params] || {}
|
629
682
|
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
683
|
+
while found.length<how_many && tries<4
|
684
|
+
time=Time.now.gmtime-timespan
|
685
|
+
params[time_column] =AttributeRange.new(:greater_than=>time)
|
686
|
+
found= find(:all,:limit=>how_many,:order=>:descending,:order_by => time_column,
|
687
|
+
:params=>params)
|
635
688
|
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
689
|
+
tries=tries+1
|
690
|
+
timespan=timespan*3
|
691
|
+
end
|
692
|
+
return found
|
640
693
|
|
641
|
-
|
694
|
+
end
|
642
695
|
|
696
|
+
end
|
643
697
|
end
|
644
698
|
end
|
645
|
-
end
|