datashift 0.11.1 → 0.12.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.
Files changed (110) hide show
  1. data/Rakefile +3 -2
  2. data/VERSION +1 -1
  3. data/datashift.gemspec +11 -174
  4. data/lib/datashift/column_packer.rb +64 -0
  5. data/lib/datashift/delimiters.rb +17 -1
  6. data/lib/datashift/exceptions.rb +7 -0
  7. data/lib/datashift/querying.rb +10 -4
  8. data/lib/loaders/csv_loader.rb +69 -32
  9. data/lib/loaders/excel_loader.rb +86 -53
  10. data/lib/loaders/loader_base.rb +32 -18
  11. data/lib/loaders/paperclip/attachment_loader.rb +11 -8
  12. data/lib/loaders/paperclip/datashift_paperclip.rb +21 -18
  13. data/lib/loaders/reporter.rb +48 -0
  14. data/spec/Gemfile.lock +129 -0
  15. data/spec/csv_exporter_spec.rb +1 -1
  16. metadata +121 -191
  17. data/.document +0 -5
  18. data/lib/java/poi-3.7/._poi-3.7-20101029.jar5645100390082102460.tmp +0 -0
  19. data/spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg +0 -0
  20. data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpeg +0 -0
  21. data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpg +0 -0
  22. data/spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg +0 -0
  23. data/spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg +0 -0
  24. data/spec/fixtures/BadAssociationName.xls +0 -0
  25. data/spec/fixtures/DemoNegativeTesting.xls +0 -0
  26. data/spec/fixtures/ProjectsDefaults.yml +0 -29
  27. data/spec/fixtures/ProjectsMultiCategories.xls +0 -0
  28. data/spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls +0 -0
  29. data/spec/fixtures/ProjectsSingleCategories.xls +0 -0
  30. data/spec/fixtures/SimpleProjects.xls +0 -0
  31. data/spec/fixtures/config/database.yml +0 -28
  32. data/spec/fixtures/db/datashift_test_models_db.sqlite +0 -0
  33. data/spec/fixtures/db/migrate/20110803201325_create_test_bed.rb +0 -96
  34. data/spec/fixtures/db/migrate/20121009161700_add_digitals.rb +0 -24
  35. data/spec/fixtures/images/DEMO_001_ror_bag.jpeg +0 -0
  36. data/spec/fixtures/images/DEMO_002_Powerstation.jpeg +0 -0
  37. data/spec/fixtures/images/DEMO_003_ror_mug.jpeg +0 -0
  38. data/spec/fixtures/images/DEMO_004_ror_ringer.jpeg +0 -0
  39. data/spec/fixtures/load_datashift.thor +0 -3
  40. data/spec/fixtures/models/category.rb +0 -7
  41. data/spec/fixtures/models/digital.rb +0 -14
  42. data/spec/fixtures/models/empty.rb +0 -2
  43. data/spec/fixtures/models/loader_release.rb +0 -10
  44. data/spec/fixtures/models/long_and_complex_table_linked_to_version.rb +0 -6
  45. data/spec/fixtures/models/milestone.rb +0 -8
  46. data/spec/fixtures/models/owner.rb +0 -7
  47. data/spec/fixtures/models/project.rb +0 -26
  48. data/spec/fixtures/models/version.rb +0 -7
  49. data/spec/fixtures/simple_export_spec.xls +0 -0
  50. data/spec/fixtures/simple_template_spec.xls +0 -0
  51. data/spec/fixtures/test_model_defs.rb +0 -9
  52. data/spec/rails_sandbox/.gitignore +0 -15
  53. data/spec/rails_sandbox/Gemfile +0 -40
  54. data/spec/rails_sandbox/README.rdoc +0 -261
  55. data/spec/rails_sandbox/Rakefile +0 -7
  56. data/spec/rails_sandbox/app/assets/images/rails.png +0 -0
  57. data/spec/rails_sandbox/app/assets/javascripts/application.js +0 -15
  58. data/spec/rails_sandbox/app/assets/stylesheets/application.css +0 -13
  59. data/spec/rails_sandbox/app/controllers/application_controller.rb +0 -3
  60. data/spec/rails_sandbox/app/helpers/application_helper.rb +0 -2
  61. data/spec/rails_sandbox/app/mailers/.gitkeep +0 -0
  62. data/spec/rails_sandbox/app/models/.gitkeep +0 -0
  63. data/spec/rails_sandbox/app/models/category.rb +0 -7
  64. data/spec/rails_sandbox/app/models/empty.rb +0 -2
  65. data/spec/rails_sandbox/app/models/loader_release.rb +0 -10
  66. data/spec/rails_sandbox/app/models/long_and_complex_table_linked_to_version.rb +0 -6
  67. data/spec/rails_sandbox/app/models/milestone.rb +0 -8
  68. data/spec/rails_sandbox/app/models/owner.rb +0 -5
  69. data/spec/rails_sandbox/app/models/project.rb +0 -26
  70. data/spec/rails_sandbox/app/models/test_model_defs.rb +0 -67
  71. data/spec/rails_sandbox/app/models/version.rb +0 -7
  72. data/spec/rails_sandbox/app/views/layouts/application.html.erb +0 -14
  73. data/spec/rails_sandbox/config.ru +0 -4
  74. data/spec/rails_sandbox/config/application.rb +0 -62
  75. data/spec/rails_sandbox/config/boot.rb +0 -6
  76. data/spec/rails_sandbox/config/database.yml +0 -20
  77. data/spec/rails_sandbox/config/environment.rb +0 -5
  78. data/spec/rails_sandbox/config/environments/development.rb +0 -37
  79. data/spec/rails_sandbox/config/environments/production.rb +0 -67
  80. data/spec/rails_sandbox/config/environments/test.rb +0 -37
  81. data/spec/rails_sandbox/config/initializers/backtrace_silencers.rb +0 -7
  82. data/spec/rails_sandbox/config/initializers/inflections.rb +0 -15
  83. data/spec/rails_sandbox/config/initializers/mime_types.rb +0 -5
  84. data/spec/rails_sandbox/config/initializers/secret_token.rb +0 -7
  85. data/spec/rails_sandbox/config/initializers/session_store.rb +0 -8
  86. data/spec/rails_sandbox/config/initializers/wrap_parameters.rb +0 -14
  87. data/spec/rails_sandbox/config/locales/en.yml +0 -5
  88. data/spec/rails_sandbox/config/routes.rb +0 -58
  89. data/spec/rails_sandbox/db/migrate/20110803201325_create_test_bed.rb +0 -96
  90. data/spec/rails_sandbox/db/schema.rb +0 -81
  91. data/spec/rails_sandbox/db/seeds.rb +0 -7
  92. data/spec/rails_sandbox/lib/assets/.gitkeep +0 -0
  93. data/spec/rails_sandbox/lib/tasks/.gitkeep +0 -0
  94. data/spec/rails_sandbox/log/.gitkeep +0 -0
  95. data/spec/rails_sandbox/public/404.html +0 -26
  96. data/spec/rails_sandbox/public/422.html +0 -26
  97. data/spec/rails_sandbox/public/500.html +0 -25
  98. data/spec/rails_sandbox/public/favicon.ico +0 -0
  99. data/spec/rails_sandbox/public/index.html +0 -241
  100. data/spec/rails_sandbox/public/robots.txt +0 -5
  101. data/spec/rails_sandbox/script/rails +0 -6
  102. data/spec/rails_sandbox/test/fixtures/.gitkeep +0 -0
  103. data/spec/rails_sandbox/test/functional/.gitkeep +0 -0
  104. data/spec/rails_sandbox/test/integration/.gitkeep +0 -0
  105. data/spec/rails_sandbox/test/performance/browsing_test.rb +0 -12
  106. data/spec/rails_sandbox/test/test_helper.rb +0 -13
  107. data/spec/rails_sandbox/test/unit/.gitkeep +0 -0
  108. data/spec/rails_sandbox/vendor/assets/javascripts/.gitkeep +0 -0
  109. data/spec/rails_sandbox/vendor/assets/stylesheets/.gitkeep +0 -0
  110. data/spec/rails_sandbox/vendor/plugins/.gitkeep +0 -0
