datashift 0.16.0 → 0.40.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 (422) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE.txt → LICENSE} +0 -0
  3. data/Rakefile +1 -20
  4. data/datashift.thor +125 -0
  5. data/lib/applications/apache_poi_extensions.rb +21 -52
  6. data/lib/applications/excel.rb +64 -57
  7. data/lib/applications/hssf_row_extensions.rb +66 -0
  8. data/lib/applications/jexcel_file.rb +99 -95
  9. data/lib/applications/jexcel_file_extensions.rb +76 -83
  10. data/lib/applications/jruby/word.rb +36 -36
  11. data/lib/applications/ruby_poi_translations.rb +34 -32
  12. data/lib/applications/spreadsheet_extensions.rb +21 -19
  13. data/lib/datashift.rb +49 -59
  14. data/lib/datashift/binder.rb +217 -0
  15. data/lib/datashift/column_packer.rb +21 -72
  16. data/lib/datashift/configuration.rb +317 -0
  17. data/lib/datashift/context_factory.rb +88 -0
  18. data/lib/datashift/core_ext/array.rb +15 -0
  19. data/lib/datashift/core_ext/csv_ext.rb +46 -0
  20. data/lib/datashift/core_ext/string.rb +49 -0
  21. data/lib/datashift/core_ext/to_b.rb +11 -0
  22. data/lib/datashift/delimiters.rb +55 -61
  23. data/lib/datashift/doc_context.rb +137 -0
  24. data/lib/datashift/excel_base.rb +93 -81
  25. data/lib/datashift/exceptions.rb +30 -28
  26. data/lib/datashift/file_definitions.rb +44 -39
  27. data/lib/datashift/guards.rb +5 -5
  28. data/lib/datashift/header.rb +25 -0
  29. data/lib/datashift/headers.rb +94 -0
  30. data/lib/datashift/inbound_data/column.rb +44 -0
  31. data/lib/datashift/inbound_data/lookup_support.rb +33 -0
  32. data/lib/datashift/inbound_data/method_binding.rb +139 -0
  33. data/lib/datashift/load_object.rb +37 -12
  34. data/lib/datashift/logging.rb +54 -27
  35. data/lib/datashift/mandatory.rb +39 -0
  36. data/lib/datashift/mapping/data_flow_schema.rb +198 -0
  37. data/lib/datashift/{model_mapper.rb → mapping/mapper_utils.rb} +30 -10
  38. data/lib/datashift/model_methods/catalogue.rb +183 -0
  39. data/lib/datashift/model_methods/collection.rb +140 -0
  40. data/lib/datashift/model_methods/model_method.rb +162 -0
  41. data/lib/datashift/model_methods/model_methods_manager.rb +76 -0
  42. data/lib/datashift/model_methods/operator.rb +62 -0
  43. data/lib/datashift/node_collection.rb +26 -0
  44. data/lib/datashift/node_context.rb +68 -0
  45. data/lib/datashift/populator.rb +308 -282
  46. data/lib/datashift/progress_monitor.rb +91 -0
  47. data/lib/datashift/querying.rb +110 -52
  48. data/lib/datashift/templates/import_export_config.erb +55 -0
  49. data/lib/datashift/transformation/factory.rb +219 -0
  50. data/lib/datashift/transformation/remove.rb +44 -0
  51. data/lib/datashift/version.rb +3 -0
  52. data/lib/exporters/configuration.rb +84 -0
  53. data/lib/exporters/csv_exporter.rb +54 -52
  54. data/lib/exporters/excel_exporter.rb +80 -61
  55. data/lib/exporters/exporter_base.rb +8 -8
  56. data/lib/generators/config_generator.rb +218 -0
  57. data/lib/generators/csv_generator.rb +13 -70
  58. data/lib/generators/excel_generator.rb +23 -111
  59. data/lib/generators/generator_base.rb +15 -70
  60. data/lib/loaders/configuration.rb +90 -0
  61. data/lib/loaders/csv_loader.rb +63 -101
  62. data/lib/loaders/excel_loader.rb +71 -156
  63. data/lib/loaders/failure_data.rb +40 -0
  64. data/lib/loaders/file_loader.rb +16 -0
  65. data/lib/loaders/loader_base.rb +82 -410
  66. data/lib/loaders/loader_factory.rb +42 -0
  67. data/lib/loaders/paperclip/attachment_loader.rb +157 -140
  68. data/lib/loaders/paperclip/datashift_paperclip.rb +18 -35
  69. data/lib/loaders/paperclip/image_loading.rb +40 -35
  70. data/lib/loaders/reporters/basic_stdout_reporter.rb +40 -0
  71. data/lib/loaders/reporters/reporter.rb +26 -0
  72. data/lib/tasks/config.thor +65 -0
  73. data/{tasks → lib/tasks}/config/seed_fu_product_template.erb +0 -0
  74. data/{tasks → lib/tasks}/config/tidy_config.txt +0 -0
  75. data/lib/tasks/export.thor +192 -0
  76. data/lib/tasks/generate.thor +190 -0
  77. data/lib/tasks/import.thor +142 -0
  78. data/lib/{thor → tasks}/paperclip.thor +69 -69
  79. data/{tasks → lib/tasks/to_convert_to_thor}/db_tasks.rake +20 -20
  80. data/lib/tasks/tools.thor +109 -0
  81. data/spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg +0 -0
  82. data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpeg +0 -0
  83. data/spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg +0 -0
  84. data/spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg +0 -0
  85. data/spec/datashift/binder_spec.rb +266 -0
  86. data/spec/datashift/config_generator_spec.rb +186 -0
  87. data/spec/datashift/configuration.rb +66 -0
  88. data/spec/datashift/context_factory_spec.rb +63 -0
  89. data/spec/datashift/data_flow_schema_spec.rb +150 -0
  90. data/spec/datashift/datashift_spec.rb +52 -0
  91. data/spec/datashift/excel_base_spec.rb +57 -0
  92. data/spec/datashift/excel_spec.rb +188 -0
  93. data/spec/datashift/failure_data_spec.rb +27 -0
  94. data/spec/{file_definitions.rb → datashift/file_definitions.rb} +9 -10
  95. data/spec/datashift/headers_spec.rb +56 -0
  96. data/spec/datashift/inbound_data_spec.rb +47 -0
  97. data/spec/datashift/mapper_utils_spec.rb +38 -0
  98. data/spec/datashift/method_binding_spec.rb +60 -0
  99. data/spec/datashift/model_method_spec.rb +109 -0
  100. data/spec/datashift/model_methods_catalogue.rb +111 -0
  101. data/spec/datashift/model_methods_collection_spec.rb +138 -0
  102. data/spec/datashift/model_methods_manager_spec.rb +329 -0
  103. data/spec/datashift/populator_spec.rb +117 -0
  104. data/spec/datashift/thor_spec.rb +314 -0
  105. data/spec/datashift/transformation/factory_spec.rb +195 -0
  106. data/spec/datashift/transformation/transformer_remove_spec.rb +43 -0
  107. data/spec/dummy/Gemfile +53 -0
  108. data/spec/dummy/Gemfile.lock +197 -0
  109. data/spec/dummy/README.rdoc +28 -0
  110. data/spec/dummy/Rakefile +6 -0
  111. data/spec/dummy/app/assets/javascripts/application.js +16 -0
  112. data/spec/dummy/app/assets/javascripts/categories.js +2 -0
  113. data/spec/dummy/app/assets/javascripts/digitals.js +2 -0
  114. data/spec/dummy/app/assets/javascripts/empties.js +2 -0
  115. data/spec/dummy/app/assets/javascripts/loader_releases.js +2 -0
  116. data/spec/dummy/app/assets/javascripts/long_and_complex_table_linked_to_versions.js +2 -0
  117. data/spec/dummy/app/assets/javascripts/milestones.js +2 -0
  118. data/spec/dummy/app/assets/javascripts/owners.js +2 -0
  119. data/spec/dummy/app/assets/javascripts/projects.js +2 -0
  120. data/spec/dummy/app/assets/javascripts/users.js +2 -0
  121. data/spec/dummy/app/assets/javascripts/versions.js +2 -0
  122. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  123. data/spec/dummy/app/assets/stylesheets/categories.css +4 -0
  124. data/spec/dummy/app/assets/stylesheets/digitals.css +4 -0
  125. data/spec/dummy/app/assets/stylesheets/empties.css +4 -0
  126. data/spec/dummy/app/assets/stylesheets/loader_releases.css +4 -0
  127. data/spec/dummy/app/assets/stylesheets/long_and_complex_table_linked_to_versions.css +4 -0
  128. data/spec/dummy/app/assets/stylesheets/milestones.css +4 -0
  129. data/spec/dummy/app/assets/stylesheets/owners.css +4 -0
  130. data/spec/dummy/app/assets/stylesheets/projects.css +4 -0
  131. data/spec/dummy/app/assets/stylesheets/scaffold.css +56 -0
  132. data/spec/dummy/app/assets/stylesheets/users.css +4 -0
  133. data/spec/dummy/app/assets/stylesheets/versions.css +4 -0
  134. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  135. data/spec/dummy/app/controllers/categories_controller.rb +58 -0
  136. data/spec/dummy/app/controllers/digitals_controller.rb +58 -0
  137. data/spec/dummy/app/controllers/empties_controller.rb +58 -0
  138. data/spec/dummy/app/controllers/loader_releases_controller.rb +58 -0
  139. data/spec/dummy/app/controllers/long_and_complex_table_linked_to_versions_controller.rb +58 -0
  140. data/spec/dummy/app/controllers/milestones_controller.rb +58 -0
  141. data/spec/dummy/app/controllers/owners_controller.rb +58 -0
  142. data/spec/dummy/app/controllers/projects_controller.rb +58 -0
  143. data/spec/dummy/app/controllers/users_controller.rb +58 -0
  144. data/spec/dummy/app/controllers/versions_controller.rb +58 -0
  145. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  146. data/spec/dummy/app/helpers/categories_helper.rb +2 -0
  147. data/spec/dummy/app/helpers/digitals_helper.rb +2 -0
  148. data/spec/dummy/app/helpers/empties_helper.rb +2 -0
  149. data/spec/dummy/app/helpers/loader_releases_helper.rb +2 -0
  150. data/spec/dummy/app/helpers/long_and_complex_table_linked_to_versions_helper.rb +2 -0
  151. data/spec/dummy/app/helpers/milestones_helper.rb +2 -0
  152. data/spec/dummy/app/helpers/owners_helper.rb +2 -0
  153. data/spec/dummy/app/helpers/projects_helper.rb +2 -0
  154. data/spec/dummy/app/helpers/users_helper.rb +2 -0
  155. data/spec/dummy/app/helpers/versions_helper.rb +2 -0
  156. data/spec/dummy/app/models/category.rb +6 -0
  157. data/spec/dummy/app/models/digital.rb +22 -0
  158. data/spec/dummy/app/models/empty.rb +2 -0
  159. data/spec/dummy/app/models/loader_release.rb +10 -0
  160. data/spec/dummy/app/models/long_and_complex_table_linked_to_version.rb +6 -0
  161. data/spec/dummy/app/models/milestone.rb +15 -0
  162. data/spec/dummy/app/models/owner.rb +13 -0
  163. data/spec/dummy/app/models/project.rb +53 -0
  164. data/spec/dummy/app/models/user.rb +5 -0
  165. data/spec/dummy/app/models/version.rb +7 -0
  166. data/spec/dummy/app/views/categories/_form.html.erb +17 -0
  167. data/spec/dummy/app/views/categories/edit.html.erb +6 -0
  168. data/spec/dummy/app/views/categories/index.html.erb +25 -0
  169. data/spec/dummy/app/views/categories/new.html.erb +5 -0
  170. data/spec/dummy/app/views/categories/show.html.erb +4 -0
  171. data/spec/dummy/app/views/digitals/_form.html.erb +17 -0
  172. data/spec/dummy/app/views/digitals/edit.html.erb +6 -0
  173. data/spec/dummy/app/views/digitals/index.html.erb +25 -0
  174. data/spec/dummy/app/views/digitals/new.html.erb +5 -0
  175. data/spec/dummy/app/views/digitals/show.html.erb +4 -0
  176. data/spec/dummy/app/views/empties/_form.html.erb +17 -0
  177. data/spec/dummy/app/views/empties/edit.html.erb +6 -0
  178. data/spec/dummy/app/views/empties/index.html.erb +25 -0
  179. data/spec/dummy/app/views/empties/new.html.erb +5 -0
  180. data/spec/dummy/app/views/empties/show.html.erb +4 -0
  181. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  182. data/spec/dummy/app/views/loader_releases/_form.html.erb +17 -0
  183. data/spec/dummy/app/views/loader_releases/edit.html.erb +6 -0
  184. data/spec/dummy/app/views/loader_releases/index.html.erb +25 -0
  185. data/spec/dummy/app/views/loader_releases/new.html.erb +5 -0
  186. data/spec/dummy/app/views/loader_releases/show.html.erb +4 -0
  187. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/_form.html.erb +17 -0
  188. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/edit.html.erb +6 -0
  189. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/index.html.erb +25 -0
  190. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/new.html.erb +5 -0
  191. data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/show.html.erb +4 -0
  192. data/spec/dummy/app/views/milestones/_form.html.erb +17 -0
  193. data/spec/dummy/app/views/milestones/edit.html.erb +6 -0
  194. data/spec/dummy/app/views/milestones/index.html.erb +25 -0
  195. data/spec/dummy/app/views/milestones/new.html.erb +5 -0
  196. data/spec/dummy/app/views/milestones/show.html.erb +4 -0
  197. data/spec/dummy/app/views/owners/_form.html.erb +17 -0
  198. data/spec/dummy/app/views/owners/edit.html.erb +6 -0
  199. data/spec/dummy/app/views/owners/index.html.erb +25 -0
  200. data/spec/dummy/app/views/owners/new.html.erb +5 -0
  201. data/spec/dummy/app/views/owners/show.html.erb +4 -0
  202. data/spec/dummy/app/views/projects/_form.html.erb +17 -0
  203. data/spec/dummy/app/views/projects/edit.html.erb +6 -0
  204. data/spec/dummy/app/views/projects/index.html.erb +25 -0
  205. data/spec/dummy/app/views/projects/new.html.erb +5 -0
  206. data/spec/dummy/app/views/projects/show.html.erb +4 -0
  207. data/spec/dummy/app/views/users/_form.html.erb +17 -0
  208. data/spec/dummy/app/views/users/edit.html.erb +6 -0
  209. data/spec/dummy/app/views/users/index.html.erb +25 -0
  210. data/spec/dummy/app/views/users/new.html.erb +5 -0
  211. data/spec/dummy/app/views/users/show.html.erb +4 -0
  212. data/spec/dummy/app/views/versions/_form.html.erb +17 -0
  213. data/spec/dummy/app/views/versions/edit.html.erb +6 -0
  214. data/spec/dummy/app/views/versions/index.html.erb +25 -0
  215. data/spec/dummy/app/views/versions/new.html.erb +5 -0
  216. data/spec/dummy/app/views/versions/show.html.erb +4 -0
  217. data/spec/dummy/bin/bundle +3 -0
  218. data/spec/dummy/bin/rails +9 -0
  219. data/spec/dummy/bin/rake +9 -0
  220. data/spec/dummy/bin/setup +29 -0
  221. data/spec/dummy/bin/spring +16 -0
  222. data/spec/dummy/config.ru +4 -0
  223. data/spec/dummy/config/application.rb +26 -0
  224. data/spec/dummy/config/boot.rb +3 -0
  225. data/spec/dummy/config/database.yml +25 -0
  226. data/spec/dummy/config/environment.rb +5 -0
  227. data/spec/dummy/config/environments/development.rb +41 -0
  228. data/spec/dummy/config/environments/production.rb +79 -0
  229. data/spec/dummy/config/environments/test.rb +42 -0
  230. data/spec/dummy/config/initializers/assets.rb +11 -0
  231. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  232. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  233. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  234. data/spec/dummy/config/initializers/inflections.rb +16 -0
  235. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  236. data/spec/dummy/config/initializers/session_store.rb +3 -0
  237. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  238. data/spec/dummy/config/locales/en.yml +23 -0
  239. data/spec/dummy/config/routes.rb +76 -0
  240. data/spec/dummy/config/secrets.yml +22 -0
  241. data/spec/dummy/db/development.sqlite3 +0 -0
  242. data/spec/dummy/db/migrate/20110803201325_create_test_bed.rb +98 -0
  243. data/spec/dummy/db/migrate/20121009161700_add_digitals.rb +24 -0
  244. data/spec/dummy/db/migrate/20161005123106_create_digitals.rb +8 -0
  245. data/spec/dummy/db/migrate/20161005123106_create_long_and_complex_table_linked_to_versions.rb +8 -0
  246. data/spec/dummy/db/migrate/20161005123107_create_loader_releases.rb +8 -0
  247. data/spec/dummy/db/migrate/20161005123108_create_owners.rb +8 -0
  248. data/spec/dummy/db/migrate/20161005123109_create_empties.rb +8 -0
  249. data/spec/dummy/db/migrate/20161005123110_create_projects.rb +8 -0
  250. data/spec/dummy/db/migrate/20161005123111_create_users.rb +8 -0
  251. data/spec/dummy/db/migrate/20161005123111_create_versions.rb +8 -0
  252. data/spec/dummy/db/migrate/20161005123112_create_milestones.rb +8 -0
  253. data/spec/dummy/db/migrate/20161005123113_create_categories.rb +8 -0
  254. data/spec/dummy/db/schema.rb +93 -0
  255. data/spec/dummy/db/seeds.rb +9 -0
  256. data/spec/dummy/db/test.sqlite3 +0 -0
  257. data/spec/dummy/log/test.log +69 -0
  258. data/spec/dummy/public/404.html +67 -0
  259. data/spec/dummy/public/422.html +67 -0
  260. data/spec/dummy/public/500.html +66 -0
  261. data/spec/dummy/public/favicon.ico +0 -0
  262. data/spec/dummy/public/robots.txt +5 -0
  263. data/spec/dummy/sandbox_example.thor +4 -0
  264. data/spec/dummy/test/controllers/categories_controller_test.rb +49 -0
  265. data/spec/dummy/test/controllers/digitals_controller_test.rb +49 -0
  266. data/spec/dummy/test/controllers/empties_controller_test.rb +49 -0
  267. data/spec/dummy/test/controllers/loader_releases_controller_test.rb +49 -0
  268. data/spec/dummy/test/controllers/long_and_complex_table_linked_to_versions_controller_test.rb +49 -0
  269. data/spec/dummy/test/controllers/milestones_controller_test.rb +49 -0
  270. data/spec/dummy/test/controllers/owners_controller_test.rb +49 -0
  271. data/spec/dummy/test/controllers/projects_controller_test.rb +49 -0
  272. data/spec/dummy/test/controllers/users_controller_test.rb +49 -0
  273. data/spec/dummy/test/controllers/versions_controller_test.rb +49 -0
  274. data/spec/dummy/test/factories/categories.rb +5 -0
  275. data/spec/dummy/test/factories/digitals.rb +5 -0
  276. data/spec/dummy/test/factories/empties.rb +5 -0
  277. data/spec/dummy/test/factories/loader_releases.rb +5 -0
  278. data/spec/dummy/test/factories/long_and_complex_table_linked_to_versions.rb +5 -0
  279. data/spec/dummy/test/factories/milestones.rb +5 -0
  280. data/spec/dummy/test/factories/owners.rb +5 -0
  281. data/spec/dummy/test/factories/projects.rb +5 -0
  282. data/spec/dummy/test/factories/users.rb +5 -0
  283. data/spec/dummy/test/factories/versions.rb +5 -0
  284. data/spec/dummy/test/models/category_test.rb +7 -0
  285. data/spec/dummy/test/models/digital_test.rb +7 -0
  286. data/spec/dummy/test/models/empty_test.rb +7 -0
  287. data/spec/dummy/test/models/loader_release_test.rb +7 -0
  288. data/spec/dummy/test/models/long_and_complex_table_linked_to_version_test.rb +7 -0
  289. data/spec/dummy/test/models/milestone_test.rb +7 -0
  290. data/spec/dummy/test/models/owner_test.rb +7 -0
  291. data/spec/dummy/test/models/project_test.rb +7 -0
  292. data/spec/dummy/test/models/user_test.rb +7 -0
  293. data/spec/dummy/test/models/version_test.rb +7 -0
  294. data/spec/dummy/test/test_helper.rb +10 -0
  295. data/spec/exporters/csv_exporter_spec.rb +240 -0
  296. data/spec/exporters/csv_generator_spec.rb +139 -0
  297. data/spec/exporters/excel_exporter_spec.rb +193 -0
  298. data/spec/exporters/excel_generator_spec.rb +181 -0
  299. data/spec/exporters/generator_base_spec.rb +45 -0
  300. data/spec/factories/categories.rb +7 -0
  301. data/spec/factories/factories.rb +18 -0
  302. data/spec/factories/milestone.rb +16 -0
  303. data/spec/factories/projects.rb +41 -0
  304. data/spec/fixtures/BadAssociationName.xls +0 -0
  305. data/spec/fixtures/DemoNegativeTesting.xls +0 -0
  306. data/spec/fixtures/ProjectConfiguration.yml +18 -0
  307. data/spec/fixtures/ProjectsMultiCategories.xls +0 -0
  308. data/spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls +0 -0
  309. data/spec/fixtures/ProjectsSingleCategories.xls +0 -0
  310. data/spec/fixtures/ProjectsSingleCategories.xlsx +0 -0
  311. data/spec/fixtures/SimpleProjects.xls +0 -0
  312. data/spec/fixtures/config/database.yml +28 -0
  313. data/spec/fixtures/csv/BadAssociationName.csv +6 -0
  314. data/spec/fixtures/csv/DemoNegativeTesting.csv +6 -0
  315. data/spec/fixtures/csv/ProjectsMultiCategories.csv +5 -0
  316. data/spec/fixtures/csv/ProjectsMultiCategoriesHeaderLookup.csv +5 -0
  317. data/spec/fixtures/csv/ProjectsSingleCategories.csv +5 -0
  318. data/spec/fixtures/csv/SimpleProjects.csv +4 -0
  319. data/spec/fixtures/db/migrate/20110803201325_create_test_bed.rb +98 -0
  320. data/spec/fixtures/db/migrate/20121009161700_add_digitals.rb +24 -0
  321. data/spec/fixtures/db/seeds.rb +9 -0
  322. data/spec/fixtures/images/DEMO_001_ror_bag.jpeg +0 -0
  323. data/spec/fixtures/images/DEMO_002_Powerstation.jpeg +0 -0
  324. data/spec/fixtures/images/DEMO_003_ror_mug.jpeg +0 -0
  325. data/spec/fixtures/images/DEMO_004_ror_ringer.jpeg +0 -0
  326. data/spec/fixtures/load_datashift.thor +3 -0
  327. data/spec/fixtures/models/category.rb +6 -0
  328. data/spec/fixtures/models/digital.rb +22 -0
  329. data/spec/fixtures/models/empty.rb +2 -0
  330. data/spec/fixtures/models/loader_release.rb +10 -0
  331. data/spec/fixtures/models/long_and_complex_table_linked_to_version.rb +6 -0
  332. data/spec/fixtures/models/milestone.rb +15 -0
  333. data/spec/fixtures/models/owner.rb +13 -0
  334. data/spec/fixtures/models/project.rb +53 -0
  335. data/spec/fixtures/models/user.rb +5 -0
  336. data/spec/fixtures/models/version.rb +7 -0
  337. data/spec/fixtures/results/exp_project_assoc_headers.xls +0 -0
  338. data/spec/fixtures/results/exp_project_collection_spec.csv +2 -0
  339. data/spec/fixtures/results/exp_project_export.xls +0 -0
  340. data/spec/fixtures/results/exp_project_first_export.xls +0 -0
  341. data/spec/fixtures/results/exp_project_plus_assoc.xls +0 -0
  342. data/spec/fixtures/results/exp_project_plus_assoc_export_spec.csv +9 -0
  343. data/spec/fixtures/results/gen_project_plus_assoc_template.xls +0 -0
  344. data/spec/fixtures/results/gen_project_plus_some_assoc_template.xls +0 -0
  345. data/spec/fixtures/results/gen_project_template.xls +0 -0
  346. data/spec/fixtures/results/project_and_assoc_in_hash_export.xls +0 -0
  347. data/spec/fixtures/results/project_and_assoc_in_json_export.csv +9 -0
  348. data/spec/fixtures/results/project_and_assoc_in_json_export.xls +0 -0
  349. data/spec/fixtures/results/project_export_spec_with_custom_delim_,.csv +2 -0
  350. data/spec/fixtures/results/project_export_spec_with_custom_delim_/302/243.csv +2 -0
  351. data/spec/fixtures/results/project_export_spec_with_custom_delim_/302/247.csv +2 -0
  352. data/spec/fixtures/results/project_plus_assoc_template.csv +1 -0
  353. data/spec/fixtures/results/project_plus_some_assoc_template.csv +1 -0
  354. data/spec/fixtures/results/project_remove_export_spec.csv +2 -0
  355. data/spec/fixtures/results/project_template.csv +1 -0
  356. data/spec/fixtures/results/project_with_methods_export_spec.csv +2 -0
  357. data/spec/fixtures/results/thor_spec_gen_project.csv +1 -0
  358. data/spec/fixtures/sandbox_example.thor +4 -0
  359. data/spec/fixtures/simple_export_spec.xls +0 -0
  360. data/spec/fixtures/simple_template_spec.xls +0 -0
  361. data/spec/fixtures/test_model_defs.rb +7 -0
  362. data/spec/loaders/csv_loader_spec.rb +206 -0
  363. data/spec/loaders/data_flow_excel_loader_spec.rb +290 -0
  364. data/spec/loaders/excel_loader_failures_spec.rb +67 -0
  365. data/spec/loaders/excel_loader_spec.rb +294 -0
  366. data/spec/loaders/loader_base_spec.rb +29 -0
  367. data/spec/loaders/paperclip_loader_spec.rb +106 -0
  368. data/spec/log/datashift.log +14930 -0
  369. data/spec/private/digitals/1/DEMO_003_ror_mug.jpeg +0 -0
  370. data/spec/private/digitals/2/DEMO_002_Powerstation.jpeg +0 -0
  371. data/spec/private/digitals/3/DEMO_004_ror_ringer.jpeg +0 -0
  372. data/spec/private/digitals/4/DEMO_001_ror_bag.jpeg +0 -0
  373. data/spec/spec_helper.rb +26 -230
  374. data/spec/support/clear_and_manage_contexts.rb +25 -0
  375. data/spec/support/database_cleaner.rb +32 -0
  376. data/spec/support/datashift_test_helpers.rb +153 -0
  377. data/spec/support/files_paths_helper.rb +13 -0
  378. data/spec/support/fixtures/results/mapping_template.yaml +15 -0
  379. data/spec/support/sandbox.rb +136 -0
  380. metadata +804 -85
  381. data/README.markdown +0 -274
  382. data/README.rdoc +0 -19
  383. data/VERSION +0 -1
  384. data/datashift.gemspec +0 -48
  385. data/lib/applications/jruby/old_pre_proxy_jexcel_file.rb +0 -437
  386. data/lib/datashift/data_transforms.rb +0 -83
  387. data/lib/datashift/mapping_file_definitions.rb +0 -88
  388. data/lib/datashift/mapping_service.rb +0 -91
  389. data/lib/datashift/method_detail.rb +0 -165
  390. data/lib/datashift/method_details_manager.rb +0 -95
  391. data/lib/datashift/method_dictionary.rb +0 -281
  392. data/lib/datashift/method_mapper.rb +0 -174
  393. data/lib/datashift/thor_base.rb +0 -38
  394. data/lib/generators/mapping_generator.rb +0 -112
  395. data/lib/helpers/core_ext/csv_file.rb +0 -33
  396. data/lib/helpers/core_ext/to_b.rb +0 -24
  397. data/lib/loaders/reporter.rb +0 -58
  398. data/lib/thor/export.thor +0 -175
  399. data/lib/thor/generate.thor +0 -191
  400. data/lib/thor/import.thor +0 -110
  401. data/lib/thor/mapping.thor +0 -65
  402. data/lib/thor/tools.thor +0 -84
  403. data/spec/Gemfile +0 -31
  404. data/spec/Gemfile.lock +0 -134
  405. data/spec/csv_exporter_spec.rb +0 -144
  406. data/spec/csv_generator_spec.rb +0 -159
  407. data/spec/csv_loader_spec.rb +0 -212
  408. data/spec/datashift_spec.rb +0 -55
  409. data/spec/excel_exporter_spec.rb +0 -199
  410. data/spec/excel_generator_spec.rb +0 -203
  411. data/spec/excel_loader_spec.rb +0 -237
  412. data/spec/excel_spec.rb +0 -203
  413. data/spec/loader_base_spec.rb +0 -166
  414. data/spec/mapping_spec.rb +0 -117
  415. data/spec/method_dictionary_spec.rb +0 -300
  416. data/spec/method_mapper_spec.rb +0 -100
  417. data/spec/model_mapper_spec.rb +0 -41
  418. data/spec/paperclip_loader_spec.rb +0 -92
  419. data/spec/populator_spec.rb +0 -128
  420. data/spec/thor_spec.rb +0 -90
  421. data/tasks/file_tasks.rake +0 -37
  422. data/tasks/word_to_seedfu.rake +0 -167
