hutch-xamplr 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/CHANGES.txt +13 -0
  2. data/VERSION.yml +1 -1
  3. data/examples/random-people/people.rb +2 -2
  4. data/examples/random-people/query.rb +16 -11
  5. data/examples/random-people-shared-addresses/Makefile +16 -0
  6. data/examples/random-people-shared-addresses/batch-load-users.rb +86 -0
  7. data/examples/random-people-shared-addresses/find-mentions.rb +50 -0
  8. data/examples/random-people-shared-addresses/find-people-by-address.rb +110 -0
  9. data/examples/random-people-shared-addresses/optimise.rb +19 -0
  10. data/examples/random-people-shared-addresses/people.rb +50 -0
  11. data/examples/random-people-shared-addresses/query.rb +78 -0
  12. data/examples/random-people-shared-addresses/query2.rb +76 -0
  13. data/examples/random-people-shared-addresses/random-names.csv +10000 -0
  14. data/examples/random-people-shared-addresses/what-to-query-on.rb +82 -0
  15. data/examples/random-people-shared-addresses/xampl-gen.rb +36 -0
  16. data/examples/random-people-shared-addresses/xml/people.xml +14 -0
  17. data/lib/xamplr/TODO +1 -3
  18. data/lib/xamplr/{persister → obsolete}/fsdb.rb +0 -0
  19. data/lib/xamplr/persistence.rb +7 -3
  20. data/lib/xamplr/persister/tokyo-cabinet.rb +70 -7
  21. data/lib/xamplr/templates/element_data.template +29 -21
  22. data/lib/xamplr/templates/element_empty.template +29 -22
  23. data/lib/xamplr/templates/element_mixed.template +31 -24
  24. data/lib/xamplr/templates/element_simple.template +29 -22
  25. data/lib/xamplr/{Makefile → test-support/Makefile} +0 -0
  26. data/lib/xamplr/{bench-cache.rb → test-support/bench-cache.rb} +1 -1
  27. data/lib/xamplr/{bench-script.rb → test-support/bench-script.rb} +0 -0
  28. data/lib/xamplr/{bench.rb → test-support/bench.rb} +0 -0
  29. data/lib/xamplr/{bench2.rb → test-support/bench2.rb} +9 -9
  30. data/lib/xamplr/{test-cache.rb → test-support/test-cache.rb} +0 -0
  31. data/lib/xamplr/{test-data → test-support/test-data}/binding.xml +0 -0
  32. data/lib/xamplr/{test-data → test-support/test-data}/example.xml +0 -0
  33. data/lib/xamplr/{test-data → test-support/test-data}/internationalization-utf8.txt +0 -0
  34. data/lib/xamplr/{test-data → test-support/test-data}/labels.xml +0 -0
  35. data/lib/xamplr/{test-data → test-support/test-data}/labels001.xml +0 -0
  36. data/lib/xamplr/{test-deep-change.rb → test-support/test-deep-change.rb} +0 -0
  37. data/lib/xamplr/{test-elements.rb → test-support/test-elements.rb} +0 -0
  38. data/lib/xamplr/{test-indexed-array.rb → test-support/test-indexed-array.rb} +0 -0
  39. data/lib/xamplr/{test-misc.rb → test-support/test-misc.rb} +0 -0
  40. data/lib/xamplr/{test-names.rb → test-support/test-names.rb} +0 -0
  41. data/lib/xamplr/{test-rollback.rb → test-support/test-rollback.rb} +0 -0
  42. data/lib/xamplr/{test.rb → test-support/test.rb} +74 -74
  43. data/lib/xamplr/to-ruby.rb +19 -15
  44. data/lib/xamplr/to-xml.rb +5 -4
  45. data/lib/xamplr/visitor.rb +6 -2
  46. data/lib/xamplr/xampl-object.rb +4 -9
  47. metadata +43 -25
  48. data/lib/xamplr/BUGS +0 -3
  49. data/lib/xamplr/CHANGES +0 -16
  50. data/lib/xamplr/REQUIREMENTS +0 -2
  51. data/lib/xamplr/sqlite/sqlite-play.rb +0 -14