data/Rakefile CHANGED
@@ -40,7 +40,8 @@ Jeweler::Tasks.new do |gem|
40
40
  gem.email = "rubygems@autotelik.co.uk"
41
41
  gem.authors = ["Thomas Statter"]
42
42
  # dependencies defined in Gemfile
43
- gem.files.exclude ['sandbox']
43
+ gem.files.exclude ['sandbox/**']
44
+ gem.files.exclude ['spec/**/*']
44
45
 
45
46
  gem.add_dependency 'spreadsheet'
46
47
  gem.add_dependency 'rubyzip'
@@ -86,7 +87,7 @@ task :build, :version do |t, args|
86
87
  puts "Installing version #{version}"
87
88
 
88
89
  gem = "#{DataShift.gem_name}-#{version}.gem"
89
- cmd = "jruby -S gem install --no-ri --no-rdoc #{gem}"
90
+ cmd = "gem install --no-ri --no-rdoc #{gem}"
90
91
  system(cmd)
91
92
  end
92
93
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.1
1
+ 0.12.0
data/datashift.gemspec CHANGED
@@ -1,15 +1,12 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
5
-
1
+ require 'rake'
2
+
6
3
  Gem::Specification.new do |s|
7
4
  s.name = "datashift"
8
- s.version = "0.11.1"
5
+ s.version = "0.12.0"
9
6
 
