importer 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +7 -0
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/importer.gemspec +17 -2
- data/lib/importer.rb +3 -0
- data/lib/importer/adapters/active_record_adapter.rb +1 -1
- data/lib/importer/adapters/data_mapper_adapter.rb +104 -0
- data/lib/importer/adapters/mongo_mapper_adapter.rb +1 -1
- data/test/helper.rb +4 -0
- data/test/importer/adapters/data_mapper_adapter_test.rb +129 -0
- metadata +67 -7
data/README.rdoc
CHANGED
@@ -12,6 +12,7 @@ Docs: http://rdoc.info/projects/szajbus/importer
|
|
12
12
|
|
13
13
|
* can import from XML and CSV formats, but it's possible to add custom parsers
|
14
14
|
* reports how many new objects got imported, how many objects was modified and how many objects were invalid
|
15
|
+
* includes ActiveRecord, DataMapper and MongoMapper adapters
|
15
16
|
|
16
17
|
== Installation
|
17
18
|
|
@@ -36,6 +37,12 @@ Add to your model
|
|
36
37
|
include Importer
|
37
38
|
end
|
38
39
|
|
40
|
+
# DataMapper
|
41
|
+
class Product
|
42
|
+
include DataMapper::Resource
|
43
|
+
include Importer
|
44
|
+
end
|
45
|
+
|
39
46
|
And start importing
|
40
47
|
|
41
48
|
Product.import(path_to_xml_or_csv_file)
|
data/Rakefile
CHANGED
@@ -14,6 +14,10 @@ begin
|
|
14
14
|
gem.add_dependency "fastercsv", ">= 1.5.0"
|
15
15
|
gem.add_development_dependency "activerecord", ">= 0"
|
16
16
|
gem.add_development_dependency "mongo_mapper", ">= 0.7.0"
|
17
|
+
gem.add_development_dependency "dm-core", ">= 0.10.2"
|
18
|
+
gem.add_development_dependency "dm-validations", ">= 0.10.2"
|
19
|
+
gem.add_development_dependency "dm-aggregates", ">= 0.10.2"
|
20
|
+
gem.add_development_dependency "do_sqlite3", ">= 0.10.1.1"
|
17
21
|
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
18
22
|
gem.add_development_dependency 'sqlite3-ruby'
|
19
23
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.2
|
data/importer.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{importer}
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Micha\305\202 Szajbe"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-05-17}
|
13
13
|
s.description = %q{Define new objects or modifications of existing ones in external file (xml, csv, etc) and import them to your application. Importer will not only import all the objects but also will give you detailed summary of the import process.}
|
14
14
|
s.email = %q{michal.szajbe@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
"importer.gemspec",
|
27
27
|
"lib/importer.rb",
|
28
28
|
"lib/importer/adapters/active_record_adapter.rb",
|
29
|
+
"lib/importer/adapters/data_mapper_adapter.rb",
|
29
30
|
"lib/importer/adapters/mongo_mapper_adapter.rb",
|
30
31
|
"lib/importer/import.rb",
|
31
32
|
"lib/importer/imported_object.rb",
|
@@ -44,6 +45,7 @@ Gem::Specification.new do |s|
|
|
44
45
|
"test/fixtures/products.xml",
|
45
46
|
"test/helper.rb",
|
46
47
|
"test/importer/adapters/active_record_adapter_test.rb",
|
48
|
+
"test/importer/adapters/data_mapper_adapter_test.rb",
|
47
49
|
"test/importer/adapters/mongo_mapper_adapter_test.rb",
|
48
50
|
"test/importer/import_test.rb",
|
49
51
|
"test/importer/imported_object_test.rb",
|
@@ -60,6 +62,7 @@ Gem::Specification.new do |s|
|
|
60
62
|
"test/factories.rb",
|
61
63
|
"test/helper.rb",
|
62
64
|
"test/importer/adapters/active_record_adapter_test.rb",
|
65
|
+
"test/importer/adapters/data_mapper_adapter_test.rb",
|
63
66
|
"test/importer/adapters/mongo_mapper_adapter_test.rb",
|
64
67
|
"test/importer/import_test.rb",
|
65
68
|
"test/importer/imported_object_test.rb",
|
@@ -77,6 +80,10 @@ Gem::Specification.new do |s|
|
|
77
80
|
s.add_runtime_dependency(%q<fastercsv>, [">= 1.5.0"])
|
78
81
|
s.add_development_dependency(%q<activerecord>, [">= 0"])
|
79
82
|
s.add_development_dependency(%q<mongo_mapper>, [">= 0.7.0"])
|
83
|
+
s.add_development_dependency(%q<dm-core>, [">= 0.10.2"])
|
84
|
+
s.add_development_dependency(%q<dm-validations>, [">= 0.10.2"])
|
85
|
+
s.add_development_dependency(%q<dm-aggregates>, [">= 0.10.2"])
|
86
|
+
s.add_development_dependency(%q<do_sqlite3>, [">= 0.10.1.1"])
|
80
87
|
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
81
88
|
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
82
89
|
else
|
@@ -84,6 +91,10 @@ Gem::Specification.new do |s|
|
|
84
91
|
s.add_dependency(%q<fastercsv>, [">= 1.5.0"])
|
85
92
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
86
93
|
s.add_dependency(%q<mongo_mapper>, [">= 0.7.0"])
|
94
|
+
s.add_dependency(%q<dm-core>, [">= 0.10.2"])
|
95
|
+
s.add_dependency(%q<dm-validations>, [">= 0.10.2"])
|
96
|
+
s.add_dependency(%q<dm-aggregates>, [">= 0.10.2"])
|
97
|
+
s.add_dependency(%q<do_sqlite3>, [">= 0.10.1.1"])
|
87
98
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
88
99
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
89
100
|
end
|
@@ -92,6 +103,10 @@ Gem::Specification.new do |s|
|
|
92
103
|
s.add_dependency(%q<fastercsv>, [">= 1.5.0"])
|
93
104
|
s.add_dependency(%q<activerecord>, [">= 0"])
|
94
105
|
s.add_dependency(%q<mongo_mapper>, [">= 0.7.0"])
|
106
|
+
s.add_dependency(%q<dm-core>, [">= 0.10.2"])
|
107
|
+
s.add_dependency(%q<dm-validations>, [">= 0.10.2"])
|
108
|
+
s.add_dependency(%q<dm-aggregates>, [">= 0.10.2"])
|
109
|
+
s.add_dependency(%q<do_sqlite3>, [">= 0.10.1.1"])
|
95
110
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
96
111
|
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
97
112
|
end
|
data/lib/importer.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'importer/adapters/active_record_adapter'
|
2
|
+
require 'importer/adapters/data_mapper_adapter'
|
2
3
|
require 'importer/adapters/mongo_mapper_adapter'
|
3
4
|
require 'importer/import'
|
4
5
|
require 'importer/imported_object'
|
@@ -32,6 +33,8 @@ module Importer
|
|
32
33
|
base.send(:include, Importer::Adapters::ActiveRecordAdapter)
|
33
34
|
elsif defined?(MongoMapper) && (base.include?(MongoMapper::Document) || base.include?(MongoMapper::EmbeddedDocument))
|
34
35
|
base.send(:include, Importer::Adapters::MongoMapperAdapter)
|
36
|
+
elsif defined?(DataMapper) && (base.include?(DataMapper::Resource))
|
37
|
+
base.send(:include, Importer::Adapters::DataMapperAdapter)
|
35
38
|
else
|
36
39
|
raise AdapterError.new("Can't determine adapter for #{base.class} class.")
|
37
40
|
end
|
@@ -64,7 +64,7 @@ module Importer
|
|
64
64
|
|
65
65
|
unless object.save
|
66
66
|
imported_object.state = "invalid_object"
|
67
|
-
imported_object.validation_errors = object.errors.full_messages
|
67
|
+
imported_object.validation_errors = object.errors.full_messages.uniq
|
68
68
|
end
|
69
69
|
|
70
70
|
imported_object.object = object
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Importer
|
2
|
+
module Adapters
|
3
|
+
# Adapter for DataMapper models
|
4
|
+
#
|
5
|
+
# Usage:
|
6
|
+
#
|
7
|
+
# class Product
|
8
|
+
# include DataMapper::Resource
|
9
|
+
# include Importer
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# Product.import(path_to_xml_or_csv_file)
|
13
|
+
#
|
14
|
+
# It sends the given file to a parser and then imports detected objects.
|
15
|
+
# Instead of simply inserting all detected objects to database, the importer
|
16
|
+
# tries to determine wheter a detected object already exists. If so, the object
|
17
|
+
# is only updated, otherwise a new object is created.
|
18
|
+
#
|
19
|
+
# To change the way how importer checks for existing objects (or to turn off this
|
20
|
+
# behavior completely) override +find_on_import+ method. The default behavior now
|
21
|
+
# is to try to find existing object by detected object's id.
|
22
|
+
#
|
23
|
+
# By default the detected object's attributes hash is literally assigned to a
|
24
|
+
# soon-to-be-saved object. If there is a need for more sophisticated behavior,
|
25
|
+
# simply override +merge_attributes_on_import+ method.
|
26
|
+
module DataMapperAdapter
|
27
|
+
|
28
|
+
class << self
|
29
|
+
def included(base)
|
30
|
+
base.send(:include, InstanceMethods)
|
31
|
+
base.send(:extend, ClassMethods)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
# The import process is wrapped in a transaction, so if anything goes wrong there is no
|
37
|
+
# harm done.
|
38
|
+
# * +file+ - path to an XML or CVS file, you can also import from other data formats,
|
39
|
+
# but you also need to provide a custom parser to read it
|
40
|
+
# Possible options:
|
41
|
+
# * +parser+ - by default the parser is determined from file extension, but you can force
|
42
|
+
# the imported to use another one by passing it's class here
|
43
|
+
# * +import+ - by default importer returns instance of +Import+ class that contains
|
44
|
+
# detailed report of import process, you can implement your own Import class and force
|
45
|
+
# the importer to use it by passing it's class here
|
46
|
+
# * +import_options+ - options passed to Import instance on it's initialization
|
47
|
+
def import(file, options = {})
|
48
|
+
import = (options[:import] || Importer::Import).new(options[:import_options])
|
49
|
+
parser = options[:parser] || Importer::Parser.get_klass(file)
|
50
|
+
data = parser.run(file)
|
51
|
+
|
52
|
+
transaction do
|
53
|
+
data.each do |attributes|
|
54
|
+
imported_object = import.build_imported_object
|
55
|
+
|
56
|
+
if object = find_on_import(import, attributes)
|
57
|
+
imported_object.state = "existing_object"
|
58
|
+
else
|
59
|
+
object = new
|
60
|
+
imported_object.state = "new_object"
|
61
|
+
end
|
62
|
+
|
63
|
+
imported_object.data = attributes
|
64
|
+
object.merge_attributes_on_import(import, attributes)
|
65
|
+
|
66
|
+
unless object.save
|
67
|
+
imported_object.state = "invalid_object"
|
68
|
+
imported_object.validation_errors = object.errors.full_messages.uniq
|
69
|
+
end
|
70
|
+
|
71
|
+
imported_object.object = object
|
72
|
+
|
73
|
+
import.add_object(imported_object)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
import
|
78
|
+
end
|
79
|
+
|
80
|
+
# Determines whether a detected object already exists in database.
|
81
|
+
# By default it tries to find an existing objects by id of the detected one.
|
82
|
+
# Returns the object or nil if it's not found.
|
83
|
+
# Override this method in your model to change that default behavior.
|
84
|
+
# * +import+ - current import
|
85
|
+
# * +attributes+ - detected object's attributes hash
|
86
|
+
def find_on_import(import, attributes)
|
87
|
+
get(attributes["id"])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
module InstanceMethods
|
92
|
+
# Merges attributes of a detected object with current object's ones.
|
93
|
+
# By default it simply assigns detected attributes to the object.
|
94
|
+
# Override this method in your model to provide some more sophisticated
|
95
|
+
# behavior.
|
96
|
+
# * +import+ - current import
|
97
|
+
# * +attributes+ - detected object's attributes hash
|
98
|
+
def merge_attributes_on_import(import, attributes)
|
99
|
+
self.attributes = attributes
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -67,7 +67,7 @@ module Importer
|
|
67
67
|
|
68
68
|
unless object.save
|
69
69
|
imported_object.state = "invalid_object"
|
70
|
-
imported_object.validation_errors = object.errors.full_messages
|
70
|
+
imported_object.validation_errors = object.errors.full_messages.uniq
|
71
71
|
end
|
72
72
|
|
73
73
|
imported_object.object = object
|
data/test/helper.rb
CHANGED
@@ -4,6 +4,9 @@ require 'shoulda'
|
|
4
4
|
require 'rr'
|
5
5
|
require 'active_record'
|
6
6
|
require 'mongo_mapper'
|
7
|
+
require 'dm-core'
|
8
|
+
require 'dm-validations'
|
9
|
+
require 'dm-aggregates'
|
7
10
|
|
8
11
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
12
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
@@ -12,6 +15,7 @@ require 'importer'
|
|
12
15
|
|
13
16
|
config = YAML::load(IO.read(File.join(File.dirname(__FILE__), 'database.yml')))
|
14
17
|
ActiveRecord::Base.establish_connection(config['test'])
|
18
|
+
DataMapper.setup(:default, config['test'])
|
15
19
|
|
16
20
|
MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017)
|
17
21
|
MongoMapper.database = 'importer-test'
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class Importer::Adapters::DataMapperAdapterTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
def_class("Product") do
|
6
|
+
include DataMapper::Resource
|
7
|
+
include Importer
|
8
|
+
|
9
|
+
property :id, DataMapper::Types::Serial
|
10
|
+
property :customid, String
|
11
|
+
property :name, String
|
12
|
+
property :description, String
|
13
|
+
property :price, Float
|
14
|
+
|
15
|
+
validates_is_number :price
|
16
|
+
|
17
|
+
def self.find_on_import(import, attributes)
|
18
|
+
first(:customid => attributes["customid"])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
DataMapper.auto_migrate!
|
23
|
+
end
|
24
|
+
|
25
|
+
def teardown
|
26
|
+
undef_class("Product")
|
27
|
+
end
|
28
|
+
|
29
|
+
context "" do
|
30
|
+
setup do
|
31
|
+
@product = Product.create(:customid => "1", :name => "A pink ball", :description => "Round glass ball.", :price => 86)
|
32
|
+
end
|
33
|
+
|
34
|
+
context "importing objects" do
|
35
|
+
setup do
|
36
|
+
@new_object = { "name" => "A red hat", "customid"=>"2", "price" => "114.00", "description" => "Party hat." }
|
37
|
+
@existing_object = { "name" => "A black ball", "customid"=>"1", "price" => "86.00", "description" => "Round glass ball." }
|
38
|
+
@invalid_object = { "name" => "A white ribbon", "customid"=>"3", "price" => "oops", "description" => "A really long one." }
|
39
|
+
|
40
|
+
data = [ @new_object, @existing_object, @invalid_object ]
|
41
|
+
|
42
|
+
stub(Importer::Parser::Xml).run(fixture_file("products.xml")) { data }
|
43
|
+
|
44
|
+
@import = Product.import(fixture_file("products.xml"))
|
45
|
+
end
|
46
|
+
|
47
|
+
should_change("product's name", :from => "A pink ball", :to => "A black ball") { @product.reload.name }
|
48
|
+
|
49
|
+
should_change("products count", :by => 1) { Product.count }
|
50
|
+
should "correctly create new product" do
|
51
|
+
product = Product.last
|
52
|
+
|
53
|
+
assert_equal "A red hat", product.name
|
54
|
+
assert_equal "Party hat.", product.description
|
55
|
+
assert_equal 114, product.price
|
56
|
+
assert_equal "2", product.customid
|
57
|
+
end
|
58
|
+
|
59
|
+
should "correctly summarize the import process" do
|
60
|
+
assert_equal 1, @import.new_imported_objects.size
|
61
|
+
assert_equal 1, @import.existing_imported_objects.size
|
62
|
+
assert_equal 1, @import.invalid_imported_objects.size
|
63
|
+
end
|
64
|
+
|
65
|
+
should "correctly build imported objects" do
|
66
|
+
new_object = @import.new_imported_objects.first
|
67
|
+
existing_object = @import.existing_imported_objects.first
|
68
|
+
invalid_object = @import.invalid_imported_objects.first
|
69
|
+
|
70
|
+
assert_equal @new_object, new_object.data
|
71
|
+
assert_equal 'new_object', new_object.state
|
72
|
+
assert_equal Product.last, new_object.object
|
73
|
+
|
74
|
+
assert_equal @existing_object, existing_object.data
|
75
|
+
assert_equal 'existing_object', existing_object.state
|
76
|
+
assert_equal @product, existing_object.object
|
77
|
+
|
78
|
+
assert_equal @invalid_object, invalid_object.data
|
79
|
+
assert_equal 'invalid_object', invalid_object.state
|
80
|
+
assert_equal ["Price must be a number"], invalid_object.validation_errors
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "when there is exception during import process" do
|
85
|
+
setup do
|
86
|
+
def_class("InvalidProduct", Product) do
|
87
|
+
storage_names[:default] = "products"
|
88
|
+
|
89
|
+
def self.find_on_import(import, attributes)
|
90
|
+
if attributes["customid"] == "3"
|
91
|
+
raise ::Exception.new("An error occured.")
|
92
|
+
else
|
93
|
+
super
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
begin
|
99
|
+
InvalidProduct.import(fixture_file("products.xml"))
|
100
|
+
rescue ::Exception => e
|
101
|
+
@exception = e
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def teardown
|
106
|
+
undef_class("InvalidProduct")
|
107
|
+
end
|
108
|
+
|
109
|
+
should_not_change("product's name") { @product.reload.name }
|
110
|
+
should_not_change("products count") { InvalidProduct.count }
|
111
|
+
should "propagate exception" do
|
112
|
+
assert_equal "An error occured.", @exception.message
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context "passing import_options to #import method" do
|
118
|
+
setup do
|
119
|
+
stub(Importer::Parser::Xml).run(fixture_file("empty.xml")) { [] }
|
120
|
+
|
121
|
+
@options = { :key => 'value' }
|
122
|
+
@import = Product.import(fixture_file("empty.xml"), :import_options => @options)
|
123
|
+
end
|
124
|
+
|
125
|
+
should "pass the options to Import instance" do
|
126
|
+
assert_equal @options, @import.options
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 4
|
8
|
-
-
|
9
|
-
version: 0.4.
|
8
|
+
- 2
|
9
|
+
version: 0.4.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- "Micha\xC5\x82 Szajbe"
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-05-17 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -72,7 +72,7 @@ dependencies:
|
|
72
72
|
type: :development
|
73
73
|
version_requirements: *id004
|
74
74
|
- !ruby/object:Gem::Dependency
|
75
|
-
name:
|
75
|
+
name: dm-core
|
76
76
|
prerelease: false
|
77
77
|
requirement: &id005 !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
@@ -80,11 +80,13 @@ dependencies:
|
|
80
80
|
- !ruby/object:Gem::Version
|
81
81
|
segments:
|
82
82
|
- 0
|
83
|
-
|
83
|
+
- 10
|
84
|
+
- 2
|
85
|
+
version: 0.10.2
|
84
86
|
type: :development
|
85
87
|
version_requirements: *id005
|
86
88
|
- !ruby/object:Gem::Dependency
|
87
|
-
name:
|
89
|
+
name: dm-validations
|
88
90
|
prerelease: false
|
89
91
|
requirement: &id006 !ruby/object:Gem::Requirement
|
90
92
|
requirements:
|
@@ -92,9 +94,64 @@ dependencies:
|
|
92
94
|
- !ruby/object:Gem::Version
|
93
95
|
segments:
|
94
96
|
- 0
|
95
|
-
|
97
|
+
- 10
|
98
|
+
- 2
|
99
|
+
version: 0.10.2
|
96
100
|
type: :development
|
97
101
|
version_requirements: *id006
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: dm-aggregates
|
104
|
+
prerelease: false
|
105
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
segments:
|
110
|
+
- 0
|
111
|
+
- 10
|
112
|
+
- 2
|
113
|
+
version: 0.10.2
|
114
|
+
type: :development
|
115
|
+
version_requirements: *id007
|
116
|
+
- !ruby/object:Gem::Dependency
|
117
|
+
name: do_sqlite3
|
118
|
+
prerelease: false
|
119
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
- 10
|
126
|
+
- 1
|
127
|
+
- 1
|
128
|
+
version: 0.10.1.1
|
129
|
+
type: :development
|
130
|
+
version_requirements: *id008
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: thoughtbot-shoulda
|
133
|
+
prerelease: false
|
134
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
segments:
|
139
|
+
- 0
|
140
|
+
version: "0"
|
141
|
+
type: :development
|
142
|
+
version_requirements: *id009
|
143
|
+
- !ruby/object:Gem::Dependency
|
144
|
+
name: sqlite3-ruby
|
145
|
+
prerelease: false
|
146
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
segments:
|
151
|
+
- 0
|
152
|
+
version: "0"
|
153
|
+
type: :development
|
154
|
+
version_requirements: *id010
|
98
155
|
description: Define new objects or modifications of existing ones in external file (xml, csv, etc) and import them to your application. Importer will not only import all the objects but also will give you detailed summary of the import process.
|
99
156
|
email: michal.szajbe@gmail.com
|
100
157
|
executables: []
|
@@ -114,6 +171,7 @@ files:
|
|
114
171
|
- importer.gemspec
|
115
172
|
- lib/importer.rb
|
116
173
|
- lib/importer/adapters/active_record_adapter.rb
|
174
|
+
- lib/importer/adapters/data_mapper_adapter.rb
|
117
175
|
- lib/importer/adapters/mongo_mapper_adapter.rb
|
118
176
|
- lib/importer/import.rb
|
119
177
|
- lib/importer/imported_object.rb
|
@@ -132,6 +190,7 @@ files:
|
|
132
190
|
- test/fixtures/products.xml
|
133
191
|
- test/helper.rb
|
134
192
|
- test/importer/adapters/active_record_adapter_test.rb
|
193
|
+
- test/importer/adapters/data_mapper_adapter_test.rb
|
135
194
|
- test/importer/adapters/mongo_mapper_adapter_test.rb
|
136
195
|
- test/importer/import_test.rb
|
137
196
|
- test/importer/imported_object_test.rb
|
@@ -172,6 +231,7 @@ test_files:
|
|
172
231
|
- test/factories.rb
|
173
232
|
- test/helper.rb
|
174
233
|
- test/importer/adapters/active_record_adapter_test.rb
|
234
|
+
- test/importer/adapters/data_mapper_adapter_test.rb
|
175
235
|
- test/importer/adapters/mongo_mapper_adapter_test.rb
|
176
236
|
- test/importer/import_test.rb
|
177
237
|
- test/importer/imported_object_test.rb
|