From 9105a7e66d6c34425eada88ab85d6165f4052416 Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Sat, 21 May 2011 15:15:49 +0100 Subject: [PATCH] Updated to libxml-ruby 2.0.5 and fixed code accordingly. I've tested this through the unit tests and by hitting it with bulk_upload.py and neither fail or cause the server to crash or go into an infinite loop. Both of these things happened randomly with 1.1.3/4 due to an apparent early deregistration of the expanded nodes. --- config/environment.rb | 2 +- lib/diff_reader.rb | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/config/environment.rb b/config/environment.rb index 58d9432f5..d5cee81e1 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -18,7 +18,7 @@ Rails::Initializer.run do |config| unless STATUS == :database_offline config.gem 'composite_primary_keys', :version => '2.2.2' end - config.gem 'libxml-ruby', :version => '~> 1.1.1', :lib => 'libxml' + config.gem 'libxml-ruby', :version => '>= 2.0.5', :lib => 'libxml' config.gem 'rmagick', :lib => 'RMagick' config.gem 'oauth', :version => '>= 0.4.3' config.gem 'oauth-plugin', :version => '0.3.14' diff --git a/lib/diff_reader.rb b/lib/diff_reader.rb index 0f0492f44..de2da3c6b 100644 --- a/lib/diff_reader.rb +++ b/lib/diff_reader.rb @@ -20,6 +20,10 @@ class DiffReader def initialize(data, changeset) @reader = XML::Reader.string(data) @changeset = changeset + # document that's (re-)used to handle elements expanded out of the + # diff processing stream. + @doc = XML::Document.new + @doc.root = XML::Node.new("osm") end ## @@ -85,8 +89,21 @@ class DiffReader model = MODELS[model_name] raise OSM::APIBadUserInput.new("Unexpected element type #{model_name}, " + "expected node, way or relation.") if model.nil? - yield model, @reader.expand + # new in libxml-ruby >= 2, expand returns an element not associated + # with a document. this means that there's no encoding parameter, + # which means basically nothing works. + expanded = @reader.expand + + # create a new, empty document to hold this expanded node + new_node = @doc.import(expanded) + @doc.root << new_node + + yield model, new_node @reader.next + + # remove element from doc - it will be garbage collected and the + # rest of the document is re-used in the next iteration. + @doc.root.child.remove! end end -- 2.39.5