10
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
8
  s.authors = ["Thomas Statter"]
12
- s.date = "2012-10-23"
9
+ s.date = "2013-01-02"
13
10
  s.description = "Comprehensive tools to import/export between Excel/CSV and ActiveRecord databases, Rails apps, and any Ruby project."
14
11
  s.email = "rubygems@autotelik.co.uk"
15
12
  s.extra_rdoc_files = [
@@ -17,183 +14,23 @@ Gem::Specification.new do |s|
17
14
  "README.markdown",
18
15
  "README.rdoc"
19
16
  ]
20
- s.files = [
21
- ".document",
17
+
18
+ s.test_files = FileList["{spec}/*"]
19
+
20
+ s.files = FileList[
22
21
  "LICENSE.txt",
23
22
  "README.markdown",
24
23
  "README.rdoc",
25
24
  "Rakefile",
26
25
  "VERSION",
27
26
  "datashift.gemspec",
28
- "lib/applications/apache_poi_extensions.rb",
29
- "lib/applications/excel.rb",
30
- "lib/applications/excel_base.rb",
31
- "lib/applications/jexcel_file.rb",
32
- "lib/applications/jexcel_file_extensions.rb",
33
- "lib/applications/jruby/old_pre_proxy_jexcel_file.rb",
34
- "lib/applications/jruby/word.rb",
35
- "lib/applications/ruby_poi_translations.rb",
36
- "lib/applications/spreadsheet_extensions.rb",
37
- "lib/datashift.rb",
38
- "lib/datashift/delimiters.rb",
39
- "lib/datashift/exceptions.rb",
40
- "lib/datashift/file_definitions.rb",
41
- "lib/datashift/logging.rb",
42
- "lib/datashift/mapping_file_definitions.rb",
43
- "lib/datashift/method_detail.rb",
44
- "lib/datashift/method_details_manager.rb",
45
- "lib/datashift/method_dictionary.rb",
46
- "lib/datashift/method_mapper.rb",
47
- "lib/datashift/model_mapper.rb",
48
- "lib/datashift/populator.rb",
49
- "lib/datashift/querying.rb",
50
- "lib/exporters/csv_exporter.rb",
51
- "lib/exporters/excel_exporter.rb",
52
- "lib/exporters/exporter_base.rb",
53
- "lib/generators/csv_generator.rb",
54
- "lib/generators/excel_generator.rb",
55
- "lib/generators/generator_base.rb",
56
- "lib/guards.rb",
57
- "lib/helpers/core_ext/to_b.rb",
58
- "lib/java/poi-3.7/._poi-3.7-20101029.jar5645100390082102460.tmp",
59
- "lib/java/poi-3.7/LICENSE",
60
- "lib/java/poi-3.7/NOTICE",
61
- "lib/java/poi-3.7/RELEASE_NOTES.txt",
62
- "lib/java/poi-3.7/lib/commons-logging-1.1.jar",
63
- "lib/java/poi-3.7/lib/junit-3.8.1.jar",
64
- "lib/java/poi-3.7/lib/log4j-1.2.13.jar",
65
- "lib/java/poi-3.7/ooxml-lib/dom4j-1.6.1.jar",
66
- "lib/java/poi-3.7/ooxml-lib/geronimo-stax-api_1.0_spec-1.0.jar",
67
- "lib/java/poi-3.7/ooxml-lib/xmlbeans-2.3.0.jar",
68
- "lib/java/poi-3.7/poi-3.7-20101029.jar",
69
- "lib/java/poi-3.7/poi-examples-3.7-20101029.jar",
70
- "lib/java/poi-3.7/poi-ooxml-3.7-20101029.jar",
71
- "lib/java/poi-3.7/poi-ooxml-schemas-3.7-20101029.jar",
72
- "lib/java/poi-3.7/poi-scratchpad-3.7-20101029.jar",
73
- "lib/loaders/csv_loader.rb",
74
- "lib/loaders/excel_loader.rb",
75
- "lib/loaders/loader_base.rb",
76
- "lib/loaders/paperclip/attachment_loader.rb",
77
- "lib/loaders/paperclip/datashift_paperclip.rb",
78
- "lib/loaders/paperclip/image_loading.rb",
79
- "lib/thor/export.thor",
80
- "lib/thor/generate.thor",
81
- "lib/thor/import.thor",
82
- "lib/thor/paperclip.thor",
83
- "lib/thor/tools.thor",
84
- "spec/Gemfile",
85
- "spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg",
86
- "spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpeg",
87
- "spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpg",
88
- "spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg",
89
- "spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg",
90
- "spec/csv_exporter_spec.rb",
91
- "spec/csv_loader_spec.rb",
92
- "spec/datashift_spec.rb",
93
- "spec/excel_exporter_spec.rb",
94
- "spec/excel_generator_spec.rb",
95
- "spec/excel_loader_spec.rb",
96
- "spec/excel_spec.rb",
97
- "spec/file_definitions.rb",
98
- "spec/fixtures/BadAssociationName.xls",
99
- "spec/fixtures/DemoNegativeTesting.xls",
100
- "spec/fixtures/ProjectsDefaults.yml",
101
- "spec/fixtures/ProjectsMultiCategories.xls",
102
- "spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls",
103
- "spec/fixtures/ProjectsSingleCategories.xls",
104
- "spec/fixtures/SimpleProjects.xls",
105
- "spec/fixtures/config/database.yml",
106
- "spec/fixtures/db/datashift_test_models_db.sqlite",
107
- "spec/fixtures/db/migrate/20110803201325_create_test_bed.rb",
108
- "spec/fixtures/db/migrate/20121009161700_add_digitals.rb",
109
- "spec/fixtures/images/DEMO_001_ror_bag.jpeg",
110
- "spec/fixtures/images/DEMO_002_Powerstation.jpeg",
111
- "spec/fixtures/images/DEMO_003_ror_mug.jpeg",
112
- "spec/fixtures/images/DEMO_004_ror_ringer.jpeg",
113
- "spec/fixtures/load_datashift.thor",
114
- "spec/fixtures/models/category.rb",
115
- "spec/fixtures/models/digital.rb",
116
- "spec/fixtures/models/empty.rb",
117
- "spec/fixtures/models/loader_release.rb",
118
- "spec/fixtures/models/long_and_complex_table_linked_to_version.rb",
119
- "spec/fixtures/models/milestone.rb",
120
- "spec/fixtures/models/owner.rb",
121
- "spec/fixtures/models/project.rb",
122
- "spec/fixtures/models/version.rb",
123
- "spec/fixtures/simple_export_spec.xls",
124
- "spec/fixtures/simple_template_spec.xls",
125
- "spec/fixtures/test_model_defs.rb",
126
- "spec/loader_spec.rb",
127
- "spec/method_dictionary_spec.rb",
128
- "spec/method_mapper_spec.rb",
129
- "spec/paperclip_loader_spec.rb",
130
- "spec/rails_sandbox/.gitignore",
131
- "spec/rails_sandbox/Gemfile",
132
- "spec/rails_sandbox/README.rdoc",
133
- "spec/rails_sandbox/Rakefile",
134
- "spec/rails_sandbox/app/assets/images/rails.png",
135
- "spec/rails_sandbox/app/assets/javascripts/application.js",
136
- "spec/rails_sandbox/app/assets/stylesheets/application.css",
137
- "spec/rails_sandbox/app/controllers/application_controller.rb",
138
- "spec/rails_sandbox/app/helpers/application_helper.rb",
139
- "spec/rails_sandbox/app/mailers/.gitkeep",
140
- "spec/rails_sandbox/app/models/.gitkeep",
141
- "spec/rails_sandbox/app/models/category.rb",
142
- "spec/rails_sandbox/app/models/empty.rb",
143
- "spec/rails_sandbox/app/models/loader_release.rb",
144
- "spec/rails_sandbox/app/models/long_and_complex_table_linked_to_version.rb",
145
- "spec/rails_sandbox/app/models/milestone.rb",
146
- "spec/rails_sandbox/app/models/owner.rb",
147
- "spec/rails_sandbox/app/models/project.rb",
148
- "spec/rails_sandbox/app/models/test_model_defs.rb",
149
- "spec/rails_sandbox/app/models/version.rb",
150
- "spec/rails_sandbox/app/views/layouts/application.html.erb",
151
- "spec/rails_sandbox/config.ru",
152
- "spec/rails_sandbox/config/application.rb",
153
- "spec/rails_sandbox/config/boot.rb",
154
- "spec/rails_sandbox/config/database.yml",
155
- "spec/rails_sandbox/config/environment.rb",
156
- "spec/rails_sandbox/config/environments/development.rb",
157
- "spec/rails_sandbox/config/environments/production.rb",
158
- "spec/rails_sandbox/config/environments/test.rb",
159
- "spec/rails_sandbox/config/initializers/backtrace_silencers.rb",
160
- "spec/rails_sandbox/config/initializers/inflections.rb",
161
- "spec/rails_sandbox/config/initializers/mime_types.rb",
162
- "spec/rails_sandbox/config/initializers/secret_token.rb",
163
- "spec/rails_sandbox/config/initializers/session_store.rb",
164
- "spec/rails_sandbox/config/initializers/wrap_parameters.rb",
165
- "spec/rails_sandbox/config/locales/en.yml",
166
- "spec/rails_sandbox/config/routes.rb",
167
- "spec/rails_sandbox/db/migrate/20110803201325_create_test_bed.rb",
168
- "spec/rails_sandbox/db/schema.rb",
169
- "spec/rails_sandbox/db/seeds.rb",
170
- "spec/rails_sandbox/lib/assets/.gitkeep",
171
- "spec/rails_sandbox/lib/tasks/.gitkeep",
172
- "spec/rails_sandbox/log/.gitkeep",
173
- "spec/rails_sandbox/public/404.html",
174
- "spec/rails_sandbox/public/422.html",
175
- "spec/rails_sandbox/public/500.html",
176
- "spec/rails_sandbox/public/favicon.ico",
177
- "spec/rails_sandbox/public/index.html",
178
- "spec/rails_sandbox/public/robots.txt",
179
- "spec/rails_sandbox/script/rails",
180
- "spec/rails_sandbox/test/fixtures/.gitkeep",
181
- "spec/rails_sandbox/test/functional/.gitkeep",
182
- "spec/rails_sandbox/test/integration/.gitkeep",
183
- "spec/rails_sandbox/test/performance/browsing_test.rb",
184
- "spec/rails_sandbox/test/test_helper.rb",
185
- "spec/rails_sandbox/test/unit/.gitkeep",
186
- "spec/rails_sandbox/vendor/assets/javascripts/.gitkeep",
187
- "spec/rails_sandbox/vendor/assets/stylesheets/.gitkeep",
188
- "spec/rails_sandbox/vendor/plugins/.gitkeep",
189
- "spec/spec_helper.rb",
190
- "spec/thor_spec.rb",
191
27
  "tasks/config/seed_fu_product_template.erb",
192
28
  "tasks/config/tidy_config.txt",
193
29
  "tasks/db_tasks.rake",
194
30
  "tasks/file_tasks.rake",
195
- "tasks/word_to_seedfu.rake"
196
- ]
31
+ "tasks/word_to_seedfu.rake",
32
+ "{lib}/**/*"].exclude("rdoc").exclude("nbproject").exclude("fixtures").exclude(".log").exclude(".contrib").to_a
33
+
197
34
  s.homepage = "http://github.com/autotelik/datashift"