@@ -22,55 +22,55 @@
22
22
  # WORD_OLE_CONST.const_get( 'LesCR' ) or WORD_OLE_CONST::LesCR
23
23
  # => 1
24
24
 
25
- if(Guards::windows?)
25
+ if Guards.windows?
26
26
 
27
- require 'win32ole'
27
+ require 'win32ole'
28
28
 
29
- # Module for constants to be loaded int
29
+ # Module for constants to be loaded int
30
30
 
31
- module WORD_OLE_CONST
32
- end
31
+ module WORD_OLE_CONST
32
+ end
33
33
 
34
- class Word
35
-
36
- attr_reader :wd, :doc
34
+ class Word
37
35
 
38
- def initialize( visible )
39
- @wd = WIN32OLE.new('Word.Application')
36
+ attr_reader :wd, :doc
40
37
 
41
- WIN32OLE.const_load(@wd, WORD_OLE_CONST) if WORD_OLE_CONST.constants.empty?
38
+ def initialize( visible )
39
+ @wd = WIN32OLE.new('Word.Application')
42
40
 
43
- @wd.Visible = visible
44
- end
41
+ WIN32OLE.const_load(@wd, WORD_OLE_CONST) if WORD_OLE_CONST.constants.empty?
45
42
 
46
- def open(file)
47
- @doc = @wd.Documents.Open(file)
48
- @doc
49
- end
43
+ @wd.Visible = visible
44
+ end
50
45
 
