datashift 0.16.0 → 0.40.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{LICENSE.txt → LICENSE} +0 -0
- data/Rakefile +1 -20
- data/datashift.thor +125 -0
- data/lib/applications/apache_poi_extensions.rb +21 -52
- data/lib/applications/excel.rb +64 -57
- data/lib/applications/hssf_row_extensions.rb +66 -0
- data/lib/applications/jexcel_file.rb +99 -95
- data/lib/applications/jexcel_file_extensions.rb +76 -83
- data/lib/applications/jruby/word.rb +36 -36
- data/lib/applications/ruby_poi_translations.rb +34 -32
- data/lib/applications/spreadsheet_extensions.rb +21 -19
- data/lib/datashift.rb +49 -59
- data/lib/datashift/binder.rb +217 -0
- data/lib/datashift/column_packer.rb +21 -72
- data/lib/datashift/configuration.rb +317 -0
- data/lib/datashift/context_factory.rb +88 -0
- data/lib/datashift/core_ext/array.rb +15 -0
- data/lib/datashift/core_ext/csv_ext.rb +46 -0
- data/lib/datashift/core_ext/string.rb +49 -0
- data/lib/datashift/core_ext/to_b.rb +11 -0
- data/lib/datashift/delimiters.rb +55 -61
- data/lib/datashift/doc_context.rb +137 -0
- data/lib/datashift/excel_base.rb +93 -81
- data/lib/datashift/exceptions.rb +30 -28
- data/lib/datashift/file_definitions.rb +44 -39
- data/lib/datashift/guards.rb +5 -5
- data/lib/datashift/header.rb +25 -0
- data/lib/datashift/headers.rb +94 -0
- data/lib/datashift/inbound_data/column.rb +44 -0
- data/lib/datashift/inbound_data/lookup_support.rb +33 -0
- data/lib/datashift/inbound_data/method_binding.rb +139 -0
- data/lib/datashift/load_object.rb +37 -12
- data/lib/datashift/logging.rb +54 -27
- data/lib/datashift/mandatory.rb +39 -0
- data/lib/datashift/mapping/data_flow_schema.rb +198 -0
- data/lib/datashift/{model_mapper.rb → mapping/mapper_utils.rb} +30 -10
- data/lib/datashift/model_methods/catalogue.rb +183 -0
- data/lib/datashift/model_methods/collection.rb +140 -0
- data/lib/datashift/model_methods/model_method.rb +162 -0
- data/lib/datashift/model_methods/model_methods_manager.rb +76 -0
- data/lib/datashift/model_methods/operator.rb +62 -0
- data/lib/datashift/node_collection.rb +26 -0
- data/lib/datashift/node_context.rb +68 -0
- data/lib/datashift/populator.rb +308 -282
- data/lib/datashift/progress_monitor.rb +91 -0
- data/lib/datashift/querying.rb +110 -52
- data/lib/datashift/templates/import_export_config.erb +55 -0
- data/lib/datashift/transformation/factory.rb +219 -0
- data/lib/datashift/transformation/remove.rb +44 -0
- data/lib/datashift/version.rb +3 -0
- data/lib/exporters/configuration.rb +84 -0
- data/lib/exporters/csv_exporter.rb +54 -52
- data/lib/exporters/excel_exporter.rb +80 -61
- data/lib/exporters/exporter_base.rb +8 -8
- data/lib/generators/config_generator.rb +218 -0
- data/lib/generators/csv_generator.rb +13 -70
- data/lib/generators/excel_generator.rb +23 -111
- data/lib/generators/generator_base.rb +15 -70
- data/lib/loaders/configuration.rb +90 -0
- data/lib/loaders/csv_loader.rb +63 -101
- data/lib/loaders/excel_loader.rb +71 -156
- data/lib/loaders/failure_data.rb +40 -0
- data/lib/loaders/file_loader.rb +16 -0
- data/lib/loaders/loader_base.rb +82 -410
- data/lib/loaders/loader_factory.rb +42 -0
- data/lib/loaders/paperclip/attachment_loader.rb +157 -140
- data/lib/loaders/paperclip/datashift_paperclip.rb +18 -35
- data/lib/loaders/paperclip/image_loading.rb +40 -35
- data/lib/loaders/reporters/basic_stdout_reporter.rb +40 -0
- data/lib/loaders/reporters/reporter.rb +26 -0
- data/lib/tasks/config.thor +65 -0
- data/{tasks → lib/tasks}/config/seed_fu_product_template.erb +0 -0
- data/{tasks → lib/tasks}/config/tidy_config.txt +0 -0
- data/lib/tasks/export.thor +192 -0
- data/lib/tasks/generate.thor +190 -0
- data/lib/tasks/import.thor +142 -0
- data/lib/{thor → tasks}/paperclip.thor +69 -69
- data/{tasks → lib/tasks/to_convert_to_thor}/db_tasks.rake +20 -20
- data/lib/tasks/tools.thor +109 -0
- data/spec/MissingAttachmentRecords/DEMO_001_ror_bag.jpeg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_002_Powerstation.jpeg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/MissingAttachmentRecords/DEMO_004_ror_ringer.jpeg +0 -0
- data/spec/datashift/binder_spec.rb +266 -0
- data/spec/datashift/config_generator_spec.rb +186 -0
- data/spec/datashift/configuration.rb +66 -0
- data/spec/datashift/context_factory_spec.rb +63 -0
- data/spec/datashift/data_flow_schema_spec.rb +150 -0
- data/spec/datashift/datashift_spec.rb +52 -0
- data/spec/datashift/excel_base_spec.rb +57 -0
- data/spec/datashift/excel_spec.rb +188 -0
- data/spec/datashift/failure_data_spec.rb +27 -0
- data/spec/{file_definitions.rb → datashift/file_definitions.rb} +9 -10
- data/spec/datashift/headers_spec.rb +56 -0
- data/spec/datashift/inbound_data_spec.rb +47 -0
- data/spec/datashift/mapper_utils_spec.rb +38 -0
- data/spec/datashift/method_binding_spec.rb +60 -0
- data/spec/datashift/model_method_spec.rb +109 -0
- data/spec/datashift/model_methods_catalogue.rb +111 -0
- data/spec/datashift/model_methods_collection_spec.rb +138 -0
- data/spec/datashift/model_methods_manager_spec.rb +329 -0
- data/spec/datashift/populator_spec.rb +117 -0
- data/spec/datashift/thor_spec.rb +314 -0
- data/spec/datashift/transformation/factory_spec.rb +195 -0
- data/spec/datashift/transformation/transformer_remove_spec.rb +43 -0
- data/spec/dummy/Gemfile +53 -0
- data/spec/dummy/Gemfile.lock +197 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +16 -0
- data/spec/dummy/app/assets/javascripts/categories.js +2 -0
- data/spec/dummy/app/assets/javascripts/digitals.js +2 -0
- data/spec/dummy/app/assets/javascripts/empties.js +2 -0
- data/spec/dummy/app/assets/javascripts/loader_releases.js +2 -0
- data/spec/dummy/app/assets/javascripts/long_and_complex_table_linked_to_versions.js +2 -0
- data/spec/dummy/app/assets/javascripts/milestones.js +2 -0
- data/spec/dummy/app/assets/javascripts/owners.js +2 -0
- data/spec/dummy/app/assets/javascripts/projects.js +2 -0
- data/spec/dummy/app/assets/javascripts/users.js +2 -0
- data/spec/dummy/app/assets/javascripts/versions.js +2 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/assets/stylesheets/categories.css +4 -0
- data/spec/dummy/app/assets/stylesheets/digitals.css +4 -0
- data/spec/dummy/app/assets/stylesheets/empties.css +4 -0
- data/spec/dummy/app/assets/stylesheets/loader_releases.css +4 -0
- data/spec/dummy/app/assets/stylesheets/long_and_complex_table_linked_to_versions.css +4 -0
- data/spec/dummy/app/assets/stylesheets/milestones.css +4 -0
- data/spec/dummy/app/assets/stylesheets/owners.css +4 -0
- data/spec/dummy/app/assets/stylesheets/projects.css +4 -0
- data/spec/dummy/app/assets/stylesheets/scaffold.css +56 -0
- data/spec/dummy/app/assets/stylesheets/users.css +4 -0
- data/spec/dummy/app/assets/stylesheets/versions.css +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/categories_controller.rb +58 -0
- data/spec/dummy/app/controllers/digitals_controller.rb +58 -0
- data/spec/dummy/app/controllers/empties_controller.rb +58 -0
- data/spec/dummy/app/controllers/loader_releases_controller.rb +58 -0
- data/spec/dummy/app/controllers/long_and_complex_table_linked_to_versions_controller.rb +58 -0
- data/spec/dummy/app/controllers/milestones_controller.rb +58 -0
- data/spec/dummy/app/controllers/owners_controller.rb +58 -0
- data/spec/dummy/app/controllers/projects_controller.rb +58 -0
- data/spec/dummy/app/controllers/users_controller.rb +58 -0
- data/spec/dummy/app/controllers/versions_controller.rb +58 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/categories_helper.rb +2 -0
- data/spec/dummy/app/helpers/digitals_helper.rb +2 -0
- data/spec/dummy/app/helpers/empties_helper.rb +2 -0
- data/spec/dummy/app/helpers/loader_releases_helper.rb +2 -0
- data/spec/dummy/app/helpers/long_and_complex_table_linked_to_versions_helper.rb +2 -0
- data/spec/dummy/app/helpers/milestones_helper.rb +2 -0
- data/spec/dummy/app/helpers/owners_helper.rb +2 -0
- data/spec/dummy/app/helpers/projects_helper.rb +2 -0
- data/spec/dummy/app/helpers/users_helper.rb +2 -0
- data/spec/dummy/app/helpers/versions_helper.rb +2 -0
- data/spec/dummy/app/models/category.rb +6 -0
- data/spec/dummy/app/models/digital.rb +22 -0
- data/spec/dummy/app/models/empty.rb +2 -0
- data/spec/dummy/app/models/loader_release.rb +10 -0
- data/spec/dummy/app/models/long_and_complex_table_linked_to_version.rb +6 -0
- data/spec/dummy/app/models/milestone.rb +15 -0
- data/spec/dummy/app/models/owner.rb +13 -0
- data/spec/dummy/app/models/project.rb +53 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/models/version.rb +7 -0
- data/spec/dummy/app/views/categories/_form.html.erb +17 -0
- data/spec/dummy/app/views/categories/edit.html.erb +6 -0
- data/spec/dummy/app/views/categories/index.html.erb +25 -0
- data/spec/dummy/app/views/categories/new.html.erb +5 -0
- data/spec/dummy/app/views/categories/show.html.erb +4 -0
- data/spec/dummy/app/views/digitals/_form.html.erb +17 -0
- data/spec/dummy/app/views/digitals/edit.html.erb +6 -0
- data/spec/dummy/app/views/digitals/index.html.erb +25 -0
- data/spec/dummy/app/views/digitals/new.html.erb +5 -0
- data/spec/dummy/app/views/digitals/show.html.erb +4 -0
- data/spec/dummy/app/views/empties/_form.html.erb +17 -0
- data/spec/dummy/app/views/empties/edit.html.erb +6 -0
- data/spec/dummy/app/views/empties/index.html.erb +25 -0
- data/spec/dummy/app/views/empties/new.html.erb +5 -0
- data/spec/dummy/app/views/empties/show.html.erb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/loader_releases/_form.html.erb +17 -0
- data/spec/dummy/app/views/loader_releases/edit.html.erb +6 -0
- data/spec/dummy/app/views/loader_releases/index.html.erb +25 -0
- data/spec/dummy/app/views/loader_releases/new.html.erb +5 -0
- data/spec/dummy/app/views/loader_releases/show.html.erb +4 -0
- data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/_form.html.erb +17 -0
- data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/edit.html.erb +6 -0
- data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/index.html.erb +25 -0
- data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/new.html.erb +5 -0
- data/spec/dummy/app/views/long_and_complex_table_linked_to_versions/show.html.erb +4 -0
- data/spec/dummy/app/views/milestones/_form.html.erb +17 -0
- data/spec/dummy/app/views/milestones/edit.html.erb +6 -0
- data/spec/dummy/app/views/milestones/index.html.erb +25 -0
- data/spec/dummy/app/views/milestones/new.html.erb +5 -0
- data/spec/dummy/app/views/milestones/show.html.erb +4 -0
- data/spec/dummy/app/views/owners/_form.html.erb +17 -0
- data/spec/dummy/app/views/owners/edit.html.erb +6 -0
- data/spec/dummy/app/views/owners/index.html.erb +25 -0
- data/spec/dummy/app/views/owners/new.html.erb +5 -0
- data/spec/dummy/app/views/owners/show.html.erb +4 -0
- data/spec/dummy/app/views/projects/_form.html.erb +17 -0
- data/spec/dummy/app/views/projects/edit.html.erb +6 -0
- data/spec/dummy/app/views/projects/index.html.erb +25 -0
- data/spec/dummy/app/views/projects/new.html.erb +5 -0
- data/spec/dummy/app/views/projects/show.html.erb +4 -0
- data/spec/dummy/app/views/users/_form.html.erb +17 -0
- data/spec/dummy/app/views/users/edit.html.erb +6 -0
- data/spec/dummy/app/views/users/index.html.erb +25 -0
- data/spec/dummy/app/views/users/new.html.erb +5 -0
- data/spec/dummy/app/views/users/show.html.erb +4 -0
- data/spec/dummy/app/views/versions/_form.html.erb +17 -0
- data/spec/dummy/app/views/versions/edit.html.erb +6 -0
- data/spec/dummy/app/views/versions/index.html.erb +25 -0
- data/spec/dummy/app/views/versions/new.html.erb +5 -0
- data/spec/dummy/app/views/versions/show.html.erb +4 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +9 -0
- data/spec/dummy/bin/rake +9 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/bin/spring +16 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +3 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +76 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20110803201325_create_test_bed.rb +98 -0
- data/spec/dummy/db/migrate/20121009161700_add_digitals.rb +24 -0
- data/spec/dummy/db/migrate/20161005123106_create_digitals.rb +8 -0
- data/spec/dummy/db/migrate/20161005123106_create_long_and_complex_table_linked_to_versions.rb +8 -0
- data/spec/dummy/db/migrate/20161005123107_create_loader_releases.rb +8 -0
- data/spec/dummy/db/migrate/20161005123108_create_owners.rb +8 -0
- data/spec/dummy/db/migrate/20161005123109_create_empties.rb +8 -0
- data/spec/dummy/db/migrate/20161005123110_create_projects.rb +8 -0
- data/spec/dummy/db/migrate/20161005123111_create_users.rb +8 -0
- data/spec/dummy/db/migrate/20161005123111_create_versions.rb +8 -0
- data/spec/dummy/db/migrate/20161005123112_create_milestones.rb +8 -0
- data/spec/dummy/db/migrate/20161005123113_create_categories.rb +8 -0
- data/spec/dummy/db/schema.rb +93 -0
- data/spec/dummy/db/seeds.rb +9 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +69 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/robots.txt +5 -0
- data/spec/dummy/sandbox_example.thor +4 -0
- data/spec/dummy/test/controllers/categories_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/digitals_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/empties_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/loader_releases_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/long_and_complex_table_linked_to_versions_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/milestones_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/owners_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/projects_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/users_controller_test.rb +49 -0
- data/spec/dummy/test/controllers/versions_controller_test.rb +49 -0
- data/spec/dummy/test/factories/categories.rb +5 -0
- data/spec/dummy/test/factories/digitals.rb +5 -0
- data/spec/dummy/test/factories/empties.rb +5 -0
- data/spec/dummy/test/factories/loader_releases.rb +5 -0
- data/spec/dummy/test/factories/long_and_complex_table_linked_to_versions.rb +5 -0
- data/spec/dummy/test/factories/milestones.rb +5 -0
- data/spec/dummy/test/factories/owners.rb +5 -0
- data/spec/dummy/test/factories/projects.rb +5 -0
- data/spec/dummy/test/factories/users.rb +5 -0
- data/spec/dummy/test/factories/versions.rb +5 -0
- data/spec/dummy/test/models/category_test.rb +7 -0
- data/spec/dummy/test/models/digital_test.rb +7 -0
- data/spec/dummy/test/models/empty_test.rb +7 -0
- data/spec/dummy/test/models/loader_release_test.rb +7 -0
- data/spec/dummy/test/models/long_and_complex_table_linked_to_version_test.rb +7 -0
- data/spec/dummy/test/models/milestone_test.rb +7 -0
- data/spec/dummy/test/models/owner_test.rb +7 -0
- data/spec/dummy/test/models/project_test.rb +7 -0
- data/spec/dummy/test/models/user_test.rb +7 -0
- data/spec/dummy/test/models/version_test.rb +7 -0
- data/spec/dummy/test/test_helper.rb +10 -0
- data/spec/exporters/csv_exporter_spec.rb +240 -0
- data/spec/exporters/csv_generator_spec.rb +139 -0
- data/spec/exporters/excel_exporter_spec.rb +193 -0
- data/spec/exporters/excel_generator_spec.rb +181 -0
- data/spec/exporters/generator_base_spec.rb +45 -0
- data/spec/factories/categories.rb +7 -0
- data/spec/factories/factories.rb +18 -0
- data/spec/factories/milestone.rb +16 -0
- data/spec/factories/projects.rb +41 -0
- data/spec/fixtures/BadAssociationName.xls +0 -0
- data/spec/fixtures/DemoNegativeTesting.xls +0 -0
- data/spec/fixtures/ProjectConfiguration.yml +18 -0
- data/spec/fixtures/ProjectsMultiCategories.xls +0 -0
- data/spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls +0 -0
- data/spec/fixtures/ProjectsSingleCategories.xls +0 -0
- data/spec/fixtures/ProjectsSingleCategories.xlsx +0 -0
- data/spec/fixtures/SimpleProjects.xls +0 -0
- data/spec/fixtures/config/database.yml +28 -0
- data/spec/fixtures/csv/BadAssociationName.csv +6 -0
- data/spec/fixtures/csv/DemoNegativeTesting.csv +6 -0
- data/spec/fixtures/csv/ProjectsMultiCategories.csv +5 -0
- data/spec/fixtures/csv/ProjectsMultiCategoriesHeaderLookup.csv +5 -0
- data/spec/fixtures/csv/ProjectsSingleCategories.csv +5 -0
- data/spec/fixtures/csv/SimpleProjects.csv +4 -0
- data/spec/fixtures/db/migrate/20110803201325_create_test_bed.rb +98 -0
- data/spec/fixtures/db/migrate/20121009161700_add_digitals.rb +24 -0
- data/spec/fixtures/db/seeds.rb +9 -0
- data/spec/fixtures/images/DEMO_001_ror_bag.jpeg +0 -0
- data/spec/fixtures/images/DEMO_002_Powerstation.jpeg +0 -0
- data/spec/fixtures/images/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/fixtures/images/DEMO_004_ror_ringer.jpeg +0 -0
- data/spec/fixtures/load_datashift.thor +3 -0
- data/spec/fixtures/models/category.rb +6 -0
- data/spec/fixtures/models/digital.rb +22 -0
- data/spec/fixtures/models/empty.rb +2 -0
- data/spec/fixtures/models/loader_release.rb +10 -0
- data/spec/fixtures/models/long_and_complex_table_linked_to_version.rb +6 -0
- data/spec/fixtures/models/milestone.rb +15 -0
- data/spec/fixtures/models/owner.rb +13 -0
- data/spec/fixtures/models/project.rb +53 -0
- data/spec/fixtures/models/user.rb +5 -0
- data/spec/fixtures/models/version.rb +7 -0
- data/spec/fixtures/results/exp_project_assoc_headers.xls +0 -0
- data/spec/fixtures/results/exp_project_collection_spec.csv +2 -0
- data/spec/fixtures/results/exp_project_export.xls +0 -0
- data/spec/fixtures/results/exp_project_first_export.xls +0 -0
- data/spec/fixtures/results/exp_project_plus_assoc.xls +0 -0
- data/spec/fixtures/results/exp_project_plus_assoc_export_spec.csv +9 -0
- data/spec/fixtures/results/gen_project_plus_assoc_template.xls +0 -0
- data/spec/fixtures/results/gen_project_plus_some_assoc_template.xls +0 -0
- data/spec/fixtures/results/gen_project_template.xls +0 -0
- data/spec/fixtures/results/project_and_assoc_in_hash_export.xls +0 -0
- data/spec/fixtures/results/project_and_assoc_in_json_export.csv +9 -0
- data/spec/fixtures/results/project_and_assoc_in_json_export.xls +0 -0
- data/spec/fixtures/results/project_export_spec_with_custom_delim_,.csv +2 -0
- data/spec/fixtures/results/project_export_spec_with_custom_delim_/302/243.csv +2 -0
- data/spec/fixtures/results/project_export_spec_with_custom_delim_/302/247.csv +2 -0
- data/spec/fixtures/results/project_plus_assoc_template.csv +1 -0
- data/spec/fixtures/results/project_plus_some_assoc_template.csv +1 -0
- data/spec/fixtures/results/project_remove_export_spec.csv +2 -0
- data/spec/fixtures/results/project_template.csv +1 -0
- data/spec/fixtures/results/project_with_methods_export_spec.csv +2 -0
- data/spec/fixtures/results/thor_spec_gen_project.csv +1 -0
- data/spec/fixtures/sandbox_example.thor +4 -0
- data/spec/fixtures/simple_export_spec.xls +0 -0
- data/spec/fixtures/simple_template_spec.xls +0 -0
- data/spec/fixtures/test_model_defs.rb +7 -0
- data/spec/loaders/csv_loader_spec.rb +206 -0
- data/spec/loaders/data_flow_excel_loader_spec.rb +290 -0
- data/spec/loaders/excel_loader_failures_spec.rb +67 -0
- data/spec/loaders/excel_loader_spec.rb +294 -0
- data/spec/loaders/loader_base_spec.rb +29 -0
- data/spec/loaders/paperclip_loader_spec.rb +106 -0
- data/spec/log/datashift.log +14930 -0
- data/spec/private/digitals/1/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/private/digitals/2/DEMO_002_Powerstation.jpeg +0 -0
- data/spec/private/digitals/3/DEMO_004_ror_ringer.jpeg +0 -0
- data/spec/private/digitals/4/DEMO_001_ror_bag.jpeg +0 -0
- data/spec/spec_helper.rb +26 -230
- data/spec/support/clear_and_manage_contexts.rb +25 -0
- data/spec/support/database_cleaner.rb +32 -0
- data/spec/support/datashift_test_helpers.rb +153 -0
- data/spec/support/files_paths_helper.rb +13 -0
- data/spec/support/fixtures/results/mapping_template.yaml +15 -0
- data/spec/support/sandbox.rb +136 -0
- metadata +804 -85
- data/README.markdown +0 -274
- data/README.rdoc +0 -19
- data/VERSION +0 -1
- data/datashift.gemspec +0 -48
- data/lib/applications/jruby/old_pre_proxy_jexcel_file.rb +0 -437
- data/lib/datashift/data_transforms.rb +0 -83
- data/lib/datashift/mapping_file_definitions.rb +0 -88
- data/lib/datashift/mapping_service.rb +0 -91
- data/lib/datashift/method_detail.rb +0 -165
- data/lib/datashift/method_details_manager.rb +0 -95
- data/lib/datashift/method_dictionary.rb +0 -281
- data/lib/datashift/method_mapper.rb +0 -174
- data/lib/datashift/thor_base.rb +0 -38
- data/lib/generators/mapping_generator.rb +0 -112
- data/lib/helpers/core_ext/csv_file.rb +0 -33
- data/lib/helpers/core_ext/to_b.rb +0 -24
- data/lib/loaders/reporter.rb +0 -58
- data/lib/thor/export.thor +0 -175
- data/lib/thor/generate.thor +0 -191
- data/lib/thor/import.thor +0 -110
- data/lib/thor/mapping.thor +0 -65
- data/lib/thor/tools.thor +0 -84
- data/spec/Gemfile +0 -31
- data/spec/Gemfile.lock +0 -134
- data/spec/csv_exporter_spec.rb +0 -144
- data/spec/csv_generator_spec.rb +0 -159
- data/spec/csv_loader_spec.rb +0 -212
- data/spec/datashift_spec.rb +0 -55
- data/spec/excel_exporter_spec.rb +0 -199
- data/spec/excel_generator_spec.rb +0 -203
- data/spec/excel_loader_spec.rb +0 -237
- data/spec/excel_spec.rb +0 -203
- data/spec/loader_base_spec.rb +0 -166
- data/spec/mapping_spec.rb +0 -117
- data/spec/method_dictionary_spec.rb +0 -300
- data/spec/method_mapper_spec.rb +0 -100
- data/spec/model_mapper_spec.rb +0 -41
- data/spec/paperclip_loader_spec.rb +0 -92
- data/spec/populator_spec.rb +0 -128
- data/spec/thor_spec.rb +0 -90
- data/tasks/file_tasks.rake +0 -37
- data/tasks/word_to_seedfu.rake +0 -167
@@ -0,0 +1,68 @@
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2016
|
2
|
+
# Author :: Tom Statter
|
3
|
+
# Date :: Aug 2016
|
4
|
+
# License:: MIT
|
5
|
+
#
|
6
|
+
# Details:: Holds the current context - the node we are dealing with
|
7
|
+
# so requires the Inbound Column details, the associated ModelMethod
|
8
|
+
# and the row node containing the actual data to apply via the model method operator
|
9
|
+
#
|
10
|
+
|
11
|
+
module DataShift
|
12
|
+
|
13
|
+
class NodeContext
|
14
|
+
|
15
|
+
include DataShift::Logging
|
16
|
+
|
17
|
+
attr_accessor :doc_context, :method_binding, :row_index
|
18
|
+
|
19
|
+
attr_accessor :populator
|
20
|
+
|
21
|
+
attr_reader :data
|
22
|
+
|
23
|
+
def initialize(doc_context, method_binding, row_idx, data)
|
24
|
+
@doc_context = doc_context
|
25
|
+
@method_binding = method_binding
|
26
|
+
@row_index = row_idx
|
27
|
+
@data = data
|
28
|
+
|
29
|
+
@populator = ContextFactory.get_populator(method_binding)
|
30
|
+
end
|
31
|
+
|
32
|
+
delegate :model_method, :operator, to: :method_binding
|
33
|
+
|
34
|
+
def contains_data?
|
35
|
+
!(data.nil? || data.to_s.empty?)
|
36
|
+
end
|
37
|
+
|
38
|
+
def next_update?
|
39
|
+
false # for now create only
|
40
|
+
# TODO : Support UPDATES
|
41
|
+
# next = ProcessingRules.next_action(method_binding )
|
42
|
+
# next == :update
|
43
|
+
end
|
44
|
+
|
45
|
+
def process
|
46
|
+
populator.prepare_and_assign(self, doc_context.load_object, data)
|
47
|
+
rescue => x
|
48
|
+
|
49
|
+
failed = FailureData.new( doc_context.load_object, self, x.message)
|
50
|
+
|
51
|
+
failed.error_messages << "Failed to process node : #{method_binding.pp}"
|
52
|
+
|
53
|
+
doc_context.progress_monitor.failure(failed)
|
54
|
+
|
55
|
+
logger.error("#{x.backtrace.first} : #{x.message}")
|
56
|
+
raise x
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
class EmptyContext < NodeContext
|
62
|
+
|
63
|
+
def initialize
|
64
|
+
super(NilClass, DataShift::NoMethodBinding.new, -1, [])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
data/lib/datashift/populator.rb
CHANGED
@@ -4,24 +4,23 @@
|
|
4
4
|
# License:: MIT
|
5
5
|
#
|
6
6
|
# Details:: The default Populator class for assigning data to models
|
7
|
-
#
|
7
|
+
#
|
8
8
|
# Provides individual population methods on an AR model.
|
9
9
|
#
|
10
10
|
# Enables users to assign values to AR object, without knowing much about that receiving object.
|
11
11
|
#
|
12
|
-
require 'to_b'
|
13
|
-
require 'logging'
|
14
|
-
|
15
12
|
module DataShift
|
16
13
|
|
17
|
-
Struct.new("Substitution", :pattern, :replacement)
|
18
|
-
|
19
14
|
class Populator
|
20
15
|
|
21
16
|
include DataShift::Logging
|
17
|
+
extend DataShift::Logging
|
18
|
+
|
19
|
+
include DataShift::Delimiters
|
20
|
+
extend DataShift::Delimiters
|
22
21
|
|
23
22
|
def self.insistent_method_list
|
24
|
-
@insistent_method_list ||= [:to_s, :to_i, :to_f, :to_b]
|
23
|
+
@insistent_method_list ||= [:to_s, :downcase, :to_i, :to_f, :to_b]
|
25
24
|
end
|
26
25
|
|
27
26
|
# When looking up an association, when no field provided, try each of these in turn till a match
|
@@ -30,211 +29,215 @@ module DataShift
|
|
30
29
|
@insistent_find_by_list ||= [:name, :title, :id]
|
31
30
|
end
|
32
31
|
|
32
|
+
attr_reader :value, :attribute_hash
|
33
33
|
|
34
|
-
|
35
|
-
# to teh whole column - hence class methods
|
36
|
-
def self.set_header_default_data(operator, data )
|
37
|
-
header_default_data[operator] = data
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.header_default_data
|
41
|
-
@header_default_data ||= {}
|
42
|
-
end
|
34
|
+
attr_accessor :previous_value, :original_data
|
43
35
|
|
36
|
+
def initialize(transformer = nil)
|
37
|
+
# reset
|
38
|
+
@transformer = transformer || Transformation.factory
|
44
39
|
|
45
|
-
|
46
|
-
|
40
|
+
@attribute_hash = {}
|
41
|
+
end
|
47
42
|
|
48
|
-
|
49
|
-
attr_reader :current_method_detail
|
43
|
+
# Main client hooks :
|
50
44
|
|
51
|
-
|
52
|
-
@current_value = nil
|
53
|
-
@current_method_detail = nil
|
54
|
-
@original_value_before_override = nil
|
55
|
-
@current_attribute_hash = {}
|
45
|
+
# Prepare the data to be populated, then assign to the Db record
|
56
46
|
|
47
|
+
def prepare_and_assign(context, record, data)
|
48
|
+
prepare_and_assign_method_binding(context.method_binding, record, data)
|
57
49
|
end
|
58
50
|
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
62
|
-
# "{:name => 'autechre'}" => Hash['name'] = autechre'
|
63
|
-
# "{:cost_price => '13.45', :price => 23, :sale_price => 4.23 }"
|
51
|
+
# This is the most pertinent hook for derived Processors, where you can provide custom
|
52
|
+
# population messages for specific Method bindings
|
64
53
|
|
65
|
-
def
|
66
|
-
|
67
|
-
str.gsub(/[{}:]/,'').split(', ').map do |e|
|
68
|
-
k,v = e.split('=>')
|
54
|
+
def prepare_and_assign_method_binding(method_binding, record, data)
|
55
|
+
prepare_data(method_binding, data)
|
69
56
|
|
70
|
-
|
71
|
-
|
57
|
+
assign(method_binding, record)
|
58
|
+
end
|
72
59
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
60
|
+
def reset
|
61
|
+
@value = nil
|
62
|
+
@previous_value = nil
|
63
|
+
@original_data = nil
|
64
|
+
@attribute_hash = {}
|
65
|
+
end
|
66
|
+
|
67
|
+
def value?
|
68
|
+
!value.nil?
|
69
|
+
end
|
82
70
|
|
83
|
-
|
71
|
+
def self.attribute_hash_const_regexp
|
72
|
+
@attribute_hash_const_regexp ||= Regexp.new( attribute_list_start + '.*' + attribute_list_end)
|
84
73
|
end
|
85
74
|
|
86
|
-
# Set member variables to hold details, value and optional attributes,
|
87
|
-
# to be set on the 'value' once created
|
88
|
-
#
|
89
75
|
# Check supplied value, validate it, and if required :
|
90
76
|
# set to provided default value
|
91
|
-
# prepend any provided prefixes
|
77
|
+
# prepend any provided prefixes
|
92
78
|
# add any provided postfixes
|
93
|
-
|
79
|
+
#
|
80
|
+
# Rtns : tuple of [:value, :attribute_hash]
|
81
|
+
#
|
82
|
+
def prepare_data(method_binding, data)
|
83
|
+
|
84
|
+
connection_adapter_column = method_binding.model_method.connection_adapter_column
|
85
|
+
|
94
86
|
|
95
|
-
raise NilDataSuppliedError
|
87
|
+
raise NilDataSuppliedError, 'No method_binding supplied for prepare_data' unless method_binding
|
88
|
+
|
89
|
+
@original_data = data
|
96
90
|
|
97
91
|
begin
|
98
|
-
@prepare_data_const_regexp ||= Regexp.new( Delimiters::attribute_list_start + ".*" + Delimiters::attribute_list_end)
|
99
|
-
|
100
|
-
if( value.is_a? ActiveRecord::Relation ) # Rails 4 - query no longer returns an array
|
101
|
-
@current_value = value.to_a
|
102
|
-
elsif( !DataShift::Guards.jruby? && value.class.ancestors.include?(Spreadsheet::Formula))
|
103
|
-
@current_value = value.value
|
104
|
-
elsif( value.class.ancestors.include?(ActiveRecord::Base) || value.is_a?(Array))
|
105
|
-
@current_value = value
|
106
|
-
else
|
107
|
-
@current_value = value.to_s
|
108
92
|
|
109
|
-
|
93
|
+
if(data.is_a?(ActiveRecord::Relation)) # Rails 4 - query no longer returns an array
|
94
|
+
@value = data.to_a
|
110
95
|
|
111
|
-
|
112
|
-
|
113
|
-
logger.info "Populator for #{@current_value} has attributes #{@current_attribute_hash.inspect}"
|
114
|
-
end
|
115
|
-
end
|
96
|
+
elsif(data.class.ancestors.include?(ActiveRecord::Base) || data.is_a?(Array))
|
97
|
+
@value = data
|
116
98
|
|
117
|
-
|
99
|
+
elsif(!DataShift::Guards.jruby? &&
|
100
|
+
(data.is_a?(Spreadsheet::Formula) || data.class.ancestors.include?(Spreadsheet::Formula)) )
|
118
101
|
|
119
|
-
|
102
|
+
@value = data.value # TOFIX jruby/apache poi equivalent ?
|
120
103
|
|
121
|
-
|
104
|
+
elsif(connection_adapter_column && connection_adapter_column.cast_type.is_a?(ActiveRecord::Type::Boolean))
|
122
105
|
|
123
|
-
|
106
|
+
# DEPRECATION WARNING: You attempted to assign a value which is not explicitly `true` or `false` ("0.00")
|
107
|
+
# to a boolean column. Currently this value casts to `false`.
|
108
|
+
# This will change to match Ruby's semantics, and will cast to `true` in Rails 5.
|
109
|
+
# If you would like to maintain the current behavior, you should explicitly handle the values you would like cast to `false`.
|
124
110
|
|
125
|
-
|
126
|
-
|
111
|
+
@value = if(data.in? [true, false])
|
112
|
+
data
|
113
|
+
else
|
114
|
+
(data.to_s.downcase == "true" || data.to_s.to_i == 1) ? true : false
|
115
|
+
end
|
127
116
|
else
|
128
|
-
|
129
|
-
if(default_value(operator))
|
130
|
-
@current_value = default_value(operator)
|
131
|
-
elsif(Populator::header_default_data[operator])
|
132
|
-
@current_value = Populator::header_default_data[operator].to_s
|
133
|
-
elsif(Populator::header_default_data[operator])
|
134
|
-
@current_value = Populator::header_default_data[operator].to_s
|
135
|
-
elsif(method_detail.find_by_value)
|
136
|
-
@current_value = method_detail.find_by_value
|
137
|
-
end if(value.nil? || value.to_s.empty?)
|
138
|
-
end
|
117
|
+
@value = data.to_s
|
139
118
|
|
140
|
-
|
119
|
+
@attribute_hash = @value.slice!( Populator.attribute_hash_const_regexp )
|
141
120
|
|
142
|
-
|
143
|
-
|
121
|
+
if attribute_hash && !attribute_hash.empty?
|
122
|
+
@attribute_hash = Populator.string_to_hash( attribute_hash )
|
123
|
+
logger.info "Populator found attribute hash :[#{attribute_hash.inspect}]"
|
124
|
+
else
|
125
|
+
@attribute_hash = {}
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
run_transforms(method_binding)
|
144
130
|
|
145
131
|
rescue => e
|
146
|
-
logger.error(
|
147
|
-
logger.error("
|
148
|
-
|
149
|
-
raise DataProcessingError.new("opulator failed to prepare data #{value} for operator #{method_detail.operator}")
|
132
|
+
logger.error(e.message)
|
133
|
+
logger.error("Populator stacktrace: #{e.backtrace.first}")
|
134
|
+
raise DataProcessingError, "Populator failed to prepare data [#{value}] for #{method_binding.pp}"
|
150
135
|
end
|
151
136
|
|
152
|
-
|
137
|
+
[value, attribute_hash]
|
153
138
|
end
|
154
139
|
|
155
|
-
|
140
|
+
def assign(method_binding, record)
|
156
141
|
|
157
|
-
|
142
|
+
model_method = method_binding.model_method
|
158
143
|
|
159
|
-
|
144
|
+
operator = model_method.operator
|
160
145
|
|
161
|
-
|
162
|
-
end
|
146
|
+
klass = model_method.klass
|
163
147
|
|
164
|
-
|
148
|
+
if model_method.operator_for(:belongs_to)
|
149
|
+
insistent_belongs_to(method_binding, record, value)
|
150
|
+
elsif model_method.operator_for(:has_many)
|
151
|
+
assign_has_many(method_binding, record)
|
152
|
+
elsif model_method.operator_for(:has_one)
|
165
153
|
|
166
|
-
|
154
|
+
if value.is_a?(model_method.klass)
|
155
|
+
record.send(operator + '=', value)
|
156
|
+
else
|
157
|
+
logger.error("Cannot assign value [#{value.inspect}]")
|
158
|
+
logger.error("Value was Type (#{value.class}) - Required Type for has_one #{operator} is [#{klass}]")
|
159
|
+
end
|
167
160
|
|
168
|
-
|
161
|
+
elsif model_method.operator_for(:assignment)
|
169
162
|
|
170
|
-
|
163
|
+
if model_method.connection_adapter_column
|
171
164
|
|
172
|
-
|
165
|
+
return if check_process_enum(record, model_method ) # TOFIX .. enum section probably belongs in prepare_data
|
173
166
|
|
174
|
-
|
167
|
+
assignment(record, value, model_method)
|
175
168
|
|
176
|
-
|
169
|
+
else
|
170
|
+
logger.debug("Brute force assignment of value #{value} => [#{operator}]")
|
171
|
+
# brute force case for assignments without a column type (which enables us to do correct type_cast)
|
172
|
+
# so in this case, attempt straightforward assignment then if that fails, basic ops such as to_s, to_i, to_f etc
|
173
|
+
insistent_assignment(record, value, operator)
|
174
|
+
end
|
177
175
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
# so how do we get from 'taxons' to Spree::Taxons ? .. check if further info in reflect_on_all_associations
|
176
|
+
elsif model_method.operator_for(:method)
|
177
|
+
logger.debug("Method delegation assignment of value #{value} => [#{operator}]")
|
178
|
+
insistent_assignment(record, value, operator)
|
182
179
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
logger.error e.inspect
|
187
|
-
logger.error "Cannot assign #{current_value.inspect} (#{current_value.class}) to has_many association [#{operator}] "
|
188
|
-
end
|
180
|
+
else
|
181
|
+
logger.warn("Cannot assign via [#{operator}] to #{record.inspect} ")
|
182
|
+
end
|
189
183
|
|
190
|
-
|
184
|
+
end
|
191
185
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
186
|
+
def assignment(record, value, model_method)
|
187
|
+
|
188
|
+
operator = model_method.operator
|
189
|
+
connection_adapter_column = model_method.connection_adapter_column
|
190
|
+
|
191
|
+
begin
|
192
|
+
if(connection_adapter_column.respond_to? :type_cast)
|
193
|
+
logger.debug("Assignment via [#{operator}] to [#{value}] (CAST TYPE [#{model_method.connection_adapter_column.type_cast(value).inspect}])")
|
194
|
+
|
195
|
+
record.send( operator + '=', model_method.connection_adapter_column.type_cast( value ) )
|
199
196
|
|
200
|
-
elsif( current_method_detail.operator_for(:assignment) && current_col_type)
|
201
|
-
# 'type_cast' was changed to 'type_cast_from_database'
|
202
|
-
if Rails::VERSION::STRING < '4.2.0'
|
203
|
-
logger.debug("Assign #{current_value} => [#{operator}] (CAST 2 TYPE #{current_col_type.type_cast( current_value ).inspect})")
|
204
|
-
record.send( operator + '=' , current_method_detail.col_type.type_cast( current_value ) )
|
205
197
|
else
|
206
|
-
logger.debug("
|
207
|
-
record.send( operator + '=' , current_method_detail.col_type.type_cast_from_database( current_value ) )
|
208
|
-
end
|
198
|
+
logger.debug("Assignment via [#{operator}] to [#{value}] (NO CAST)")
|
209
199
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
200
|
+
# Good guide on diff ways to set attributes
|
201
|
+
# http://www.davidverhasselt.com/set-attributes-in-activerecord/
|
202
|
+
if(DataShift::Configuration.call.update_and_validate)
|
203
|
+
record.update( operator => value)
|
204
|
+
else
|
205
|
+
record.send( operator + '=', value)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
rescue => e
|
209
|
+
logger.error e.backtrace.first
|
210
|
+
logger.error("Assignment failed #{e.inspect}")
|
211
|
+
raise DataProcessingError, "Failed to set [#{value}] via [#{operator}] due to ERROR : #{e.message}"
|
218
212
|
end
|
219
213
|
end
|
220
214
|
|
221
215
|
def insistent_assignment(record, value, operator)
|
222
216
|
|
223
|
-
op = operator + '=' unless
|
217
|
+
op = operator + '=' unless operator.include?('=')
|
224
218
|
|
219
|
+
# TODO: - fix this crap - perhaps recursion ??
|
225
220
|
begin
|
226
221
|
record.send(op, value)
|
227
|
-
rescue
|
222
|
+
rescue
|
223
|
+
begin
|
224
|
+
op = operator.downcase
|
225
|
+
op += '=' unless operator.include?('=')
|
228
226
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
227
|
+
record.send(op, value)
|
228
|
+
|
229
|
+
rescue => e
|
230
|
+
|
231
|
+
Populator.insistent_method_list.each do |f|
|
232
|
+
begin
|
233
|
+
record.send(op, value.send(f) )
|
234
|
+
break
|
235
|
+
rescue => e
|
236
|
+
if f == Populator.insistent_method_list.last
|
237
|
+
logger.error(e.inspect)
|
238
|
+
logger.error("Failed to assign [#{value}] via operator #{operator}")
|
239
|
+
raise DataProcessingError, "Failed to assign [#{value}] to #{operator}" unless value.nil?
|
240
|
+
end
|
238
241
|
end
|
239
242
|
end
|
240
243
|
end
|
@@ -242,48 +245,41 @@ module DataShift
|
|
242
245
|
end
|
243
246
|
|
244
247
|
# Attempt to find the associated object via id, name, title ....
|
245
|
-
def insistent_belongs_to(
|
248
|
+
def insistent_belongs_to(method_binding, record, value )
|
249
|
+
|
250
|
+
operator = method_binding.operator
|
246
251
|
|
247
|
-
|
252
|
+
klass = method_binding.model_method.operator_class
|
248
253
|
|
249
|
-
if
|
254
|
+
if value.class == klass
|
250
255
|
logger.info("Populator assigning #{value} to belongs_to association #{operator}")
|
251
256
|
record.send(operator) << value
|
252
257
|
else
|
253
258
|
|
254
|
-
|
255
|
-
|
259
|
+
unless method_binding.klass.respond_to?('where')
|
260
|
+
raise CouldNotAssignAssociation, "Populator failed to assign [#{value}] to belongs_to [#{operator}]"
|
261
|
+
end
|
256
262
|
|
257
|
-
|
263
|
+
# Try the default field names
|
258
264
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
else
|
263
|
-
logger.error("Could not find or create [#{value}] for belongs_to association [#{operator}]")
|
264
|
-
raise CouldNotAssignAssociation.new "Populator failed to assign [#{value}] to belongs_to association [#{operator}]"
|
265
|
-
end
|
265
|
+
# TODO: - add find by operators from headers or configuration to insistent_find_by_list
|
266
|
+
Populator.insistent_find_by_list.each do |find_by|
|
267
|
+
begin
|
266
268
|
|
267
|
-
|
268
|
-
#try the default field names
|
269
|
-
Populator::insistent_find_by_list.each do |x|
|
270
|
-
begin
|
269
|
+
item = klass.where(find_by => value).first_or_create
|
271
270
|
|
272
|
-
|
271
|
+
next unless item
|
273
272
|
|
274
|
-
|
273
|
+
logger.info("Populator assigning #{item.inspect} to belongs_to association #{operator}")
|
274
|
+
record.send(operator + '=', item)
|
275
|
+
break
|
275
276
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
logger.error(e.inspect)
|
283
|
-
logger.error("Failed attempting to find belongs_to for #{method_detail.pp}")
|
284
|
-
if(x == Populator::insistent_method_list.last)
|
285
|
-
raise CouldNotAssignAssociation.new "Populator failed to assign [#{value}] to belongs_to association [#{operator}]" unless value.nil?
|
286
|
-
end
|
277
|
+
rescue => e
|
278
|
+
logger.error(e.inspect)
|
279
|
+
logger.error("Failed attempting to find belongs_to for #{method_binding.pp}")
|
280
|
+
if find_by == Populator.insistent_method_list.last
|
281
|
+
raise CouldNotAssignAssociation,
|
282
|
+
"Populator failed to assign [#{value}] to belongs_to association [#{operator}]" unless value.nil?
|
287
283
|
end
|
288
284
|
end
|
289
285
|
end
|
@@ -291,154 +287,184 @@ module DataShift
|
|
291
287
|
end
|
292
288
|
end
|
293
289
|
|
294
|
-
def
|
290
|
+
def check_process_enum(record, model_method)
|
295
291
|
|
296
|
-
|
292
|
+
klass = model_method.klass
|
293
|
+
operator = model_method.operator
|
297
294
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
295
|
+
if klass.respond_to?(operator.pluralize)
|
296
|
+
|
297
|
+
enums = klass.send(operator.pluralize)
|
298
|
+
|
299
|
+
logger.debug("Checking for enum - #{enums.inspect} - #{value.parameterize.underscore}" )
|
300
|
+
|
301
|
+
if enums.is_a?(Hash) && enums.keys.include?(value.parameterize.underscore)
|
302
|
+
# ENUM
|
303
|
+
logger.debug("[#{operator}] Appears to be an ENUM - setting to [#{value}])")
|
304
|
+
|
305
|
+
# TODO: - now we know this column is an enum set operator type to :enum to save this check in future
|
306
|
+
# probably requires changes above to just assign enum directly without this check
|
307
|
+
model_method.operator_for(:assignment)
|
308
|
+
|
309
|
+
record.send( operator + '=', value.parameterize.underscore)
|
310
|
+
return true
|
311
311
|
end
|
312
312
|
end
|
313
313
|
end
|
314
314
|
|
315
|
+
def self.string_to_hash( str )
|
316
|
+
str.to_hash_object
|
317
|
+
end
|
318
|
+
|
319
|
+
private
|
315
320
|
|
316
|
-
|
317
|
-
|
318
|
-
#
|
319
|
-
|
320
|
-
|
321
|
-
# datashift_defaults:
|
322
|
-
# value_as_string: "Default Project Value"
|
323
|
-
# category: reference:category_002
|
324
|
-
#
|
325
|
-
# datashift_overrides:
|
326
|
-
# value_as_double: 99.23546
|
327
|
-
#
|
328
|
-
def configure_from(load_object_class, yaml_file)
|
321
|
+
attr_writer :value, :attribute_hash
|
322
|
+
|
323
|
+
# TOFIX - Does not belong in this class
|
324
|
+
def run_transforms(method_binding)
|
325
|
+
default( method_binding ) if value.blank?
|
329
326
|
|
330
|
-
|
327
|
+
override( method_binding )
|
331
328
|
|
332
|
-
|
329
|
+
substitute( method_binding )
|
330
|
+
|
331
|
+
prefix( method_binding )
|
332
|
+
|
333
|
+
postfix( method_binding )
|
334
|
+
|
335
|
+
# TODO: - enable clients to register their own transformation methods and call them here
|
336
|
+
end
|
333
337
|
|
334
|
-
|
338
|
+
# A single column can contain multiple lookup key:value definitions.
|
339
|
+
# These are delimited by special char defined in Delimiters
|
340
|
+
#
|
341
|
+
# For example:
|
342
|
+
#
|
343
|
+
# size:large | colour:red,green,blue |
|
344
|
+
#
|
345
|
+
def split_multi_assoc_value
|
346
|
+
value.to_s.split( multi_assoc_delim )
|
347
|
+
end
|
335
348
|
|
336
|
-
|
349
|
+
def assign_has_many(method_binding, load_object)
|
337
350
|
|
338
|
-
|
339
|
-
|
351
|
+
# there are times when we need to save early, for example before assigning to
|
352
|
+
# has_and_belongs_to associations which require the load_object has an id for the join table
|
340
353
|
|
341
|
-
|
354
|
+
load_object.save_if_new
|
342
355
|
|
343
|
-
|
344
|
-
|
345
|
-
logger.info("Set Populator overrides: #{override_values.inspect}")
|
356
|
+
collection = []
|
357
|
+
columns = []
|
346
358
|
|
347
|
-
|
359
|
+
if value.is_a?(Array)
|
348
360
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
361
|
+
value.each do |record|
|
362
|
+
if record.class.ancestors.include?(ActiveRecord::Base)
|
363
|
+
collection << record
|
364
|
+
else
|
365
|
+
columns << record
|
366
|
+
end
|
367
|
+
end
|
353
368
|
|
369
|
+
else
|
370
|
+
# A single column can contain multiple lookup key:value definitions, delimited by special char
|
371
|
+
# size:large | colour:red,green,blue => [where size: 'large'], [where colour: IN ['red,green,blue']
|
372
|
+
columns = split_multi_assoc_value
|
354
373
|
end
|
355
374
|
|
356
|
-
|
375
|
+
operator = method_binding.operator
|
357
376
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
substitutions[operator] ||= []
|
377
|
+
columns.each do |col_str|
|
378
|
+
# split into usable parts ; size:large or colour:red,green,blue
|
379
|
+
field, find_by_values = Querying.where_field_and_values(method_binding, col_str )
|
362
380
|
|
363
|
-
|
364
|
-
end
|
381
|
+
raise "Cannot perform DB find by #{field}. Expected format key:value" unless field && find_by_values
|
365
382
|
|
366
|
-
|
367
|
-
@substitutions ||= {}
|
368
|
-
end
|
383
|
+
found_values = []
|
369
384
|
|
370
|
-
|
371
|
-
|
385
|
+
# we are looking up an association so need the Class of the Association
|
386
|
+
klass = method_binding.model_method.operator_class
|
372
387
|
|
373
|
-
|
374
|
-
|
375
|
-
@current_value = @original_value_before_override.gsub(s.pattern.to_s, s.replacement.to_s)
|
376
|
-
end
|
377
|
-
end
|
388
|
+
raise CouldNotDeriveAssociationClass,
|
389
|
+
"Failed to find class for has_many Association : #{method_binding.pp}" unless klass
|
378
390
|
|
391
|
+
logger.info("Running where clause on #{klass} : [#{field} IN #{find_by_values.inspect}]")
|
379
392
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
393
|
+
find_by_values.each do |v|
|
394
|
+
begin
|
395
|
+
found_values << klass.where(field => v).first_or_create
|
396
|
+
rescue => e
|
397
|
+
logger.error(e.inspect)
|
398
|
+
logger.error("Failed to find or create #{klass} where #{field} => #{v}")
|
399
|
+
# TODO: some way to define if this is a fatal error or not ?
|
400
|
+
end
|
401
|
+
end
|
385
402
|
|
386
|
-
|
387
|
-
@override_values ||= {}
|
388
|
-
end
|
403
|
+
logger.info("Scan result #{found_values.inspect}")
|
389
404
|
|
390
|
-
|
391
|
-
|
392
|
-
|
405
|
+
unless find_by_values.size == found_values.size
|
406
|
+
found = found_values.collect { |f| f.send(field) }
|
407
|
+
load_object.errors.add( operator, "Association with key(s) #{(find_by_values - found).inspect} NOT found")
|
408
|
+
logger.error "Association [#{operator}] with key(s) #{(find_by_values - found).inspect} NOT found - Not added."
|
409
|
+
next if found_values.empty?
|
410
|
+
end
|
393
411
|
|
394
|
-
|
395
|
-
end
|
396
|
-
end
|
412
|
+
logger.info("Assigning to has_many [#{operator}] : #{found_values.inspect} (#{found_values.class})")
|
397
413
|
|
414
|
+
begin
|
415
|
+
load_object.send(operator) << found_values
|
416
|
+
rescue => e
|
417
|
+
logger.error e.inspect
|
418
|
+
logger.error "Cannot assign #{found_values.inspect} to has_many [#{operator}] "
|
419
|
+
end
|
398
420
|
|
399
|
-
|
400
|
-
|
421
|
+
logger.info("Assignment to has_many [#{operator}] COMPLETE)")
|
422
|
+
end # END HAS_MANY
|
401
423
|
end
|
402
424
|
|
403
|
-
#
|
404
|
-
# Generally defaults will be used when no value supplied.
|
405
|
-
def set_default_value(operator, value )
|
406
|
-
default_values[operator] = value
|
407
|
-
end
|
425
|
+
# Transformations
|
408
426
|
|
409
|
-
def
|
410
|
-
|
411
|
-
end
|
427
|
+
def default( method_binding )
|
428
|
+
default = Transformation.factory.default(method_binding)
|
412
429
|
|
413
|
-
|
414
|
-
def default_value(operator)
|
415
|
-
default_values[operator]
|
416
|
-
end
|
430
|
+
return unless default
|
417
431
|
|
418
|
-
|
419
|
-
|
432
|
+
@previous_value = value
|
433
|
+
@value = default
|
420
434
|
end
|
421
435
|
|
422
|
-
|
423
|
-
|
424
|
-
|
436
|
+
# Checks Transformation for a substitution for column defined in method_binding
|
437
|
+
def substitute( method_binding )
|
438
|
+
sub = Transformation.factory.substitution(method_binding)
|
425
439
|
|
426
|
-
|
427
|
-
@
|
440
|
+
return unless sub
|
441
|
+
@previous_value = value
|
442
|
+
@value = previous_value.gsub(sub.pattern.to_s, sub.replacement.to_s)
|
428
443
|
end
|
429
444
|
|
430
|
-
def
|
431
|
-
|
445
|
+
def override( method_binding )
|
446
|
+
override = Transformation.factory.override(method_binding)
|
447
|
+
|
448
|
+
return unless override
|
449
|
+
@previous_value = value
|
450
|
+
@value = override
|
432
451
|
end
|
433
452
|
|
434
|
-
def
|
435
|
-
|
453
|
+
def prefix( method_binding )
|
454
|
+
prefix = Transformation.factory.prefix(method_binding)
|
455
|
+
|
456
|
+
return unless prefix
|
457
|
+
@previous_value = value
|
458
|
+
@value = prefix + @value
|
436
459
|
end
|
437
460
|
|
438
|
-
def
|
439
|
-
|
461
|
+
def postfix( method_binding )
|
462
|
+
postfix = Transformation.factory.postfix(method_binding)
|
463
|
+
|
464
|
+
return unless postfix
|
465
|
+
@previous_value = value
|
466
|
+
@value += postfix
|
440
467
|
end
|
441
468
|
|
442
469
|
end
|
443
|
-
|
444
470
|
end
|