198
35
  s.licenses = ["MIT"]
199
36
  s.require_paths = ["lib"]
@@ -0,0 +1,64 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2011
2
+ # Author :: Tom Statter
3
+ # Date :: Dec 2012
4
+ # License:: MIT
5
+ #
6
+ # Details:: Helper for creating consistent import/export format
7
+ # of model's attributes/associations
8
+ #
9
+ #
10
+ require 'exporter_base'
11
+ require 'csv'
12
+
13
+ module DataShift
14
+
15
+ module ColumnPacker
16
+
17
+
18
+ def text_delim
19
+ @text_delim ||= "\'"
20
+ end
21
+
22
+ def text_delim=(x)
23
+ @text_delim = x
24
+ end
25
+
26
+ # Return opposite of text delim - "hello, 'barry'" => '"hello, "barry""'
27
+ def escape_text_delim
28
+ return '"' if text_delim == "\'"
29
+ "\'"
30
+ end
31
+
32
+
33
+ # Convert an AR instance to a single column
34
+
35
+ def record_to_column(record, attribute_delim = Delimiters::csv_delim)
36
+
37
+ csv_data = []
38
+ record.serializable_hash.each do |name, value|
39
+ value = 'nil' if value.nil?
40
+ text = value.to_s.gsub(@text_delim, escape_text_delim())
41
+ csv_data << "#{name.to_sym} => #{text}"
42
+ end
43
+ "#{csv_data.join(attribute_delim)}"
44
+ end
45
+
46
+
47
+ # Convert an AR instance to a set of CSV columns
48
+ def record_to_csv(record, options = {})
49
+ csv_data = record.serializable_hash.values.collect { |value| escape_for_csv(value) }
50
+
51
+ [*options[:methods]].each { |x| csv_data << escape_for_csv(record.send(x)) if(record.respond_to?(x)) } if(options[:methods])
52
+
53
+ csv_data.join( Delimiters::csv_delim )
54
+ end
55
+
56
+ def escape_for_csv(value)
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
+
63
+ end
64
+ end
@@ -67,15 +67,31 @@ module DataShift
67
67
  @multi_assoc_delim
