valkyrie 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +0 -24
  3. data/Appraisals +0 -4
  4. data/CHANGELOG.md +65 -0
  5. data/README.md +2 -2
  6. data/db/schema.rb +0 -40
  7. data/gemfiles/activerecord_5_2.gemfile +2 -0
  8. data/gemfiles/activerecord_6_0.gemfile +2 -0
  9. data/lib/valkyrie.rb +20 -2
  10. data/lib/valkyrie/id.rb +16 -1
  11. data/lib/valkyrie/logging.rb +72 -0
  12. data/lib/valkyrie/persistence/composite_persister.rb +1 -1
  13. data/lib/valkyrie/persistence/fedora.rb +2 -0
  14. data/lib/valkyrie/persistence/fedora/list_node.rb +3 -6
  15. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +2 -2
  16. data/lib/valkyrie/persistence/fedora/permissive_schema.rb +2 -2
  17. data/lib/valkyrie/persistence/fedora/persister.rb +2 -1
  18. data/lib/valkyrie/persistence/fedora/query_service.rb +20 -17
  19. data/lib/valkyrie/persistence/memory/query_service.rb +32 -10
  20. data/lib/valkyrie/persistence/postgres/query_service.rb +66 -13
  21. data/lib/valkyrie/persistence/solr/persister.rb +4 -17
  22. data/lib/valkyrie/persistence/solr/queries/find_all_query.rb +6 -0
  23. data/lib/valkyrie/persistence/solr/query_service.rb +33 -44
  24. data/lib/valkyrie/persistence/solr/repository.rb +2 -1
  25. data/lib/valkyrie/rdf_patches.rb +2 -2
  26. data/lib/valkyrie/resource.rb +10 -2
  27. data/lib/valkyrie/specs/shared_specs/persister.rb +3 -3
  28. data/lib/valkyrie/specs/shared_specs/queries.rb +112 -9
  29. data/lib/valkyrie/storage/fedora.rb +1 -1
  30. data/lib/valkyrie/storage_adapter.rb +5 -2
  31. data/lib/valkyrie/types.rb +2 -0
  32. data/lib/valkyrie/version.rb +1 -1
  33. data/solr/config/solrconfig.xml +0 -10
  34. data/valkyrie.gemspec +1 -0
  35. metadata +17 -4
  36. data/db/seeds.rb +0 -8
  37. data/gemfiles/activerecord_5_1.gemfile +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 06e5a897c18679418660d531ae88c69f4ed675289080ddf712a52d2efa700344
4
- data.tar.gz: 78c96247bff42a505751b299f3314c4028240c2e68ac727d42cb71d1f92ab8af
3
+ metadata.gz: 67949cb5bed2cbcf96fa0919446f7e94288874371cca3f706fed156775b3c63f
4
+ data.tar.gz: febfd165c53533252232090bd427fb5f970b85053a314ff991f15d851bda078a
5
5
  SHA512:
6
- metadata.gz: dcbf37ca3daa89d25bf7c28d0d1684c2959fb6d26eff6ba8ca427b64f6a4413774702dd588a19e797648266b26786f526eb3b6423a2aeb48d78e8a0d4c6603f5
7
- data.tar.gz: 20dc3cc1aacd225b29eec0d2cdafe8bc42c7d46b0bdbd4ad81af75dae79017477fb116b00320c9d4be4bf5e7aa5fcd23b6a88c8d4b5c7ac7dbaeb436ebed8caa
6
+ metadata.gz: ba0e9e518bb437c93c1e27a21c851af5eaea423cbc863b7f68b555017a98a663ead92ea51bfcb5edcf5975b013b95f2179a5805aca9f988e269ff0beef85686a
7
+ data.tar.gz: ae2a939e6ab89a5e704a2a8234a7addc93d1f946a260aa9860d0beab87ef8eeb66d6d789a06e3fe40c2abd8d92f2ec25edd7f9889c4f23cdc8ea213cf29d1a4c
@@ -75,26 +75,14 @@ workflows:
75
75
  gemfile: "gemfiles/activerecord_5_2.gemfile"
