MikeSofaer-sax-mapper 0.0.1 → 0.0.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 CHANGED
@@ -8,6 +8,8 @@ You can also set a column as a remote primary key, and it will overwrite rather
8
8
  than add records where that key is a duplicate (you need to separately set
9
9
  the column to be have a unique index, since it uses ON DUPLICATE KEY UPDATE)
10
10
 
11
+ You can specify a batch size to save in, and whether to wrap the save in a transaction.
12
+
11
13
  Finally, you can mark fields as required, and it will raise an expection if the
12
14
  XML is missing that field.
13
15
 
@@ -33,9 +35,9 @@ end
33
35
  Person.parse_multiple(xml) will return an array of Person objects, found inside
34
36
  <person></person> tags. You can save them to the DB with Person.save(array)
35
37
 
36
- Multiple values with the same sourced_id will replace each other in the DB.
38
+ Person.save(array, :batch_size => 3000, :transaction => true) will try to save them in batches of 3000, and roll everything back if any save fails.
37
39
 
38
- Query batching is not built in, you have to slice the array.
40
+ Multiple values with the same sourced_id will replace each other in the DB.
39
41
 
40
42
  gem install MikeSofaer-sax-mapper
41
43
 
@@ -1,5 +1,6 @@
1
1
  require 'sax-machine'
2
2
  require 'dm-core'
3
+ require 'enumerator'
3
4
 
4
5
  module SaxMapper
5
6
  class MissingElementError < Exception; end
@@ -80,8 +81,19 @@ module SaxMapper
80
81
  " ON DUPLICATE KEY UPDATE " + (column_names - [:created_at, @key_column]).map {|c| c.to_s + "=VALUES(" + c.to_s + ")"}.join(', ')
81
82
  end
82
83
 
83
- def save(rows)
84
- connection.execute sql(rows), *bind_values(rows)
84
+ def save(rows, options = {})
85
+ connection.execute "BEGIN" if options[:transaction]
86
+ if options[:batch_size]
87
+ rows.each_slice(options[:batch_size]) do |batch|
88
+ connection.execute sql(batch), *bind_values(batch)
89
+ end
90
+ else
91
+ connection.execute sql(rows), *bind_values(rows)
92
+ end
93
+ connection.execute "COMMIT" if options[:transaction]
94
+ rescue Exception => e
95
+ connection.execute "ROLLBACK" if options[:transaction]
96
+ raise e
85
97
  end
86
98
  end
87
99
 
@@ -70,9 +70,30 @@ describe "SaxMapper" do
70
70
  @klass.datamapper_class.all[0].title.should == "Hello, Everyone!"
71
71
  @klass.datamapper_class.all[1].title.should == "Someone's Cat"
72
72
  end
73
+ it "should support chunking into multiple queries" do
74
+ documents = @klass.parse_multiple(@xml)
75
+ @adapter.should_receive(:execute).exactly(3).times
76
+ @klass.save documents, :batch_size => 1
77
+ end
78
+ it "should work when chunking" do
79
+ documents = @klass.parse_multiple(@xml)
80
+ @klass.save documents
81
+ @klass.datamapper_class.all[0].title.should == "Hello, Everyone!"
82
+ @klass.datamapper_class.all[1].title.should == "Someone's Cat"
83
+ end
84
+ it "should do the chunks in a transaction if asked" do
85
+ t = DateTime.now.to_s
86
+ @adapter.execute "create unique index key_column on documents(written_on)"
87
+ xml= "<xml><document><title>Hello, Everyone!</title><written_on>#{t}</written_on></document><document><title>Someone's Cat</title><written_on>#{t}</written_on></document></xml>"
88
+ documents = @klass.parse_multiple xml
89
+ go = lambda{@klass.save documents, :batch_size => 1, :transaction => true}
90
+ go.should raise_error
91
+ @klass.datamapper_class.all.size.should == 0
92
+ end
73
93
  end
74
94
  describe "replication" do
75
95
  it "should update fields on rows with a repeated primary key" do
96
+ DataMapper.auto_migrate!
76
97
  @klass.key_column :written_on
77
98
  @adapter.execute "create unique index key_column on documents(written_on)"
78
99
  t = DateTime.now.to_s
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: MikeSofaer-sax-mapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Sofaer