68
68
  end
69
69
 
70
-
71
70
  def self.set_multi_assoc_delim(x) @multi_assoc_delim = x; end
72
71
 
73
72
 
73
+ # Delimiters for {:abc => 2, :efg => 'some text}
74
+
75
+ def self.attribute_list_start
76
+ @attribute_list_start ||= '{';
77
+ end
78
+
79
+ def self.attribute_list_start=(x) @attribute_list_start = x; end
80
+
81
+ def self.attribute_list_end
82
+ @attribute_list_end ||= '}'
83
+ end
84
+
85
+ def self.attribute_list_end=(x)
86
+ @attribute_list_end = x;
87
+ end
88
+
74
89
  def self.csv_delim
75
90
  @csv_delim ||= ','
76
91
  @csv_delim
77
92
  end
78
93
 
94
+ def self.csv_delim=(x) set_csv_delim(x); end
79
95
  def self.set_csv_delim(x) @csv_delim = x; end
80
96
 
81
97
  def self.eol
@@ -6,10 +6,17 @@ module DataShift
6
6
  class BadFile < StandardError; end
7
7
 
8
8
  class MappingDefinitionError < StandardError; end
9
+ class DataProcessingError < StandardError; end
9
10
 
10
11
  class MissingHeadersError < StandardError; end