@@ -0,0 +1,82 @@
1
+ $LOAD_PATH.unshift("xampl_generated_code")
2
+
3
+ require 'set'
4
+ require 'fastercsv'
5
+ require 'RandomPeople'
6
+ require 'people'
7
+
8
+ Xampl.set_default_persister_kind(:tokyo_cabinet)
9
+ Xampl.set_default_persister_format(:xml_format)
10
+
11
+ module RandomPeople
12
+ arr_of_arrs = FasterCSV.read("random-names.csv")
13
+
14
+ surnames = Set.new
15
+ cities = Set.new
16
+ states = Set.new
17
+ email_domains = Set.new
18
+
19
+ arr_of_arrs.each do | row |
20
+ surname = row[1]
21
+ city = row[3]
22
+ state = row[4]
23
+
24
+ surnames << surname
25
+ cities << city
26
+ states << state
27
+
28
+ email = row[6]
29
+ domain = email.split("@")
30
+ if 2 == domain.size then
31
+ email_domains << domain[1]
32
+ end
33
+
34
+ end
35
+
36
+ puts "surnames: #{ surnames.size }"
37
+ puts "cities: #{ cities.size }"
38
+ puts "states: #{ states.size }"
39
+ puts "email_domains: #{ email_domains.size }"
40
+
41
+ puts "STATES:"
42
+ puts states.to_a.sort.inspect
43
+
44
+ puts "EMAIL DOMAINS:"
45
+ puts email_domains.to_a.sort.inspect
46
+
47
+ #GivenName,Surname,StreetAddress,City,State,ZipCode,EmailAddress,TelephoneNumber
48
+ #<people pid='' xmlns="http://xampl.com/people">
49
+ # <person pid=''
50
+ # given-name=''
51
+ # surname=''
52
+ # street-address=''
53
+ # city=''
54
+ # state=''
55
+ # postal-code=''
56
+ # email=''
57
+ # phone=''/>
58
+ #</people>
59
+
60
+ # Xampl.transaction("random-people") do
61
+ #
62
+ # people = People.new('people')
63
+ #
64
+ # arr_of_arrs.each_with_index do | row, i |
65
+ # person = people.new_person("person-#{ i }")
66
+ # person.given_name = row[0]
67
+ # person.surname = row[1]
68
+ # person.street_address = row[2]
69
+ # person.city = row[3]
70
+ # person.state = row[4]
71
+ # person.postal_code = row[5]
72
+ # person.email = row[6]
73
+ # person.phone = row[7]
74
+ # end
75
+ # end
76
+ #
77
+ # processed_at = Time.now
78
+ #
79
+ # p counts
80
+ # p "parsed in #{ parsed_at - start_at }, counted in: #{ counted_at - parsed_at }, processed in: #{ processed_at - counted_at }"
81
+
82
+ end
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby -w -I..
2
+
3
+ if $0 == __FILE__ then
4
+
5
+ class File
6
+ def File.sjoin(*args)
7
+ File.join(args.select{ | o | o })
8
+ end
9
+ end
10
+
11
+ require 'xamplr-generator'
12
+
13
+ include XamplGenerator
14
+ include Xampl
15
+
16
+ Xampl.transaction("setup", :in_memory) do
17
+ directory = File.sjoin(".", "xampl_generated_code")
18
+
19
+ options = Xampl.make(Options) do |options|
20
+ options.new_index_attribute("pid").persisted = true
21
+ options.new_index_attribute("id")
22
+
23
+ options.resolve("http://xampl.com/people", "RandomPeople", "p")
24
+ end
25
+
26
+ filenames = Dir.glob("./xml/**/*.xml")
27
+
28
+ generator = Generator.new
29
+ generator.go(:options => options,
30
+ :filenames => filenames,
31
+ :directory => directory)
32
+
33
+ #puts generator.print_elements("./generated-elements.xml")
34
+ exit!
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ <people pid=''
2
+ xmlns="http://xampl.com/people">
3
+ <person pid=''
4
+ given-name=''
5
+ surname=''
6
+ email=''
7
+ phone=''>
8
+ <address pid=''
9
+ street-address=''
10
+ city=''
11
+ state=''
12
+ postal-code=''/>
13
+ </person>
14
+ </people>
data/lib/xamplr/TODO CHANGED
@@ -1,3 +1 @@
1
- -- add a way of ignoring namespaces (e.g. xhtml) during load and comprehension
2
- (have this for pp_xml)
3
- -- escaped content is being repeatedly escaped
1
+ -- escaped content is being repeatedly escaped (confirm, just a suspiscion from a long time ago)
File without changes
@@ -518,6 +518,10 @@ module Xampl
518
518
  @@persister.find_pids(hint) { | q | yield q } if @@persister
519
519
  end
520
520
 
521
+ def Xampl.find_mentions_of(xampl)
522
+ @@persister.find_mentions_of(xampl) if @@persister
523
+ end
524
+
521
525
  class Persister
522
526
  attr_accessor :name,
523
527
  :automatic,
@@ -636,14 +640,14 @@ module Xampl
636
640
  @@persister.introduce(new_xampl)
