bulkrax 7.0.0 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/bulkrax/datatables.js +1 -1
  3. data/app/concerns/loggable.rb +25 -0
  4. data/app/controllers/bulkrax/exporters_controller.rb +1 -1
  5. data/app/controllers/bulkrax/importers_controller.rb +2 -1
  6. data/app/controllers/concerns/bulkrax/datatables_behavior.rb +15 -15
  7. data/app/factories/bulkrax/object_factory.rb +135 -163
  8. data/app/factories/bulkrax/object_factory_interface.rb +483 -0
  9. data/app/factories/bulkrax/valkyrie_object_factory.rb +402 -0
  10. data/app/factories/bulkrax/valkyrize-hyku.code-workspace +19 -0
  11. data/app/helpers/bulkrax/importers_helper.rb +1 -1
  12. data/app/helpers/bulkrax/validation_helper.rb +4 -4
  13. data/app/jobs/bulkrax/create_relationships_job.rb +27 -16
  14. data/app/jobs/bulkrax/delete_job.rb +3 -2
  15. data/app/jobs/bulkrax/download_cloud_file_job.rb +16 -3
  16. data/app/jobs/bulkrax/import_file_set_job.rb +23 -19
  17. data/app/jobs/bulkrax/importer_job.rb +18 -2
  18. data/app/matchers/bulkrax/application_matcher.rb +0 -2
  19. data/app/models/bulkrax/csv_collection_entry.rb +1 -1
  20. data/app/models/bulkrax/csv_entry.rb +7 -6
  21. data/app/models/bulkrax/entry.rb +7 -11
  22. data/app/models/bulkrax/exporter.rb +2 -2
  23. data/app/models/bulkrax/importer.rb +1 -3
  24. data/app/models/bulkrax/oai_entry.rb +0 -3
  25. data/app/models/bulkrax/oai_set_entry.rb +1 -1
  26. data/app/models/bulkrax/rdf_collection_entry.rb +1 -1
  27. data/app/models/bulkrax/rdf_entry.rb +70 -69
  28. data/app/models/bulkrax/xml_entry.rb +0 -1
  29. data/app/models/concerns/bulkrax/dynamic_record_lookup.rb +2 -19
  30. data/app/models/concerns/bulkrax/export_behavior.rb +2 -2
  31. data/app/models/concerns/bulkrax/file_factory.rb +178 -118
  32. data/app/models/concerns/bulkrax/file_set_entry_behavior.rb +2 -2
  33. data/app/models/concerns/bulkrax/has_matchers.rb +39 -25
  34. data/app/models/concerns/bulkrax/import_behavior.rb +10 -17
  35. data/app/models/concerns/bulkrax/importer_exporter_behavior.rb +3 -2
  36. data/app/parsers/bulkrax/application_parser.rb +31 -7
  37. data/app/parsers/bulkrax/bagit_parser.rb +175 -174
  38. data/app/parsers/bulkrax/csv_parser.rb +15 -5
  39. data/app/parsers/bulkrax/oai_dc_parser.rb +18 -0
  40. data/app/parsers/bulkrax/parser_export_record_set.rb +18 -22
  41. data/app/parsers/bulkrax/xml_parser.rb +0 -2
  42. data/app/services/bulkrax/factory_class_finder.rb +2 -0
  43. data/app/services/bulkrax/remove_relationships_for_importer.rb +3 -1
  44. data/app/services/hyrax/custom_queries/find_by_source_identifier.rb +50 -0
  45. data/app/services/wings/custom_queries/find_by_source_identifier.rb +32 -0
  46. data/app/views/bulkrax/entries/_parsed_metadata.html.erb +2 -2
  47. data/app/views/bulkrax/entries/_raw_metadata.html.erb +2 -2
  48. data/app/views/bulkrax/entries/show.html.erb +9 -8
  49. data/app/views/bulkrax/exporters/edit.html.erb +1 -1
  50. data/app/views/bulkrax/exporters/new.html.erb +1 -1
  51. data/app/views/bulkrax/exporters/show.html.erb +4 -2
  52. data/app/views/bulkrax/importers/_browse_everything.html.erb +2 -2
  53. data/app/views/bulkrax/importers/_csv_fields.html.erb +1 -1
  54. data/app/views/bulkrax/importers/edit.html.erb +1 -1
  55. data/app/views/bulkrax/importers/new.html.erb +1 -1
  56. data/app/views/bulkrax/importers/show.html.erb +1 -1
  57. data/app/views/bulkrax/importers/upload_corrected_entries.html.erb +2 -2
  58. data/app/views/bulkrax/shared/_bulkrax_errors.html.erb +1 -1
  59. data/app/views/bulkrax/shared/_bulkrax_field_mapping.html.erb +1 -1
  60. data/config/locales/bulkrax.en.yml +7 -0
  61. data/db/migrate/20230608153601_add_indices_to_bulkrax.rb +20 -9
  62. data/db/migrate/20240307053156_add_index_to_metadata_bulkrax_identifier.rb +18 -0
  63. data/lib/bulkrax/engine.rb +23 -6
  64. data/lib/bulkrax/version.rb +1 -1
  65. data/lib/bulkrax.rb +54 -52
  66. data/lib/generators/bulkrax/templates/config/initializers/bulkrax.rb +2 -0
  67. data/lib/tasks/bulkrax_tasks.rake +1 -0
  68. data/lib/tasks/reset.rake +4 -4
  69. metadata +25 -7
  70. data/lib/bulkrax/persistence_layer/active_fedora_adapter.rb +0 -27
  71. data/lib/bulkrax/persistence_layer/valkyrie_adapter.rb +0 -8
  72. data/lib/bulkrax/persistence_layer.rb +0 -38
