xamplr 1.9.5 → 1.9.6
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.md +8 -0
- data/VERSION.yml +1 -1
- data/lib/xamplr/persistence.rb +4 -0
- data/lib/xamplr/persister.rb +26 -12
- data/lib/xamplr/persisters/filesystem.rb +1 -1
- data/lib/xamplr/persisters/mongo.rb +547 -0
- data/lib/xamplr/persisters/tokyo-cabinet.rb +10 -10
- data/regression/require-within-generated-code/project-generator.rb +32 -0
- data/regression/require-within-generated-code/test.rb +6 -0
- data/regression/require-within-generated-code/xml/customers.xml +17 -0
- data/regression/require-within-generated-code/xml/docmodel.xml +49 -0
- data/xamplr.gemspec +7 -2
- metadata +7 -2
data/README.md
CHANGED
@@ -18,6 +18,8 @@ For more information, see [the xampl page on xampl.com](http://xampl.com/so/xamp
|
|
18
18
|
|
19
19
|
## Installation:
|
20
20
|
|
21
|
+
If you are a developer then install xamplr-gen:
|
22
|
+
|
21
23
|
> sudo gem install xamplr-gen
|
22
24
|
|
23
25
|
This will install all three gems.
|
@@ -28,6 +30,12 @@ these might be loaded or partially loaded when trying to use xampl.
|
|
28
30
|
If you don't you'll experience strange exceptions with hutch-xamplr
|
29
31
|
or hutch-xamplr-pp on the stack trace.
|
30
32
|
|
33
|
+
If you just want the runtime, then:
|
34
|
+
|
35
|
+
> sudo gem install xamplr
|
36
|
+
|
37
|
+
Though this would normally be done through some sort of dependency management tool (like gems).
|
38
|
+
|
31
39
|
|
32
40
|
## License:
|
33
41
|
|
data/VERSION.yml
CHANGED
data/lib/xamplr/persistence.rb
CHANGED
@@ -145,6 +145,8 @@ module Xampl
|
|
145
145
|
case Xampl.default_persister_kind
|
146
146
|
when :tokyo_cabinet then
|
147
147
|
Xampl::TokyoCabinetPersister.add_lexical_indexs(indexes)
|
148
|
+
when :monto then
|
149
|
+
Xampl::MongoPersister.add_lexical_indexs(indexes)
|
148
150
|
else
|
149
151
|
raise IncompatiblePersisterConfiguration.new(Xampl.default_persister_kind, "lexical_indexes")
|
150
152
|
end
|
@@ -154,6 +156,8 @@ module Xampl
|
|
154
156
|
case Xampl.default_persister_kind
|
155
157
|
when :tokyo_cabinet then
|
156
158
|
Xampl::TokyoCabinetPersister.add_numerical_indexs(indexes)
|
159
|
+
when :mongo then
|
160
|
+
Xampl::MongoPersister.add_numerical_indexs(indexes)
|
157
161
|
else
|
158
162
|
raise IncompatiblePersisterConfiguration.new(Xampl.default_persister_kind, "numerical_indexs")
|
159
163
|
end
|
data/lib/xamplr/persister.rb
CHANGED
@@ -277,10 +277,10 @@ module Xampl
|
|
277
277
|
puts "SOME NOT EXPUNGED: #{ @expunged.inspect }" unless 0 == @expunged.size
|
278
278
|
@expunged = Set.new
|
279
279
|
|
280
|
-
@total_read_count
|
281
|
-
@total_write_count
|
282
|
-
@total_cache_hits
|
283
|
-
@total_sync_count
|
280
|
+
@total_read_count += @read_count
|
281
|
+
@total_write_count += @write_count
|
282
|
+
@total_cache_hits += @cache_hits
|
283
|
+
@total_sync_count += 1
|
284
284
|
|
285
285
|
@last_cache_hits = @cache_hits
|
286
286
|
@last_write_count = @write_count
|
@@ -323,12 +323,14 @@ module Xampl
|
|
323
323
|
printf(" cache_hits: %d, reads: %d, writes: %d, time: %fms \n",
|
324
324
|
@last_cache_hits, @read_count, @last_write_count, @last_sync_time)
|
325
325
|
printf(" syncs: %d\n", @total_sync_count)
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
326
|
+
if 0 < @changed.size then
|
327
|
+
printf(" changed count: %d (%d)\n", count_changed, @changed.size)
|
328
|
+
@changed.each do |thing, ignore|
|
329
|
+
if thing.is_changed then
|
330
|
+
puts " changed: #{thing}, index: #{thing.get_the_index}"
|
331
|
+
else
|
332
|
+
puts " UNCHANGED: #{thing}, index: #{thing.get_the_index} <<<<<<<<<<<<<<<<<<< BAD!"
|
333
|
+
end
|
332
334
|
end
|
333
335
|
end
|
334
336
|
end
|
@@ -339,8 +341,20 @@ module Xampl
|
|
339
341
|
require "xamplr/persisters/in-memory"
|
340
342
|
require "xamplr/persisters/filesystem"
|
341
343
|
|
342
|
-
|
343
|
-
require
|
344
|
+
begin
|
345
|
+
if require 'tokyocabinet' then
|
346
|
+
require "xamplr/persisters/tokyo-cabinet"
|
347
|
+
end
|
348
|
+
rescue
|
349
|
+
# Well. No Tokyo Cabinet.
|
350
|
+
end
|
351
|
+
|
352
|
+
begin
|
353
|
+
if require 'mongo' then
|
354
|
+
require "xamplr/persisters/mongo"
|
355
|
+
end
|
356
|
+
rescue
|
357
|
+
# Well. No MongoDB.
|
344
358
|
end
|
345
359
|
|
346
360
|
end
|
@@ -0,0 +1,547 @@
|
|
1
|
+
module Xampl
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'set'
|
5
|
+
require 'json'
|
6
|
+
require 'yaml'
|
7
|
+
require 'logger'
|
8
|
+
|
9
|
+
require 'mongo'
|
10
|
+
|
11
|
+
require 'xamplr/persisters/caching'
|
12
|
+
|
13
|
+
# require 'ruby-prof'
|
14
|
+
|
15
|
+
class MongoPersister < AbstractCachingPersister
|
16
|
+
# class MongoPersister < Persister
|
17
|
+
|
18
|
+
# $lexical_indexes = Set.new(%w{ class pid time-stamp xampl-from xampl-to xampl-place }) unless defined?($lexical_indexes)
|
19
|
+
# $numeric_indexes = Set.new(%w{ scheduled-delete-at }) unless defined?($numeric_indexes)
|
20
|
+
$lexical_indexes = Set.new(%w{ class pid time-stamp }) unless defined?($lexical_indexes)
|
21
|
+
$numeric_indexes = Set.new(%w{ scheduled-delete-at }) unless defined?($numeric_indexes)
|
22
|
+
|
23
|
+
def MongoPersister.kind
|
24
|
+
:mongo
|
25
|
+
end
|
26
|
+
|
27
|
+
def kind
|
28
|
+
MongoPersister.kind
|
29
|
+
end
|
30
|
+
|
31
|
+
def MongoPersister.add_lexical_indexs(indexes)
|
32
|
+
$lexical_indexes.merge(indexes)
|
33
|
+
end
|
34
|
+
|
35
|
+
def MongoPersister.add_numeric_indexs(indexes)
|
36
|
+
$numeric_indexes.merge(indexes)
|
37
|
+
end
|
38
|
+
|
39
|
+
def connect(db_name, name)
|
40
|
+
return if @db
|
41
|
+
@logger = Logger.new('xampl.log')
|
42
|
+
@m = Mongo::Connection.new(:logger => @logger)
|
43
|
+
|
44
|
+
=begin
|
45
|
+
|
46
|
+
@logger.info "connection: #{ @m }"
|
47
|
+
@m.database_names.each do |name|
|
48
|
+
@logger.info " DB: #{ name }"
|
49
|
+
# puts " DB: #{ name }"
|
50
|
+
end
|
51
|
+
@m.database_info.each do |info|
|
52
|
+
@logger.info " #{ info.inspect }"
|
53
|
+
# puts " #{ info.inspect }"
|
54
|
+
end
|
55
|
+
|
56
|
+
=end
|
57
|
+
|
58
|
+
#@m.drop_database(db_name) # !!!! kill the old one
|
59
|
+
@db = @m.db(db_name)
|
60
|
+
@coll = @db[name]
|
61
|
+
|
62
|
+
|
63
|
+
index_info = @coll.index_information
|
64
|
+
existing_indexes = Set.new
|
65
|
+
index_info.each do | k, v |
|
66
|
+
existing_indexes << v.first.first
|
67
|
+
end
|
68
|
+
existing_indexes.delete("_id")
|
69
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] existing indexes: #{ existing_indexes.inspect }"
|
70
|
+
|
71
|
+
$lexical_indexes.each do | index_name |
|
72
|
+
mongo_index_name = "idx.#{ index_name }"
|
73
|
+
unless existing_indexes.include?(mongo_index_name) then
|
74
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] create index: #{ mongo_index_name }"
|
75
|
+
@coll.create_index(mongo_index_name)
|
76
|
+
end
|
77
|
+
existing_indexes.delete(mongo_index_name)
|
78
|
+
end
|
79
|
+
$numeric_indexes.each do | index_name |
|
80
|
+
mongo_index_name = "idx.#{ index_name }"
|
81
|
+
unless existing_indexes.include?(mongo_index_name) then
|
82
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] create index: #{ mongo_index_name }"
|
83
|
+
@coll.create_index(mongo_index_name)
|
84
|
+
end
|
85
|
+
existing_indexes.delete(mongo_index_name)
|
86
|
+
end
|
87
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] un-explained indexes: #{ existing_indexes.inspect }"
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
#@logger.info @db.inspect
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def initialize(name=nil, format=nil, root=File.join(".", "repo"))
|
96
|
+
super(root, name, format)
|
97
|
+
|
98
|
+
@format = :xml_format
|
99
|
+
|
100
|
+
connect('xampl', name)
|
101
|
+
|
102
|
+
@root_dir = File.join(root, name)
|
103
|
+
|
104
|
+
if Xampl.raw_persister_options[:write_through] then
|
105
|
+
@files_dir = "#{ @root_dir }/files"
|
106
|
+
FileUtils.mkdir_p(@files_dir) unless File.exist?(@files_dir)
|
107
|
+
else
|
108
|
+
@files_dir = nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def setup_db
|
113
|
+
|
114
|
+
#TODO -- define indexes
|
115
|
+
# $lexical_indexes.each do | index_name |
|
116
|
+
# r = @tc_db.setindex(index_name, TDB::ITLEXICAL | TDB::ITKEEP)
|
117
|
+
# end
|
118
|
+
# $numeric_indexes.each do | index_name |
|
119
|
+
# @tc_db.setindex(index_name, TDB::ITDECIMAL | TDB::ITKEEP)
|
120
|
+
# end
|
121
|
+
end
|
122
|
+
|
123
|
+
def close
|
124
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] WHO IS CALLING ME???"
|
125
|
+
end
|
126
|
+
|
127
|
+
=begin
|
128
|
+
|
129
|
+
def query_implemented
|
130
|
+
true
|
131
|
+
end
|
132
|
+
|
133
|
+
def query(hint=false)
|
134
|
+
setup_db
|
135
|
+
query = TableQuery.new(@tc_db)
|
136
|
+
|
137
|
+
yield query
|
138
|
+
|
139
|
+
result_keys = nil
|
140
|
+
the_hint = nil
|
141
|
+
if hint then
|
142
|
+
result_keys, the_hint = query.search(true)
|
143
|
+
else
|
144
|
+
result_keys = query.search
|
145
|
+
end
|
146
|
+
results = result_keys.collect { | key | @tc_db[ key ] }
|
147
|
+
|
148
|
+
class_cache = {}
|
149
|
+
results.each do | result |
|
150
|
+
next unless result
|
151
|
+
|
152
|
+
class_name = result['class']
|
153
|
+
result_class = class_cache[class_name]
|
154
|
+
unless result_class then
|
155
|
+
class_name.split("::").each do | chunk |
|
156
|
+
if result_class then
|
157
|
+
result_class = result_class.const_get( chunk )
|
158
|
+
else
|
159
|
+
result_class = Kernel.const_get( chunk )
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
class_cache[class_name] = result_class
|
164
|
+
end
|
165
|
+
|
166
|
+
result['xampl'] = self.lookup(result_class, result['pid'])
|
167
|
+
end
|
168
|
+
|
169
|
+
if hint then
|
170
|
+
return results.uniq, the_hint
|
171
|
+
else
|
172
|
+
return results.uniq
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
=end
|
177
|
+
|
178
|
+
=begin
|
179
|
+
|
180
|
+
def find_xampl(hint=false)
|
181
|
+
setup_db
|
182
|
+
query = TableQuery.new(@tc_db)
|
183
|
+
|
184
|
+
yield query
|
185
|
+
|
186
|
+
class_cache = {}
|
187
|
+
|
188
|
+
result_keys = nil
|
189
|
+
the_hint = nil
|
190
|
+
if hint then
|
191
|
+
result_keys, the_hint = query.search(true)
|
192
|
+
else
|
193
|
+
result_keys = query.search
|
194
|
+
end
|
195
|
+
|
196
|
+
results = result_keys.collect do | key |
|
197
|
+
result = @tc_db[ key ]
|
198
|
+
next unless result
|
199
|
+
|
200
|
+
class_name = result['class']
|
201
|
+
result_class = class_cache[class_name]
|
202
|
+
unless result_class then
|
203
|
+
class_name.split("::").each do | chunk |
|
204
|
+
if result_class then
|
205
|
+
result_class = result_class.const_get( chunk )
|
206
|
+
else
|
207
|
+
result_class = Kernel.const_get( chunk )
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
class_cache[class_name] = result_class
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
self.lookup(result_class, result['pid'])
|
216
|
+
end
|
217
|
+
|
218
|
+
if hint then
|
219
|
+
return results.uniq, the_hint
|
220
|
+
else
|
221
|
+
return results.uniq
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
def find_pids(hint=false)
|
226
|
+
setup_db
|
227
|
+
query = TableQuery.new(@tc_db)
|
228
|
+
|
229
|
+
yield query
|
230
|
+
|
231
|
+
result_keys = nil
|
232
|
+
the_hint = nil
|
233
|
+
if hint then
|
234
|
+
result_keys, the_hint = query.search(true)
|
235
|
+
else
|
236
|
+
result_keys = query.search
|
237
|
+
end
|
238
|
+
|
239
|
+
results = result_keys.collect do |key|
|
240
|
+
meta = @tc_db[ key ]
|
241
|
+
meta['xampl-place'] || meta['place']
|
242
|
+
end
|
243
|
+
|
244
|
+
if hint then
|
245
|
+
return results.uniq, the_hint
|
246
|
+
else
|
247
|
+
return results.uniq
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def find_meta(hint=false)
|
252
|
+
setup_db
|
253
|
+
query = TableQuery.new(@tc_db)
|
254
|
+
|
255
|
+
yield query
|
256
|
+
|
257
|
+
result_keys = nil
|
258
|
+
the_hint = nil
|
259
|
+
if hint then
|
260
|
+
result_keys, the_hint = query.search(true)
|
261
|
+
else
|
262
|
+
result_keys = query.search
|
263
|
+
end
|
264
|
+
|
265
|
+
results = result_keys.collect { | key | @tc_db[ key ] }
|
266
|
+
|
267
|
+
if hint then
|
268
|
+
return results, the_hint
|
269
|
+
else
|
270
|
+
return results
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
def find_mentions_of(xampl)
|
275
|
+
setup_db
|
276
|
+
|
277
|
+
place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
|
278
|
+
|
279
|
+
query = TableQuery.new(@tc_db)
|
280
|
+
query.add_condition('xampl-to', :equals, place)
|
281
|
+
result_keys = query.search
|
282
|
+
|
283
|
+
class_cache = {}
|
284
|
+
results = result_keys.collect do | key |
|
285
|
+
result = @tc_db[ key ]
|
286
|
+
next unless result
|
287
|
+
|
288
|
+
mentioner = result['xampl-from']
|
289
|
+
class_name = result['mentioned_class']
|
290
|
+
result_class = class_cache[class_name]
|
291
|
+
unless result_class then
|
292
|
+
class_name.split("::").each do | chunk |
|
293
|
+
if result_class then
|
294
|
+
result_class = result_class.const_get( chunk )
|
295
|
+
else
|
296
|
+
result_class = Kernel.const_get( chunk )
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
class_cache[class_name] = result_class
|
301
|
+
end
|
302
|
+
|
303
|
+
self.lookup(result_class, result['pid'])
|
304
|
+
end
|
305
|
+
return results.uniq
|
306
|
+
end
|
307
|
+
|
308
|
+
=end
|
309
|
+
|
310
|
+
def start_sync_write
|
311
|
+
setup_db
|
312
|
+
end
|
313
|
+
|
314
|
+
def done_sync_write
|
315
|
+
# @logger.info "there are now #{ @coll.count } xampl cluster documents in the database"
|
316
|
+
# puts "there are now #{ @coll.count } xampl cluster documents in the database"
|
317
|
+
end
|
318
|
+
|
319
|
+
|
320
|
+
def do_sync_write
|
321
|
+
@time_stamp = Time.now.to_f.to_s
|
322
|
+
|
323
|
+
@changed.each do |xampl, ignore|
|
324
|
+
write(xampl)
|
325
|
+
end
|
326
|
+
rescue => e
|
327
|
+
#puts "------------------------------------------------------------------------"
|
328
|
+
#puts "MongoPersister Error:: #{ e }"
|
329
|
+
#puts e.backtrace.join("\n")
|
330
|
+
#puts "------------------------------------------------------------------------"
|
331
|
+
raise RuntimeError, "MongoPersister Error:: #{ e }", e.backtrace
|
332
|
+
end
|
333
|
+
|
334
|
+
=begin
|
335
|
+
|
336
|
+
def how_indexed(xampl)
|
337
|
+
raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index
|
338
|
+
place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
|
339
|
+
|
340
|
+
setup_db
|
341
|
+
|
342
|
+
result_keys = Set.new
|
343
|
+
|
344
|
+
query = TableQuery.new(@tc_db)
|
345
|
+
query.add_condition('xampl-place', :equals, place)
|
346
|
+
search_results = query.search
|
347
|
+
result_keys.merge( search_results)
|
348
|
+
|
349
|
+
primary = @tc_db[ place ]
|
350
|
+
if primary then
|
351
|
+
primary.delete('xampl')
|
352
|
+
end
|
353
|
+
|
354
|
+
results = primary ? [ primary ] : []
|
355
|
+
result_keys.each do | key |
|
356
|
+
result = @tc_db[ key ]
|
357
|
+
next unless result
|
358
|
+
|
359
|
+
result.delete('xampl')
|
360
|
+
|
361
|
+
results << result
|
362
|
+
end
|
363
|
+
|
364
|
+
results
|
365
|
+
end
|
366
|
+
|
367
|
+
=end
|
368
|
+
|
369
|
+
=begin
|
370
|
+
|
371
|
+
def remove_all_mention(root, xampl)
|
372
|
+
#TODO -- I THINK THIS IS WRONG... IS IT GOING WAY TOO DEEP??
|
373
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] in #{ root } of #{ xampl }"
|
374
|
+
xampl.remove_from(root)
|
375
|
+
root.children.each do | child |
|
376
|
+
remove_all_mention(child, xampl)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def expunge(xampl)
|
381
|
+
#NOTE -- this *must* be in a xampl transaction
|
382
|
+
#NOTE -- the expunge operation is in two steps and is completed in write
|
383
|
+
|
384
|
+
mentions = Xampl.find_mentions_of(xampl)
|
385
|
+
mentions.each do | has_a_xampl |
|
386
|
+
remove_all_mention(has_a_xampl, xampl)
|
387
|
+
end
|
388
|
+
xampl.changed
|
389
|
+
self.expunged << xampl
|
390
|
+
|
391
|
+
false
|
392
|
+
end
|
393
|
+
|
394
|
+
=end
|
395
|
+
|
396
|
+
def write(xampl)
|
397
|
+
unless xampl.get_the_index then
|
398
|
+
# raise XamplException.new(:no_index_so_no_persist)
|
399
|
+
@logger.warn("trying to persist a #{ xampl.class.name } with no key")
|
400
|
+
return
|
401
|
+
end
|
402
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] #{ xampl }"
|
403
|
+
|
404
|
+
expunging = self.expunged.include?(xampl)
|
405
|
+
self.expunged.delete(xampl) if expunging
|
406
|
+
|
407
|
+
place_dir = xampl.class.name.split("::")
|
408
|
+
place = File.join( place_dir, xampl.get_the_index)
|
409
|
+
mentions = Set.new
|
410
|
+
xampl_in_xml = represent(xampl, mentions)
|
411
|
+
unless xampl_in_xml && 0 < xampl_in_xml.size then
|
412
|
+
@logger.warn "Cannot persist #{ xampl } because representation is unobtainable"
|
413
|
+
return
|
414
|
+
end
|
415
|
+
|
416
|
+
=begin
|
417
|
+
|
418
|
+
#get rid of any supplimentary indexes associated with this xampl object
|
419
|
+
query = TableQuery.new(@tc_db)
|
420
|
+
query.add_condition('xampl-from', :equals, place)
|
421
|
+
query.searchout
|
422
|
+
|
423
|
+
query = TableQuery.new(@tc_db)
|
424
|
+
query.add_condition('xampl-place', :equals, place)
|
425
|
+
query.searchout
|
426
|
+
|
427
|
+
=end
|
428
|
+
|
429
|
+
if expunging then
|
430
|
+
puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] "
|
431
|
+
file_place = "#{ @files_dir }/#{ place }"
|
432
|
+
File.delete(file_place) if File.exists?(file_place)
|
433
|
+
@coll.remove({ '_id' => place })
|
434
|
+
|
435
|
+
uncache(xampl)
|
436
|
+
else
|
437
|
+
|
438
|
+
# We can do secondary descriptions in two primary ways: include in a single document containing them
|
439
|
+
# in an attribute called 'secondary'; introducing a document for each secondary description that
|
440
|
+
# refers to the primary document. The single doc approach has some advantages but the semantics of the
|
441
|
+
# indexes might be different (e.g. one thing uses 'kind' as a primary and another as a secondary, then they
|
442
|
+
# will not be indexed in the same way). The biggest advantage is that we have fewer documents, and it is
|
443
|
+
# what the tokyo cabinet persister does.
|
444
|
+
#
|
445
|
+
# Will go with the single doc approach to start
|
446
|
+
#
|
447
|
+
|
448
|
+
single_document = {
|
449
|
+
'_id' => place,
|
450
|
+
'class' => xampl.class.name,
|
451
|
+
'pid' => xampl.get_the_index,
|
452
|
+
'time-stamp' => @time_stamp,
|
453
|
+
'xampl' => xampl_in_xml
|
454
|
+
}
|
455
|
+
|
456
|
+
if Xampl.raw_persister_options[:mentions] then
|
457
|
+
if 0 < mentions.size
|
458
|
+
single_document['mentions'] = mentions_array = []
|
459
|
+
mentions.each do | mention |
|
460
|
+
mentions_array << {
|
461
|
+
'xampl-from' => place,
|
462
|
+
'mentioned_class' => xampl.class.name,
|
463
|
+
'pid' => xampl.get_the_index,
|
464
|
+
'xampl-to' => File.join(mention.class.name.split("::"), mention.get_the_index)
|
465
|
+
}
|
466
|
+
end
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
if xampl.should_schedule_delete? and xampl.scheduled_for_deletion_at then
|
471
|
+
single_document['scheduled-delete-at'] = xampl.scheduled_for_deletion_at
|
472
|
+
end
|
473
|
+
|
474
|
+
primary_description, secondary_descriptions = xampl.describe_yourself
|
475
|
+
|
476
|
+
if secondary_descriptions && 0 < secondary_descriptions.size then
|
477
|
+
single_document['idx'] = secondary_descriptions.insert(0, primary_description)
|
478
|
+
else
|
479
|
+
single_document['idx'] = [primary_description]
|
480
|
+
end
|
481
|
+
|
482
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] \n#{ single_document.inspect }"
|
483
|
+
|
484
|
+
# @coll.update(single_document, upsert: true)
|
485
|
+
|
486
|
+
# @coll.remove({ '_id' => place })
|
487
|
+
# @coll.insert(single_document)
|
488
|
+
|
489
|
+
@coll.save(single_document)
|
490
|
+
|
491
|
+
begin
|
492
|
+
if Xampl.raw_persister_options[:write_through] then
|
493
|
+
place_dir = File.join( @files_dir, place_dir )
|
494
|
+
FileUtils.mkdir_p(place_dir) unless File.exist?(place_dir)
|
495
|
+
file_place = "#{ @files_dir }/#{ place }"
|
496
|
+
File.open(file_place, "w") do |out|
|
497
|
+
out.write xampl_in_xml
|
498
|
+
if :sync == Xampl.raw_persister_options[:write_through] then
|
499
|
+
out.fsync
|
500
|
+
if $is_darwin then
|
501
|
+
out.fcntl(51, 0) # Attempt an F_FULLFSYNC fcntl to commit data to disk (darwin *ONLY*)
|
502
|
+
end
|
503
|
+
end
|
504
|
+
end
|
505
|
+
if single_document['idx'] then
|
506
|
+
single_document.delete('xampl')
|
507
|
+
File.open(file_place + ".idx", "w") do |out|
|
508
|
+
out.write single_document.to_yaml
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
rescue => e
|
513
|
+
puts "#{ File.basename __FILE__ }:#{ __LINE__ } [#{__method__}] write through failed #{ xampl }"
|
514
|
+
end
|
515
|
+
|
516
|
+
@write_count = @write_count + 1
|
517
|
+
xampl.changes_accepted
|
518
|
+
end
|
519
|
+
|
520
|
+
return true
|
521
|
+
end
|
522
|
+
|
523
|
+
def read_representation(klass, pid)
|
524
|
+
representation = nil
|
525
|
+
|
526
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] #{ klass }[#{ pid }]"
|
527
|
+
place = File.join(klass.name.split("::"), pid)
|
528
|
+
found = @coll.find_one({ '_id' => place })
|
529
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] found: #{found.class.name}/#{ found.inspect }"
|
530
|
+
|
531
|
+
if found then
|
532
|
+
representation = found['xampl']
|
533
|
+
else
|
534
|
+
#TODO -- enable/disable this functionality
|
535
|
+
# try the filesystem if it is not in the TC repository
|
536
|
+
filename = File.join(@root_dir, klass.name.split("::"), pid)
|
537
|
+
representation = File.read(filename) if File.exist?(filename)
|
538
|
+
end
|
539
|
+
|
540
|
+
# puts "#{File.basename(__FILE__)}:#{__LINE__} [#{ __method__ }] #{ klass }[#{ pid }] found: #{ representation.class.name }"
|
541
|
+
return representation
|
542
|
+
end
|
543
|
+
end
|
544
|
+
|
545
|
+
Xampl.register_persister_kind(MongoPersister)
|
546
|
+
end
|
547
|
+
|
@@ -61,7 +61,7 @@ module Xampl
|
|
61
61
|
@tc_db = nil
|
62
62
|
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] file: #{ @filename }, db: #{ @tc_db.class.name }"
|
63
63
|
|
64
|
-
|
64
|
+
setup_db()
|
65
65
|
|
66
66
|
# note_errors("TC[[#{ @filename }]]:: optimisation error: %s\n") do
|
67
67
|
# @tc_db.optimize(-1, -1, -1, TDB::TDEFLATE)
|
@@ -175,7 +175,7 @@ module Xampl
|
|
175
175
|
end
|
176
176
|
|
177
177
|
def query(hint=false)
|
178
|
-
|
178
|
+
setup_db
|
179
179
|
query = TableQuery.new(@tc_db)
|
180
180
|
|
181
181
|
yield query
|
@@ -218,7 +218,7 @@ module Xampl
|
|
218
218
|
end
|
219
219
|
|
220
220
|
def find_xampl(hint=false)
|
221
|
-
|
221
|
+
setup_db
|
222
222
|
query = TableQuery.new(@tc_db)
|
223
223
|
|
224
224
|
yield query
|
@@ -263,7 +263,7 @@ module Xampl
|
|
263
263
|
end
|
264
264
|
|
265
265
|
def find_pids(hint=false)
|
266
|
-
|
266
|
+
setup_db
|
267
267
|
query = TableQuery.new(@tc_db)
|
268
268
|
|
269
269
|
yield query
|
@@ -289,7 +289,7 @@ module Xampl
|
|
289
289
|
end
|
290
290
|
|
291
291
|
def find_meta(hint=false)
|
292
|
-
|
292
|
+
setup_db
|
293
293
|
query = TableQuery.new(@tc_db)
|
294
294
|
|
295
295
|
yield query
|
@@ -312,7 +312,7 @@ module Xampl
|
|
312
312
|
end
|
313
313
|
|
314
314
|
def find_mentions_of(xampl)
|
315
|
-
|
315
|
+
setup_db
|
316
316
|
|
317
317
|
place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
|
318
318
|
|
@@ -353,7 +353,7 @@ module Xampl
|
|
353
353
|
# puts " 2 #{ callers[2] }"
|
354
354
|
|
355
355
|
@currently_syncing = true
|
356
|
-
|
356
|
+
setup_db
|
357
357
|
end
|
358
358
|
|
359
359
|
def done_sync_write
|
@@ -427,7 +427,7 @@ module Xampl
|
|
427
427
|
raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index
|
428
428
|
place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
|
429
429
|
|
430
|
-
|
430
|
+
setup_db
|
431
431
|
|
432
432
|
result_keys = Set.new
|
433
433
|
|
@@ -635,7 +635,7 @@ module Xampl
|
|
635
635
|
|
636
636
|
unless @tc_db then
|
637
637
|
# puts "#{ __FILE__ }:#{ __LINE__ } [#{__method__}] READ REP"
|
638
|
-
|
638
|
+
setup_db
|
639
639
|
end
|
640
640
|
|
641
641
|
place = File.join(klass.name.split("::"), pid)
|
@@ -646,7 +646,7 @@ module Xampl
|
|
646
646
|
# puts "#{File.basename(__FILE__)}:#{__LINE__} TC: #{ klass }/#{ pid }" if representation
|
647
647
|
$TC_COUNT += 1 if representation
|
648
648
|
|
649
|
-
#
|
649
|
+
#puts "read: #{ place }, size: #{ (representation || []).size }"
|
650
650
|
# puts representation[0..100]
|
651
651
|
|
652
652
|
unless representation then
|
@@ -0,0 +1,32 @@
|
|
1
|
+
class ProjectGenerator
|
2
|
+
|
3
|
+
def print_options
|
4
|
+
# return an array containing any (or none) of:
|
5
|
+
# :schema -- a schema-like xml representation of the generated code
|
6
|
+
# :graphml -- a graphml file describing the class model (compatible with yEd)
|
7
|
+
# :yuml -- a yuml file that represents a simplified class model (compatible with yUML)
|
8
|
+
|
9
|
+
[ :yuml ]
|
10
|
+
[]
|
11
|
+
end
|
12
|
+
|
13
|
+
def directory
|
14
|
+
# return the path name to the generator's output directory
|
15
|
+
File.join(%w{ . xampl-generated-code })
|
16
|
+
end
|
17
|
+
|
18
|
+
def resolve_namespaces
|
19
|
+
# any array of arrays
|
20
|
+
# each sub-array:
|
21
|
+
# 0: a string or an array of strings, containing xml namespaces found
|
22
|
+
# in the example xml files an empty string is the default namespace
|
23
|
+
# 1: a ruby Module name (get the character cases right)
|
24
|
+
# 2: a namespace prefix used when writing xml, optional. A generated
|
25
|
+
# prefix will be used otherwise.
|
26
|
+
|
27
|
+
[
|
28
|
+
['http://soldierofcode.com/ivorydocs/docmodel', 'OADocModel', 'oadocmodel_ns1'],
|
29
|
+
['http://soldierofcode.com/ivorydocs', 'IvoryDocsModel', 'ivorydocsmodel_ns1'],
|
30
|
+
]
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<ivorydocs pid=""
|
2
|
+
xmlns="http://soldierofcode.com/ivorydocs"
|
3
|
+
xmlns:docs="http://soldierofcode.com/ivorydocs/docmodel">
|
4
|
+
|
5
|
+
<customer pid=""
|
6
|
+
login_id=""
|
7
|
+
login_pwd=""
|
8
|
+
name=""
|
9
|
+
email=""
|
10
|
+
stamp=""
|
11
|
+
state="">
|
12
|
+
|
13
|
+
<docs:doc pid=""/>
|
14
|
+
|
15
|
+
</customer>
|
16
|
+
|
17
|
+
</ivorydocs>
|
@@ -0,0 +1,49 @@
|
|
1
|
+
<oadevdoc pid=""
|
2
|
+
xmlns="http://soldierofcode.com/ivorydocs/docmodel">
|
3
|
+
|
4
|
+
<doc pid=""
|
5
|
+
name=""
|
6
|
+
urlid=""
|
7
|
+
state=""
|
8
|
+
stamp=""
|
9
|
+
last-modified=""
|
10
|
+
version="">
|
11
|
+
|
12
|
+
<section pid=""
|
13
|
+
name=""
|
14
|
+
urlid=""
|
15
|
+
state=""
|
16
|
+
stamp=""
|
17
|
+
last-modified=""
|
18
|
+
version=""
|
19
|
+
doc=""
|
20
|
+
title=""
|
21
|
+
zorder=""
|
22
|
+
icon=""
|
23
|
+
tags=""
|
24
|
+
summary="">
|
25
|
+
|
26
|
+
<page pid=""
|
27
|
+
prev-page=""
|
28
|
+
next-page=""
|
29
|
+
state=""
|
30
|
+
stamp=""
|
31
|
+
last-modified=""
|
32
|
+
version=""
|
33
|
+
title=""
|
34
|
+
tags=""
|
35
|
+
section=""
|
36
|
+
urlid="">
|
37
|
+
|
38
|
+
<block id=""
|
39
|
+
title="">
|
40
|
+
<![CDATA[PUT HTML HERE]]>
|
41
|
+
</block>
|
42
|
+
|
43
|
+
</page>
|
44
|
+
|
45
|
+
</section>
|
46
|
+
</doc>
|
47
|
+
|
48
|
+
|
49
|
+
</oadevdoc>
|
data/xamplr.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{xamplr}
|
8
|
-
s.version = "1.9.
|
8
|
+
s.version = "1.9.6"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Bob Hutchison"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-08}
|
13
13
|
s.description = %q{xamplr is the ruby version of xampl.}
|
14
14
|
s.email = %q{hutch@recursive.ca}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -47,6 +47,7 @@ Gem::Specification.new do |s|
|
|
47
47
|
"lib/xamplr/persisters/dumb.rb",
|
48
48
|
"lib/xamplr/persisters/filesystem.rb",
|
49
49
|
"lib/xamplr/persisters/in-memory.rb",
|
50
|
+
"lib/xamplr/persisters/mongo.rb",
|
50
51
|
"lib/xamplr/persisters/simple.rb",
|
51
52
|
"lib/xamplr/persisters/tokyo-cabinet.rb",
|
52
53
|
"lib/xamplr/persisters/tokyo-cabinet.rb.1-DB",
|
@@ -91,6 +92,10 @@ Gem::Specification.new do |s|
|
|
91
92
|
"regression/parsing-namespaced-xml/project-generator.rb",
|
92
93
|
"regression/parsing-namespaced-xml/simple.rb",
|
93
94
|
"regression/parsing-namespaced-xml/xml/simple.xml",
|
95
|
+
"regression/require-within-generated-code/project-generator.rb",
|
96
|
+
"regression/require-within-generated-code/test.rb",
|
97
|
+
"regression/require-within-generated-code/xml/customers.xml",
|
98
|
+
"regression/require-within-generated-code/xml/docmodel.xml",
|
94
99
|
"regression/tc-indexes-crossing-pid-boundaries/Makefile",
|
95
100
|
"regression/tc-indexes-crossing-pid-boundaries/bad-idea.rb",
|
96
101
|
"regression/tc-indexes-crossing-pid-boundaries/fail-badly.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xamplr
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.9.
|
4
|
+
version: 1.9.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Hutchison
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-08 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- lib/xamplr/persisters/dumb.rb
|
73
73
|
- lib/xamplr/persisters/filesystem.rb
|
74
74
|
- lib/xamplr/persisters/in-memory.rb
|
75
|
+
- lib/xamplr/persisters/mongo.rb
|
75
76
|
- lib/xamplr/persisters/simple.rb
|
76
77
|
- lib/xamplr/persisters/tokyo-cabinet.rb
|
77
78
|
- lib/xamplr/persisters/tokyo-cabinet.rb.1-DB
|
@@ -116,6 +117,10 @@ files:
|
|
116
117
|
- regression/parsing-namespaced-xml/project-generator.rb
|
117
118
|
- regression/parsing-namespaced-xml/simple.rb
|
118
119
|
- regression/parsing-namespaced-xml/xml/simple.xml
|
120
|
+
- regression/require-within-generated-code/project-generator.rb
|
121
|
+
- regression/require-within-generated-code/test.rb
|
122
|
+
- regression/require-within-generated-code/xml/customers.xml
|
123
|
+
- regression/require-within-generated-code/xml/docmodel.xml
|
119
124
|
- regression/tc-indexes-crossing-pid-boundaries/Makefile
|
120
125
|
- regression/tc-indexes-crossing-pid-boundaries/bad-idea.rb
|
121
126
|
- regression/tc-indexes-crossing-pid-boundaries/fail-badly.rb
|