637
641
  end
638
642
 
639
- def represent(xampl)
643
+ def represent(xampl, mentions)
640
644
  #puts "REPRESENT #{xampl} load needed: #{xampl.load_needed}"
641
645
  # return nil if xampl.load_needed
642
646
  case xampl.default_persister_format || @format
643
647
  when nil, :xml_format then
644
- return xampl.persist
648
+ return xampl.persist("", mentions)
645
649
  when :ruby_format then
646
- return xampl.to_ruby
650
+ return xampl.to_ruby(mentions)
647
651
  when :yaml_format then
648
652
  return xampl.as_yaml
649
653
  end
@@ -15,17 +15,16 @@ module Xampl
15
15
  unless result then
16
16
  rmsg = sprintf(msg, @tc_db.errmsg(@tc_db.ecode))
17
17
  STDERR.printf(rmsg)
18
- # STDERR.printf("CODE: " + @tc_db.ecode)
19
- puts "---------"
18
+ STDERR.puts "---------"
20
19
  caller(0).each do |trace|
21
20
  STDERR.puts(trace)
22
21
  end
23
- puts "---------"
22
+ STDERR.puts "---------"
24
23
  end
25
24
  return rmsg
26
25
  end
27
26
 
28
- $lexical_indexes = Set.new(%w{ class pid time-stamp }) unless defined?($lexical_indexes)
27
+ $lexical_indexes = Set.new(%w{ class pid time-stamp xampl_from xampl_to }) unless defined?($lexical_indexes)
29
28
  $numeric_indexes = Set.new unless defined?($numeric_indexes)
30
29
 
31
30
  def TokyoCabinetPersister.add_lexical_indexs(indexes)
@@ -64,6 +63,7 @@ module Xampl
64
63
  end
65
64
 
66
65
  # Don't care if there are errors (in fact, if the index exists a failure is the expected thing)
66
+
67
67
  $lexical_indexes.each do | index_name |
68
68
  @tc_db.setindex(index_name, TDB::ITLEXICAL | TDB::ITKEEP)
69
69
  end
@@ -193,7 +193,6 @@ module Xampl
193
193
  else
194
194
  return results
195
195
  end
196
-
197
196
  end
198
197
 
199
198
  def find_pids(hint=false)
@@ -215,7 +214,6 @@ module Xampl
215
214
  else
216
215
  return result_keys
217
216
  end
218
-
219
217
  end
220
218
 
221
219
  def find_meta(hint=false)
@@ -239,7 +237,40 @@ module Xampl
239
237
  else
240
238
  return results
241
239
  end
240
+ end
241
+
242
+ def find_mentions_of(xampl)
243
+ open_tc_db
244
+
245
+ place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
246
+
247
+ query = TableQuery.new(@tc_db)
248
+ query.add_condition('xampl_to', :equals, place)
249
+ result_keys = query.search
250
+
251
+ class_cache = {}
252
+ results = result_keys.collect do | key |
253
+ result = @tc_db[ key ]
254
+ next unless result
255
+
256
+ mentioner = result['xampl_from']
257
+ class_name = result['class']
258
+ result_class = class_cache[class_name]
259
+ unless result_class then
260
+ class_name.split("::").each do | chunk |
261
+ if result_class then
262
+ result_class = result_class.const_get( chunk )
263
+ else
264
+ result_class = Kernel.const_get( chunk )
265
+ end
266
+ end
242
267
 
268
+ class_cache[class_name] = result_class
269
+ end
270
+
271
+ self.lookup(result_class, result['pid'])
272
+ end
273
+ return results
243
274
  end
244
275
 
245
276
  def do_sync_write
@@ -281,7 +312,31 @@ module Xampl
281
312
  raise XamplException.new(:no_index_so_no_persist) unless xampl.get_the_index
282
313
 
283
314
  place = File.join(xampl.class.name.split("::"), xampl.get_the_index)
284
- data = represent(xampl)
315
+ mentions = Set.new
316
+ data = represent(xampl, mentions)
317
+
318
+ query = TableQuery.new(@tc_db)
319
+ query.add_condition('xampl_from', :equals, place)
320
+ note_errors("TC:: failed to remove from mentions, error: %s\n") do
321
+ query.searchout
322
+ end
323
+
324
+ mentions.each do | mention |
325
+ mention_place = File.join(mention.class.name.split("::"), mention.get_the_index)
326
+ #TODO -- will repeadedly changing a persisted xampl object fragment the TC db?
327
+
328
+ pk = @tc_db.genuid
329
+ mention_hash = {
330
+ 'xampl_from' => place,
331
+ 'class' => xampl.class.name,
332
+ 'pid' => xampl.get_the_index,
333
+ 'xampl_to' => mention_place
334
+ }
335
+
336
+ note_errors("TC:: write error: %s\n") do
337
+ @tc_db.put(pk, mention_hash)
338
+ end
339
+ end
285
340
 
