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 +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
|