11
12
  class MissingMandatoryError < StandardError; end
12
13
 
13
14
  class RecordNotFound < StandardError; end
14
15
 
16
+ class PathError < StandardError; end
17
+
18
+ class BadUri < StandardError; end
19
+
20
+ class CreateAttachmentFailed < StandardError; end
21
+
15
22
  end
@@ -18,11 +18,9 @@ module DataShift
18
18
 
19
19
  # Options:
20
20
  #
21
- # :split_on_prefix : Add a prefix to each search term
22
21
  # :case_sensitive : Default is a case insensitive lookup.
23
22
  # :use_like : Attempts a lookup using ike and x% rather than equality
24
23
  #
25
-
26
24
  def search_for_record(klazz, field, search_term, options = {})
27
25
 
28
26
  begin
@@ -50,7 +48,7 @@ module DataShift
50
48
  #
51
49
  # :add_prefix : Add a prefix to each search term
52
50
  # :case_sensitive : Default is a case insensitive lookup.
53
- # :use_like : Attempts a lookup using ike and x% rather than equality
51
+ # :use_like : Attempts a lookup using like and x% rather than equality
54
52
  #
55
53
  # Returns nil if no record found
56
54
  def get_record_by(klazz, field, search_term, split_on = ' ', options = {})
@@ -59,7 +57,11 @@ module DataShift
59
57
 