51
- def save()
52
- @doc.Save()
53
- @doc
54
- end
46
+ def open(file)
47
+ @doc = @wd.Documents.Open(file)
48
+ @doc
49
+ end
55
50
 
56
- # Format : From WORD_OLE_CONST e.g WORD_OLE_CONST::WdFormatHTML
57
- #
58
- def save_as(name, format)
59
- @doc.SaveAs(name, format)
60
- return @doc
61
- end
51
+ def save
52
+ @doc.Save()
53
+ @doc
54
+ end
62
55
 
63
- # WdFormatFilteredHTML
64
- # WdFormatHTML
65
- def save_as_html(name)
66
- @doc.SaveAs(name, WORD_OLE_CONST::WdFormatHTML)
67
- return @doc
68
- end
56
+ # Format : From WORD_OLE_CONST e.g WORD_OLE_CONST::WdFormatHTML
57
+ #
58
+ def save_as(name, format)
59
+ @doc.SaveAs(name, format)
60
+ @doc
61
+ end
69
62
 
70
- def quit
71
- @wd.quit()
63
+ # WdFormatFilteredHTML
64
+ # WdFormatHTML
65
+ def save_as_html(name)
66
+ @doc.SaveAs(name, WORD_OLE_CONST::WdFormatHTML)
67
+ @doc
68
+ end
69
+
70
+ def quit
71
+ @wd.quit
72
+ end
72
73
  end
