data_active 0.0.5 → 0.0.6
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/features/step_definitions/sync_books_with_xml.rb +48 -3
- data/features/support/fixtures/xml/books_fresh_without_ids.xml +5 -0
- data/features/support/fixtures/xml/ms_access/books_fresh_without_ids.xml +5 -0
- data/features/sync_one_to_many.feature +1 -0
- data/lib/data_active.rb +46 -60
- data/lib/data_active/version.rb +1 -1
- metadata +3 -3
@@ -110,6 +110,12 @@ When /^the book price will be identical to those in "([^"]*)"$/ do |xml_document
|
|
110
110
|
if book_price.nil?
|
111
111
|
fail "BookPrice with id #{book_price_id} is missing"
|
112
112
|
else
|
113
|
+
if book_price.book_id.nil?
|
114
|
+
fail "BookPrice.book_id in database isn't being set (expecting book_id = #{book_id})"
|
115
|
+
elsif book_price.book_id != book_id.to_i
|
116
|
+
fail "BookPrice.book_id in database is set incorrectly (expecting book_id = #{book_id} and got #{book_price.book_id})"
|
117
|
+
end
|
118
|
+
|
113
119
|
book_price_sell = book_price_element.xpath("sell").text
|
114
120
|
book_price_educational = book_price_element.xpath("educational").text
|
115
121
|
book_price_cost = book_price_element.xpath("cost").text
|
@@ -141,6 +147,40 @@ When /^the book price will be identical to those in "([^"]*)"$/ do |xml_document
|
|
141
147
|
end
|
142
148
|
end
|
143
149
|
|
150
|
+
When /^the book price will be identical to those in "([^"]*)" with new ids$/ do |xml_document_file|
|
151
|
+
xml_document = Nokogiri::XML(File.open(Rails.root.join(xml_document_file)).read)
|
152
|
+
|
153
|
+
# Ensure that all chapters in the xml document have been recorded
|
154
|
+
xml_document.xpath('//book').each do |book_element|
|
155
|
+
book = Book.find_by_name book_element.xpath('name')[0].text
|
156
|
+
book_id = book.id
|
157
|
+
book_price_element = book_element.xpath('book_price')
|
158
|
+
book_price = BookPrice.find_by_book_id book_id
|
159
|
+
|
160
|
+
fail 'Too many book prices' if book_price_element.count > 1
|
161
|
+
|
162
|
+
if book_price.nil?
|
163
|
+
fail "BookPrice for book '#{book.name}' is missing"
|
164
|
+
else
|
165
|
+
book_price_sell = book_price_element.xpath('sell').text
|
166
|
+
book_price_educational = book_price_element.xpath('educational').text
|
167
|
+
book_price_cost = book_price_element.xpath('cost').text
|
168
|
+
|
169
|
+
if Float(book_price_sell) != book_price.sell
|
170
|
+
fail "BookPrice 'sell' in database doesn't match book price sell in xml for book '#{book.name}', XML: #{book_price_sell}, Database: #{book_price.sell}"
|
171
|
+
end
|
172
|
+
|
173
|
+
if Float(book_price_cost) != book_price.cost
|
174
|
+
fail "BookPrice 'cost' in database doesn't match book price cost in xml for book '#{book.name}', XML: #{book_price_cost}, Database: #{book_price.cost}"
|
175
|
+
end
|
176
|
+
|
177
|
+
if Float(book_price_educational) != book_price.educational
|
178
|
+
fail "BookPrice 'educational' in database doesn't match book price educational in xml for book '#{book.name}', XML: #{book_price_educational}, Database: #{book_price.educational}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
144
184
|
When /^the chapters will be identical to those in "([^"]*)"$/ do |xml_document_file|
|
145
185
|
chapters_in_database = Chapter.all
|
146
186
|
if chapters_in_database.count > 0
|
@@ -190,18 +230,23 @@ When /^the chapters will be identical to those in "([^"]*)" with new ids$/ do |x
|
|
190
230
|
xml_document.xpath("//book").each do |book_element|
|
191
231
|
book = Book.where(:name => book_element.xpath("name")[0].text).first
|
192
232
|
book_id = book.id
|
193
|
-
xml_document.xpath("//book[name[text()='#{
|
233
|
+
xml_document.xpath("//book[name[text()='#{book.name}']]/chapters/chapter").each do |chapter_element|
|
194
234
|
chapter_title = chapter_element.xpath("title")[0].text
|
195
235
|
chapter_introduction = chapter_element.xpath("introduction")[0].text
|
196
|
-
chapter = book.chapters.where(:title => chapter_title)
|
236
|
+
chapter = book.chapters.where(:title => chapter_title).first
|
197
237
|
|
198
238
|
if chapter == nil
|
199
239
|
fail "Chapters #{chapter_title} is missing"
|
200
240
|
else
|
241
|
+
if chapter.book_id.nil?
|
242
|
+
fail "Chapter.book_id in database isn't being set (expecting book_id = #{book_id}"
|
243
|
+
elsif chapter.book_id != book_id
|
244
|
+
fail "Chapter.book_id in database is set incorrectly (expecting book_id = #{book_id} and got #{chapter.book_id})"
|
245
|
+
end
|
201
246
|
if chapter_introduction != chapter.introduction
|
202
247
|
fail "Chapter introduction in database doesn't match chapter introduction in xml for chapter #{chapter_title}, XML: #{chapter_introduction}, Database: #{chapter.introduction}"
|
203
248
|
end
|
204
|
-
if book_id != chapter.book_id
|
249
|
+
if book_id != chapter.book_id
|
205
250
|
fail "Chapter book_id in database doesn't match chapter book_id in xml for chapter #{chapter_title}, XML: #{book_id}, Database: #{chapter.book_id}"
|
206
251
|
end
|
207
252
|
end
|
@@ -110,6 +110,11 @@
|
|
110
110
|
</book>
|
111
111
|
<book>
|
112
112
|
<name>Book 2</name>
|
113
|
+
<book_price>
|
114
|
+
<sell>50.00</sell>
|
115
|
+
<educational>35.00</educational>
|
116
|
+
<cost>20.00</cost>
|
117
|
+
</book_price>
|
113
118
|
<chapter>
|
114
119
|
<title>B2 Chapter 1</title>
|
115
120
|
<introduction>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus purus nulla, condimentum vitae
|
@@ -45,6 +45,7 @@ Feature: Synchronise one to many relationships
|
|
45
45
|
When I synchronise with "<xml_file>"
|
46
46
|
Then the books in the database will be identical to those in "<xml_file>" with new ids
|
47
47
|
And the chapters will be identical to those in "<xml_file>" with new ids
|
48
|
+
And the book price will be identical to those in "<xml_file>" with new ids
|
48
49
|
|
49
50
|
Examples:
|
50
51
|
| xml_file |
|
data/lib/data_active.rb
CHANGED
@@ -28,7 +28,7 @@ module DataActive
|
|
28
28
|
# Load or create a new record
|
29
29
|
pk_node = current_node.xpath self.primary_key.to_s
|
30
30
|
|
31
|
-
active_record =
|
31
|
+
active_record = find_or_create_based_on(pk_node)
|
32
32
|
|
33
33
|
unless active_record.nil?
|
34
34
|
# Process the attributes
|
@@ -41,7 +41,6 @@ module DataActive
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# Check through associations and apply sync appropriately
|
44
|
-
associations = self.reflect_on_all_associations
|
45
44
|
self.reflect_on_all_associations.each do |association|
|
46
45
|
foreign_key = foreign_key_from(association)
|
47
46
|
klass = association.klass
|
@@ -101,7 +100,11 @@ module DataActive
|
|
101
100
|
new_record = klass.one_from_xml(single_objects[0], options)
|
102
101
|
if new_record != nil
|
103
102
|
new_record[foreign_key.to_sym] = active_record[self.primary_key.to_s]
|
104
|
-
new_record
|
103
|
+
if active_record.new_record?
|
104
|
+
active_record.send("#{klass.name.underscore.to_sym}=", new_record)
|
105
|
+
else
|
106
|
+
new_record.save!
|
107
|
+
end
|
105
108
|
end
|
106
109
|
end
|
107
110
|
elsif single_objects.count > 1
|
@@ -142,6 +145,44 @@ module DataActive
|
|
142
145
|
end
|
143
146
|
|
144
147
|
private
|
148
|
+
def many_from(current_node)
|
149
|
+
case
|
150
|
+
when (is_ms_access_xml?(current_node) or is_rails_like_xml?(current_node))
|
151
|
+
process_children_for current_node
|
152
|
+
|
153
|
+
when self.name.underscore.eql?(current_node.name.underscore)
|
154
|
+
raise "The supplied XML (#{current_node.name}) is a single instance of '#{self.name}'. Please use one_from_xml"
|
155
|
+
|
156
|
+
else
|
157
|
+
raise "The supplied XML (#{current_node.name}) cannot be mapped to this class (#{self.name})"
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def process_children_for(current_node)
|
163
|
+
records = []
|
164
|
+
recorded_ids = []
|
165
|
+
|
166
|
+
current_node.xpath(".//#{self.name.underscore}").each do |node|
|
167
|
+
record = self.one_from_xml(node, @data_active_options)
|
168
|
+
if record
|
169
|
+
recorded_ids << record[primary_key.to_sym]
|
170
|
+
records << record
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
remove_records_not_in recorded_ids
|
175
|
+
records
|
176
|
+
end
|
177
|
+
|
178
|
+
def is_ms_access_xml?(node)
|
179
|
+
node.name.eql?('dataroot') and node.namespace_definitions.map { |ns| ns.href }.include?('urn:schemas-microsoft-com:officedata')
|
180
|
+
end
|
181
|
+
|
182
|
+
def is_rails_like_xml?(current_node)
|
183
|
+
self.name.pluralize.underscore.eql?(current_node.name.underscore)
|
184
|
+
end
|
185
|
+
|
145
186
|
def xml_node_matches_class(xml_node)
|
146
187
|
if xml_node.attributes['type'].blank?
|
147
188
|
xml_node.name.underscore == self.name.underscore
|
@@ -150,7 +191,7 @@ module DataActive
|
|
150
191
|
end
|
151
192
|
end
|
152
193
|
|
153
|
-
def
|
194
|
+
def find_or_create_based_on(pk_node)
|
154
195
|
ar = nil
|
155
196
|
if pk_node
|
156
197
|
begin
|
@@ -232,7 +273,7 @@ module DataActive
|
|
232
273
|
# Support for Rails earlier than 3.1
|
233
274
|
foreign_key = association.primary_key_name
|
234
275
|
else
|
235
|
-
raise
|
276
|
+
raise 'Unsupported version of ActiveRecord. Unable to identify the foreign key.'
|
236
277
|
end
|
237
278
|
foreign_key
|
238
279
|
end
|
@@ -259,61 +300,6 @@ module DataActive
|
|
259
300
|
end
|
260
301
|
end
|
261
302
|
end
|
262
|
-
|
263
|
-
def many_from_rails_xml(current_node)
|
264
|
-
records = []
|
265
|
-
recorded_ids = []
|
266
|
-
|
267
|
-
current_node.element_children.each do |node|
|
268
|
-
record = self.one_from_xml(node, @data_active_options)
|
269
|
-
if record
|
270
|
-
recorded_ids << record[primary_key.to_sym]
|
271
|
-
records << record
|
272
|
-
end
|
273
|
-
end
|
274
|
-
|
275
|
-
remove_records_not_in recorded_ids
|
276
|
-
|
277
|
-
records
|
278
|
-
end
|
279
|
-
|
280
|
-
def many_from_ms_xml(current_node)
|
281
|
-
records = []
|
282
|
-
recorded_ids = []
|
283
|
-
|
284
|
-
current_node.element_children.each do |node|
|
285
|
-
if self.name.underscore.eql?(node.name.underscore)
|
286
|
-
record = self.one_from_xml(node, @data_active_options)
|
287
|
-
if record
|
288
|
-
recorded_ids << record[primary_key.to_sym]
|
289
|
-
records << record
|
290
|
-
end
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
|
-
remove_records_not_in recorded_ids
|
295
|
-
|
296
|
-
records
|
297
|
-
end
|
298
|
-
|
299
|
-
def many_from(current_node)
|
300
|
-
case
|
301
|
-
when self.name.pluralize.underscore.eql?(current_node.name.underscore)
|
302
|
-
many_from_rails_xml current_node
|
303
|
-
|
304
|
-
when (current_node.name.eql?('dataroot') \
|
305
|
-
and current_node.namespace_definitions.map { |ns| ns.href }.include?('urn:schemas-microsoft-com:officedata'))
|
306
|
-
# Identified as data generated from Microsoft Access
|
307
|
-
many_from_ms_xml current_node
|
308
|
-
|
309
|
-
when self.name.underscore.eql?(current_node.name.underscore)
|
310
|
-
raise "The supplied XML (#{current_node.name}) is a single instance of '#{self.name}'. Please use one_from_xml"
|
311
|
-
|
312
|
-
else
|
313
|
-
raise "The supplied XML (#{current_node.name}) cannot be mapped to this class (#{self.name})"
|
314
|
-
|
315
|
-
end
|
316
|
-
end
|
317
303
|
end
|
318
304
|
end
|
319
305
|
|
data/lib/data_active/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: data_active
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-04-
|
12
|
+
date: 2013-04-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -280,7 +280,7 @@ rubyforge_project: data_active
|
|
280
280
|
rubygems_version: 1.8.22
|
281
281
|
signing_key:
|
282
282
|
specification_version: 3
|
283
|
-
summary: data_active 0.0.
|
283
|
+
summary: data_active 0.0.6
|
284
284
|
test_files:
|
285
285
|
- features/remove_records_missing_in_xml.feature
|
286
286
|
- features/step_definitions/remove_records_missing_in_xml.rb
|