286
341
  xampl_hash = {
287
342
  'class' => xampl.class.name,
@@ -427,6 +482,14 @@ module Xampl
427
482
  end
428
483
  end
429
484
 
485
+ #
486
+ # Performs the search and removes whatever's found
487
+ #
488
+
489
+ def searchout
490
+ r = @query.searchout
491
+ end
492
+
430
493
  # limits the search
431
494
 
432
495
  def setlimit(max=nil, skip=nil)
@@ -5,7 +5,7 @@
5
5
  |if @element.persisted then
6
6
  |
7
7
  include Xampl::XamplPersistedObject
8
-
8
+
9
9
  @@default_persister_format = nil
10
10
 
11
11
  def default_persister_format
@@ -18,6 +18,14 @@
18
18
  @@default_persister_format = format
19
19
  end
20
20
 
21
+ def #{@element.class_name}.find_by_query
22
+ things = Xampl.find_xampl do | q |
23
+ q.add_condition('class', :equals, self.name)
24
+ yield(q)
25
+ end
26
+ end
27
+
28
+
21
29
  |
22
30
  |else
23
31
  |
@@ -78,7 +86,7 @@
78
86
  |
79
87
  "@children",
80
88
  "@_content"
81
- ]
89
+ ]
82
90
 
83
91
  def to_yaml_properties
84
92
  |
@@ -154,7 +162,7 @@
154
162
  |
155
163
  | else
156
164
  |
157
-
165
+
158
166
  def initialize
159
167
  super
160
168
  |
@@ -183,7 +191,7 @@
183
191
  |
184
192
  |}
185
193
  |
186
-
194
+
187
195
  yield(self) if block_given?
188
196
  init_hook
189
197
 
@@ -201,11 +209,11 @@
201
209
  |}
202
210
  |
203
211
  end
204
-
212
+
205
213
  def append_to(other)
206
214
  other.add_#{@element.attribute_name}(self)
207
215
  end
208
-
216
+
209
217
  |
210
218
  |if @element.persisted then
211
219
  |
@@ -234,11 +242,11 @@
234
242
  def #{@element.class_name}.tag
235
243
  @@tag
236
244
  end
237
-
245
+
238
246
  def #{@element.class_name}.ns
239
247
  @@ns
240
248
  end
241
-
249
+
242
250
  def #{@element.class_name}.ns_tag
243
251
  @@ns_tag
244
252
  end
@@ -246,19 +254,19 @@
246
254
  def #{@element.class_name}.safe_name
247
255
  @@safe_name
248
256
  end
249
-
257
+
250
258
  def #{@element.class_name}.module_name
251
259
  @@module_name
252
260
  end
253
-
261
+
254
262
  def tag
255
263
  @@tag
256
264
  end
257
-
265
+
258
266
  def ns
259
267
  @@ns
260
268
  end
261
-
269
+
262
270
  def ns_tag
263
271
  @@ns_tag
264
272
  end
@@ -266,45 +274,45 @@
266
274
  def safe_name
267
275
  @@safe_name
268
276
  end
269
-
277
+
270
278
  def module_name
271
279
  @@module_name
272
280
  end
273
-
281
+
274
282
  def attributes
275
283
  @@attributes
276
284
  end
277
285
  |
278
286
  |if @element.indexed_by_attr
279
287
  |
280
-
288
+
281
289
  def indexed_by
282
290
  :#{@element.indexed_by_attr}
283
291
  end
284
-
292
+
285
293
  def get_the_index
286
294
  @#{@element.indexed_by_attr}
287
295
  end
288
-
296
+
289
297
  def set_the_index(index)
290
298
  @#{@element.indexed_by_attr} = index
291
299
  end
292
300
  |
293
301
  |end
294
302
  |
295
-
303
+
296
304
  def substitute_in_visit(visitor)
297
305
  return visitor.substitute_in_visit_#{@element.attribute_name}(self) || self
298
306
  end
299
-
307
+
300
308
  def before_visit(visitor)
301
309
  visitor.before_visit_#{@element.attribute_name}(self)
302
310
  end
303
-
311
+
304
312
  def visit(visitor)
305
313
  visitor.visit_#{@element.attribute_name}(self)
306
314
  end
307
-
315
+
308
316
  def after_visit(visitor)