73
- end
74
74
 
75
75
  else
76
76
 
@@ -1,18 +1,19 @@
1
1
  # Copyright:: Autotelik Media Ltd
2
2
  # Author :: Tom Statter
3
3
  # Date :: July 2010
4
- # License::
4
+ # License::
5
5
  #
6
+ # Translate Apache Poi Java data types/va;pues to Ruby world
6
7
  #
7
- if(DataShift::Guards::jruby?)
8
-
8
+ if DataShift::Guards.jruby?
9
+
9
10
  require 'java'
10
-
11
+
11
12
  require 'benchmark'
12
- require "poi-3.7-20101029.jar"
13
-
13
+ require 'poi-3.7-20101029.jar'
14
+
14
15
  module RubyPoiTranslations
15
-
16
+
16
17
  java_import 'org.apache.poi.poifs.filesystem.POIFSFileSystem'
17
18
 
18
19
  java_import 'org.apache.poi.hssf.usermodel.HSSFCell'
@@ -21,53 +22,54 @@ if(DataShift::Guards::jruby?)
21
22
  java_import 'org.apache.poi.hssf.usermodel.HSSFDataFormat'
22
23
  java_import 'org.apache.poi.hssf.usermodel.HSSFClientAnchor'
23
24
  java_import 'org.apache.poi.hssf.usermodel.HSSFRichTextString'
