MikeSofaer-sax-mapper 0.0.1 → 0.0.2

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