strokedb 0.0.2.1 → 0.0.2.2
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/README +18 -20
- data/bench.html +4001 -0
- data/bin/strokedb +14 -0
- data/examples/movies.rb +105 -0
- data/examples/movies2.rb +97 -0
- data/examples/strokewiki/README +28 -0
- data/examples/strokewiki/view/edit.xhtml +27 -0
- data/examples/strokewiki/view/new.xhtml +26 -0
- data/examples/strokewiki/view/pages.xhtml +27 -0
- data/examples/strokewiki/view/show.xhtml +40 -0
- data/examples/strokewiki/view/versions.xhtml +25 -0
- data/examples/strokewiki/wiki.rb +106 -0
- data/examples/todo.rb +92 -0
- data/lib/strokedb.rb +85 -0
- data/lib/{config → strokedb}/config.rb +14 -9
- data/lib/strokedb/console.rb +87 -0
- data/lib/strokedb/core_ext.rb +10 -0
- data/lib/{util/ext → strokedb/core_ext}/blank.rb +1 -1
- data/lib/{util/ext → strokedb/core_ext}/enumerable.rb +0 -0
- data/lib/{util/ext → strokedb/core_ext}/fixnum.rb +0 -0
- data/lib/strokedb/core_ext/float.rb +4 -0
- data/lib/{util/ext → strokedb/core_ext}/hash.rb +0 -0
- data/lib/strokedb/core_ext/infinity.rb +33 -0
- data/lib/strokedb/core_ext/kernel.rb +41 -0
- data/lib/strokedb/core_ext/object.rb +16 -0
- data/lib/{util/ext → strokedb/core_ext}/string.rb +28 -1
- data/lib/strokedb/core_ext/symbol.rb +13 -0
- data/lib/strokedb/data_structures.rb +5 -0
- data/lib/strokedb/data_structures/chunked_skiplist.rb +123 -0
- data/lib/{data_structures → strokedb/data_structures}/inverted_list.rb +0 -0
- data/lib/{data_structures → strokedb/data_structures}/point_query.rb +0 -0
- data/lib/strokedb/data_structures/simple_skiplist.rb +350 -0
- data/lib/{data_structures → strokedb/data_structures}/skiplist.rb +1 -1
- data/lib/{document → strokedb}/document.rb +180 -71
- data/lib/{document → strokedb/document}/callback.rb +0 -0
- data/lib/{document → strokedb/document}/delete.rb +2 -2
- data/lib/strokedb/document/dsl.rb +4 -0
- data/lib/{document → strokedb/document/dsl}/associations.rb +0 -0
- data/lib/{document → strokedb/document/dsl}/coercions.rb +0 -0
- data/lib/strokedb/document/dsl/meta_dsl.rb +7 -0
- data/lib/{document → strokedb/document/dsl}/validations.rb +26 -21
- data/lib/{document → strokedb/document/dsl}/virtualize.rb +0 -0
- data/lib/{document → strokedb/document}/meta.rb +92 -29
- data/lib/{document → strokedb/document}/slot.rb +17 -5
- data/lib/{document → strokedb/document}/util.rb +0 -0
- data/lib/{document → strokedb/document}/versions.rb +2 -2
- data/lib/strokedb/index.rb +2 -0
- data/lib/strokedb/nsurl.rb +24 -0
- data/lib/strokedb/store.rb +149 -0
- data/lib/strokedb/stores.rb +6 -0
- data/lib/{stores → strokedb/stores}/chainable_storage.rb +20 -14
- data/lib/strokedb/stores/file_storage.rb +118 -0
- data/lib/{stores/inverted_list_index → strokedb/stores}/inverted_list_file_storage.rb +50 -0
- data/lib/strokedb/stores/memory_storage.rb +80 -0
- data/lib/{stores → strokedb/stores}/remote_store.rb +10 -4
- data/lib/strokedb/sync.rb +4 -0
- data/lib/{sync → strokedb/sync}/chain_sync.rb +0 -0
- data/lib/{sync → strokedb/sync}/diff.rb +12 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/array.rb +1 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/default.rb +0 -0
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/hash.rb +1 -1
- data/lib/{sync/stroke_diff → strokedb/sync/diff}/string.rb +1 -1
- data/lib/{sync → strokedb/sync}/lamport_timestamp.rb +0 -0
- data/lib/{sync → strokedb/sync}/store_sync.rb +15 -7
- data/lib/strokedb/transaction.rb +78 -0
- data/lib/{util → strokedb}/util.rb +14 -7
- data/lib/strokedb/util/attach_dsl.rb +29 -0
- data/lib/{util → strokedb/util}/blankslate.rb +0 -0
- data/lib/strokedb/util/class_optimization.rb +93 -0
- data/lib/{util → strokedb/util}/inflect.rb +0 -0
- data/lib/strokedb/util/java_util.rb +13 -0
- data/lib/{util → strokedb/util}/lazy_array.rb +0 -0
- data/lib/{util → strokedb/util}/lazy_mapping_array.rb +4 -0
- data/lib/{util → strokedb/util}/lazy_mapping_hash.rb +0 -0
- data/lib/{util → strokedb/util}/serialization.rb +21 -0
- data/lib/strokedb/util/uuid.rb +159 -0
- data/lib/{util → strokedb/util}/xml.rb +0 -0
- data/lib/{view → strokedb}/view.rb +2 -2
- data/lib/strokedb/volumes.rb +5 -0
- data/lib/strokedb/volumes/archive_volume.rb +165 -0
- data/lib/strokedb/volumes/block_volume.rb +169 -0
- data/lib/strokedb/volumes/distributed_pointer.rb +43 -0
- data/lib/strokedb/volumes/fixed_length_skiplist_volume.rb +109 -0
- data/lib/strokedb/volumes/map_volume.rb +268 -0
- data/meta/MANIFEST +175 -0
- data/script/console +2 -70
- data/spec/integration/remote_store_spec.rb +70 -0
- data/spec/integration/search_spec.rb +76 -0
- data/spec/integration/spec_helper.rb +1 -0
- data/spec/lib/spec_helper.rb +1 -0
- data/spec/lib/strokedb/config_spec.rb +250 -0
- data/spec/lib/strokedb/core_ext/blank_spec.rb +20 -0
- data/spec/lib/strokedb/core_ext/extract_spec.rb +42 -0
- data/spec/lib/strokedb/core_ext/float_spec.rb +62 -0
- data/spec/lib/strokedb/core_ext/infinity_spec.rb +40 -0
- data/spec/lib/strokedb/core_ext/spec_helper.rb +1 -0
- data/spec/lib/strokedb/core_ext/string_spec.rb +25 -0
- data/spec/lib/strokedb/core_ext/symbol_spec.rb +8 -0
- data/spec/lib/strokedb/data_structures/chunked_skiplist_spec.rb +144 -0
- data/spec/lib/strokedb/data_structures/inverted_list_spec.rb +172 -0
- data/spec/lib/strokedb/data_structures/simple_skiplist_spec.rb +200 -0
- data/spec/lib/strokedb/data_structures/skiplist_spec.rb +253 -0
- data/spec/lib/strokedb/data_structures/spec_helper.rb +1 -0
- data/spec/lib/strokedb/document/associations_spec.rb +319 -0
- data/spec/lib/strokedb/document/callbacks_spec.rb +134 -0
- data/spec/lib/strokedb/document/coercions_spec.rb +110 -0
- data/spec/lib/strokedb/document/document_spec.rb +1063 -0
- data/spec/lib/strokedb/document/meta_meta_spec.rb +30 -0
- data/spec/lib/strokedb/document/meta_spec.rb +435 -0
- data/spec/lib/strokedb/document/metaslot_spec.rb +43 -0
- data/spec/lib/strokedb/document/slot_spec.rb +130 -0
- data/spec/lib/strokedb/document/spec_helper.rb +1 -0
- data/spec/lib/strokedb/document/validations_spec.rb +1081 -0
- data/spec/lib/strokedb/document/virtualize_spec.rb +80 -0
- data/spec/lib/strokedb/nsurl_spec.rb +73 -0
- data/spec/lib/strokedb/spec_helper.rb +1 -0
- data/spec/lib/strokedb/stores/chained_storages_spec.rb +116 -0
- data/spec/lib/strokedb/stores/spec_helper.rb +1 -0
- data/spec/lib/strokedb/stores/store_spec.rb +201 -0
- data/spec/lib/strokedb/stores/transaction_spec.rb +107 -0
- data/spec/lib/strokedb/sync/chain_sync_spec.rb +43 -0
- data/spec/lib/strokedb/sync/diff_spec.rb +111 -0
- data/spec/lib/strokedb/sync/lamport_timestamp_spec.rb +174 -0
- data/spec/lib/strokedb/sync/slot_diff_spec.rb +164 -0
- data/spec/lib/strokedb/sync/spec_helper.rb +1 -0
- data/spec/lib/strokedb/sync/store_sync_spec.rb +181 -0
- data/spec/lib/strokedb/sync/stroke_diff/array_spec.rb +97 -0
- data/spec/lib/strokedb/sync/stroke_diff/complex_spec.rb +58 -0
- data/spec/lib/strokedb/sync/stroke_diff/hash_spec.rb +144 -0
- data/spec/lib/strokedb/sync/stroke_diff/scalar_spec.rb +23 -0
- data/spec/lib/strokedb/sync/stroke_diff/spec_helper.rb +25 -0
- data/spec/lib/strokedb/sync/stroke_diff/string_spec.rb +61 -0
- data/spec/lib/strokedb/util/attach_dsl_spec.rb +45 -0
- data/spec/lib/strokedb/util/inflect_spec.rb +14 -0
- data/spec/lib/strokedb/util/lazy_array_spec.rb +157 -0
- data/spec/lib/strokedb/util/lazy_mapping_array_spec.rb +174 -0
- data/spec/lib/strokedb/util/lazy_mapping_hash_spec.rb +92 -0
- data/spec/lib/strokedb/util/spec_helper.rb +1 -0
- data/spec/lib/strokedb/util/uuid_spec.rb +46 -0
- data/spec/lib/strokedb/view_spec.rb +228 -0
- data/spec/lib/strokedb/volumes/archive_volume_spec.rb +105 -0
- data/spec/lib/strokedb/volumes/block_volume_spec.rb +100 -0
- data/spec/lib/strokedb/volumes/distributed_pointer_spec.rb +14 -0
- data/spec/lib/strokedb/volumes/fixed_length_skiplist_volume_spec.rb +177 -0
- data/spec/lib/strokedb/volumes/map_volume_spec.rb +172 -0
- data/spec/lib/strokedb/volumes/spec_helper.rb +1 -0
- data/spec/regression/docref_spec.rb +94 -0
- data/spec/regression/meta_spec.rb +23 -0
- data/spec/regression/spec_helper.rb +1 -0
- data/spec/regression/sync_spec.rb +36 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/temp/storages/TIMESTAMP +1 -0
- data/spec/temp/storages/UUID +1 -0
- data/spec/temp/storages/database-sync/TIMESTAMP +1 -0
- data/spec/temp/storages/database-sync/UUID +1 -0
- data/spec/temp/storages/database-sync/config +1 -0
- data/spec/temp/storages/database-sync/file/LAST +1 -0
- data/spec/temp/storages/database-sync/file/bd/f6/bdf675e5-8a7b-494e-97f2-f74a14ccd95d.av +0 -0
- data/spec/temp/storages/database-sync/file/uindex.wal +0 -0
- data/spec/temp/storages/database-sync/inverted_list_file/INVERTED_INDEX +1 -0
- data/spec/temp/storages/inverted_list_storage/INVERTED_INDEX +0 -0
- data/strokedb.gemspec +120 -0
- data/task/benchmark.task +9 -0
- data/task/ditz.task +30 -0
- data/task/echoe.rb +17 -0
- data/task/rcov.task +50 -0
- data/task/rdoc.task +10 -0
- data/task/rspec.task +0 -0
- data/vendor/java_inline.rb +106 -0
- data/vendor/rbmodexcl/mrimodexcl.rb +82 -0
- data/vendor/rbmodexcl/rbmodexcl.rb +5 -0
- data/vendor/rbmodexcl/rbxmodexcl.rb +48 -0
- data/vendor/rbmodexcl/spec/unextend_spec.rb +50 -0
- data/vendor/rbmodexcl/spec/uninclude_spec.rb +26 -0
- metadata +271 -79
- data/CONTRIBUTORS +0 -7
- data/CREDITS +0 -13
- data/bin/sdbc +0 -2
- data/lib/init.rb +0 -57
- data/lib/stores/inverted_list_index/inverted_list_index.rb +0 -49
- data/lib/stores/skiplist_store/chunk.rb +0 -119
- data/lib/stores/skiplist_store/chunk_storage.rb +0 -21
- data/lib/stores/skiplist_store/file_chunk_storage.rb +0 -44
- data/lib/stores/skiplist_store/memory_chunk_storage.rb +0 -37
- data/lib/stores/skiplist_store/skiplist_store.rb +0 -217
- data/lib/stores/store.rb +0 -5
- data/lib/sync/stroke_diff/stroke_diff.rb +0 -9
- data/lib/util/ext/object.rb +0 -8
- data/lib/util/java_util.rb +0 -9
- data/lib/util/trigger_partition.rb +0 -136
- data/strokedb.rb +0 -75
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
require 'document/dsl'
|
|
2
|
+
require 'document/util'
|
|
3
|
+
require 'document/meta'
|
|
4
|
+
require 'document/callback'
|
|
5
|
+
require 'document/delete'
|
|
6
|
+
require 'document/slot'
|
|
7
|
+
require 'document/versions'
|
|
8
|
+
|
|
1
9
|
module StrokeDB
|
|
2
10
|
# Slots which contain references to another documents are matched
|
|
3
11
|
# with these regexps.
|
|
@@ -17,23 +25,23 @@ module StrokeDB
|
|
|
17
25
|
def initialize(slotname)
|
|
18
26
|
@slotname = slotname
|
|
19
27
|
end
|
|
20
|
-
|
|
28
|
+
|
|
21
29
|
def message
|
|
22
30
|
"Can't find slot #{@slotname}"
|
|
23
31
|
end
|
|
24
|
-
|
|
32
|
+
|
|
25
33
|
def inspect
|
|
26
34
|
"#<#{self.class.name}: #{message}>"
|
|
27
35
|
end
|
|
28
36
|
end
|
|
29
|
-
|
|
37
|
+
|
|
30
38
|
#
|
|
31
|
-
# Raised when Document#save! is called on an invalid document
|
|
39
|
+
# Raised when Document#save! is called on an invalid document
|
|
32
40
|
# (for which doc.valid? returns false)
|
|
33
41
|
#
|
|
34
42
|
class InvalidDocumentError < StandardError #:nodoc:
|
|
35
43
|
attr_reader :document
|
|
36
|
-
|
|
44
|
+
|
|
37
45
|
def initialize(document)
|
|
38
46
|
@document = document
|
|
39
47
|
end
|
|
@@ -41,7 +49,7 @@ module StrokeDB
|
|
|
41
49
|
def message
|
|
42
50
|
"Validation failed: #{@document.errors.messages.join(", ")}"
|
|
43
51
|
end
|
|
44
|
-
|
|
52
|
+
|
|
45
53
|
def inspect
|
|
46
54
|
"#<#{self.class.name}: #{message}>"
|
|
47
55
|
end
|
|
@@ -62,9 +70,17 @@ module StrokeDB
|
|
|
62
70
|
# authors: ["Yurii Rashkovskii","Oleg Andreev"]
|
|
63
71
|
#
|
|
64
72
|
class Document
|
|
65
|
-
include Validations::InstanceMethods
|
|
73
|
+
include StrokeDB::Validations::InstanceMethods
|
|
66
74
|
|
|
67
|
-
attr_reader :
|
|
75
|
+
attr_reader :callbacks #:nodoc:
|
|
76
|
+
|
|
77
|
+
def store
|
|
78
|
+
if (txns = Thread.current[:strokedb_transactions]) && !txns.nil? && !txns.empty?
|
|
79
|
+
txns.last
|
|
80
|
+
else
|
|
81
|
+
@store
|
|
82
|
+
end
|
|
83
|
+
end
|
|
68
84
|
|
|
69
85
|
def marshal_dump #:nodoc:
|
|
70
86
|
(@new ? '1' : '0') + (@saved ? '1' : '0') + to_raw.to_json
|
|
@@ -82,13 +98,34 @@ module StrokeDB
|
|
|
82
98
|
def initialize(document)
|
|
83
99
|
@document = document
|
|
84
100
|
_meta = document[:meta]
|
|
85
|
-
concat
|
|
101
|
+
concat _meta.to_a
|
|
86
102
|
end
|
|
87
103
|
|
|
88
104
|
def <<(meta)
|
|
89
105
|
add_meta(meta, :call_initialization_callbacks => true)
|
|
90
106
|
end
|
|
91
107
|
|
|
108
|
+
alias :_delete :delete
|
|
109
|
+
def delete(meta)
|
|
110
|
+
case meta
|
|
111
|
+
when Document
|
|
112
|
+
_delete meta
|
|
113
|
+
_module = StrokeDB::Document.collect_meta_modules(@document.store, meta).first
|
|
114
|
+
when Meta
|
|
115
|
+
_delete meta.document(@document.store)
|
|
116
|
+
_module = meta
|
|
117
|
+
else
|
|
118
|
+
raise ArgumentError, "Meta should be either document or meta module"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
@document[:meta] = self
|
|
122
|
+
|
|
123
|
+
if _module
|
|
124
|
+
@document.unextend(_module)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end
|
|
128
|
+
|
|
92
129
|
def add_meta(meta, opts = {})
|
|
93
130
|
opts = opts.stringify_keys
|
|
94
131
|
_module = nil
|
|
@@ -110,10 +147,8 @@ module StrokeDB
|
|
|
110
147
|
|
|
111
148
|
if _module
|
|
112
149
|
@document.extend(_module)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if opts['call_initialization_callbacks']
|
|
150
|
+
|
|
151
|
+
if opts['call_initialization_callbacks']
|
|
117
152
|
@document.send!(:execute_callbacks_for, _module, :on_initialization)
|
|
118
153
|
@document.send!(:execute_callbacks_for, _module, :on_new_document) if @document.new?
|
|
119
154
|
end
|
|
@@ -168,6 +203,7 @@ module StrokeDB
|
|
|
168
203
|
# If slot was not found, it will return <tt>nil</tt>
|
|
169
204
|
#
|
|
170
205
|
def [](slotname)
|
|
206
|
+
slotname = slotname.document.uuid if (slotname.is_a?(Meta) && slotname.is_a?(Module)) || (slotname == Meta)
|
|
171
207
|
@slots[slotname.to_s].value rescue nil
|
|
172
208
|
end
|
|
173
209
|
|
|
@@ -177,11 +213,12 @@ module StrokeDB
|
|
|
177
213
|
# document[:slot_1] = "some value"
|
|
178
214
|
#
|
|
179
215
|
def []=(slotname, value)
|
|
216
|
+
slotname = slotname.document.uuid if (slotname.is_a?(Meta) && slotname.is_a?(Module)) || (slotname == Meta)
|
|
180
217
|
slotname = slotname.to_s
|
|
181
218
|
|
|
182
219
|
(@slots[slotname] ||= Slot.new(self, slotname)).value = value
|
|
183
220
|
update_version!(slotname)
|
|
184
|
-
|
|
221
|
+
|
|
185
222
|
value
|
|
186
223
|
end
|
|
187
224
|
|
|
@@ -206,7 +243,7 @@ module StrokeDB
|
|
|
206
243
|
#
|
|
207
244
|
def remove_slot!(slotname)
|
|
208
245
|
slotname = slotname.to_s
|
|
209
|
-
|
|
246
|
+
|
|
210
247
|
@slots.delete slotname
|
|
211
248
|
update_version! slotname
|
|
212
249
|
|
|
@@ -233,9 +270,9 @@ module StrokeDB
|
|
|
233
270
|
|
|
234
271
|
def pretty_print #:nodoc:
|
|
235
272
|
slots = to_raw.except('meta')
|
|
236
|
-
|
|
237
|
-
s = is_a?(ImmutableDocument) ? "
|
|
238
|
-
|
|
273
|
+
|
|
274
|
+
s = is_a?(ImmutableDocument) ? "#<^" : "#<"
|
|
275
|
+
|
|
239
276
|
Util.catch_circular_reference(self) do
|
|
240
277
|
if self[:meta] && name = meta[:name]
|
|
241
278
|
s << "#{name} "
|
|
@@ -245,9 +282,13 @@ module StrokeDB
|
|
|
245
282
|
|
|
246
283
|
slots.keys.sort.each do |k|
|
|
247
284
|
if %w(version previous_version).member?(k) && v = self[k]
|
|
248
|
-
s << "#{k}: #{v
|
|
285
|
+
s << "#{k}: #{v[0,4]}..., "
|
|
249
286
|
else
|
|
250
|
-
|
|
287
|
+
if k.match(/^#{UUID_RE}$/)
|
|
288
|
+
s << "[#{store.find(k).name}]: #{self[k].inspect}, " rescue s << "#{k}: #{self[k].inspect}, "
|
|
289
|
+
else
|
|
290
|
+
s << "#{k}: #{self[k].inspect}, "
|
|
291
|
+
end
|
|
251
292
|
end
|
|
252
293
|
end
|
|
253
294
|
|
|
@@ -255,7 +296,7 @@ module StrokeDB
|
|
|
255
296
|
s.chomp!(' ')
|
|
256
297
|
s << ">"
|
|
257
298
|
end
|
|
258
|
-
|
|
299
|
+
|
|
259
300
|
s
|
|
260
301
|
rescue Util::CircularReferenceCondition
|
|
261
302
|
"#(#{(self[:meta] ? "#{meta}" : "Doc")} #{('@#'+uuid)[0,5]}...)"
|
|
@@ -287,8 +328,8 @@ module StrokeDB
|
|
|
287
328
|
@slots.each_pair do |k,v|
|
|
288
329
|
raw_slots[k.to_s] = v.to_raw
|
|
289
330
|
end
|
|
290
|
-
|
|
291
|
-
raw_slots
|
|
331
|
+
|
|
332
|
+
raw_slots.to_raw
|
|
292
333
|
end
|
|
293
334
|
|
|
294
335
|
def to_optimized_raw #:nodoc:
|
|
@@ -298,14 +339,12 @@ module StrokeDB
|
|
|
298
339
|
#
|
|
299
340
|
# Creates a document from a serialized representation
|
|
300
341
|
#
|
|
301
|
-
def self.from_raw(store, raw_slots, opts = {}) #:nodoc:
|
|
302
|
-
doc = new(store, raw_slots, true)
|
|
342
|
+
def self.from_raw(store, raw_slots, opts = {}, &block) #:nodoc:
|
|
343
|
+
doc = new(store, raw_slots, true, &block)
|
|
303
344
|
|
|
304
345
|
collect_meta_modules(store, raw_slots['meta']).each do |meta_module|
|
|
305
346
|
unless doc.is_a? meta_module
|
|
306
347
|
doc.extend(meta_module)
|
|
307
|
-
|
|
308
|
-
meta_module.send!(:setup_callbacks, doc) rescue nil
|
|
309
348
|
end
|
|
310
349
|
end
|
|
311
350
|
|
|
@@ -330,10 +369,14 @@ module StrokeDB
|
|
|
330
369
|
# If first argument is Store, that particular store will be used; otherwise default store will be assumed.
|
|
331
370
|
def self.find(*args)
|
|
332
371
|
store = nil
|
|
333
|
-
if
|
|
334
|
-
store =
|
|
372
|
+
if (txns = Thread.current[:strokedb_transactions]) && !txns.nil? && !txns.empty?
|
|
373
|
+
store = txns.last
|
|
335
374
|
else
|
|
336
|
-
|
|
375
|
+
if args.empty? || args.first.is_a?(String) || args.first.is_a?(Hash) || args.first.nil?
|
|
376
|
+
store = StrokeDB.default_store
|
|
377
|
+
else
|
|
378
|
+
store = args.shift
|
|
379
|
+
end
|
|
337
380
|
end
|
|
338
381
|
raise NoDefaultStoreError.new unless store
|
|
339
382
|
query = args.first
|
|
@@ -343,7 +386,7 @@ module StrokeDB
|
|
|
343
386
|
when Hash
|
|
344
387
|
store.search(query)
|
|
345
388
|
else
|
|
346
|
-
raise
|
|
389
|
+
raise ArgumentError, "use UUID or query to find document(s)"
|
|
347
390
|
end
|
|
348
391
|
end
|
|
349
392
|
|
|
@@ -386,30 +429,42 @@ module StrokeDB
|
|
|
386
429
|
store.save!(self)
|
|
387
430
|
@new = false
|
|
388
431
|
@saved = true
|
|
389
|
-
|
|
432
|
+
|
|
390
433
|
execute_callbacks :after_save
|
|
391
|
-
|
|
434
|
+
|
|
392
435
|
self
|
|
393
436
|
end
|
|
394
437
|
|
|
395
|
-
#
|
|
396
|
-
# Updates slots with specified <tt>hash</tt> and returns itself.
|
|
397
|
-
#
|
|
438
|
+
# Updates slots with a specified <tt>hash</tt> and returns itself.
|
|
398
439
|
def update_slots(hash)
|
|
399
440
|
hash.each do |k, v|
|
|
400
|
-
self[k]
|
|
441
|
+
send("#{k}=", v) unless self[k] == v
|
|
401
442
|
end
|
|
402
|
-
|
|
403
443
|
self
|
|
404
444
|
end
|
|
405
445
|
|
|
406
|
-
#
|
|
407
446
|
# Same as update_slots, but also saves the document.
|
|
408
|
-
#
|
|
409
447
|
def update_slots!(hash)
|
|
410
448
|
update_slots(hash).save!
|
|
411
449
|
end
|
|
412
450
|
|
|
451
|
+
|
|
452
|
+
# Updates nil/false slots with a specified <tt>hash</tt> and returns itself.
|
|
453
|
+
# Already set slots are not modified (<tt>||=</tt> is used).
|
|
454
|
+
# Acts like <tt>hash1.reverse_merge(hash2)</tt> (<tt>hash2.merge(hash1)</tt>).
|
|
455
|
+
#
|
|
456
|
+
def reverse_update_slots(hash)
|
|
457
|
+
hash.each do |k, v|
|
|
458
|
+
self[k] ||= v
|
|
459
|
+
end
|
|
460
|
+
self
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
# Same as reverse_update_slots, but also saves the document.
|
|
464
|
+
def reverse_update_slots!(hash)
|
|
465
|
+
reverse_update_slots(hash).save!
|
|
466
|
+
end
|
|
467
|
+
|
|
413
468
|
#
|
|
414
469
|
# Returns document's metadocument (if any). In case if document has more than one metadocument,
|
|
415
470
|
# it will combine all metadocuments into one 'virtual' metadocument
|
|
@@ -419,14 +474,14 @@ module StrokeDB
|
|
|
419
474
|
# simple case
|
|
420
475
|
return m || Document.new(@store)
|
|
421
476
|
end
|
|
422
|
-
|
|
477
|
+
|
|
423
478
|
return m.first if m.size == 1
|
|
424
479
|
|
|
425
480
|
mm = m.clone
|
|
426
481
|
collected_meta = mm.shift.clone
|
|
427
482
|
|
|
428
483
|
names = collected_meta[:name].split(',') rescue []
|
|
429
|
-
|
|
484
|
+
|
|
430
485
|
mm.each do |next_meta|
|
|
431
486
|
next_meta = next_meta.clone
|
|
432
487
|
collected_meta += next_meta
|
|
@@ -455,7 +510,7 @@ module StrokeDB
|
|
|
455
510
|
# Please not that it accept both meta modules and their documents, there is no difference
|
|
456
511
|
#
|
|
457
512
|
def metas
|
|
458
|
-
Metas.new(self)
|
|
513
|
+
@metas ||= Metas.new(self)
|
|
459
514
|
end
|
|
460
515
|
|
|
461
516
|
#
|
|
@@ -472,6 +527,10 @@ module StrokeDB
|
|
|
472
527
|
@uuid ||= self[:uuid]
|
|
473
528
|
end
|
|
474
529
|
|
|
530
|
+
def raw_uuid #:nodoc:
|
|
531
|
+
@raw_uuid ||= uuid.to_raw_uuid
|
|
532
|
+
end
|
|
533
|
+
|
|
475
534
|
#
|
|
476
535
|
# Returns document's previous version (which is stored in <tt>previous_version</tt> slot)
|
|
477
536
|
#
|
|
@@ -498,7 +557,7 @@ module StrokeDB
|
|
|
498
557
|
case doc
|
|
499
558
|
when Document, DocumentReferenceValue
|
|
500
559
|
doc = doc.load if doc.kind_of? DocumentReferenceValue
|
|
501
|
-
|
|
560
|
+
|
|
502
561
|
# we make a quick UUID check here to skip two heavy to_raw calls
|
|
503
562
|
doc.uuid == uuid && doc.to_raw == to_raw
|
|
504
563
|
else
|
|
@@ -526,16 +585,16 @@ module StrokeDB
|
|
|
526
585
|
|
|
527
586
|
def method_missing(sym, *args) #:nodoc:
|
|
528
587
|
sym = sym.to_s
|
|
529
|
-
|
|
588
|
+
|
|
530
589
|
return send(:[]=, sym.chomp('='), *args) if sym.ends_with? '='
|
|
531
590
|
return self[sym] if slotnames.include? sym
|
|
532
591
|
return !!send(sym.chomp('?'), *args) if sym.ends_with? '?'
|
|
533
|
-
|
|
592
|
+
|
|
534
593
|
raise SlotNotFoundError.new(sym) if (callbacks['when_slot_not_found'] || []).empty?
|
|
535
594
|
|
|
536
595
|
r = execute_callbacks(:when_slot_not_found, sym)
|
|
537
596
|
raise r if r.is_a? SlotNotFoundError # TODO: spec this behavior
|
|
538
|
-
|
|
597
|
+
|
|
539
598
|
r
|
|
540
599
|
end
|
|
541
600
|
|
|
@@ -568,21 +627,21 @@ module StrokeDB
|
|
|
568
627
|
end
|
|
569
628
|
end
|
|
570
629
|
|
|
571
|
-
# initialize the document. initialize_raw is true when
|
|
630
|
+
# initialize the document. initialize_raw is true when
|
|
572
631
|
# document is initialized from a raw serialized form
|
|
573
632
|
def do_initialize(store, slots={}, initialize_raw = false) #:nodoc:
|
|
574
633
|
@callbacks = {}
|
|
575
634
|
@store = store
|
|
576
635
|
|
|
577
636
|
if initialize_raw
|
|
578
|
-
initialize_raw_slots slots
|
|
637
|
+
initialize_raw_slots slots
|
|
579
638
|
@saved = true
|
|
580
639
|
else
|
|
581
640
|
@new = true
|
|
582
641
|
initialize_slots slots
|
|
583
642
|
|
|
584
643
|
self[:uuid] = Util.random_uuid unless self[:uuid]
|
|
585
|
-
|
|
644
|
+
self[:version] ||= NIL_UUID
|
|
586
645
|
end
|
|
587
646
|
end
|
|
588
647
|
|
|
@@ -591,24 +650,23 @@ module StrokeDB
|
|
|
591
650
|
@slots = {}
|
|
592
651
|
slots = slots.stringify_keys
|
|
593
652
|
|
|
594
|
-
# there is a reason for meta slot is initialized separately —
|
|
653
|
+
# there is a reason for meta slot is initialized separately —
|
|
595
654
|
# we need to setup coercions before initializing actual slots
|
|
596
655
|
if meta = slots['meta']
|
|
597
656
|
meta = [meta] unless meta.is_a?(Array)
|
|
598
657
|
meta.each {|m| metas.add_meta(m) }
|
|
599
658
|
end
|
|
600
|
-
|
|
601
|
-
slots.except('meta').each {|name,value|
|
|
659
|
+
|
|
660
|
+
slots.except('meta').each {|name,value| send("#{name}=", value) }
|
|
602
661
|
|
|
603
662
|
# now, when we have all slots initialized, we can run initialization callbacks
|
|
604
663
|
execute_callbacks :on_initialization
|
|
605
664
|
execute_callbacks :on_new_document
|
|
606
665
|
end
|
|
607
|
-
|
|
666
|
+
|
|
608
667
|
# initialize slots from a raw representation
|
|
609
668
|
def initialize_raw_slots(slots) #:nodoc:
|
|
610
669
|
@slots = {}
|
|
611
|
-
|
|
612
670
|
slots.each do |name,value|
|
|
613
671
|
s = Slot.new(self, name)
|
|
614
672
|
s.raw_value = value
|
|
@@ -617,26 +675,73 @@ module StrokeDB
|
|
|
617
675
|
end
|
|
618
676
|
end
|
|
619
677
|
|
|
620
|
-
# returns an array of meta modules (as constants) for a given something
|
|
621
|
-
# (a document reference, a document itself, or an array of the former)
|
|
622
|
-
def self.collect_meta_modules(store, meta) #:nodoc:
|
|
623
|
-
meta_names = []
|
|
624
678
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
679
|
+
class MetaModulesCollector
|
|
680
|
+
def initialize(store, subject)
|
|
681
|
+
@store = store
|
|
682
|
+
@subject = subject
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
def resolve_module_name(uuid)
|
|
686
|
+
if metadoc = @store.find(uuid, self.lookup_version_for_meta(@subject))
|
|
687
|
+
mod = Module.find_by_nsurl(metadoc[:nsurl])
|
|
688
|
+
|
|
689
|
+
if self.has_defined_constant_for_meta?(mod, metadoc)
|
|
690
|
+
at_top_level?(mod) ? "::#{metadoc[:name]}" : "#{mod.name}::#{metadoc[:name]}"
|
|
691
|
+
else
|
|
692
|
+
Meta.resolve_uuid_name(metadoc[:nsurl], metadoc[:name])
|
|
693
|
+
end
|
|
629
694
|
end
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
695
|
+
end
|
|
696
|
+
|
|
697
|
+
def at_top_level?(mod)
|
|
698
|
+
mod == Module || mod.nil?
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
def collect!
|
|
702
|
+
meta_names = []
|
|
703
|
+
|
|
704
|
+
case @subject
|
|
705
|
+
when VERSIONREF, DOCREF
|
|
706
|
+
meta_names << resolve_module_name($1)
|
|
707
|
+
when Array
|
|
708
|
+
meta_names = @subject.map { |subj| subj = MetaModulesCollector.new(@store, subj).collect! }.flatten
|
|
709
|
+
when Document
|
|
710
|
+
meta_names << @subject[:name]
|
|
633
711
|
end
|
|
634
|
-
|
|
635
|
-
meta_names
|
|
636
|
-
|
|
637
|
-
|
|
712
|
+
|
|
713
|
+
meta_names
|
|
714
|
+
end
|
|
715
|
+
|
|
716
|
+
def lookup_version_for_meta(meta)
|
|
717
|
+
version = case meta
|
|
718
|
+
when VERSIONREF then $2
|
|
719
|
+
else nil
|
|
720
|
+
end
|
|
721
|
+
version
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
def has_defined_constant_for_meta?(mod, metadoc)
|
|
725
|
+
top_level_meta?(mod, metadoc) || has_meta_definition?(mod, metadoc)
|
|
638
726
|
end
|
|
639
727
|
|
|
728
|
+
def top_level_meta?(mod, doc)
|
|
729
|
+
(mod == Module && Object.constants.include?(doc[:name]))
|
|
730
|
+
end
|
|
731
|
+
|
|
732
|
+
def has_meta_definition?(mod, metadoc)
|
|
733
|
+
(mod && mod.constants.include?(metadoc[:name]))
|
|
734
|
+
end
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
|
|
739
|
+
# returns an array of meta modules (as constants) for a given something
|
|
740
|
+
# (a document reference, a document itself, or an array of the former)
|
|
741
|
+
def self.collect_meta_modules(store, meta) #:nodoc:
|
|
742
|
+
@collector = MetaModulesCollector.new(store, meta)
|
|
743
|
+
meta_names = @collector.collect!
|
|
744
|
+
|
|
640
745
|
meta_names.map { |m| m.is_a?(String) ? (m.constantize rescue nil) : m }.compact
|
|
641
746
|
end
|
|
642
747
|
|
|
@@ -649,7 +754,7 @@ module StrokeDB
|
|
|
649
754
|
self[:previous_version] = version unless version.nil?
|
|
650
755
|
|
|
651
756
|
generate_new_version!
|
|
652
|
-
|
|
757
|
+
|
|
653
758
|
@saved = nil
|
|
654
759
|
end
|
|
655
760
|
end
|
|
@@ -680,5 +785,9 @@ module StrokeDB
|
|
|
680
785
|
def save!
|
|
681
786
|
self
|
|
682
787
|
end
|
|
788
|
+
|
|
789
|
+
def make_mutable!
|
|
790
|
+
unextend(ImmutableDocument)
|
|
791
|
+
end
|
|
683
792
|
end
|
|
684
793
|
end
|