24
-
25
+
25
26
  java_import 'org.apache.poi.hssf.util.HSSFColor'
26
27
 
27
28
  java_import 'java.io.ByteArrayOutputStream'
28
29
  java_import 'java.util.Date'
29
30
  java_import 'java.io.FileInputStream'
30
31
  java_import 'java.io.FileOutputStream'
31
-
32
- # Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_STRING, Cell.CELL_TYPE_FORMULA,
32
+
33
+ # Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_STRING, Cell.CELL_TYPE_FORMULA,
33
34
  # Cell.CELL_TYPE_BLANK, Cell.CELL_TYPE_BOOLEAN, Cell.CELL_TYPE_ERROR
34
35
 
35
36
  def cell_value(cell)
36
- case (cell.getCellType())
37
- when HSSFCell::CELL_TYPE_FORMULA then return cell.getCellFormula()
38
- when HSSFCell::CELL_TYPE_NUMERIC then return cell.getNumericCellValue()
39
- when HSSFCell::CELL_TYPE_STRING then return cell.getStringCellValue()
40
- when HSSFCell::CELL_TYPE_BOOLEAN then return cell.getBooleanCellValue()
41
- when HSSFCell::CELL_TYPE_ERROR then return cell.getErrorCellValue()
42
-
43
- when HSSFCell::CELL_TYPE_BLANK then return ""
37
+ return '' unless(cell)
38
+
39
+ case cell.getCellType
40
+ when HSSFCell::CELL_TYPE_FORMULA then return cell.getCellFormula
41
+ when HSSFCell::CELL_TYPE_NUMERIC then return cell.getNumericCellValue
42
+ when HSSFCell::CELL_TYPE_STRING then return cell.getStringCellValue
43
+ when HSSFCell::CELL_TYPE_BOOLEAN then return cell.getBooleanCellValue
44
+ when HSSFCell::CELL_TYPE_ERROR then return cell.getErrorCellValue
45
+
46
+ when HSSFCell::CELL_TYPE_BLANK then return ''
44
47
  end