@@ -57,7 +57,7 @@ module Bulkrax
57
57
  obj = entry.factory.find
58
58
  next if obj.is_a?(Bulkrax.file_model_class) # FileSets must be attached to a Work
59
59
 
60
- if obj.is_a?(Collection)
60
+ if obj.is_a?(Bulkrax.collection_model_class)
61
61
  remove_relationships_from_collection(obj)
62
62
  else
63
63
  remove_relationships_from_work(obj)
@@ -78,12 +78,14 @@ module Bulkrax
78
78
 
79
79
  return if defined?(Hyrax)
80
80
 
81
+ # NOTE: This should not need to be migrated to the object factory.
81
82
  # Remove parent collection relationships
82
83
  collection.member_of_collections.each do |parent_col|
83
84
  Hyrax::Collections::NestedCollectionPersistenceService
84
85
  .remove_nested_relationship_for(parent: parent_col, child: collection)
85
86
  end
86
87
 
88
+ # NOTE: This should not need to be migrated to the object factory.
87
89
  # Remove child collection relationships
88
90
  collection.member_collections.each do |child_col|
89
91
  Hyrax::Collections::NestedCollectionPersistenceService
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hyrax
4
+ module CustomQueries
5
+ ##
6
+ # @see https://github.com/samvera/valkyrie/wiki/Queries#custom-queries
7
+ class FindBySourceIdentifier
8
+ def self.queries
9
+ [:find_by_model_and_property_value]
10
+ end
11
+
12
+ def initialize(query_service:)
13
+ @query_service = query_service
14
+ end
15
+
16
+ attr_reader :query_service
17
+ delegate :resource_factory, to: :query_service
18
+ delegate :orm_class, to: :resource_factory
19
+
20
+ ##
21
+ # @param model [Class, #internal_resource]
22
+ # @param property [#to_s] the name of the property we're attempting to
23
+ # query.
24
+ # @param value [#to_s] the propety's value that we're trying to match.
25
+ #
26
+ # @return [NilClass] when no record was found
27
+ # @return [Valkyrie::Resource] when a record was found
28
+ #
29
+ # @note This is not a real estate transaction nor a Zillow lookup.
30
+ def find_by_model_and_property_value(model:, property:, value:)
31
+ sql_query = sql_for_find_by_model_and_property_value
32
+ # NOTE: Do we need to ask the model for it's internal_resource?
33
+ # TODO: no => undefined method `internal_resource' for Image:Class
34
+ query_service.run_query(sql_query, model, property, value).first
35
+ end
36
+
37
+ private
38
+
39
+ def sql_for_find_by_model_and_property_value
40
+ # NOTE: This is querying the first element of the property, but we might
41
+ # want to check all of the elements.
42
+ <<-SQL
43
+ SELECT * FROM orm_resources
44
+ WHERE internal_resource = ? AND metadata -> ? ->> 0 = ?
45
+ LIMIT 1;
46
+ SQL
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wings
4
+ module CustomQueries
5
+ class FindBySourceIdentifier
6
+ # Custom query override specific to Wings
7
+
8
+ def self.queries
9
+ [:find_by_model_and_property_value]
10
+ end
11
+
12
+ attr_reader :query_service
13
+ delegate :resource_factory, to: :query_service
14
+
15
+ def initialize(query_service:)
16
+ @query_service = query_service
17
+ end
18
+
19
+ def find_by_model_and_property_value(model:, property:, value:, use_valkyrie: Hyrax.config.use_valkyrie?)
20
+ # NOTE: This is using the Bulkrax::ObjectFactory (e.g. the one
21
+ # envisioned for ActiveFedora). In doing this, we avoid the situation
22
+ # where Bulkrax::ValkyrieObjectFactory calls this custom query.
23
+ af_object = Bulkrax::ObjectFactory.search_by_property(value: value, klass: model, field: property)
24
+
25
+ return if af_object.blank?
26
+ return af_object unless use_valkyrie
27
+
28
+ resource_factory.to_resource(object: af_object)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -5,7 +5,7 @@
5
5
  Parsed Metadata:
