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 +4 -2
- data/lib/sax-mapper.rb +14 -2
- data/spec/sax-mapper/sax-mapper_spec.rb +21 -0
- metadata +1 -1
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
|
-
|
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
|
-
|
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
|
|
data/lib/sax-mapper.rb
CHANGED
@@ -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
|
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
|