45
48
  end
46
-
47
-
48
- # Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_STRING, Cell.CELL_TYPE_FORMULA,
49
+
50
+ # Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_STRING, Cell.CELL_TYPE_FORMULA,
49
51
  # Cell.CELL_TYPE_BLANK, Cell.CELL_TYPE_BOOLEAN, Cell.CELL_TYPE_ERROR
50
52
 
51
- # TODO - properly
53
+ # TODO: - properly
52
54
  def poi_cell_value(data)
53
- case(data)
55
+ case data
54
56
  when BigDecimal
55
57
  data.to_f
56
58
  when Numeric, TrueClass, FalseClass
57
- data
59
+ data
58
60
  else
59
61
  data.to_s
60
62
  end
61
63
  end
62
-
63
- # Return the suitable type for a HSSFCell from a Ruby data type
64
+
65
+ # Return the suitable type for a HSSFCell from a Ruby data type
64
66
  def poi_cell_type(data)
65
-
66
- if(data.is_a?(Numeric))
67
+
68
+ if data.is_a?(Numeric)
67
69
  HSSFCell::CELL_TYPE_NUMERIC
68
- elsif(data.nil?)
70
+ elsif data.nil?
69
71
  HSSFCell::CELL_TYPE_BLANK
70
- elsif(data.is_a?(TrueClass) || data.is_a?(FalseClass))
72
+ elsif data.is_a?(TrueClass) || data.is_a?(FalseClass)
71
73
  HSSFCell::CELL_TYPE_BOOLEAN
72
74
  else
73
75
  HSSFCell::CELL_TYPE_STRING
@@ -75,5 +77,5 @@ if(DataShift::Guards::jruby?)
75
77
  # HSSFCell::CELL_TYPE_FORMULA
76
78
  end
77
79
  end
78
-
79
- end
80
+
81
+ end
@@ -1,31 +1,33 @@
1
1
  # Copyright:: Autotelik Media Ltd
2
2
  # Author :: Tom Statter
3
3
  # Date :: July 2010
4
- # License::
4
+ # License::
5
5
  #
6
6
  #
7
7
  # Extend the Sporeadsheet classes with some of our common methods
8
- #
8
+ #
9
9
  # ... to do extract into separate module with pure ruby that works with both POI and Spreadsheet
10
10
 
11
11
  require 'excel_base'
12
-
13
- class Spreadsheet::Worksheet
14
-
15
- include ExcelBase
16
-
17
- # Convert array into a header row
18
- def set_headers(headers, apply_style = nil)
19
- return if headers.empty?
20
-
21
- headers.each_with_index do |datum, i|
22
- self[0, i] = datum
12
+
13
+ module Spreadsheet
14
+
15
+ class Worksheet
16
+
17
+ include DataShift::ExcelBase
18
+
19
+ # Convert array into a header row
20
+ def set_headers(headers, _apply_style = nil)
21
+ return if headers.empty?
22
+
23
+ headers.each_with_index do |header, i|
24
+ self[0, i] = header.to_s
25
+ end
23
26
  end
27
+
28
+ def num_rows
29
+ rows.size
30
+ end
31
+
24
32
  end
25
-
26
- def num_rows
27
- rows.size
28
- end
29
-
30
33
  end
31
-
@@ -1,6 +1,6 @@
1
- # Copyright:: (c) Autotelik Media Ltd 2010 - 2012 Tom Statter
1
+ # Copyright:: (c) Autotelik Media Ltd 2010 - 2015 Tom Statter
2
2
  # Author :: Tom Statter