6
6
  </a>
7
7
  <a role="button" data-toggle="collapse" data-target="#parsed-metadata-show" aria-expanded="true" aria-controls="parsed-metadata-show">
8
- <div class="accordion-icon glyphicon glyphicon-remove-circle" aria-hidden="true"></div>
8
+ <div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
9
9
  </a>
10
10
  </div>
11
11
  <div id="parsed-metadata-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="parsed-metadata-show">
@@ -16,4 +16,4 @@
16
16
  </div>
17
17
  </div>
18
18
  </div>
19
- <% end %>
19
+ <% end %>
@@ -5,7 +5,7 @@
5
5
  Raw Metadata:
6
6
  </a>
7
7
  <a role="button" data-toggle="collapse" data-target="#raw-metadata-show" aria-expanded="true" aria-controls="raw-metadata-show">
8
- <div class="accordion-icon glyphicon glyphicon-remove-circle" aria-hidden="true"></div>
8
+ <div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
9
9
  </a>
10
10
  </div>
11
11
  <div id="raw-metadata-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="raw-metadata-show">
@@ -16,4 +16,4 @@
16
16
  </div>
17
17
  </div>
18
18
  </div>
19
- <% end %>
19
+ <% end %>
@@ -33,13 +33,14 @@
33
33
 
34
34
  <p class='bulkrax-p-align'>
35
35
  <% if @importer.present? %>
36
+ <%# TODO Consider how to account for Bulkrax.collection_model_class %>
36
37
  <% factory_record = @entry.factory.find %>
37
38
  <% if factory_record.present? && @entry.factory_class %>
38
- <strong><%= @entry.factory_class.to_s %> Link:</strong>
39
- <% if @entry.factory_class.to_s == 'Collection' %>
40
- <%= link_to @entry.factory_class.to_s, hyrax.polymorphic_path(factory_record) %>
39
+ <strong><%= @entry.factory_class.model_name.human %> Link:</strong>
40
+ <% if defined?(Hyrax) && @entry.factory_class.model_name.human == 'Collection' %>
41
+ <%= link_to @entry.factory_class.model_name.human, hyrax.polymorphic_path(factory_record) %>
41
42
  <% else %>
42
- <%= link_to @entry.factory_class.to_s, main_app.polymorphic_path(factory_record) %>
43
+ <%= link_to @entry.factory_class.model_name.human, main_app.polymorphic_path(factory_record) %>
43
44
  <% end %>
44
45
  <% else %>
45
46
  <strong>Item Link:</strong> Item has not yet been imported successfully
@@ -47,11 +48,11 @@
47
48
  <% else %>
48
49
  <% record = @entry&.hyrax_record %>
49
50
  <% if record.present? && @entry.factory_class %>
50
- <strong><%= record.class.to_s %> Link:</strong>
51
- <% if defined?(Collection) && record.is_a?(Collection) %>
52
- <%= link_to record.class.to_s, hyrax.polymorphic_path(record) %>
51
+ <strong><%= record.model_name.human %> Link:</strong>
52
+ <% if defined?(Hyrax) && record.model_name.human == "Collection" %>
53
+ <%= link_to record.model_name.human, hyrax.polymorphic_path(record) %>
53
54
  <% else %>
