excelsieur 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bc2a5b6867db27c9dfac13298c6cdb8f3a4e1ec0d611fa0a8558042a9256d0af
4
+ data.tar.gz: b265a594c260c4fb291187c8d2102409b3634715e037b54adfe2c835d24e15e0
5
+ SHA512:
6
+ metadata.gz: ffd75bada8a82f9f6e22949ee85136c2086b7f10e09b830445e9d63233bfc5a22efce028f60eb00e7cec6be6b2459c61eef80eb647e9fc3147fa4f59f19d1df6
7
+ data.tar.gz: 20d9ecdc25839f7a67316d47f246d6f562819b306d06fb6bc1313b9698c6e60bb057009124eb6cd8db5eac2707038b089b7e3422f8cff29c247c4b80a26ed171
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /test/test.sqlite3
@@ -0,0 +1,18 @@
1
+ image: ruby:2.5
2
+
3
+ cache:
4
+ paths:
5
+ - vendor/
6
+
7
+ before_script:
8
+ - bundle install -j $(nproc) --path vendor
9
+
10
+ test:
11
+ stage: test
12
+ script:
13
+ - bundle exec rake test
14
+
15
+ rubocop:
16
+ stage: test
17
+ script:
18
+ - bundle exec rubocop
@@ -0,0 +1,10 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+
4
+ # exclude for tests
5
+ Metrics/BlockLength:
6
+ ExcludedMethods: ['describe', 'it']
7
+
8
+ # don't require documentation on classes / modules
9
+ Style/Documentation:
10
+ Enabled: false
@@ -0,0 +1 @@
1
+ 2.5.1
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in excelsieur.gemspec
8
+ gemspec
@@ -0,0 +1,152 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ excelsieur (0.1.0)
5
+ activerecord (>= 4.0.0)
6
+ rails (>= 4.0.0)
7
+ simple_xlsx_reader (~> 1.0.2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ actioncable (5.2.0)
13
+ actionpack (= 5.2.0)
14
+ nio4r (~> 2.0)
15
+ websocket-driver (>= 0.6.1)
16
+ actionmailer (5.2.0)
17
+ actionpack (= 5.2.0)
18
+ actionview (= 5.2.0)
19
+ activejob (= 5.2.0)
20
+ mail (~> 2.5, >= 2.5.4)
21
+ rails-dom-testing (~> 2.0)
22
+ actionpack (5.2.0)
23
+ actionview (= 5.2.0)
24
+ activesupport (= 5.2.0)
25
+ rack (~> 2.0)
26
+ rack-test (>= 0.6.3)
27
+ rails-dom-testing (~> 2.0)
28
+ rails-html-sanitizer (~> 1.0, >= 1.0.2)
29
+ actionview (5.2.0)
30
+ activesupport (= 5.2.0)
31
+ builder (~> 3.1)
32
+ erubi (~> 1.4)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.0.3)
35
+ activejob (5.2.0)
36
+ activesupport (= 5.2.0)
37
+ globalid (>= 0.3.6)
38
+ activemodel (5.2.0)
39
+ activesupport (= 5.2.0)
40
+ activerecord (5.2.0)
41
+ activemodel (= 5.2.0)
42
+ activesupport (= 5.2.0)
43
+ arel (>= 9.0)
44
+ activestorage (5.2.0)
45
+ actionpack (= 5.2.0)
46
+ activerecord (= 5.2.0)
47
+ marcel (~> 0.3.1)
48
+ activesupport (5.2.0)
49
+ concurrent-ruby (~> 1.0, >= 1.0.2)
50
+ i18n (>= 0.7, < 2)
51
+ minitest (~> 5.1)
52
+ tzinfo (~> 1.1)
53
+ arel (9.0.0)
54
+ ast (2.4.0)
55
+ builder (3.2.3)
56
+ concurrent-ruby (1.0.5)
57
+ crass (1.0.4)
58
+ erubi (1.7.1)
59
+ globalid (0.4.1)
60
+ activesupport (>= 4.2.0)
61
+ i18n (1.0.1)
62
+ concurrent-ruby (~> 1.0)
63
+ loofah (2.2.2)
64
+ crass (~> 1.0.2)
65
+ nokogiri (>= 1.5.9)
66
+ mail (2.7.0)
67
+ mini_mime (>= 0.1.1)
68
+ marcel (0.3.2)
69
+ mimemagic (~> 0.3.2)
70
+ method_source (0.9.0)
71
+ mimemagic (0.3.2)
72
+ mini_mime (1.0.0)
73
+ mini_portile2 (2.3.0)
74
+ minitest (5.11.3)
75
+ nio4r (2.3.1)
76
+ nokogiri (1.8.2)
77
+ mini_portile2 (~> 2.3.0)
78
+ parallel (1.12.1)
79
+ parser (2.5.1.0)
80
+ ast (~> 2.4.0)
81
+ powerpack (0.1.1)
82
+ rack (2.0.5)
83
+ rack-test (1.0.0)
84
+ rack (>= 1.0, < 3)
85
+ rails (5.2.0)
86
+ actioncable (= 5.2.0)
87
+ actionmailer (= 5.2.0)
88
+ actionpack (= 5.2.0)
89
+ actionview (= 5.2.0)
90
+ activejob (= 5.2.0)
91
+ activemodel (= 5.2.0)
92
+ activerecord (= 5.2.0)
93
+ activestorage (= 5.2.0)
94
+ activesupport (= 5.2.0)
95
+ bundler (>= 1.3.0)
96
+ railties (= 5.2.0)
97
+ sprockets-rails (>= 2.0.0)
98
+ rails-dom-testing (2.0.3)
99
+ activesupport (>= 4.2.0)
100
+ nokogiri (>= 1.6)
101
+ rails-html-sanitizer (1.0.4)
102
+ loofah (~> 2.2, >= 2.2.2)
103
+ railties (5.2.0)
104
+ actionpack (= 5.2.0)
105
+ activesupport (= 5.2.0)
106
+ method_source
107
+ rake (>= 0.8.7)
108
+ thor (>= 0.18.1, < 2.0)
109
+ rainbow (3.0.0)
110
+ rake (10.5.0)
111
+ rubocop (0.56.0)
112
+ parallel (~> 1.10)
113
+ parser (>= 2.5)
114
+ powerpack (~> 0.1)
115
+ rainbow (>= 2.2.2, < 4.0)
116
+ ruby-progressbar (~> 1.7)
117
+ unicode-display_width (~> 1.0, >= 1.0.1)
118
+ ruby-progressbar (1.9.0)
119
+ rubyzip (1.2.2)
120
+ simple_xlsx_reader (1.0.2)
121
+ nokogiri
122
+ rubyzip
123
+ sprockets (3.7.2)
124
+ concurrent-ruby (~> 1.0)
125
+ rack (> 1, < 3)
126
+ sprockets-rails (3.2.1)
127
+ actionpack (>= 4.0)
128
+ activesupport (>= 4.0)
129
+ sprockets (>= 3.0.0)
130
+ sqlite3 (1.3.13)
131
+ thor (0.20.0)
132
+ thread_safe (0.3.6)
133
+ tzinfo (1.2.5)
134
+ thread_safe (~> 0.1)
135
+ unicode-display_width (1.3.3)
136
+ websocket-driver (0.7.0)
137
+ websocket-extensions (>= 0.1.0)
138
+ websocket-extensions (0.1.3)
139
+
140
+ PLATFORMS
141
+ ruby
142
+
143
+ DEPENDENCIES
144
+ bundler (~> 1.16)
145
+ excelsieur!
146
+ minitest (~> 5.0)
147
+ rake (~> 10.0)
148
+ rubocop (~> 0.56.0)
149
+ sqlite3
150
+
151
+ BUNDLED WITH
152
+ 1.16.5
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Immanuel Häussermann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,160 @@
1
+ <img src="docs/excelsieur-logo.png" width="480">
2
+
3
+ ---
4
+
5
+ A straightforward way to import data from an excel sheet into your ruby app.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'excelsieur'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install excelsieur
22
+
23
+ ## How to use it
24
+
25
+ Create a class which declares how columns from an excel sheet map to your ruby object model by extending from the `Excelsieur::Importer` class:
26
+
27
+ ```ruby
28
+ class UserImporter < Excelsieur::Importer
29
+ # declare the source file
30
+ source "static/ftp/users.xlsx"
31
+
32
+ # declare the mapping
33
+ map "First Name", to: :firstname
34
+ map "Last Name", to: :lastname
35
+ map "E-Mail", to: :email
36
+ end
37
+ ```
38
+
39
+ Create an instance of your import and run it. By default it infers the model
40
+ to be imported from the classname, e.g.:
41
+
42
+ ```ruby
43
+ import = UserImport.new
44
+ import.run # calls User.create!(row) for each row
45
+ ```
46
+
47
+ The result is an instance of `Excelsieur::Result`:
48
+
49
+ ```ruby
50
+ result = import.run
51
+ result.status
52
+ # => :succeeded
53
+ result.errors
54
+ # => { missing_column: [], model: [] }
55
+ result.report
56
+ # => #<struct Excelsieur::Report inserted=2, failed=0>
57
+ ```
58
+
59
+ ### Model validation
60
+
61
+ A summary of the `ActiveRecord` model validations is available after running
62
+ the importer. The `Error` objects indicates the failed excel row and the
63
+ corresponding errors.
64
+
65
+ ```ruby
66
+ import = UserImport.new
67
+ import.run
68
+
69
+ import.errors[:model]
70
+ # => [#<struct Excelsieur::Error row=3, errors=["First name can't be blank"]>]
71
+ ```
72
+
73
+ ### Report
74
+
75
+ A summary of the successfully inserted and failed records is available after
76
+ running the importer.
77
+
78
+ ```ruby
79
+ import = UserImport.new
80
+ import.run
81
+
82
+ import.report
83
+ # => #<struct Excelsieur::Report inserted=2, failed=1>
84
+
85
+ import.total
86
+ # => 3
87
+ ```
88
+
89
+ ### Transactions
90
+
91
+ When setting `transaction true` no record is inserted if any one of them has an error.
92
+
93
+ ```ruby
94
+ class UserImporter < Excelsieur::Importer
95
+ # declare the source file
96
+ source "static/ftp/users.xlsx"
97
+
98
+ # only insert all rows if none of them have an error
99
+ transaction true
100
+
101
+ # declare the mapping
102
+ map "First Name", to: :firstname
103
+ map "Last Name", to: :lastname
104
+ map "E-Mail", to: :email
105
+ end
106
+ ```
107
+
108
+ If a block is passed to `run` the block needs to raise an error in order to
109
+ roll back the transaction.
110
+
111
+ This means that the following will trigger a rollback if the model is not
112
+ valid:
113
+
114
+ ```ruby
115
+ UserImport.new.run do |row|
116
+ User.create!(row)
117
+ end
118
+ ```
119
+
120
+ On the other hand, the following won't trigger a rollback if the model is
121
+ invalid:
122
+
123
+ ```ruby
124
+ UserImport.new.run do |row|
125
+ User.create(row)
126
+ end
127
+ ```
128
+
129
+
130
+ ### Extended API
131
+
132
+ You may want to pass an excel file per instance. You can also define your own
133
+ import behavior by passing a block to the `run` method:
134
+
135
+ ```ruby
136
+ import = UserImport.new("users/all.xlsx")
137
+ import.run do |row|
138
+ User.create!(row) # raise an exception if the data doesn't match your expectations
139
+ end
140
+ ```
141
+
142
+ ## Limitations
143
+ Be aware of a few limitations when considering this gem:
144
+ - only supports the first sheet in an excel file
145
+ - only supports `.xlsx` file format
146
+ - no export, just import
147
+
148
+ ## Development
149
+
150
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
151
+
152
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
153
+
154
+ ## Contributing
155
+
156
+ Bug reports and pull requests are welcome on GitHub at https://github.com/panter/excelsieur.
157
+
158
+ ## License
159
+
160
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
10
+ t.options = '-b'
11
+ end
12
+
13
+ task default: :test
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'excelsieur'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
Binary file
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'excelsieur/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'excelsieur'
9
+ spec.version = Excelsieur::VERSION
10
+ spec.authors = ['Immanuel Häussermann', 'Alexis Reigel']
11
+ spec.email = ['hai@panter.ch', 'lex@panter.ch']
12
+
13
+ spec.summary = 'Helps you import data from an excel sheet'
14
+ spec.description = 'Provides a concise DSL to map, validate and import data ' \
15
+ 'from an excel sheet into your ruby app'
16
+ spec.homepage = 'https://git.panter.ch/open-source/excelsieur'
17
+ spec.license = 'MIT'
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
20
+ f.match(%r{^(test|spec|features)/})
21
+ end
22
+ spec.bindir = 'exe'
23
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.add_development_dependency 'bundler', '~> 1.16'
27
+ spec.add_development_dependency 'minitest', '~> 5.0'
28
+ spec.add_development_dependency 'rake', '~> 10.0'
29
+ spec.add_development_dependency 'rubocop', '~> 0.56.0'
30
+ spec.add_development_dependency 'sqlite3'
31
+
32
+ spec.add_runtime_dependency 'activerecord', '>= 4.0.0'
33
+ spec.add_runtime_dependency 'rails', '>= 4.0.0'
34
+ spec.add_runtime_dependency 'simple_xlsx_reader', '~> 1.0.2'
35
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'excelsieur/version'
4
+
5
+ module Excelsieur
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excelsieur
4
+ Error = Struct.new(:row, :errors)
5
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'simple_xlsx_reader'
4
+ require 'rails'
5
+ require 'active_record'
6
+ require 'excelsieur/source'
7
+ require 'excelsieur/mapping'
8
+ require 'excelsieur/error'
9
+ require 'excelsieur/report'
10
+ require 'excelsieur/transaction'
11
+ require 'excelsieur/result'
12
+
13
+ module Excelsieur
14
+ class Import
15
+ include Source
16
+ include Mapping
17
+ include Transaction
18
+
19
+ attr_accessor :source, :fields, :rows, :columns, :result
20
+ delegate :errors, :report, to: :result
21
+
22
+ def initialize(file = nil)
23
+ self.source = file || self.class.source_file
24
+ self.fields = self.class.fields
25
+
26
+ @doc = ::SimpleXlsxReader.open(source)
27
+ @sheet = @doc.sheets.first
28
+
29
+ @columns = @sheet.rows.shift
30
+ @rows = @sheet.rows
31
+
32
+ @result = Result.new(@rows.length)
33
+ end
34
+
35
+ def run(&block)
36
+ check_columns!
37
+
38
+ return if result.failed?
39
+
40
+ if self.class.use_transaction
41
+ run_with_transaction(&block)
42
+ else
43
+ insert_rows(&block)
44
+ end
45
+
46
+ result
47
+ end
48
+
49
+ private
50
+
51
+ def check_columns!
52
+ fields.to_a.each do |f|
53
+ errors[:missing_column] << { missing: f[:header] } unless @columns.include?(f[:header])
54
+ end
55
+ end
56
+
57
+ def model_class
58
+ self.class.name.gsub('Import', '').constantize
59
+ end
60
+
61
+ def run_with_transaction(&block)
62
+ model_class.transaction do
63
+ insert_rows(&block)
64
+
65
+ raise ActiveRecord::Rollback if report.failed.positive?
66
+ end
67
+ end
68
+
69
+ def add_model_errors(record, index)
70
+ if record.errors.empty?
71
+ report_insert
72
+ return
73
+ end
74
+
75
+ report_failure
76
+
77
+ errors[:model] << Error.new(index + 1, record.errors.full_messages)
78
+ end
79
+
80
+ def report_insert
81
+ report.inserted += 1
82
+ end
83
+
84
+ def report_failure
85
+ report.failed += 1
86
+ end
87
+
88
+ def insert_rows(&block)
89
+ @rows.map.with_index do |row, i|
90
+ attributes = map_row_values(row, @columns)
91
+ insert_row(attributes, i, &block)
92
+ end
93
+ end
94
+
95
+ def insert_row(attributes, index, &block)
96
+ if block_given?
97
+ insert_row_with_block(attributes, &block)
98
+ else
99
+ insert_row_without_block(attributes, index)
100
+ end
101
+ end
102
+
103
+ def insert_row_with_block(attributes)
104
+ result = yield(attributes)
105
+ report_insert
106
+ result
107
+ rescue StandardError
108
+ report_failure
109
+ end
110
+
111
+ def insert_row_without_block(attributes, index)
112
+ record = model_class.create(attributes)
113
+ add_model_errors(record, index)
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excelsieur
4
+ module Mapping
5
+ def self.included(host_class)
6
+ host_class.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_reader :fields
11
+
12
+ def map(header, options = {})
13
+ @fields ||= []
14
+ @fields << {
15
+ attribute: options.fetch(:to),
16
+ header: header
17
+ }
18
+ end
19
+ end
20
+
21
+ def map_row_values(row, columns)
22
+ @fields.to_a.each_with_object({}) do |field, acc|
23
+ idx = columns.index(field[:header])
24
+ acc[field[:attribute]] = row[idx]
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excelsieur
4
+ Report = Struct.new(:expected, :inserted, :failed) do
5
+ def initialize(*args)
6
+ super(*args)
7
+
8
+ self.expected ||= 0
9
+ self.inserted ||= 0
10
+ self.failed ||= 0
11
+ end
12
+
13
+ def total
14
+ inserted + failed
15
+ end
16
+
17
+ def done?
18
+ expected == total
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excelsieur
4
+ class Result
5
+ module Statuses
6
+ PENDING = :pending
7
+ SUCCEEDED = :succeeded
8
+ FAILED = :failed
9
+ end
10
+
11
+ attr_accessor :errors, :report
12
+
13
+ def initialize(total_rows)
14
+ self.errors = {
15
+ missing_column: [],
16
+ model: []
17
+ }
18
+ self.report = Report.new(total_rows)
19
+ end
20
+
21
+ def status
22
+ return Statuses::FAILED if errors[:missing_column].any? || errors[:model].any?
23
+
24
+ if report.done?
25
+ Statuses::SUCCEEDED
26
+ else
27
+ Statuses::PENDING
28
+ end
29
+ end
30
+
31
+ def failed?
32
+ status == Result::Statuses::FAILED
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excelsieur
4
+ module Source
5
+ def self.included(host_class)
6
+ host_class.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_accessor :source_file
11
+
12
+ def source(file)
13
+ self.source_file = file
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excelsieur
4
+ module Transaction
5
+ def self.included(host_class)
6
+ host_class.extend ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_accessor :use_transaction
11
+
12
+ def transaction(use_transaction)
13
+ self.use_transaction = use_transaction
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Excelsieur
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,181 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: excelsieur
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Immanuel Häussermann
8
+ - Alexis Reigel
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2018-11-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.16'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.16'
28
+ - !ruby/object:Gem::Dependency
29
+ name: minitest
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '5.0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '5.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '10.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '10.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rubocop
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 0.56.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 0.56.0
70
+ - !ruby/object:Gem::Dependency
71
+ name: sqlite3
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: activerecord
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 4.0.0
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 4.0.0
98
+ - !ruby/object:Gem::Dependency
99
+ name: rails
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 4.0.0
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: 4.0.0
112
+ - !ruby/object:Gem::Dependency
113
+ name: simple_xlsx_reader
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - "~>"
117
+ - !ruby/object:Gem::Version
118
+ version: 1.0.2
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - "~>"
124
+ - !ruby/object:Gem::Version
125
+ version: 1.0.2
126
+ description: Provides a concise DSL to map, validate and import data from an excel
127
+ sheet into your ruby app
128
+ email:
129
+ - hai@panter.ch
130
+ - lex@panter.ch
131
+ executables: []
132
+ extensions: []
133
+ extra_rdoc_files: []
134
+ files:
135
+ - ".gitignore"
136
+ - ".gitlab-ci.yml"
137
+ - ".rubocop.yml"
138
+ - ".ruby-version"
139
+ - Gemfile
140
+ - Gemfile.lock
141
+ - LICENSE
142
+ - README.md
143
+ - Rakefile
144
+ - bin/console
145
+ - bin/setup
146
+ - docs/excelsieur-logo.png
147
+ - excelsieur.gemspec
148
+ - lib/excelsieur.rb
149
+ - lib/excelsieur/error.rb
150
+ - lib/excelsieur/import.rb
151
+ - lib/excelsieur/mapping.rb
152
+ - lib/excelsieur/report.rb
153
+ - lib/excelsieur/result.rb
154
+ - lib/excelsieur/source.rb
155
+ - lib/excelsieur/transaction.rb
156
+ - lib/excelsieur/version.rb
157
+ homepage: https://git.panter.ch/open-source/excelsieur
158
+ licenses:
159
+ - MIT
160
+ metadata: {}
161
+ post_install_message:
162
+ rdoc_options: []
163
+ require_paths:
164
+ - lib
165
+ required_ruby_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ requirements: []
176
+ rubyforge_project:
177
+ rubygems_version: 2.7.6
178
+ signing_key:
179
+ specification_version: 4
180
+ summary: Helps you import data from an excel sheet
181
+ test_files: []