hutch-xamplr 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
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