54
- <%= link_to record.class.to_s, main_app.polymorphic_path(record) %>
55
+ <%= link_to record.model_name.human, main_app.polymorphic_path(record) %>
55
56
  <% end %>
56
57
  <% else %>
57
58
  <strong>Item Link:</strong> No item associated with this entry or class unknown
@@ -14,7 +14,7 @@
14
14
  <%= form.button :submit, value: 'Update and Re-Export All Items', class: 'btn btn-primary' %>
15
15
  |
16
16
  <% cancel_path = form.object.persisted? ? exporter_path(form.object) : exporters_path %>
17
- <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
17
+ <%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
18
18
  </div>
19
19
  </div>
20
20
  <% end %>
@@ -14,7 +14,7 @@
14
14
  <%= form.button :submit, value: 'Create', class: 'btn btn-primary' %>
15
15
  |
16
16
  <% cancel_path = form.object.persisted? ? exporter_path(form.object) : exporters_path %>
17
- <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
17
+ <%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
18
18
  </div>
19
19
  </div>
20
20
  <% end %>
@@ -39,8 +39,10 @@
39
39
  <strong><%= t('bulkrax.exporter.labels.export_source') %>:</strong>
40
40
  <% case @exporter.export_from %>
41
41
  <% when 'collection' %>
42
- <% collection = Collection.find(@exporter.export_source) %>
43
- <%= link_to collection&.title&.first, hyrax.dashboard_collection_path(collection.id) %>
42
+ <% collection = Bulkrax.object_factory.find_or_nil(@exporter.export_source) %>
43
+ <% id = collection&.id || @exporter.export_source %>
44
+ <% title = collection&.title&.first || @exporter.export_source %>
45
+ <%= link_to title, hyrax.dashboard_collection_path(id) %>
44
46
  <% when 'importer' %>
45
47
  <% importer = Bulkrax::Importer.find(@exporter.export_source) %>
46
48
  <%= link_to importer.name, bulkrax.importer_path(importer.id) %>
@@ -3,10 +3,10 @@
3
3
  f = "#{form.lookup_action}_importer"
4
4
  f = "#{f}_#{@importer.id}" unless @importer.new_record?
5
5
  %>
6
- <div id='cloud-files'>
6
+ <div id='cloud-files'>
7
7
  <button type="button" data-toggle="browse-everything" data-route="<%=browse_everything_engine.root_path%>"
8
8
  data-target="#<%= f %>" class="btn btn-primary" id="browse">
9
- <span class="glyphicon glyphicon-plus"></span>
9
+ <span class="fa fa-plus"></span>
10
10
  Add Cloud Files
11
11
  </button>
12
12
  </div>
@@ -29,7 +29,7 @@
29
29
  <% file_style_list << 'Existing Entries' unless importer.new_record? %>
30
30
  <%= fi.input :file_style, collection: file_style_list, as: :radio_buttons, label: false %>
31
31
  <div id='file_upload'>
32
- <%= fi.input 'file', as: :file, input_html: { accept: 'text/csv,application/zip' } %><br />
32
+ <%= fi.input 'file', as: :file, input_html: { accept: 'text/csv,application/zip,application/gzip' } %><br />
33
33
  </div>
34
34
  <div id='file_path'>
35
35
  <%= fi.input :import_file_path, as: :string, input_html: { value: importer.parser_fields['import_file_path'] } %>
@@ -15,7 +15,7 @@
15
15
  </button>
16
16
  <%= render 'edit_form_buttons', form: form %>
17
17
  <% cancel_path = form.object.persisted? ? importer_path(form.object) : importers_path %>
18
- | <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
18
+ | <%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
19
19
  </div>
20
20
  </div>
21
21
  <% end %>
@@ -18,7 +18,7 @@
18
18
  <%= form.button :submit, value: 'Create', class: 'btn btn-primary' %>
19
19
  |
20
20
  <% cancel_path = form.object.persisted? ? importer_path(form.object) : importers_path %>
21
- <%= link_to t('.cancel'), cancel_path, class: 'btn btn-default ' %>
21
+ <%= link_to t('bulkrax.cancel'), cancel_path, class: 'btn btn-default ' %>
22
22
  </div>
23
23
  </div>
24
24
  <% end %>
@@ -45,7 +45,7 @@
45
45
  Parser fields:
46
46
  </a>
47
47
  <a role="button" data-toggle="collapse" data-target="#parser-fields-importer-show" aria-expanded="true" aria-controls="parser-fields-importer-show">
48
- <div class="accordion-icon glyphicon glyphicon-remove-circle" aria-hidden="true"></div>
48
+ <div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
49
49
  </a>
50
50
  </div>
51
51
  <div id="parser-fields-importer-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="parser-fields-heading">
@@ -7,7 +7,7 @@
7
7
  <p>
8
8
  Upload <b>only</b> the corrected entries for the <b><%= @importer.name %></b> importer. To export failed entries for correction,
9
9
  <%= link_to importer_export_errors_path(@importer.id) do %>
10
- click here <span class='glyphicon glyphicon-download-alt'></span>
10
+ click here <span class='fa fa-download'></span>
11
11
  <% end %>
12
12
  </p>
13
13
  <p>Only CSV files are allowed.</p>
@@ -18,7 +18,7 @@
18
18
  <div class='fileupload-buttonbar hide-required-tag'>
19
19
  <%= fi.input 'file',
20
20
  as: :file,
21
- label: "<span class='glyphicon glyphicon-plus'></span><span> Add file...</span>".html_safe,
21
+ label: "<span class='fa fa-plus'></span><span> Add file...</span>".html_safe,
22
22
  label_html: {
23
23
  class: 'btn btn-success'
24
24
  },
@@ -5,7 +5,7 @@
5
5
  Errors:
6
6
  </a>
7
7
  <a role="button" data-toggle="collapse" data-target="#error-trace-show" aria-expanded="true" aria-controls="error-trace-show">
8
- <div class="accordion-icon glyphicon glyphicon-remove-circle" aria-hidden="true"></div>
8
+ <div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
9
9
  </a>
10
10
  </div>
11
11
  <div id="error-trace-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="error-trace-show">
@@ -5,7 +5,7 @@
5
5
  <strong>Field mapping:</strong>
6
6
  </a>
7
7
  <a role="button" data-toggle="collapse" data-target="#field-mapping-show" aria-expanded="true" aria-controls="field-mapping-show">
8
- <div class="accordion-icon glyphicon glyphicon-remove-circle" aria-hidden="true"></div>
8
+ <div class="accordion-icon fa fa-times-circle" aria-hidden="true"></div>
9
9
  </a>
10
10
  </div>
11
11
  <div id="field-mapping-show" class="accordion-collapse collapse" role="tabpanel" aria-labelledby="field-mapping-show">
@@ -1,9 +1,16 @@
1
1
  en:
2
+ helpers:
3
+ action:
4
+ importer:
5
+ new: "New"
6
+ exporter:
7
+ new: "New"
2
8
  bulkrax:
3
9
  admin:
4
10
  sidebar:
5
11
  exporters: Exporters
6
12
  importers: Importers
13
+ cancel: "Cancel"
7
14
  exporter:
8
15
  labels:
9
16
  all: All
@@ -1,14 +1,25 @@
1
+ # This migration comes from bulkrax (originally 20230608153601)
1
2
  class AddIndicesToBulkrax < ActiveRecord::Migration[5.1]
2
3
  def change
3
- add_index :bulkrax_entries, :identifier unless index_exists?(:bulkrax_entries, :identifier)
4
- add_index :bulkrax_entries, :type unless index_exists?(:bulkrax_entries, :type)
5
- add_index :bulkrax_entries, [:importerexporter_id, :importerexporter_type], name: 'bulkrax_entries_importerexporter_idx' unless index_exists?(:bulkrax_entries, [:importerexporter_id, :importerexporter_type], name: 'bulkrax_entries_importerexporter_idx')
6
-
7
- add_index :bulkrax_pending_relationships, :parent_id unless index_exists?(:bulkrax_pending_relationships, :parent_id)
8
- add_index :bulkrax_pending_relationships, :child_id unless index_exists?(:bulkrax_pending_relationships, :child_id)
4
+ check_and_add_index :bulkrax_entries, :identifier
5
+ check_and_add_index :bulkrax_entries, :type
6
+ check_and_add_index :bulkrax_entries, [:importerexporter_id, :importerexporter_type], name: 'bulkrax_entries_importerexporter_idx'
7
+ check_and_add_index :bulkrax_pending_relationships, :parent_id
8
+ check_and_add_index :bulkrax_pending_relationships, :child_id
9
+ check_and_add_index :bulkrax_statuses, [:statusable_id, :statusable_type], name: 'bulkrax_statuses_statusable_idx'
10
+ check_and_add_index :bulkrax_statuses, [:runnable_id, :runnable_type], name: 'bulkrax_statuses_runnable_idx'
11
+ check_and_add_index :bulkrax_statuses, :error_class
12
+ end
9
13
 