76
76
  ruby: 2.6.3
77
77
  name: "Ruby2-6_Rails5-2"
78
- - build:
79
- gemfile: "gemfiles/activerecord_5_1.gemfile"
80
- ruby: 2.6.3
81
- name: "Ruby2-6_Rails5-1"
82
78
  - build:
83
79
  gemfile: "gemfiles/activerecord_5_2.gemfile"
84
80
  ruby: 2.5.5
85
81
  name: "Ruby2-5_Rails5-2"
86
- - build:
87
- gemfile: "gemfiles/activerecord_5_1.gemfile"
88
- ruby: 2.5.5
89
- name: "Ruby2-5_Rails5-1"
90
82
  - build:
91
83
  gemfile: "gemfiles/activerecord_5_2.gemfile"
92
84
  ruby: 2.4.6
93
85
  name: "Ruby2-4_Rails5-2"
94
- - build:
95
- gemfile: "gemfiles/activerecord_5_1.gemfile"
96
- ruby: 2.4.6
97
- name: "Ruby2-4_Rails5-1"
98
86
  nightly:
99
87
  triggers:
100
88
  - schedule:
@@ -112,23 +100,11 @@ workflows:
112
100
  gemfile: "gemfiles/activerecord_5_2.gemfile"
113
101
  ruby: 2.6.3
114
102
  name: "Ruby2-6_Rails5-2"
115
- - build:
116
- gemfile: "gemfiles/activerecord_5_1.gemfile"
117
- ruby: 2.6.3
118
- name: "Ruby2-6_Rails5-1"
119
103
  - build:
120
104
  gemfile: "gemfiles/activerecord_5_2.gemfile"
121
105
  ruby: 2.5.5
122
106
  name: "Ruby2-5_Rails5-2"
123
- - build:
124
- gemfile: "gemfiles/activerecord_5_1.gemfile"
125
- ruby: 2.5.5
126
- name: "Ruby2-5_Rails5-1"
127
107
  - build:
128
108
  gemfile: "gemfiles/activerecord_5_2.gemfile"
129
109
  ruby: 2.4.6
130
110
  name: "Ruby2-4_Rails5-2"
131
- - build:
132
- gemfile: "gemfiles/activerecord_5_1.gemfile"
133
- ruby: 2.4.6
134
- name: "Ruby2-4_Rails5-1"
data/Appraisals CHANGED
@@ -6,7 +6,3 @@ end
6
6
  appraise "activerecord-5-2" do
7
7
  gem "activerecord", "~> 5.2.0"
8
8
  end