309
317
  visitor.after_visit_#{@element.attribute_name}(self)
310
318
  end
@@ -4,7 +4,7 @@
4
4
  |if @element.persisted then
5
5
  |
6
6
  include Xampl::XamplPersistedObject
7
-
7
+
8
8
  @@default_persister_format = nil
9
9
 
10
10
  def default_persister_format
@@ -17,6 +17,13 @@
17
17
  @@default_persister_format = format
18
18
  end
19
19
 
20
+ def #{@element.class_name}.find_by_query
21
+ things = Xampl.find_xampl do | q |
22
+ q.add_condition('class', :equals, self.name)
23
+ yield(q)
24
+ end
25
+ end
26
+
20
27
  |
21
28
  |else
22
29
  |
@@ -25,7 +32,7 @@
25
32
  |end
26
33
  |
27
34
  include Xampl::XamplWithoutContent
28
-
35
+
29
36
  @@tag = "#{element.name}"
30
37
  @@ns = "#{@element.namespace}"
31
38
  @@ns_tag = "{#{@element.namespace}}#{element.name}"
@@ -59,7 +66,7 @@
59
66
  |
60
67
 
61
68
  @@to_yaml_properties = [ "@#{@element.indexed_by_attr}" ]
62
- @@to_yaml_properties_all = [
69
+ @@to_yaml_properties_all = [
63
70
 
64
71
  |
65
72
  |else
@@ -75,8 +82,8 @@
75
82
  |
76
83
  |}
77
84
  |
78
- ]
79
-
85
+ ]
86
+
80
87
  def to_yaml_properties
81
88
  |
82
89
  |if @element.persisted then
@@ -160,7 +167,7 @@
160
167
  |
161
168
  | else
162
169
  |
163
-
170
+
164
171
  def initialize
165
172
  super
166
173
  |
@@ -194,7 +201,7 @@
194
201
 
195
202
  changed
196
203
  end
197
-
204
+
198
205
  def clear_non_persistent_index_attributes
199
206
  |
200
207
  |@element.attribute_child.each{ | attribute |
@@ -206,11 +213,11 @@
206
213
  |}
207
214
  |
208
215
  end
209
-
216
+
210
217
  def append_to(other)
211
218
  other.add_#{element.attribute_name}(self)
212
219
  end
213
-
220
+
214
221
  |
215
222
  |if @element.persisted then
216
223
  |
@@ -239,11 +246,11 @@
239
246
  def #{@element.class_name}.tag
240
247
  @@tag
241
248
  end
242
-
249
+
243
250
  def #{@element.class_name}.ns
244
251
  @@ns
245
252
  end
246
-
253
+
247
254
  def #{@element.class_name}.ns_tag
248
255
  @@ns_tag
249
256
  end
@@ -251,19 +258,19 @@
251
258
  def #{@element.class_name}.safe_name
252
259
  @@safe_name
253
260
  end
254
-
261
+
255
262
  def #{@element.class_name}.module_name
256
263
  @@module_name
257
264
  end
258
-
265
+
259
266
  def tag
260
267
  @@tag
261
268
  end
262
-
269
+
263
270
  def ns
264
271
  @@ns
265
272
  end
266
-
273
+
267
274
  def ns_tag
268
275
  @@ns_tag
269
276
  end
@@ -271,11 +278,11 @@
271
278
  def safe_name
272
279
  @@safe_name
273
280
  end
274
-
281
+
275
282
  def module_name
276
283
  @@module_name
277
284
  end
278
-
285
+
279
286
  def attributes
280
287
  @@attributes
281
288
  end
@@ -286,11 +293,11 @@
286
293
  def indexed_by
287
294
  :#{@element.indexed_by_attr}
288
295
  end
289
-
296
+
290
297
  def get_the_index
291
298
  @#{@element.indexed_by_attr}
292
299
  end
293
-
300
+
294
301
  def set_the_index(index)
295
302
  @#{@element.indexed_by_attr} = index
296
303
  end
@@ -301,15 +308,15 @@
301
308
  def substitute_in_visit(visitor)
302
309
  return visitor.substitute_in_visit_#{@element.attribute_name}(self) || self
303
310
  end
304
-
311
+
305
312
  def before_visit(visitor)
306
313
  visitor.before_visit_#{@element.attribute_name}(self)
307
314
  end
308
-
315
+
309
316
  def visit(visitor)
310
317
  visitor.visit_#{@element.attribute_name}(self)
311
318
  end
312
-
319
+
313
320
  def after_visit(visitor)
314
321
  visitor.after_visit_#{@element.attribute_name}(self)
315
322
  end