10
- add_index :bulkrax_statuses, [:statusable_id, :statusable_type], name: 'bulkrax_statuses_statusable_idx' unless index_exists?(:bulkrax_statuses, [:statusable_id, :statusable_type], name: 'bulkrax_statuses_statusable_idx')
11
- add_index :bulkrax_statuses, [:runnable_id, :runnable_type], name: 'bulkrax_statuses_runnable_idx' unless index_exists?(:bulkrax_statuses, [:runnable_id, :runnable_type], name: 'bulkrax_statuses_runnable_idx')
12
- add_index :bulkrax_statuses, :error_class unless index_exists?(:bulkrax_statuses, :error_class)
14
+ if RUBY_VERSION =~ /^2/
15
+ def check_and_add_index(table_name, column_name, options = {})
16
+ add_index(table_name, column_name, options) unless index_exists?(table_name, column_name, options)
17
+ end
18
+ elsif RUBY_VERSION =~ /^3/
19
+ def check_and_add_index(table_name, column_name, **options)
20
+ add_index(table_name, column_name, **options) unless index_exists?(table_name, column_name, **options)
21
+ end
22
+ else
23
+ raise "Ruby version #{RUBY_VERSION} is unknown"
13
24
  end
14
25
  end
@@ -0,0 +1,18 @@
1
+ class AddIndexToMetadataBulkraxIdentifier < ActiveRecord::Migration[5.2]
2
+ def up
3
+ return unless table_exists?(:orm_resources)
4
+ return if index_exists?(:orm_resources, "(((metadata -> 'bulkrax_identifier'::text) ->> 0))", name: 'index_on_bulkrax_identifier')
5
+
6
+ # This creates an expression index on the first element of the bulkrax_identifier array
7
+ add_index :orm_resources,
8
+ "(metadata -> 'bulkrax_identifier' ->> 0)",
9
+ name: 'index_on_bulkrax_identifier',
10
+ where: "metadata -> 'bulkrax_identifier' IS NOT NULL"
11
+ end
12
+
13
+ def down
14
+ return unless table_exists?(:orm_resources)
15
+
16
+ remove_index :orm_resources, name: 'index_on_bulkrax_identifier'
17
+ end
18
+ end
@@ -5,6 +5,7 @@ require 'oai'
5
5
  module Bulkrax
6
6
  class Engine < ::Rails::Engine
7
7
  isolate_namespace Bulkrax
8
+
8
9
  initializer :append_migrations do |app|
9
10
  if !app.root.to_s.match(root.to_s) && app.root.join('db/migrate').children.none? { |path| path.fnmatch?("*.bulkrax.rb") }
10
11
  config.paths["db/migrate"].expanded.each do |expanded_path|
@@ -13,12 +14,6 @@ module Bulkrax
13
14
  end
14
15
  end
15
16
 
16
- initializer 'requires' do
17
- require 'bulkrax/persistence_layer'
18
- require 'bulkrax/persistence_layer/active_fedora_adapter' if defined?(ActiveFedora)
19
- require 'bulkrax/persistence_layer/valkyrie_adapter' if defined?(Valkyrie)
20
- end
21
-
22
17
  config.generators do |g|
23
18
  g.test_framework :rspec
24
19
  begin