9
-
10
- appraise "activerecord-5-1" do
11
- gem "activerecord", "~> 5.1.0"
12
- end
@@ -1,3 +1,68 @@
1
+ # v2.1.0 2020-01-09
2
+
3
+ ## Changes since last release
4
+
5
+ * Use `::` prefixed names for `JSON::LD` references.
6
+ [no-reply](https://github.com/no-reply)
7
+ * Use SVG instead of PNG for version badge.
8
+ [hackmastera](https://github.com/hackmastera)
9
+ * Fix Rubocop for latest Bixby.
10
+ [hackmastera](https://github.com/hackmastera)
11
+ * Valkyrie IDs equal string equivalent of ID to String with config
12
+ [jlevnhv](https://github.com/jlevnhv)
13
+ * Add optional model parameter to find_inverse_references_by and
14
+ find_references_by
15
+ [elrayle](https://github.com/elrayle)
16
+ [laritakr](https://github.com/laritakr)
17
+ * Add parity in schema.key lookup for `ordered_attribute?`
18
+ [jeremyf](https://github.com/jeremyf)
19
+ * Order member_ids when using schema-style attributes method.
20
+ [no-reply](https://github.com/no-reply)
21
+ * Use DEFAULT_FEDORA_VERSION constant for Fedora adapter.
22
+ [no-reply](https://github.com/no-reply)
23
+ * Stop testing ActiveRecord 5.1
24
+ [scherztc](https://github.com/scherztc)
25
+ * Rename ListNode#target_uri to ListNode#target
26
+ [mbklein](https://github.com/mbklein)
27
+ * Document that Solr Persister is intended to be used as a secondary persister.
28
+ [hweng](https://github.com/hweng)
29
+ * Remove unused database tables from schema.rb
30
+ [scherztc](https://github.com/scherztc)
31
+ * Alternate Identifier documentation
32
+ [escowles](https://github.com/escowles)
33
+ * Remove suggest component in example Solr Config
34
+ [hweng](https://github.com/hweng)
35
+ * Remove unused db/seeds.rb
36
+ [scherztc](https://github.com/scherztc)
37
+ * Replace YARD Doc for Solr adapter with references to Memory Adapter.
38
+ [afred](https://github.com/afred)
39
+ * Refactor shadowed variable in buffered persister spec.
40
+ [jeremyf](https://github.com/jeremyf)
41
+ * Use example.com instead of made-up URLs
42
+ [escowles](https://github.com/escowles)
43
+ * Add count_all_of_model query
44
+ [christinach](https://github.com/christinach)
45
+ [blancoj](https://github.com/blancoj)
46
+ * Raise an error when unable to find a StorageAdapter
47
+ [bkiahstroud](https://github.com/bkiahstroud)
48
+ [FCRodriguez7](https://github.com/FCRodriguez7)
49
+ [kcompsci](https://github.com/kcompsci)
50
+ * Allow find_inverse_reference_by property to be either ordered or not.
51
+ [elrayle](https://github.com/elrayle)
52
+ * Randomized spec order
53
+ [jeremyf](https://github.com/jeremyf)
54
+ * Allow Valkyrie logging to be tagged with a context and suppressed.
55
+ [jeremyf](https://github.com/jeremyf)
56
+ * Fix documentation for Valkyrie::Persister::Memory being disassociated.
57
+ [jeremyf](https://github.com/jeremyf)
58
+ * Suppress Solr warnings in tests.
59
+ [jeremyf](https://github.com/jeremyf)
60
+ * Add `Valkyrie::Types::Relation` and `Valkyrie::Types::OrderedRelation`
61
+ [luisgreg99](https://github.com/luisgreg99)
62
+ [lsat12357](https://github.com/lsat12357)
63
+ [foglabs](https://github.com/foglabs)
64
+ [dgcliff](https://github.com/dgcliff)
65
+
1
66
  # v2.0.2 2019-10-17
2
67
 
3
68
  ## Changes since last release
data/README.md CHANGED
@@ -4,7 +4,7 @@ Valkyrie is a gem for enabling multiple backends for storage of files and metada
4
4
 
5
5
  ![Valkyrie Logo](valkyrie_logo.png)
6
6
 
7
- Code: [![Version](https://badge.fury.io/rb/valkyrie.png)](http://badge.fury.io/rb/valkyrie)
7
+ Code: [![Gem Version](https://badge.fury.io/rb/valkyrie.svg)](https://badge.fury.io/rb/valkyrie)
8
8
  [![Build Status](https://circleci.com/gh/samvera/valkyrie.svg?style=svg)](https://circleci.com/gh/samvera/valkyrie)
9
9
  ![Coverage Status](https://img.shields.io/badge/Coverage-100-brightgreen.svg)
10
10
 
@@ -107,7 +107,7 @@ The initializer registers four `Valkyrie::MetadataAdapter` instances for storing
107
107
  * `:memory` which stores metadata in an in-memory cache (this cache is not persistent, so it is only
108
108
  appropriate for testing).
109
109
  * `:postgres` which stores metadata in a PostgreSQL database.
110
- * `:solr` which stores metadata in a Solr Index.
110
+ * `:solr` which stores metadata in a Solr Index (Solr Persister issues a warning if it has to generate an ID for a new resource because it is intended to be used as a secondary persister).
111
111
 
112
112
  Other adapter options include `Valkyrie::Persistence::BufferedPersister` for buffering in memory before bulk
113
113
  updating another persister, `Valkyrie::Persistence::CompositePersister` for storing in more than one adapter
@@ -15,18 +15,6 @@ ActiveRecord::Schema.define(version: 20170531004548) do
15
15
  enable_extension "plpgsql"
16
16
  enable_extension "uuid-ossp"
17
17
 
18
- create_table "bookmarks", id: :serial, force: :cascade do |t|
19
- t.integer "user_id", null: false
20
- t.string "user_type"
21
- t.string "document_id"
22
- t.string "document_type"
23
- t.binary "title"
24
- t.datetime "created_at", null: false
25
- t.datetime "updated_at", null: false
26
- t.index ["document_id"], name: "index_bookmarks_on_document_id"
27
- t.index ["user_id"], name: "index_bookmarks_on_user_id"
28
- end
29
-
30
18
  create_table "orm_resources", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t|
31
19
  t.jsonb "metadata", default: {}, null: false
32
20
  t.datetime "created_at", null: false
@@ -34,32 +22,4 @@ ActiveRecord::Schema.define(version: 20170531004548) do
34
22
  t.string "internal_resource"
35
23
  t.index ["metadata"], name: "index_orm_resources_on_metadata", using: :gin
36
24
  end
37
-
38
- create_table "searches", id: :serial, force: :cascade do |t|
39
- t.binary "query_params"
40
- t.integer "user_id"
41
- t.string "user_type"
42
- t.datetime "created_at", null: false
43
- t.datetime "updated_at", null: false
44
- t.index ["user_id"], name: "index_searches_on_user_id"
45
- end
46
-
47
- create_table "users", id: :serial, force: :cascade do |t|
48
- t.string "email", default: "", null: false
49
- t.string "encrypted_password", default: "", null: false
50
- t.string "reset_password_token"
51
- t.datetime "reset_password_sent_at"
52
- t.datetime "remember_created_at"
53
- t.integer "sign_in_count", default: 0, null: false
54
- t.datetime "current_sign_in_at"
55
- t.datetime "last_sign_in_at"
56
- t.inet "current_sign_in_ip"
57
- t.inet "last_sign_in_ip"
58
- t.datetime "created_at", null: false
59
- t.datetime "updated_at", null: false
60
- t.boolean "guest", default: false
61
- t.index ["email"], name: "index_users_on_email", unique: true
62
- t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
63
- end
64
-
65
25
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
5
  source "https://rubygems.org"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This file was generated by Appraisal
2
4
 
3
5
  source "https://rubygems.org"
@@ -14,6 +14,7 @@ require 'logger'
14
14
  require 'rdf/vocab'
15
15
 
16
16
  module Valkyrie
17
+ require 'valkyrie/logging'
17
18
  require 'valkyrie/id'
18
19
  require 'valkyrie/change_set'
19
20
  require 'valkyrie/value_mapper'
@@ -61,12 +62,16 @@ module Valkyrie
61
62
  end
62
63
  end
63
64
 
65
+ # @return [Valkyrie::Logging]
64
66
  def logger
65
- @logger ||= Logger.new(STDOUT)
67
+ @logger ||= Valkyrie::Logging.new(logger: Logger.new(STDOUT))
66
68
  end
67
69
 
70
+ # Wraps the given logger in an instance of Valkyrie::Logging
71
+ #
72
+ # @param logger [Logger]
68
73
  def logger=(logger)
69
- @logger = logger
74
+ @logger = Valkyrie::Logging.new(logger: logger)
70
75
  end
71
76
 
72
77
  class Config < OpenStruct
@@ -82,6 +87,19 @@ module Valkyrie
82
87
  Valkyrie::StorageAdapter.find(super.to_sym)
83
88
  end
84
89
 
90
+ # @api public
91
+ # Configure id_string_equality to be true in order to make Valkyrie::ID
92
+ # equal to the string value they contain. This will be the default behavior
93
+ # in v3.0.0.
94
+ #
95
+ # @return [Boolean] Whether `Valkyrie::ID` should be equal to their string counterpart.
96
+ def id_string_equality
97
+ super
98
+ end
99
+
100
+ # @!attribute [w] id_string_equality=
101
+ # The setter for #id_string_equality; see it's implementation
102
+
85
103
  # @api public
86
104
  #
87
105
  # The returned anonymous method (e.g. responds to #call) has a signature of
@@ -17,12 +17,27 @@ module Valkyrie
17
17
  delegate :hash, to: :state
18
18
 
19
19
  def eql?(other)
20
- other.class == self.class && other.state == state
20
+ return (default_equality(other) || string_equality(other)) if Valkyrie.config.id_string_equality == true
21
+ default_equality(other)
21
22
  end
22
23
  alias == eql?
23
24
 
24
25
  protected
25
26
 
27
+ def default_equality(other)
28
+ output = (other.class == self.class && other.state == state)
29
+ return output if output == true
30
+ if output == false && string_equality(other) && Valkyrie.config.id_string_equality.nil?
31
+ warn "[DEPRECATION] Valkyrie::IDs will always be equal to their string counterparts in 3.0.0. " \
32
+ "To silence this message, please either compare IDs or set Valkyrie.config.id_string_equality = true."
33
+ end
34
+ false
35
+ end
36
+
37
+ def string_equality(other)
38
+ other.to_s == to_s
39
+ end
40
+
26
41
  def state
27
42
  [@id]
28
43
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie
3
+ # A wrapper class for Valkyrie logging. This class attempts to provide
4
+ # tooling that helps improve the communication through-out the stack.
5
+ #
6
+ # In gem development there are several considerations regarding logging.
7
+ #
8
+ # 1) The development on the gem directly, in particular specs
9
+ # 2) The downstream development that leverages the gem, both when specs are
10
+ # running and when running the downstream processes in a development
11
+ # environment.
12
+ # 3) The downstream behaviors that are called in production environments.
13
+ #
14
+ # In each of these cases, different considerations regarding logging may be
15
+ # relevant.
16
+ #
17
+ # In the below example,
18
+ #
19
+ # @example
20
+ # Valkyrie.logger.suppress_logging_for_contexts!("A Named Context") do
21
+ # # The following will NOT be logged
22
+ # Valkyrie.logger.warn('Hello', logging_context: "A Named Context")
23
+ #
24
+ # # The following will be logged
25
+ # Valkyrie.logger.warn('Hello')
26
+ # end
27
+ # # The following will be logged
28
+ # Valkyrie.logger.warn('Hello', logging_context: "A Named Context")
29
+
30
+ class Logging < SimpleDelegator
31
+ # @param logger [Logger] the logger to which we'll delegate messages
32
+ def initialize(logger:)
33
+ @suppressions = {}
34
+ super(logger)
35
+ end
36
+
37
+ def warn(*args, logging_context: false, &block)
38
+ super(*args, *block) unless @suppressions.key?(logging_context)
39
+ end
40
+
41
+ def error(*args, logging_context: false, &block)
42
+ super(*args, *block) unless @suppressions.key?(logging_context)
43
+ end
44
+
45
+ def info(*args, logging_context: false, &block)
46
+ super(*args, *block) unless @suppressions.key?(logging_context)
47
+ end
48
+
49
+ def debug(*args, logging_context: false, &block)
50
+ super(*args, *block) unless @suppressions.key?(logging_context)
51
+ end
52
+
53
+ def fatal(*args, logging_context: false, &block)
54
+ super(*args, *block) unless @suppressions.key?(logging_context)
55
+ end
56
+
57
+ def suppress_logging_for_contexts!(*logging_contexts)
58
+ Array(logging_contexts).each do |logging_context|
59
+ @suppressions[logging_context] = true
60
+ end
61
+ return unless block_given?
62
+ yield
63
+ clear_suppressions!(*logging_contexts)
64
+ end
65
+
66
+ def clear_suppressions!(*logging_contexts)
67
+ Array(logging_contexts).each do |logging_context|
68
+ @suppressions.delete(logging_context)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -30,7 +30,7 @@ module Valkyrie::Persistence
30
30
  cached_resource = first.save(resource: resource)
31
31
  # Don't pass opt lock tokens to other persisters
32
32
  internal_resource = cached_resource.dup
33
- internal_resource.send("#{Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK}=", []) if internal_resource.optimistic_locking_enabled?
33
+ internal_resource.clear_optimistic_lock_token!
34
34
  rest.inject(internal_resource) { |m, persister| persister.save(resource: m) }
35
35
  # return the one with the desired opt lock token
36
36
  cached_resource
@@ -19,5 +19,7 @@ module Valkyrie::Persistence
19
19
  require 'valkyrie/persistence/fedora/ordered_list'
20
20
  require 'valkyrie/persistence/fedora/ordered_reader'
21
21
  require 'valkyrie/persistence/fedora/list_node'
22
+
23
+ DEFAULT_FEDORA_VERSION = 5
22
24
  end
23
25
  end
@@ -18,7 +18,6 @@ module Valkyrie::Persistence::Fedora
18
18
  class ListNode
19
19
  attr_reader :rdf_subject, :graph
20
20
  attr_writer :next, :prev
21
- attr_accessor :target
22
21
  attr_writer :next_uri, :prev_uri
23
22
  attr_accessor :proxy_in, :proxy_for
24
23
  attr_reader :adapter
@@ -59,16 +58,15 @@ module Valkyrie::Persistence::Fedora
59
58
  def to_graph
60
59
  return RDF::Graph.new if target_id.blank?
61
60
  g = Resource.new(rdf_subject)
62
- g.proxy_for = target_uri
61
+ g.proxy_for = target
63
62
  g.proxy_in = proxy_in.try(:uri)
64
63
  g.next = self.next.try(:rdf_subject)
65
64
  g.prev = prev.try(:rdf_subject)
66
65
  g.graph
67
66
  end
68
67
 
69
- # Resolves the URI for the value of the list expression
70
- # @return [RDF::URI]
71
- def target_uri
68
+ # @return [RDF::URI] or [String]
69
+ def target
72
70
  if target_id.is_a?(Valkyrie::ID)
73
71
  adapter.id_to_uri(target_id.to_s)
74
72
  else
@@ -76,7 +74,6 @@ module Valkyrie::Persistence::Fedora
76
74
  end
77
75
  end
78
76
 
79
- # Generates the string ID value for the value in the list expression
80
77
  # @return [String]
81
78
  def target_id
82
79
  if proxy_for.to_s.include?("/") && proxy_for.to_s.start_with?(adapter.connection_prefix)
@@ -6,7 +6,7 @@ module Valkyrie::Persistence::Fedora
6
6
  # Valkyrie::Persistence::Fedora::MetadataAdapter.new(
7
7
  # connection: ::Ldp::Client.new("http://localhost:8988/rest"),
8
8
  # base_path: "test_fed",
9
- # schema: Valkyrie::Persistence::Fedora::PermissiveSchema.new(title: RDF::URI("http://bad.com/title"))
9
+ # schema: Valkyrie::Persistence::Fedora::PermissiveSchema.new(title: RDF::URI("http://example.com/title"))
10
10
  # )
11
11
  class MetadataAdapter
12
12
  attr_reader :connection, :base_path, :schema, :fedora_version
@@ -15,7 +15,7 @@ module Valkyrie::Persistence::Fedora
15
15
  # @param [String] base_path
16
16
  # @param [Valkyrie::Persistence::Fedora::PermissiveSchema] schema
17
17
  # @param [Integer] fedora_version
18
- def initialize(connection:, base_path: "/", schema: Valkyrie::Persistence::Fedora::PermissiveSchema.new, fedora_version: 5)
18
+ def initialize(connection:, base_path: "/", schema: Valkyrie::Persistence::Fedora::PermissiveSchema.new, fedora_version: Valkyrie::Persistence::Fedora::DEFAULT_FEDORA_VERSION)
19
19
  @connection = connection
20
20
  @base_path = base_path
21
21
  @schema = schema