3
- # Date :: Aug 2010
3
+ # Date :: Aug 2015
4
4
  # License:: Free, Open Source.
5
5
  #
6
6
  # Permission is hereby granted, free of charge, to any person obtaining
@@ -22,33 +22,16 @@
22
22
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
23
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24
24
  #++
25
-
26
-
27
- # Details:: Active Record Import/Export for .xls or CSV
28
- #
29
- # To pull DataShift commands into your main application :
30
- #
31
- # require 'datashift'
32
- #
33
- # DataShift::load_commands
34
25
  #
26
+ require_relative 'datashift/guards'
27
+ require_relative 'datashift/logging'
35
28
 
36
- module DataShift
29
+ require 'active_support/core_ext/module/delegation'
37
30
 
38
- def self.gem_version
39
- unless(@gem_version)
40
- if(File.exists?('VERSION'))
41
- File.read( File.join('VERSION') ).match(/.*(\d+.\d+.\d+)/)
42
- @gem_version = $1
43
- else
44
- @gem_version = '1.0.0'
45
- end
46
- end
47
- @gem_version
48
- end
31
+ module DataShift
49
32
 
50
33
  def self.gem_name
51
- "datashift"
34
+ 'datashift'
52
35
  end
53
36
 
54
37
  def self.root_path
@@ -61,31 +44,55 @@ module DataShift
61
44
 
62
45
  def self.require_libraries
63
46
 
64
- loader_libs = %w{ lib }
47
+ loader_libs = %w(lib)
65
48
 
66
49
  # Base search paths - these will be searched recursively
67
50
  loader_paths = []
68
51
 
69
- loader_libs.each {|l| loader_paths << File.join(root_path(), l) }
52
+ loader_libs.each { |l| loader_paths << File.join(root_path, l) }
70
53
 
71
54
  # Define require search paths, any dir in here will be added to LOAD_PATH
72
55
 
73
56
  loader_paths.each do |base|
74
- $:.unshift base if File.directory?(base)
57
+ $LOAD_PATH.unshift base if File.directory?(base)
75
58
  Dir[File.join(base, '**', '**')].each do |p|
76
- if File.directory? p
77
- $:.unshift p
78
- end
59
+ $LOAD_PATH.unshift p if File.directory?(p)
79
60
  end
80
61
  end
81
62
 
82
- require_libs = %w{ datashift loaders generators helpers }
63
+ begin
64
+ require_relative 'datashift/delimiters'
65
+ require_relative 'datashift/load_object'
66
+ require_relative 'generators/generator_base'
67
+ require_relative 'loaders/reporters/reporter'
68
+ require_relative 'loaders/loader_base'
69
+ require_relative 'exporters/exporter_base'
70
+ rescue => x
71
+ puts "Problem initializing gem #{x.inspect}"
72
+ end
73
+
74
+ require_libs = %w(
75
+ datashift/core_ext
76
+ datashift
77
+ datashift/mapping
78
+ datashift/model_methods
79
+ datashift/transformation
80
+ datashift/inbound_data
81
+ loaders
82
+ loaders/reporters
83
+ exporters
84
+ generators
85
+ helpers
86
+ applications
87
+ )
83
88
 
84
89
  require_libs.each do |base|
85
90
  Dir[File.join(library_path, base, '*.rb')].each do |rb|
86
- unless File.directory? rb
87
- #puts rb
88
- require rb
91
+ # puts rb
92
+ begin
93
+ require_relative rb unless File.directory?(rb)
94
+ rescue => x
95
+ puts "Problem loading datashift file #{rb} - #{x.inspect}"
89
96
  end
90
97
  end
91
98
  end
@@ -101,7 +108,7 @@ module DataShift
101
108
 
102
109
  end
103
110
 
104
- # Load all the datashift rake tasks and make them available throughout app
111
+ # Load all the datashift tasks and make them available throughout app
105
112
  def self.load_tasks
106
113
  # Long parameter lists so ensure rake -T produces nice wide output
107
114
  ENV['RAKE_COLUMNS'] = '180'
@@ -109,45 +116,28 @@ module DataShift
109
116
  Dir["#{base}/*.rake"].sort.each { |ext| load ext }
110
117
  end
111
118
 
119
+ # Load all public datashift Thor commands and make them available throughout app
112
120
 
113
- # Load all the datashift Thor commands and make them available throughout app
114
-
115
- def self.load_commands()
116
- base = File.join(library_path, 'thor', '**')
121
+ def self.load_commands
122
+ base = File.join(library_path, 'tasks')
117
123
 
118
124
  Dir["#{base}/*.thor"].each do |f|
119
125
  next unless File.file?(f)
120
- Thor::Util.load_thorfile(f)
126
+ load(f)
121
127
  end
122
128
  end
123
129
 
124
130
  end
125
131
 
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
-
141
- DataShift::require_libraries
142
-
132
+ DataShift.require_libraries
143
133
 
144
134
  module DataShift
145
- if(Guards::jruby?)
135
+ if Guards.jruby?
146
136
  require 'java'
147
137
 
148
138
  class Object
149
139
  def add_to_classpath(path)
150
- $CLASSPATH << File.join( DataShift.root_path, 'lib', path.gsub("\\", "/") )
140
+ $CLASSPATH << File.join( DataShift.root_path, 'lib', path.tr('\\', '/') )
151
141
  end
152
142
  end
153
143
  end