@@ -38,6 +33,28 @@ module Bulkrax
38
33
  hyrax_view_path = paths.detect { |path| path.match(%r{^#{hyrax_engine_root}}) }
39
34
  paths.insert(paths.index(hyrax_view_path), File.join(my_engine_root, 'app', 'views')) if hyrax_view_path
40
35
  ActionController::Base.view_paths = paths.uniq
36
+
37
+ custom_query_strategies = {
38
+ find_by_model_and_property_value: :find_single_or_nil
39
+ }
40
+
41
+ if defined?(::Goddess::CustomQueryContainer)
42
+ strategies = ::Goddess::CustomQueryContainer.known_custom_queries_and_their_strategies
43
+ strategies = strategies.merge(custom_query_strategies)
44
+ ::Goddess::CustomQueryContainer.known_custom_queries_and_their_strategies = strategies
45
+ end
46
+
47
+ if defined?(::Frigg::CustomQueryContainer)
48
+ strategies = ::Frigg::CustomQueryContainer.known_custom_queries_and_their_strategies
49
+ strategies = strategies.merge(custom_query_strategies)
50
+ ::Frigg::CustomQueryContainer.known_custom_queries_and_their_strategies = strategies
51
+ end
52
+
53
+ if defined?(::Freyja::CustomQueryContainer)
54
+ strategies = ::Freyja::CustomQueryContainer.known_custom_queries_and_their_strategies
55
+ strategies = strategies.merge(custom_query_strategies)
56
+ ::Freyja::CustomQueryContainer.known_custom_queries_and_their_strategies = strategies
57
+ end
41
58
  end
42
59
  end
43
60
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bulkrax
4
- VERSION = '7.0.0'
4
+ VERSION = '8.1.0'
5
5
  end
data/lib/bulkrax.rb CHANGED
@@ -3,8 +3,27 @@
3
3
  require "bulkrax/version"
4
4
  require "bulkrax/engine"
5
5
  require 'active_support/all'
6
+
6
7
  require 'coderay'
8
+ require 'csv'
7
9
  require 'denormalize_fields'
10
+ require 'erb'
11
+ require 'iso8601'
12
+ require 'language_list'
13
+ require 'marcel'
14
+ require 'nokogiri'
15
+ require 'ostruct'
16
+ require 'zip'
17
+
18
+ def conditional_require(gem_name)
19
+ require gem_name
20
+ rescue LoadError
21
+ ENV["BULKRAX_NO_#{gem_name.upcase}"] = 'true'
22
+ end
23
+
24
+ conditional_require 'bagit'
25
+ conditional_require 'rdf'
26
+
8
27
  # rubocop:disable Metrics/ModuleLength
9
28
  module Bulkrax
10
29
  extend self # rubocop:disable Style/ModuleFunction
@@ -14,12 +33,10 @@ module Bulkrax
14
33
  # @api public
15
34
  class Configuration
16
35
  attr_accessor :api_definition,
17
- :curation_concerns,
18
36
  :default_field_mapping,
19
37
  :default_work_type,
20
38
  :export_path,
21
39
  :field_mappings,
22
- :file_model_class,
23
40
  :generated_metadata_mapping,
24
41
  :import_path,
25
42
  :multi_value_element_join_on,
@@ -40,10 +57,6 @@ module Bulkrax
40
57
  # second parameter is an Integer for the index of the record encountered in the import.
41
58
  attr_accessor :fill_in_blank_source_identifiers
42
59
 
43
- ##
44
- # @param adapter [Class<Bulkrax::PersistenceLayer::AbstractAdapter>]
45
- attr_writer :persistence_adapter
46
-
47
60
  ##
48
61
  # @param [String]
49
62
  attr_writer :solr_key_for_member_file_ids
@@ -78,6 +91,36 @@ module Bulkrax
78
91
  @factory_class_name_coercer || Bulkrax::FactoryClassFinder::DefaultCoercer
79
92
  end
80
93
 
94
+ def collection_model_class
95
+ @collection_model_class ||= Collection
96
+ end
97
+
98
+ attr_writer :collection_model_class
99
+
100
+ def collection_model_internal_resource
101
+ collection_model_class.try(:internal_resource) || collection_model_class.to_s
102
+ end
103
+
104
+ def file_model_class
105
+ @file_model_class ||= defined?(::Hyrax) ? ::FileSet : File
106
+ end
107
+
108
+ attr_writer :file_model_class
109
+
110
+ def file_model_internal_resource
111
+ file_model_class.try(:internal_resource) || file_model_class.to_s
112
+ end
113
+
114
+ def curation_concerns
115
+ @curation_concerns ||= defined?(::Hyrax) ? ::Hyrax.config.curation_concerns : []
116
+ end
117
+
118
+ attr_writer :curation_concerns
119
+
120
+ def curation_concern_internal_resources
121
+ curation_concerns.map { |cc| cc.try(:internal_resource) || cc.to_s }.uniq
122
+ end
123
+
81
124
  attr_writer :ingest_queue_name
82
125
  ##
83
126
  # @return [String, Proc]
@@ -87,34 +130,6 @@ module Bulkrax
87
130
  :import
88
131
  end
89
132
 
90
- ##
91
- # Configure the persistence adapter used for persisting imported data.
92
- #
93
- # @return [Class<Bulkrax::PersistenceLayer::AbstractAdapter>]
94
- # @see Bulkrax::PersistenceLayer
95
- def persistence_adapter
96
- @persistence_adapter || derived_persistence_adapter
97
- end
98
-
99
- def derived_persistence_adapter
100
- if defined?(Hyrax)
101
- # There's probably some configuration of Hyrax we could use to better refine this; but it's
102
- # likely a reasonable guess. The main goal is to not break existing implementations and
103
- # maintain an upgrade path.
104
- if Gem::Version.new(Hyrax::VERSION) >= Gem::Version.new('6.0.0')
105
- Bulkrax::PersistenceLayer::ValkyrieAdapter
106
- else
107
- Bulkrax::PersistenceLayer::ActiveFedoraAdapter
108
- end
109
- elsif defined?(ActiveFedora)
110
- Bulkrax::PersistenceLayer::ActiveFedoraAdapter
111
- elsif defined?(Valkyrie)
112
- Bulkrax::PersistenceLayer::ValkyrieAdapter
113
- else
114
- raise "Unable to derive a persistence adapter"
115
- end
116
- end
117
-
118
133
  attr_writer :use_locking
119
134
 
120
135
  def use_locking
@@ -135,8 +150,12 @@ module Bulkrax
135
150
  def_delegators :@config,
136
151
  :api_definition,
137
152
  :api_definition=,
153
+ :collection_model_class,
154
+ :collection_model_internal_resource,
155
+ :collection_model_class=,
138
156
  :curation_concerns,
139
157
  :curation_concerns=,
158
+ :curation_concern_internal_resources,
140
159
  :default_field_mapping,
141
160
  :default_field_mapping=,
142
161
  :default_work_type,
@@ -149,6 +168,7 @@ module Bulkrax
149
168
  :field_mappings=,
150
169
  :file_model_class,
151
170
  :file_model_class=,
171
+ :file_model_internal_resource,
152
172
  :fill_in_blank_source_identifiers,
153
173
  :fill_in_blank_source_identifiers=,
154
174
  :generated_metadata_mapping,
@@ -163,8 +183,6 @@ module Bulkrax
163
183
  :object_factory=,
164
184
  :parsers,
165
185
  :parsers=,
166
- :persistence_adapter,
167
- :persistence_adapter=,
168
186
  :qa_controlled_properties,
169
187
  :qa_controlled_properties=,
170
188
  :related_children_field_mapping,
@@ -203,22 +221,6 @@ module Bulkrax
203
221
  conf.relationship_job_class = "Bulkrax::CreateRelationshipsJob"
204
222
  conf.required_elements = ['title']
205
223
 
206
- def conf.curation_concerns
207
- @curation_concerns ||= defined?(::Hyrax) ? ::Hyrax.config.curation_concerns : []
208
- end
209
-
210
- def conf.curation_concerns=(val)
211
- @curation_concerns = val
212
- end
213
-
214
- def conf.file_model_class
215
- @file_model_class ||= defined?(::Hyrax) ? ::FileSet : File
216
- end
217
-
218
- def conf.file_model_class=(val)
219
- @file_model_class = val
220
- end
221
-
222
224
  # Hash of Generic field_mappings for use in the view
223
225
  # There must be one field_mappings hash per view partial
224
226
  # Based on Hyrax CoreMetadata && BasicMetadata
@@ -12,6 +12,8 @@ Bulkrax.setup do |config|
12
12
 
13
13
  # Factory Class to use when generating and saving objects
14
14
  config.object_factory = Bulkrax::ObjectFactory
15
+ # Use this for a Postgres-backed Valkyrized Hyrax
16
+ # config.object_factory = Bulkrax::ValkyrieObjectFactory
15
17
 
16
18
  # Path to store pending imports
17
19
  # config.import_path = 'tmp/imports'
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+ require 'ruby-progressbar'
2
3
 
3
4
  namespace :bulkrax do
4
5
  desc 'Update all status messages from the latest status. This is to refresh the denormalized field'