60
58
  split_on_prefix = options[:add_prefix]
61
59
 
62
- record = search_for_record(klazz, field, search_term)
60
+ z = (split_on_prefix) ? "#{split_on_prefix}#{search_term}": search_term
61
+
62
+ logger.info("Scanning for record where #{klazz}.#{field} ~= #{z}")
63
+
64
+ record = search_for_record(klazz, field, z)
63
65
 
64
66
  # try individual portions of search_term, front -> back i.e "A_B_C_D" => A, B, C etc
65
67
  search_term.split(split_on).each do |str|
@@ -76,6 +78,10 @@ module DataShift
76
78
  term
77
79
  end unless(record)
78
80
 
81
+ if(record && record.respond_to?(field))
82
+ logger.info("Record found for #{klazz}.#{field} : #{record.send(field)}" )
83
+ end
84
+
79
85
  return record
80
86
  rescue => e
81
87
  logger.error("Exception attempting to find a record for [#{search_term}] on #{klazz}.#{field}")
@@ -15,9 +15,16 @@ module DataShift
15
15
  module CsvLoading
16
16
 
17
17
  include DataShift::Logging
18
-
19
- # Assumes header_row is first row i.e row 0
18
+
19
+ # Load data through active Record models into DB from a CSV file
20
+ #
21
+ # Assumes header_row is first row i.e row 0
20
22
  #
23
+ #
24
+ # OPTIONS :
25
+ #
26
+ # [:dummy] : Perform a dummy run - attempt to load everything but then roll back
27
+ #
21
28
  # Options passed through to : populate_method_mapper_from_headers
22
29
  #
23
30
  # [:mandatory] : Array of mandatory column names
@@ -40,45 +47,75 @@ module DataShift
40
47
 
41
48
  puts "\n\n\nLoading from CSV file: #{file_name}"
42
49
  puts "Processing #{@parsed_file.size} rows"
50
+ begin
51
+
52
+ load_object_class.transaction do
53
+ @reporter.reset
43
54
 