@@ -0,0 +1,217 @@
1
+ # Copyright:: (c) Autotelik Media Ltd 2015
2
+ # Author :: Tom Statter
3
+ # License:: MIT
4
+ #
5
+ # Details:: Binds incoming string headers to domain model's attribute/association.
6
+ #
7
+ # So a binding is a mapping between an Inbound Column and a ModelMethod
8
+ #
9
+ # Example usage, load from a spreadsheet where the column names are only
10
+ # an approximation of the actual associations.
11
+ #
12
+ # Given a column heading of 'Product Properties' on class Product, map_inbound_headers would search
13
+ # the Product AR model, for a matching method or association, in this case would
14
+ # bind this column, 'Product Properties', to the has_many association 'product_properties'.
15
+ #
16
+ # This binding can be used to send spreadsheet row data to populate the product_properties on a product
17
+ #
18
+ # Sometimes there may be no automatic binding available, but you may want to supply a custom method to process
19
+ # that column, in which case the following options may come into play
20
+ #
21
+ # You can specify a list of columns to be bound even if no mapping is found using
22
+ # DataShift::Configuration.force_inclusion_of_columns = []
23
+ #
24
+ # You can force inclusion of all columns despite whether mapping found or not using
25
+ # DataShift::Configuration.include_all = true
26
+ #
27
+ #
28
+ module DataShift
29
+
30
+ class Binder
31
+
32
+ include DataShift::Logging
33
+
34
+ include DataShift::Delimiters
35
+ extend DataShift::Delimiters
36
+
37
+ attr_reader :mapped_class
38
+
39
+ attr_accessor :bindings, :missing_bindings
40
+
41
+ def initialize
42
+ reset
43
+ end
44
+
45
+ def reset
46
+ @bindings = []
47
+ @missing_bindings = []
48
+ end
49
+
50
+ def missing_bindings?
51
+ !missing_bindings.empty?
52
+ end
53
+
54
+ def headers_missing_bindings
55
+ missing_bindings.collect(&:inbound_name)
56
+ end
57
+
58
+ def indexes_missing_bindings
59
+ missing_bindings.collect(&:inbound_index)
60
+ end
61
+
62
+ def forced_inclusion_columns
63
+ [*DataShift::Configuration.call.force_inclusion_of_columns]
64
+ end
65
+
66
+ def forced
67
+ forced_inclusion_columns.compact.collect { |f| f.to_s.downcase }
68
+ end
69
+
70
+ def forced?(column_name)
71
+ forced.include?(column_name.to_s.downcase)
72
+ end
73
+
74
+ def include_all?
75
+ DataShift::Configuration.call.include_all_columns == true
76
+ end
77
+
78
+ # Build complete picture of the methods whose names listed in columns
79
+ # Handles method names as defined by a user, from spreadsheets or file headers where the names
80
+ # specified may not be exactly as required e.g handles capitalisation, white space, _ etc
81
+ #
82
+ # The header can also contain the fields to use in lookups, separated with Delimiters ::column_delim
83
+ # For example specify that lookups on has_one association called 'product', be performed using name'
84
+ # product:name
85
+ #
86
+ # The header can also contain a default value for the lookup field, again separated with Delimiters ::column_delim
87
+ #
88
+ # For example specify lookups on assoc called 'user', be performed using 'email' == 'test@blah.com'
89
+ #
90
+ # user:email:test@blah.com
91
+ #
92
+ # Returns: Array of matching method_details, including nils for non matched items
93
+ #
94
+ # N.B Columns that could not be mapped are left in the array as NIL
95
+ #
96
+ # This is to support clients that need to map via the index on @method_details
97
+ #
98
+ # Other callers can simply call compact on the results if the index not important.
99
+ #
100
+ # The MethodDetails instance will contain a pointer to the column index from which it was mapped.
101
+ #
102
+ def map_inbound_headers(klass, columns)
103
+
104
+ @mapped_class = klass
105
+
106
+ # If klass not in Dictionary yet, add to dictionary all possible operators on klass
107
+ # which can be used to map headers and populate an object of type klass
108
+ model_method_mgr = ModelMethods::Manager.catalog_class(klass)
109
+
110
+ reset
111
+
112
+ [*columns].each_with_index do |col_data, col_index|
113
+ raw_col_data = col_data.to_s
114
+
115
+ if raw_col_data.nil? || raw_col_data.empty?
116
+ logger.warn("Column list contains empty or null header at index #{col_index}")
117
+ bindings << NoMethodBinding.new(raw_col_data, col_index)
118
+ next
119
+ end
120
+
121
+ # Header DSL Name::Where::Value:Misc
122
+
123
+ raw_col_name, where_field, where_value, *data = raw_col_data.split(column_delim)
124
+
125
+ # Find the domain model method details
126
+ model_method = model_method_mgr.search(raw_col_name)
127
+
128
+ # if not found via raw name, try various alternatives
129
+
130
+ if( model_method.nil? && (include_all? || forced?(raw_col_name)) )
131
+ logger.debug("Operator #{raw_col_name} not found but forced inclusion set - adding as :method")
132
+ model_method = model_method_mgr.insert(raw_col_name, :method)
133
+ end
134
+
135
+ unless model_method
136
+ Binder.substitutions(raw_col_name).each do |n|
137
+ model_method = model_method_mgr.search(n)
138
+ break if model_method
139
+ end
140
+ end
141
+
142
+ if(model_method)
143
+
144
+ binding = MethodBinding.new(raw_col_name, col_index, model_method)
145
+
146
+ # we slurped up all possible data in split, turn it back into original string
147
+ binding.add_column_data(data.join(column_delim))
148
+
149
+ if where_field
150
+ logger.info("Lookup query field [#{where_field}] - specified for association #{model_method.operator}")
151
+
152
+ begin
153
+ binding.add_lookup(model_method, where_field, where_value)
154
+ rescue
155
+ add_missing(raw_col_data, col_index,
156
+ "Field [#{where_field}] Not Found for [#{raw_col_name}] (#{model_method.operator})")
157
+ next
158
+ end
159
+
160
+ end
161
+
162
+ logger.debug("Column [#{col_data}] (#{col_index}) - mapped to :\n#{model_method.pp}")
163
+
164
+ bindings << binding
165
+
166
+ else
167
+ logger.debug("No operator or association found for Header [#{raw_col_name}]")
168
+
169
+ add_missing(raw_col_data, col_index, "No operator or association found for Header [#{raw_col_name}]")
170
+ end
171
+ end
172
+
173
+ bindings
174
+ end
175
+
176
+ # Essentially we map any string collection of field names, not just headers from files
177
+ alias map_inbound_fields map_inbound_headers
178
+
179
+ def add_missing(col_data, col_index, reason)
180
+ logger.warn(reason)
181
+
182
+ missing = NoMethodBinding.new(col_data, col_index, reason: reason)
183
+
184
+ missing_bindings << missing
185
+ bindings << missing
186
+ end
187
+
188
+ # TODO: - check out regexp to do this work better plus Inflections ??
189
+ # Want to be able to handle any of ["Count On hand", 'count_on_hand', "Count OnHand", "COUNT ONHand" etc]
190
+ def self.substitutions(external_name)
191
+ name = external_name.to_s
192
+
193
+ [
194
+ name.downcase,
195
+ name.tableize,
196
+ name.tr(' ', '_'),
197
+ name.tr(' ', '_').downcase,
198
+ name.gsub(/(\s+)/, '_').downcase,
199
+ name.delete(' '),
200
+ name.delete(' ').downcase,
201
+ name.tr(' ', '_').underscore
202
+ ]
203
+ end
204
+
205
+ # The raw client supplied names
206
+ def method_names
207
+ bindings.collect( &:inbound_name )
208
+ end
209
+
210
+ # The true operator names discovered from model
211
+ def operator_names
212
+ bindings.collect( &:operator )
213
+ end
214
+
215
+ end
216
+
217
+ end