datashift 0.15.0 → 0.16.0
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.
- checksums.yaml +7 -0
- data/README.markdown +91 -55
- data/VERSION +1 -1
- data/datashift.gemspec +8 -23
- data/lib/applications/jexcel_file.rb +1 -2
- data/lib/datashift.rb +34 -15
- data/lib/datashift/column_packer.rb +98 -34
- data/lib/datashift/data_transforms.rb +83 -0
- data/lib/datashift/delimiters.rb +58 -10
- data/lib/datashift/excel_base.rb +123 -0
- data/lib/datashift/exceptions.rb +45 -7
- data/lib/datashift/load_object.rb +25 -0
- data/lib/datashift/mapping_service.rb +91 -0
- data/lib/datashift/method_detail.rb +40 -62
- data/lib/datashift/method_details_manager.rb +18 -2
- data/lib/datashift/method_dictionary.rb +27 -10
- data/lib/datashift/method_mapper.rb +49 -41
- data/lib/datashift/model_mapper.rb +42 -22
- data/lib/datashift/populator.rb +258 -143
- data/lib/datashift/thor_base.rb +38 -0
- data/lib/exporters/csv_exporter.rb +57 -145
- data/lib/exporters/excel_exporter.rb +73 -60
- data/lib/generators/csv_generator.rb +65 -5
- data/lib/generators/generator_base.rb +69 -3
- data/lib/generators/mapping_generator.rb +112 -0
- data/lib/helpers/core_ext/csv_file.rb +33 -0
- data/lib/loaders/csv_loader.rb +41 -39
- data/lib/loaders/excel_loader.rb +130 -116
- data/lib/loaders/loader_base.rb +190 -146
- data/lib/loaders/paperclip/attachment_loader.rb +4 -4
- data/lib/loaders/paperclip/datashift_paperclip.rb +5 -3
- data/lib/loaders/paperclip/image_loading.rb +9 -7
- data/lib/loaders/reporter.rb +17 -8
- data/lib/thor/export.thor +12 -13
- data/lib/thor/generate.thor +1 -9
- data/lib/thor/import.thor +13 -24
- data/lib/thor/mapping.thor +65 -0
- data/spec/Gemfile +13 -11
- data/spec/Gemfile.lock +98 -93
- data/spec/csv_exporter_spec.rb +104 -99
- data/spec/csv_generator_spec.rb +159 -0
- data/spec/csv_loader_spec.rb +197 -16
- data/spec/datashift_spec.rb +9 -0
- data/spec/excel_exporter_spec.rb +149 -58
- data/spec/excel_generator_spec.rb +35 -44
- data/spec/excel_loader_spec.rb +196 -178
- data/spec/excel_spec.rb +8 -5
- data/spec/loader_base_spec.rb +47 -7
- data/spec/mapping_spec.rb +117 -0
- data/spec/method_dictionary_spec.rb +24 -11
- data/spec/method_mapper_spec.rb +5 -7
- data/spec/model_mapper_spec.rb +41 -0
- data/spec/paperclip_loader_spec.rb +3 -6
- data/spec/populator_spec.rb +48 -14
- data/spec/spec_helper.rb +85 -73
- data/spec/thor_spec.rb +40 -5
- metadata +93 -86
- data/lib/applications/excel_base.rb +0 -63
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4e73de99a2466b06c8dfb6bab01cb7c2ab00fb54
|
4
|
+
data.tar.gz: 73c47634a567004886c55e75b1f03a63a75ff155
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec2035080b4d6cfc1560530639084e35271f2716a6772f0b8ada9d2d62752f8c3e5756babc4e5bc9afa83636b9adef4c047bc5db99ad26e31e8e75e51ff3b89d
|
7
|
+
data.tar.gz: 426c72aadaab70fa3e1a09c8b131a0b862e75d94ad138316474cf75cf9af0a27aaf7d72037f85404d94dbdab7c668b8a47f5939da56914d0c6591421fd79fd4a
|
data/README.markdown
CHANGED
@@ -1,59 +1,20 @@
|
|
1
1
|
## DataShift
|
2
2
|
|
3
|
+
- [Installation](#Installation)
|
3
4
|
- [Features](#features)
|
4
|
-
- [
|
5
|
-
- [Active Record - Import/Export](#Active Record - Import/Export)
|
5
|
+
- [Testing](#testing)
|
6
6
|
- [License](#license)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
Import and export models fully with all associations.
|
8
|
+
Shift data between Excel/CSV files and Rails or Ruby applications
|
11
9
|
|
12
10
|
Comprehensive Wiki here : **https://github.com/autotelik/datashift/wiki**
|
13
11
|
|
14
|
-
|
15
|
-
now separate gem at [datashift_spree](https://github.com/autotelik/datashift_spree "Datashift Spree")
|
16
|
-
|
17
|
-
|
18
|
-
### Features
|
19
|
-
|
20
|
-
Import and Export ActiveRecord models direct to CSV or Excel/OpenOffice (.xls) (JRuby, 1.8.7, REE, 1.9.3)
|
21
|
-
|
22
|
-
You can select which associations to include and for import, set configurable defaults or over rides.
|
23
|
-
|
24
|
-
Create, parse and use Excel/OpenOffice (.xls) documents dynamically from Ruby (JRuby, 1.8.7, REE, 1.9.3)
|
25
|
-
|
26
|
-
Generate a sample template with headers only.
|
27
|
-
|
28
|
-
Export template and populate with model data
|
29
|
-
|
30
|
-
Bulk import tools for Paperclip attachments.
|
31
|
-
|
32
|
-
Easily extendable Loader functionality to deal with non trivial import cases, such
|
33
|
-
as complex association lookups.
|
34
|
-
|
35
|
-
High level rake and thor command line tasks for import/export provided.
|
36
|
-
|
37
|
-
Specific loaders and command line tasks provided out the box for **Spree E-Commerce**,
|
38
|
-
enabling import/export of Product data including creating Variants with different
|
39
|
-
count on hands and all associations including Properties/Taxons/OptionTypes and Images.
|
40
|
-
|
41
|
-
Loaders can be configured via YAML with over ride values, default values and mandatory column settings.
|
42
|
-
|
43
|
-
Many example Spreadsheets/CSV files in spec/fixtures, fully documented with comments for each column.
|
44
|
-
|
45
|
-
## Installation
|
12
|
+
### <a name="Installation">Installation</a>
|
46
13
|
|
47
14
|
Add gem 'datashift' to your Gemfile/bundle or use ```gem install```
|
48
15
|
|
49
|
-
```ruby
|
50
|
-
gem 'datashift'
|
51
|
-
```
|
52
|
-
|
53
|
-
For Spree support also add :
|
54
|
-
|
55
|
-
```ruby
|
56
|
-
gem 'datashift_spree'
|
16
|
+
```ruby
|
17
|
+
gem 'datashift'
|
57
18
|
```
|
58
19
|
|
59
20
|
To use :
|
@@ -64,7 +25,7 @@ To use the Thor command line applications, pull in the tasks.
|
|
64
25
|
|
65
26
|
Generally the easiest way is to, create a high level .thor file in your Rails root directory
|
66
27
|
|
67
|
-
e.g mysite.thor
|
28
|
+
e.g mysite.thor
|
68
29
|
|
69
30
|
Edit the file and add the following to pull in the thor commands :
|
70
31
|
|
@@ -89,6 +50,33 @@ To get usage information use thor help <command>, for example
|
|
89
50
|
|
90
51
|
To use Excel OLE and MS Excel are NOT required.
|
91
52
|
|
53
|
+
Specific tools for Spree E-Commerce now separate gem [datashift_spree](https://github.com/autotelik/datashift_spree "Datashift Spree")
|
54
|
+
|
55
|
+
|
56
|
+
#### <a name="Features">Features</a>
|
57
|
+
|
58
|
+
Import and Export ActiveRecord models direct to CSV or Excel/OpenOffice (.xls)
|
59
|
+
|
60
|
+
You can select which associations to include and for import, set configurable defaults or over rides.
|
61
|
+
|
62
|
+
Create, parse and use Excel/OpenOffice (.xls) documents dynamically from Ruby
|
63
|
+
|
64
|
+
Generate a sample template with headers only.
|
65
|
+
|
66
|
+
Export template and populate with model data
|
67
|
+
|
68
|
+
Bulk import tools for Paperclip attachments.
|
69
|
+
|
70
|
+
Easily extendable Loader functionality to deal with non trivial import cases, such
|
71
|
+
as complex association lookups.
|
72
|
+
|
73
|
+
High level rake and thor command line tasks for import/export provided.
|
74
|
+
|
75
|
+
|
76
|
+
Loaders can be configured via YAML with over ride values, default values and mandatory column settings.
|
77
|
+
|
78
|
+
Many example Spreadsheets/CSV files in spec/fixtures, fully documented with comments for each column.
|
79
|
+
|
92
80
|
Features a common Excel interface over both our own wrapper around Apache POI (JRuby) and spreadsheet gem (all main Rubies)
|
93
81
|
|
94
82
|
This means you can switch seamlessly between the two libraries, and if required drop down to make use of advanced
|
@@ -102,7 +90,7 @@ Guards are provided, and used internally, for mixed Ruby setups. Can be used lik
|
|
102
90
|
..do something with speadsheet
|
103
91
|
end
|
104
92
|
|
105
|
-
|
93
|
+
#### Active Record - Import/Export
|
106
94
|
|
107
95
|
Provides high level tasks for importing data via ActiveRecord models into a DB,
|
108
96
|
from various sources, currently csv or .xls files (Excel/Open Office)
|
@@ -145,7 +133,7 @@ complicated lookup requirements. Spree is the prime Open Source e-commerce proje
|
|
145
133
|
and the specific loaders and tasks support loading Spree Products, and associated data such as Variants,
|
146
134
|
OptionTypes, Properties and Images.
|
147
135
|
|
148
|
-
|
136
|
+
#### Template Generation and Export
|
149
137
|
|
150
138
|
Template generation tasks can be used to export a model's definition as column headings to CSV or .xls.
|
151
139
|
These can be provided to developers or business users, as a template for data collection and then loading.
|
@@ -155,7 +143,7 @@ Export tasks can be used to export of a model's definition and any existing data
|
|
155
143
|
This data can be exported directly to CSV or Excel/OpenOffice spreadsheets.
|
156
144
|
|
157
145
|
|
158
|
-
|
146
|
+
#### Example Spreadsheets
|
159
147
|
|
160
148
|
A number of example Spreadsheets with headers and comments, can be found in the spec/fixtures directory.
|
161
149
|
|
@@ -165,7 +153,7 @@ This data can be exported directly to CSV or Excel/OpenOffice spreadsheets.
|
|
165
153
|
Column headings contain comments with full descriptions and instructions on syntax.
|
166
154
|
|
167
155
|
|
168
|
-
|
156
|
+
#### Excel
|
169
157
|
|
170
158
|
|
171
159
|
MS Excel itself does not need to be installed.
|
@@ -181,7 +169,7 @@ This data can be exported directly to CSV or Excel/OpenOffice spreadsheets.
|
|
181
169
|
without converting first to CSV or YAML.
|
182
170
|
|
183
171
|
|
184
|
-
|
172
|
+
#### Associations
|
185
173
|
|
186
174
|
To perform a lookup for an associated model, the primary column(s) must be supplied, along with required select values for those columns.
|
187
175
|
|
@@ -199,7 +187,7 @@ During loading, a call to find_all_by_reference will be made, picking up the 2 c
|
|
199
187
|
and our Project model will contain those two i.e project.categories = [category_002,category_003]
|
200
188
|
|
201
189
|
|
202
|
-
|
190
|
+
### TODO
|
203
191
|
|
204
192
|
- Smart sorting of column processing order ....
|
205
193
|
|
@@ -208,14 +196,62 @@ During loading, a call to find_all_by_reference will be made, picking up the 2 c
|
|
208
196
|
- Look at implementing import/export API using something like https://github.com/ianwhite/orm_adapter
|
209
197
|
rather than active record, so we can support additional ORMs
|
210
198
|
|
211
|
-
|
199
|
+
|
200
|
+
### <a name="Testing">Testing</a>
|
201
|
+
Specs have own Gemfile, so you can specify versions of active record that you want specs to run against :
|
202
|
+
|
203
|
+
Edit
|
204
|
+
```ruby spec/Gemfile. ```
|
205
|
+
|
206
|
+
Then run :
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
cd spec
|
210
|
+
bundle install
|
211
|
+
```
|
212
|
+
|
213
|
+
#### Changing Versions
|
214
|
+
|
215
|
+
A sandbox will be generated in spec/sandbox if no such directory exists.
|
216
|
+
|
217
|
+
**N.B Manual Step**
|
218
|
+
When changing versions you probably need to **delete this whole directory** spec/sandbox. Next time you run spree specs it will be auto generated using latest Rails versions
|
219
|
+
|
220
|
+
The database are created in sqlite3 and are stored in spec/fixtures. When switching versions, of say Spree,
|
221
|
+
you will probably want to and to clear out old versions and retrigger the migrations
|
222
|
+
|
223
|
+
rm spec/fixtures/*.sqlite
|
224
|
+
|
225
|
+
You will probably also want to remove lock file :
|
226
|
+
|
227
|
+
rm spec/Gemfile.lock
|
228
|
+
|
229
|
+
First time the sandbox is regenerated, alot of tests may fail,perhaps not everything loads correctly during regeneration process.
|
230
|
+
|
231
|
+
Invariably the next run, the specs pass, so a fix is low priority.
|
232
|
+
|
233
|
+
#### Run the Tests
|
234
|
+
|
235
|
+
** N.B You should run the specs from within the specs directory. **
|
236
|
+
```ruby
|
237
|
+
bundle exec rspec -c .
|
238
|
+
```
|
239
|
+
|
240
|
+
A datashift **log **will be written within **spec/logs**, which hooks into the standard active record logger
|
241
|
+
|
242
|
+
/log/datashift.log
|
243
|
+
spec/logs/datashift_spec.log
|
244
|
+
|
245
|
+
|
246
|
+
|
247
|
+
|
212
248
|
## License
|
213
249
|
|
214
|
-
Copyright:: (c) Autotelik Media Ltd
|
250
|
+
Copyright:: (c) Autotelik Media Ltd 2015
|
215
251
|
|
216
252
|
Author :: Tom Statter
|
217
253
|
|
218
|
-
Date :: Dec
|
254
|
+
Date :: Dec 2015
|
219
255
|
|
220
256
|
The MIT License
|
221
257
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.16.0
|
data/datashift.gemspec
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
require 'rake'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
$:.unshift lib unless $:.include?(lib)
|
6
|
-
|
7
|
-
require 'datashift'
|
3
|
+
#TODO version = File.read("VERSION").strip
|
8
4
|
|
9
5
|
Gem::Specification.new do |s|
|
10
6
|
s.name = "datashift"
|
11
|
-
s.version =
|
12
|
-
s.date = Date.today.to_s
|
7
|
+
s.version = "0.16.0"
|
13
8
|
|
14
9
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
15
10
|
|
16
11
|
s.authors = ["Thomas Statter"]
|
17
12
|
|
18
|
-
s.description = "Comprehensive
|
13
|
+
s.description = "Comprehensive import/export tools between Excel/CSV & ActiveRecord Databases, Rails apps, and any Ruby project."
|
19
14
|
s.email = "rubygems@autotelik.co.uk"
|
20
15
|
s.extra_rdoc_files = [
|
21
16
|
"LICENSE.txt",
|
@@ -42,22 +37,12 @@ Gem::Specification.new do |s|
|
|
42
37
|
s.homepage = "http://github.com/autotelik/datashift"
|
43
38
|
s.licenses = ["MIT"]
|
44
39
|
s.require_paths = ["lib"]
|
45
|
-
|
40
|
+
|
46
41
|
s.summary = "Shift data betwen Excel/CSV and any Ruby app"
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
s.add_runtime_dependency(%q<spreadsheet>, [">= 0"])
|
53
|
-
s.add_runtime_dependency(%q<rubyzip>, [">= 0"])
|
54
|
-
else
|
55
|
-
s.add_dependency(%q<spreadsheet>, [">= 0"])
|
56
|
-
s.add_dependency(%q<rubyzip>, [">= 0"])
|
57
|
-
end
|
58
|
-
else
|
59
|
-
s.add_dependency(%q<spreadsheet>, [">= 0"])
|
60
|
-
s.add_dependency(%q<rubyzip>, [">= 0"])
|
61
|
-
end
|
43
|
+
s.add_dependency 'spreadsheet'
|
44
|
+
s.add_dependency 'rubyzip'
|
45
|
+
|
46
|
+
|
62
47
|
end
|
63
48
|
|
data/lib/datashift.rb
CHANGED
@@ -25,7 +25,7 @@
|
|
25
25
|
|
26
26
|
|
27
27
|
# Details:: Active Record Import/Export for .xls or CSV
|
28
|
-
#
|
28
|
+
#
|
29
29
|
# To pull DataShift commands into your main application :
|
30
30
|
#
|
31
31
|
# require 'datashift'
|
@@ -58,9 +58,9 @@ module DataShift
|
|
58
58
|
def self.library_path
|
59
59
|
File.expand_path("#{File.dirname(__FILE__)}/../lib")
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
def self.require_libraries
|
63
|
-
|
63
|
+
|
64
64
|
loader_libs = %w{ lib }
|
65
65
|
|
66
66
|
# Base search paths - these will be searched recursively
|
@@ -78,8 +78,8 @@ module DataShift
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
81
|
-
|
82
|
-
require_libs = %w{ datashift loaders helpers }
|
81
|
+
|
82
|
+
require_libs = %w{ datashift loaders generators helpers }
|
83
83
|
|
84
84
|
require_libs.each do |base|
|
85
85
|
Dir[File.join(library_path, base, '*.rb')].each do |rb|
|
@@ -90,6 +90,15 @@ module DataShift
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
+
if(DataShift::Guards.jruby?)
|
94
|
+
require 'jexcel_file'
|
95
|
+
JExcelFile
|
96
|
+
else
|
97
|
+
require 'spreadsheet'
|
98
|
+
require 'spreadsheet_extensions'
|
99
|
+
Spreadsheet
|
100
|
+
end
|
101
|
+
|
93
102
|
end
|
94
103
|
|
95
104
|
# Load all the datashift rake tasks and make them available throughout app
|
@@ -100,36 +109,46 @@ module DataShift
|
|
100
109
|
Dir["#{base}/*.rake"].sort.each { |ext| load ext }
|
101
110
|
end
|
102
111
|
|
103
|
-
|
112
|
+
|
104
113
|
# Load all the datashift Thor commands and make them available throughout app
|
105
114
|
|
106
115
|
def self.load_commands()
|
107
116
|
base = File.join(library_path, 'thor', '**')
|
108
|
-
|
117
|
+
|
109
118
|
Dir["#{base}/*.thor"].each do |f|
|
110
119
|
next unless File.file?(f)
|
111
120
|
Thor::Util.load_thorfile(f)
|
112
121
|
end
|
113
122
|
end
|
114
|
-
|
123
|
+
|
115
124
|
end
|
116
125
|
|
126
|
+
|
127
|
+
require_relative 'datashift/delimiters'
|
128
|
+
require_relative 'datashift/column_packer'
|
129
|
+
require_relative 'datashift/logging'
|
130
|
+
require_relative 'datashift/exceptions'
|
131
|
+
require_relative 'datashift/guards'
|
132
|
+
|
133
|
+
require_relative 'helpers/core_ext/to_b'
|
134
|
+
require_relative 'helpers/core_ext/csv_file'
|
135
|
+
|
136
|
+
require_relative 'datashift/method_detail'
|
137
|
+
require_relative 'datashift/method_dictionary'
|
138
|
+
require_relative 'datashift/method_mapper'
|
139
|
+
require_relative 'datashift/model_mapper'
|
140
|
+
|
117
141
|
DataShift::require_libraries
|
118
142
|
|
119
|
-
require 'datashift/guards'
|
120
|
-
require 'datashift/logging'
|
121
|
-
require 'datashift/method_detail'
|
122
|
-
require 'datashift/method_dictionary'
|
123
|
-
require 'datashift/method_mapper'
|
124
143
|
|
125
144
|
module DataShift
|
126
145
|
if(Guards::jruby?)
|
127
146
|
require 'java'
|
128
|
-
|
147
|
+
|
129
148
|
class Object
|
130
149
|
def add_to_classpath(path)
|
131
150
|
$CLASSPATH << File.join( DataShift.root_path, 'lib', path.gsub("\\", "/") )
|
132
151
|
end
|
133
152
|
end
|
134
153
|
end
|
135
|
-
end
|
154
|
+
end
|
@@ -5,60 +5,124 @@
|
|
5
5
|
#
|
6
6
|
# Details:: Helper for creating consistent import/export format
|
7
7
|
# of model's attributes/associations
|
8
|
-
#
|
9
8
|
#
|
10
|
-
require 'exporter_base'
|
11
|
-
require 'csv'
|
12
|
-
|
13
9
|
module DataShift
|
14
10
|
|
15
11
|
module ColumnPacker
|
16
12
|
|
17
|
-
|
18
|
-
def text_delim
|
19
|
-
@text_delim ||= "\'"
|
20
|
-
end
|
13
|
+
include Delimiters
|
21
14
|
|
22
|
-
def text_delim=(x)
|
23
|
-
@text_delim = x
|
24
|
-
end
|
25
|
-
|
26
15
|
# Return opposite of text delim - "hello, 'barry'" => '"hello, "barry""'
|
27
16
|
def escape_text_delim
|
28
17
|
return '"' if text_delim == "\'"
|
29
18
|
"\'"
|
30
19
|
end
|
31
|
-
|
32
|
-
|
20
|
+
|
21
|
+
|
22
|
+
# Ensure a value is written to CSV correctly
|
23
|
+
# TODO - better ways ?? - see transcoding and String#encode
|
24
|
+
|
25
|
+
def escape_for_csv(value)
|
26
|
+
text = value.to_s.gsub(text_delim, escape_text_delim()).gsub("\n", "\\n")
|
27
|
+
|
28
|
+
text = "#{text_delim}#{text}#{text_delim}" if(text.include?(Delimiters::csv_delim))
|
29
|
+
text
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def to_headers( records, associations = nil, options = {} )
|
34
|
+
return if( !records.first.is_a?(ActiveRecord::Base) || records.empty?)
|
35
|
+
|
36
|
+
only = *options[:only] ? [*options[:only]] : nil
|
37
|
+
|
38
|
+
headers =[]
|
39
|
+
|
40
|
+
if associations
|
41
|
+
details_mgr = DataShift::MethodDictionary.method_details_mgrs[records.first.class]
|
42
|
+
|
43
|
+
[*associations].each do |a|
|
44
|
+
|
45
|
+
details_mgr.get_list(a).each do |md|
|
46
|
+
|
47
|
+
next if(only && !only.include?( md.name.to_sym ) )
|
48
|
+
|
49
|
+
headers << "#{md.operator}"
|
50
|
+
|
51
|
+
end
|
52
|
+
end if(details_mgr)
|
53
|
+
|
54
|
+
else
|
55
|
+
|
56
|
+
headers = records.first.class.columns.collect( &:name )
|
57
|
+
end
|
58
|
+
|
59
|
+
headers
|
60
|
+
end
|
61
|
+
|
62
|
+
|
33
63
|
# Convert an AR instance to a single column
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
64
|
+
# e.g User : ":name = > 'tom', :role => 'developer'"
|
65
|
+
#
|
66
|
+
# OPTIONS
|
67
|
+
# with_only Specify (as symbols) columns for association types to export
|
68
|
+
# json: Export association data in single column in JSON format
|
69
|
+
#
|
70
|
+
def record_to_column(record, options = {})
|
71
|
+
|
72
|
+
return "" if(record.nil? || (record.respond_to?(:each) && record.empty?) )
|
73
|
+
|
74
|
+
with_only = *options[:with_only] ? [*options[:with_only]] : nil
|
75
|
+
|
76
|
+
return record.to_json if(options[:json] && !with_only) # packs associations into single column
|
77
|
+
|
78
|
+
if( record.respond_to?(:each) )
|
79
|
+
|
80
|
+
return "" if(record.empty?)
|
81
|
+
|
82
|
+
data = []
|
83
|
+
|
84
|
+
record.each { |r| data << record_to_column(r, options); }
|
85
|
+
|
86
|
+
if(options[:json])
|
87
|
+
return data.to_json
|
88
|
+
else
|
89
|
+
return "#{data.join(Delimiters::multi_assoc_delim)}"
|
90
|
+
end
|
91
|
+
|
92
|
+
else
|
93
|
+
|
94
|
+
data = options[:json] ? {} : []
|
95
|
+
|
96
|
+
record.serializable_hash.each do |name, value|
|
97
|
+
next if(with_only && !with_only.include?( name.to_sym ) )
|
98
|
+
|
99
|
+
if(options[:json])
|
100
|
+
data[name] = value
|
101
|
+
else
|
102
|
+
data << "#{name.to_sym} #{Delimiters::key_value_sep} #{value.to_s.gsub(text_delim, escape_text_delim)}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
if(options[:json])#
|
107
|
+
return data.to_json
|
108
|
+
else
|
109
|
+
"#{Delimiters::attribute_list_start}#{data.join(Delimiters::multi_value_delim)}#{Delimiters::attribute_list_end}"
|
110
|
+
end
|
111
|
+
|
42
112
|
end
|
43
|
-
|
113
|
+
|
44
114
|
end
|
45
|
-
|
46
|
-
|
115
|
+
|
116
|
+
|
47
117
|
# Convert an AR instance to a set of CSV columns
|
48
118
|
def record_to_csv(record, options = {})
|
49
119
|
csv_data = record.serializable_hash.values.collect { |value| escape_for_csv(value) }
|
50
120
|
|
51
121
|
[*options[:methods]].each { |x| csv_data << escape_for_csv(record.send(x)) if(record.respond_to?(x)) } if(options[:methods])
|
52
|
-
|
122
|
+
|
53
123
|
csv_data.join( Delimiters::csv_delim )
|
54
124
|
end
|
55
|
-
|
56
|
-
|
57
|
-
text = value.to_s.gsub(@text_delim, escape_text_delim())
|
58
|
-
|
59
|
-
text = "#{@text_delim}#{text}#{@text_delim}" if(text.include?(Delimiters::csv_delim))
|
60
|
-
text
|
61
|
-
end
|
62
|
-
|
125
|
+
|
126
|
+
|
63
127
|
end
|
64
128
|
end
|