44
- load_object_class.transaction do
45
- @loaded_objects = []
46
-
47
- @parsed_file.each do |row|
48
-
49
- # First assign any default values for columns not included in parsed_file
50
- process_missing_columns_with_defaults
55
+ @parsed_file.each_with_index do |row, i|
56
+
57
+ @current_row = row
58
+
59
+ @reporter.processed_object_count += 1
60
+
61
+ begin
62
+ # First assign any default values for columns not included in parsed_file
63
+ process_missing_columns_with_defaults
51
64
 
52
- # TODO - Smart sorting of column processing order ....
53
- # Does not currently ensure mandatory columns (for valid?) processed first but model needs saving
54
- # before associations can be processed so user should ensure mandatory columns are prior to associations
65
+ # TODO - Smart sorting of column processing order ....
66
+ # Does not currently ensure mandatory columns (for valid?) processed first but model needs saving
67
+ # before associations can be processed so user should ensure mandatory columns are prior to associations
55
68
 
56
- # as part of this we also attempt to save early, for example before assigning to
57
- # has_and_belongs_to associations which require the load_object has an id for the join table
69
+ # as part of this we also attempt to save early, for example before assigning to
70
+ # has_and_belongs_to associations which require the load_object has an id for the join table
58
71
 
59
- # Iterate over the columns method_mapper found in Excel,
60
- # pulling data out of associated column
61
- @method_mapper.method_details.each_with_index do |method_detail, col|
72
+ # Iterate over the columns method_mapper found in Excel,
73
+ # pulling data out of associated column
74
+ @method_mapper.method_details.each_with_index do |method_detail, col|
62
75
 
63
- value = row[col]
76
+ value = row[col]
64
77
 
65
- prepare_data(method_detail, value)
78
+ prepare_data(method_detail, value)
66
79
 
67
- process()
68
- end
69
-
70
- # TODO - handle when it's not valid ?
71
- # Process rest and dump out an exception list of Products ??
72
-
73
- logger.info "Saving csv row #{row} to table object : #{load_object.inspect}"
74
-
75
- save
76
-
77
- # don't forget to reset the object or we'll update rather than create
78
- new_load_object
80
+ process()
81
+ end
82
+
83
+ rescue => e
84
+ failure( row, true )
85
+ logger.error "Failed to process row [#{i}] (#{@current_row})"
86
+ # don't forget to reset the load object
87
+ new_load_object
88
+ next
89
+ end
90
+
91
+ # TODO - make optional - all or nothing or carry on and dump out the exception list at end
92
+ unless(save)
93
+ failure
94
+ logger.error "Failed to save row [#{@current_row}] (#{load_object.inspect})"
95
+ logger.error load_object.errors.inspect if(load_object)
96
+ else
97
+ logger.info "Row #{@current_row} succesfully SAVED : ID #{load_object.id}"
98
+ @reporter.add_loaded_object(@load_object)
99
+ end
100
+
101
+ # don't forget to reset the object or we'll update rather than create
102
+ new_load_object
79
103
 
104
+ end
105
+
106
+ raise ActiveRecord::Rollback if(options[:dummy]) # Don't actually create/upload to DB if we are doing dummy run
80
107
  end
108
+ rescue => e
109
+ puts "CAUGHT ", e.backtrace, e.inspect
110
+ if e.is_a?(ActiveRecord::Rollback) && options[:dummy]
111
+ puts "CSV loading stage complete - Dummy run so Rolling Back."
112
+ else
113
+ raise e
114
+ end
115
+ ensure
116
+ report
81
117
  end
118
+
82
119
  end
83
120
  end
84
121
 
@@ -94,7 +131,7 @@ module DataShift
94
131
  def perform_load( file_name, options = {} )
95
132
  perform_csv_load( file_name, options )
96
133
 
97
- puts "CSV loading stage complete - #{loaded_objects.size} rows added."
134
+ puts "CSV loading stage complete - #{loaded_count} rows added."
98
135
  end
99
136
 
100
137
  end