valkyrie-sequel 2.0.1 → 3.0.0.pre.beta.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a74b8f8a7ba365deb8fcda493a2289a579580018ba4d9251684a9bcc02d3665
4
- data.tar.gz: 70774d437ef4fdc8e75566ca4c1942bbc66f247eee19b49a3017cea3097b66af
3
+ metadata.gz: b6d42b77cece523b4eeacf7f4853bc20e0fac7f5b8df24e742ae4ef1e6b7df12
4
+ data.tar.gz: 6edac9cf3f494640dfe74e062dd3760d9f0386d8d3b60dcf2ea7f01190e3fc3d
5
5
  SHA512:
6
- metadata.gz: dad38881c3959f86f9febc7fe1a1ea5e62fea9310af9715c27da3087cfe4af6ebfed20ab9e48de6b99e775901f818aeca5beb2e3fd215b3a7adf81cb87ceff1e
7
- data.tar.gz: 160c5f59b084e3594995d492773d16734daaaa98141b9340f4859914a7710fa3426d3f5b38e97efd56b19f527ac618210280e96de2f8521b6afca55de352d05d
6
+ metadata.gz: 53f9dc78cec19cb0eaac3e7001eaf2f8d2cf8c29e3ec10795fa0f1b69162ba34d8a237582c9f7345022fc0d82d422eac490be84eb8596f39941b2dffad2af812
7
+ data.tar.gz: 51faaaad25361de2f20885dafa49307a56bb75bd91a2a907607ae4228bef125764acf7d6ef162a34c2fbc50270ff3a6e5a5b1922074c33030a0415a2b4e97d87
data/.circleci/config.yml CHANGED
@@ -3,9 +3,10 @@ version: 2
3
3
  jobs:
4
4
  build:
5
5
  docker:
6
- - image: circleci/ruby:2.4.6-node-browsers
6
+ - image: circleci/ruby:2.7.2-node-browsers
7
7
  environment:
8
8
  RAILS_ENV: test
9
+ BUNDLE_PATH: vendor/bundle
9
10
  DB_HOST: localhost
10
11
  DB_USERNAME: valkyrie_sequel
11
12
  DB_PASSWORD: ""
@@ -23,7 +24,7 @@ jobs:
23
24
  key: valkyrie-sequel-{{ checksum "Gemfile" }}
24
25
  - run: gem install bundler -v '~> 2.0'
25
26
  # Bundle install dependencies
26
- - run: bundle install --path vendor/bundle
27
+ - run: bundle install
27
28
  # Cache Dependencies
28
29
  - type: cache-save
29
30
  name: Store bundle cache
data/.rubocop.yml CHANGED
@@ -2,7 +2,6 @@ inherit_gem:
2
2
  bixby: bixby_default.yml
3
3
  AllCops:
4
4
  DisplayCopNames: true
5
- TargetRubyVersion: 2.3
6
5
  Exclude:
7
6
  - 'bin/*'
8
7
  - 'db/schema.rb'
@@ -24,3 +23,5 @@ Metrics/ParameterLists:
24
23
  RSpec/ExampleLength:
25
24
  Exclude:
26
25
  - 'spec/valkyrie/sequel/persister_spec.rb'
26
+ Rails/RakeEnvironment:
27
+ Enabled: false
@@ -48,16 +48,16 @@ module Valkyrie::Sequel
48
48
 
49
49
  private
50
50
 
51
- def host
52
- connection.opts[:host]
53
- end
51
+ def host
52
+ connection.opts[:host]
53
+ end
54
54
 
55
- def port
56
- connection.opts[:port]
57
- end
55
+ def port
56
+ connection.opts[:port]
57
+ end
58
58
 
59
- def database
60
- connection.opts[:database]
61
- end
59
+ def database
60
+ connection.opts[:database]
61
+ end
62
62
  end
63
63
  end
@@ -8,9 +8,9 @@ module Valkyrie::Sequel
8
8
  @adapter = adapter
9
9
  end
10
10
 
11
- def save(resource:)
11
+ def save(resource:, external_resource: false)
12
12
  object_attributes = resource_factory.from_resource(resource: resource)
13
- output = create_or_update(resource: resource, attributes: object_attributes)
13
+ output = create_or_update(resource: resource, attributes: object_attributes, external_resource: external_resource)
14
14
  resource_factory.to_resource(object: output)
15
15
  end
16
16
 
@@ -121,32 +121,39 @@ module Valkyrie::Sequel
121
121
 
122
122
  private
123
123
 
124
- def create_or_update(resource:, attributes:)
125
- attributes[:updated_at] = Time.now.utc
126
- attributes[:created_at] ||= Time.now.utc
127
- return create(resource: resource, attributes: attributes) unless resource.persisted? && !exists?(id: attributes[:id])
124
+ def create_or_update(resource:, attributes:, external_resource:)
125
+ attributes[:updated_at] = Time.now.utc
126
+ attributes[:created_at] ||= Time.now.utc
127
+ if exists?(id: attributes[:id])
128
128
  update(resource: resource, attributes: attributes)
129
+ else
130
+ if !external_resource && resource.persisted?
131
+ # This resource has been deleted in the meantime, error.
132
+ raise Valkyrie::Persistence::ObjectNotFoundError, "The object #{resource.id} is previously persisted but not found at save time." unless exists?(id: attributes[:id])
133
+ end
134
+ create(resource: resource, attributes: attributes)
129
135
  end
136
+ end
130
137
 
131
- def create(resource:, attributes:)
132
- attributes[:lock_version] = 0 if resource.optimistic_locking_enabled? && resources.columns.include?(:lock_version)
133
- Array(resources.returning.insert(attributes)).first
134
- end
138
+ def create(resource:, attributes:)
139
+ attributes[:lock_version] = 0 if resource.optimistic_locking_enabled? && resources.columns.include?(:lock_version)
140
+ Array(resources.returning.insert(attributes)).first
141
+ end
135
142
 
136
- def update(resource:, attributes:)
137
- relation = resources.where(id: attributes[:id])
138
- if resource.optimistic_locking_enabled?
139
- relation = relation.where(Sequel.function(:coalesce, :lock_version, 0) => attributes[:lock_version] || 0)
140
- attributes[:lock_version] = (Sequel.function(:coalesce, :lock_version, 0) + 1)
141
- end
142
- attributes.delete(:lock_version) if attributes[:lock_version].nil?
143
- output = relation.returning.update(attributes)
144
- raise Valkyrie::Persistence::StaleObjectError, "The object #{resource.id} has been updated by another process." if output.blank? && resource.optimistic_locking_enabled?
145
- Array(output).first
143
+ def update(resource:, attributes:)
144
+ relation = resources.where(id: attributes[:id])
145
+ if resource.optimistic_locking_enabled?
146
+ relation = relation.where(Sequel.function(:coalesce, :lock_version, 0) => attributes[:lock_version] || 0)
147
+ attributes[:lock_version] = (Sequel.function(:coalesce, :lock_version, 0) + 1)
146
148
  end
149
+ attributes.delete(:lock_version) if attributes[:lock_version].nil?
150
+ output = relation.returning.update(attributes)
151
+ raise Valkyrie::Persistence::StaleObjectError, "The object #{resource.id} has been updated by another process." if output.blank? && resource.optimistic_locking_enabled?
152
+ Array(output).first
153
+ end
147
154
 
148
- def exists?(id:)
149
- resources.select(1).first(id: id).nil?
150
- end
155
+ def exists?(id:)
156
+ !resources.select(1).first(id: id).nil?
157
+ end
151
158
  end
152
159
  end
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
  module Valkyrie::Sequel
3
3
  class QueryService
4
+ # ACCEPTABLE_UUID is deprecated and unused.
5
+ # which IDs are acceptable is now decided by the database.
4
6
  ACCEPTABLE_UUID = %r{\A(\{)?([a-fA-F0-9]{4}-?){8}(?(1)\}|)\z}.freeze
7
+ DEFAULT_ID_TYPE = :uuid
8
+
5
9
  attr_reader :adapter
6
10
  delegate :resources, :resource_factory, :connection, to: :adapter
7
11
  def initialize(adapter:)
@@ -14,14 +18,27 @@ module Valkyrie::Sequel
14
18
  end
15
19
  end
16
20
 
21
+ # rubocop:disable Metrics/MethodLength
17
22
  def find_by(id:)
18
23
  id = Valkyrie::ID.new(id.to_s) if id.is_a?(String)
19
24
  validate_id(id)
20
- raise Valkyrie::Persistence::ObjectNotFoundError unless ACCEPTABLE_UUID.match?(id.to_s)
21
- attributes = resources.first(id: id.to_s)
25
+ attributes = nil
26
+ # Create a nested transaction so it can rollback to a non-essential
27
+ # savepoint if the query fails, not wrecking upstream transactions.
28
+ connection.transaction(savepoint: true) do
29
+ attributes = resources.first(id: id.to_s)
30
+ end
22
31
  raise Valkyrie::Persistence::ObjectNotFoundError unless attributes
23
32
  resource_factory.to_resource(object: attributes)
33
+ rescue Sequel::DatabaseError => err
34
+ case err.cause
35
+ when PG::InvalidTextRepresentation
36
+ raise Valkyrie::Persistence::ObjectNotFoundError
37
+ else
38
+ raise err
39
+ end
24
40
  end
41
+ # rubocop:enable Metrics/MethodLength
25
42
 
26
43
  def find_all_of_model(model:)
27
44
  resources.where(internal_resource: model.to_s).map do |attributes|
@@ -29,37 +46,45 @@ module Valkyrie::Sequel
29
46
  end
30
47
  end
31
48
 
49
+ # Count all records for a specific resource type
50
+ # @param [Class] model
51
+ # @return integer
52
+ def count_all_of_model(model:)
53
+ resources.where(internal_resource: model.to_s).count
54
+ end
55
+
32
56
  def find_many_by_ids(ids:)
33
57
  ids = ids.map do |id|
34
58
  id = Valkyrie::ID.new(id.to_s) if id.is_a?(String)
35
59
  validate_id(id)
36
60
  id.to_s
37
61
  end
38
- ids = ids.select do |id|
39
- ACCEPTABLE_UUID.match?(id)
40
- end
41
62
 
42
- resources.where(id: ids).map do |attributes|
63
+ resources.where(Sequel.lit('(id::varchar) IN ?', ids)).map do |attributes|
43
64
  resource_factory.to_resource(object: attributes)
44
65
  end
45
66
  end
46
67
 
47
- def find_references_by(resource:, property:)
68
+ def find_references_by(resource:, property:, model: nil)
48
69
  return [] if resource.id.blank? || resource[property].blank?
49
70
  # only return ordered if needed to avoid performance penalties
50
71
  if ordered_property?(resource: resource, property: property)
51
- run_query(find_ordered_references_query, property.to_s, resource.id.to_s)
72
+ find_ordered_references_by(resource: resource, property: property, model: model)
52
73
  else
53
- run_query(find_references_query, property.to_s, resource.id.to_s)
74
+ find_unordered_references_by(resource: resource, property: property, model: model)
54
75
  end
55
76
  end
56
77
 
57
- def find_inverse_references_by(resource: nil, id: nil, property:)
78
+ def find_inverse_references_by(resource: nil, id: nil, model: nil, property:)
58
79
  raise ArgumentError, "Provide resource or id" unless resource || id
59
80
  ensure_persisted(resource) if resource
60
81
  id ||= resource.id
61
82
  internal_array = { property => [id: id.to_s] }
62
- run_query(find_inverse_references_query, internal_array.to_json)
83
+ if model
84
+ run_query(find_inverse_references_with_model_query, internal_array.to_json, model.to_s)
85
+ else
86
+ run_query(find_inverse_references_query, internal_array.to_json)
87
+ end
63
88
  end
64
89
 
65
90
  # Find and a record using a Valkyrie ID for an alternate ID, and construct
@@ -100,106 +125,149 @@ module Valkyrie::Sequel
100
125
 
101
126
  private
102
127
 
103
- # Generate the SQL query for retrieving member resources in PostgreSQL using a
104
- # resource ID as an argument.
105
- # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
106
- # @note this uses a CROSS JOIN for all combinations of member IDs with the
107
- # IDs of their parents
108
- # @see https://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-FROM
109
- # This also uses JSON functions in order to retrieve JSON property values
110
- # @see https://www.postgresql.org/docs/current/static/functions-json.html
111
- # @return [String]
112
- def find_members_query
113
- <<-SQL
128
+ # Generate the SQL query for retrieving member resources in PostgreSQL using a
129
+ # resource ID as an argument.
130
+ # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
131
+ # @note this uses a CROSS JOIN for all combinations of member IDs with the
132
+ # IDs of their parents
133
+ # @see https://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-FROM
134
+ # This also uses JSON functions in order to retrieve JSON property values
135
+ # @see https://www.postgresql.org/docs/current/static/functions-json.html
136
+ # @return [String]
137
+ def find_members_query
138
+ <<-SQL
114
139
  SELECT member.* FROM orm_resources a,
115
140
  jsonb_array_elements(a.metadata->'member_ids') WITH ORDINALITY AS b(member, member_pos)
116
141
  JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ?
117
142
  ORDER BY b.member_pos
118
143
  SQL
119
- end
144
+ end
120
145
 
121
- # Generate the SQL query for retrieving member resources in PostgreSQL using a
122
- # resource ID and resource type as arguments.
123
- # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
124
- # @note this uses a CROSS JOIN for all combinations of member IDs with the
125
- # IDs of their parents
126
- # @see https://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-FROM
127
- # This also uses JSON functions in order to retrieve JSON property values
128
- # @see https://www.postgresql.org/docs/current/static/functions-json.html
129
- # @return [String]
130
- def find_members_with_type_query
131
- <<-SQL
146
+ # Generate the SQL query for retrieving member resources in PostgreSQL using a
147
+ # resource ID and resource type as arguments.
148
+ # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
149
+ # @note this uses a CROSS JOIN for all combinations of member IDs with the
150
+ # IDs of their parents
151
+ # @see https://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-FROM
152
+ # This also uses JSON functions in order to retrieve JSON property values
153
+ # @see https://www.postgresql.org/docs/current/static/functions-json.html
154
+ # @return [String]
155
+ def find_members_with_type_query
156
+ <<-SQL
132
157
  SELECT member.* FROM orm_resources a,
133
158
  jsonb_array_elements(a.metadata->'member_ids') WITH ORDINALITY AS b(member, member_pos)
134
159
  JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ?
135
160
  AND member.internal_resource = ?
136
161
  ORDER BY b.member_pos
137
162
  SQL
138
- end
163
+ end
139
164
 
140
- # Generate the SQL query for retrieving member resources in PostgreSQL using a
141
- # JSON object literal as an argument (e. g. { "alternate_ids": [{"id": "d6e88f80-41b3-4dbf-a2a0-cd79e20f6d10"}] }).
142
- # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
143
- # This uses JSON functions in order to retrieve JSON property values
144
- # @see https://www.postgresql.org/docs/current/static/functions-json.html
145
- # @return [String]
146
- def find_inverse_references_query
147
- <<-SQL
165
+ # Generate the SQL query for retrieving member resources in PostgreSQL using a
166
+ # JSON object literal as an argument (e. g. { "alternate_ids": [{"id": "d6e88f80-41b3-4dbf-a2a0-cd79e20f6d10"}] }).
167
+ # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
168
+ # This uses JSON functions in order to retrieve JSON property values
169
+ # @see https://www.postgresql.org/docs/current/static/functions-json.html
170
+ # @return [String]
171
+ def find_inverse_references_query
172
+ <<-SQL
148
173
  SELECT * FROM orm_resources WHERE
149
174
  metadata @> ?
150
175
  SQL
151
- end
176
+ end
177
+
178
+ def find_inverse_references_with_model_query
179
+ <<-SQL
180
+ SELECT * FROM orm_resources WHERE
181
+ metadata @> ?
182
+ AND internal_resource = ?
183
+ SQL
184
+ end
152
185
 
153
- # Generate the SQL query for retrieving member resources in PostgreSQL using a
154
- # JSON object literal and resource ID as arguments.
155
- # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
156
- # @note this uses a CROSS JOIN for all combinations of member IDs with the
157
- # IDs of their parents
158
- # @see https://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-FROM
159
- # This also uses JSON functions in order to retrieve JSON property values
160
- # @see https://www.postgresql.org/docs/current/static/functions-json.html
161
- # @return [String]
162
- def find_references_query
163
- <<-SQL
186
+ # Generate the SQL query for retrieving member resources in PostgreSQL using a
187
+ # JSON object literal and resource ID as arguments.
188
+ # @see https://guides.rubyonrails.org/active_record_querying.html#array-conditions
189
+ # @note this uses a CROSS JOIN for all combinations of member IDs with the
190
+ # IDs of their parents
191
+ # @see https://www.postgresql.org/docs/current/static/queries-table-expressions.html#QUERIES-FROM
192
+ # This also uses JSON functions in order to retrieve JSON property values
193
+ # @see https://www.postgresql.org/docs/current/static/functions-json.html
194
+ # @return [String]
195
+ def find_references_query
196
+ <<-SQL
164
197
  SELECT DISTINCT member.* FROM orm_resources a,
165
198
  jsonb_array_elements(a.metadata->?) AS b(member)
166
199
  JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ?
167
200
  SQL
168
- end
201
+ end
202
+
203
+ def find_references_with_type_query
204
+ <<-SQL
205
+ SELECT DISTINCT member.* FROM orm_resources a,
206
+ jsonb_array_elements(a.metadata->?) AS b(member)
207
+ JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ?
208
+ AND member.internal_resource = ?
209
+ SQL
210
+ end
169
211
 
170
- def find_ordered_references_query
171
- <<-SQL
212
+ def find_ordered_references_query
213
+ <<-SQL
172
214
  SELECT member.* FROM orm_resources a,
173
215
  jsonb_array_elements(a.metadata->?) WITH ORDINALITY AS b(member, member_pos)
174
216
  JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ?
175
217
  ORDER BY b.member_pos
176
218
  SQL
177
- end
219
+ end
178
220
 
179
- # Accesses the data type in PostgreSQL used for the primary key
180
- # (For example, a UUID)
181
- # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html#method-i-columns_hash
182
- # @return [Symbol]
183
- def id_type
184
- @id_type ||= :uuid
185
- end
221
+ def find_ordered_references_with_type_query
222
+ <<-SQL
223
+ SELECT member.* FROM orm_resources a,
224
+ jsonb_array_elements(a.metadata->?) WITH ORDINALITY AS b(member, member_pos)
225
+ JOIN orm_resources member ON (b.member->>'id')::#{id_type} = member.id WHERE a.id = ?
226
+ AND member.internal_resource = ?
227
+ ORDER BY b.member_pos
228
+ SQL
229
+ end
186
230
 
187
- # Determines whether or not an Object is a Valkyrie ID
188
- # @param [Object] id
189
- # @raise [ArgumentError]
190
- def validate_id(id)
191
- raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
192
- end
231
+ # Accesses the data type in PostgreSQL used for the primary key
232
+ # (For example, a UUID)
233
+ # @see https://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaCache.html#method-i-columns_hash
234
+ # @return [Symbol]
235
+ def id_type
236
+ @id_type ||= DEFAULT_ID_TYPE
237
+ end
193
238
 
194
- # Determines whether or not a resource has been persisted
195
- # @param [Object] resource
196
- # @raise [ArgumentError]
197
- def ensure_persisted(resource)
198
- raise ArgumentError, 'resource is not saved' unless resource.persisted?
239
+ # Determines whether or not an Object is a Valkyrie ID
240
+ # @param [Object] id
241
+ # @raise [ArgumentError]
242
+ def validate_id(id)
243
+ raise ArgumentError, 'id must be a Valkyrie::ID' unless id.is_a? Valkyrie::ID
244
+ end
245
+
246
+ # Determines whether or not a resource has been persisted
247
+ # @param [Object] resource
248
+ # @raise [ArgumentError]
249
+ def ensure_persisted(resource)
250
+ raise ArgumentError, 'resource is not saved' unless resource.persisted?
251
+ end
252
+
253
+ def ordered_property?(resource:, property:)
254
+ resource.ordered_attribute?(property)
255
+ end
256
+
257
+ def find_ordered_references_by(resource:, property:, model: nil)
258
+ if model
259
+ run_query(find_ordered_references_with_type_query, property.to_s, resource.id.to_s, model.to_s)
260
+ else
261
+ run_query(find_ordered_references_query, property.to_s, resource.id.to_s)
199
262
  end
263
+ end
200
264
 
201
- def ordered_property?(resource:, property:)
202
- resource.ordered_attribute?(property)
265
+ def find_unordered_references_by(resource:, property:, model: nil)
266
+ if model
267
+ run_query(find_references_with_type_query, property.to_s, resource.id.to_s, model.to_s)
268
+ else
269
+ run_query(find_references_query, property.to_s, resource.id.to_s)
203
270
  end
271
+ end
204
272
  end
205
273
  end
@@ -13,48 +13,48 @@ module Valkyrie::Sequel
13
13
 
14
14
  private
15
15
 
16
- # Construct a new Valkyrie Resource using the attributes retrieved from the database
17
- # @return [Valkyrie::Resource]
18
- def resource
19
- resource_klass.new(
20
- attributes.merge(
21
- new_record: false,
22
- Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK => lock_token
23
- )
16
+ # Construct a new Valkyrie Resource using the attributes retrieved from the database
17
+ # @return [Valkyrie::Resource]
18
+ def resource
19
+ resource_klass.new(
20
+ attributes.merge(
21
+ new_record: false,
22
+ Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK => lock_token
24
23
  )
25
- end
26
-
27
- # Construct the optimistic lock token using the adapter and lock version for the Resource
28
- # @return [Valkyrie::Persistence::OptimisticLockToken]
29
- def lock_token
30
- return nil unless object[:lock_version].present?
31
- @lock_token ||=
32
- Valkyrie::Persistence::OptimisticLockToken.new(
33
- adapter_id: resource_factory.adapter_id,
34
- token: object[:lock_version]
35
- )
36
- end
37
-
38
- # Retrieve the Class used to construct the Valkyrie Resource
39
- # @return [Class]
40
- def resource_klass
41
- internal_resource.constantize
42
- end
43
-
44
- # Access the String for the Valkyrie Resource type within the attributes
45
- # @return [String]
46
- def internal_resource
47
- attributes[:internal_resource]
48
- end
49
-
50
- def attributes
51
- @attributes ||= object.except(:metadata).merge(rdf_metadata).symbolize_keys
52
- end
53
-
54
- # Generate a Hash derived from Valkyrie Resource metadata encoded in the RDF
55
- # @return [Hash]
56
- def rdf_metadata
57
- @rdf_metadata ||= Valkyrie::Persistence::Shared::JSONValueMapper.new(object[:metadata]).result
58
- end
24
+ )
25
+ end
26
+
27
+ # Construct the optimistic lock token using the adapter and lock version for the Resource
28
+ # @return [Valkyrie::Persistence::OptimisticLockToken]
29
+ def lock_token
30
+ return nil if object[:lock_version].blank?
31
+ @lock_token ||=
32
+ Valkyrie::Persistence::OptimisticLockToken.new(
33
+ adapter_id: resource_factory.adapter_id,
34
+ token: object[:lock_version]
35
+ )
36
+ end
37
+
38
+ # Retrieve the Class used to construct the Valkyrie Resource
39
+ # @return [Class]
40
+ def resource_klass
41
+ internal_resource.constantize
42
+ end
43
+
44
+ # Access the String for the Valkyrie Resource type within the attributes
45
+ # @return [String]
46
+ def internal_resource
47
+ attributes[:internal_resource]
48
+ end
49
+
50
+ def attributes
51
+ @attributes ||= object.except(:metadata).merge(rdf_metadata).symbolize_keys
52
+ end
53
+
54
+ # Generate a Hash derived from Valkyrie Resource metadata encoded in the RDF
55
+ # @return [Hash]
56
+ def rdf_metadata
57
+ @rdf_metadata ||= Valkyrie::Persistence::Shared::JSONValueMapper.new(object[:metadata]).result
58
+ end
59
59
  end
60
60
  end
@@ -8,7 +8,7 @@ module Valkyrie::Sequel
8
8
  :internal_resource
9
9
  ].freeze
10
10
 
11
- BLACKLIST_TERMS = [
11
+ DISALLOWED_TERMS = [
12
12
  :new_record
13
13
  ].freeze
14
14
 
@@ -23,53 +23,52 @@ module Valkyrie::Sequel
23
23
  def convert!
24
24
  output = database_hash
25
25
  output[:id] = resource.id.to_s if resource.id
26
- output.delete(:id) unless !output[:id] || QueryService::ACCEPTABLE_UUID.match?(output[:id].to_s)
27
26
  process_lock_token(output)
28
27
  output
29
28
  end
30
29
 
31
30
  private
32
31
 
33
- # Retrieves the optimistic lock token from the Valkyrie attribute value and
34
- # sets it to the lock_version on ORM resource
35
- # @see https://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
36
- # @param [ORM::Resource] orm_object
37
- def process_lock_token(orm_object)
38
- return unless resource.respond_to?(Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK)
39
- postgres_token = (resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK] || []).find do |token|
40
- token.adapter_id == resource_factory.adapter_id
41
- end
42
- return unless postgres_token
43
- orm_object[:lock_version] = postgres_token.token
44
- end
45
-
46
- def database_hash
47
- resource_hash.select do |k, _v|
48
- PRIMARY_TERMS.include?(k)
49
- end.compact.merge(
50
- metadata: ::Sequel.pg_json(metadata_hash)
51
- )
32
+ # Retrieves the optimistic lock token from the Valkyrie attribute value and
33
+ # sets it to the lock_version on ORM resource
34
+ # @see https://api.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html
35
+ # @param [ORM::Resource] orm_object
36
+ def process_lock_token(orm_object)
37
+ return unless resource.respond_to?(Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK)
38
+ postgres_token = (resource[Valkyrie::Persistence::Attributes::OPTIMISTIC_LOCK] || []).find do |token|
39
+ token.adapter_id == resource_factory.adapter_id
52
40
  end
41
+ return unless postgres_token
42
+ orm_object[:lock_version] = postgres_token.token
43
+ end
53
44
 
54
- def resource_hash
55
- @resource_hash ||= resource.__attributes__
56
- end
45
+ def database_hash
46
+ resource_hash.select do |k, _v|
47
+ PRIMARY_TERMS.include?(k)
48
+ end.compact.merge(
49
+ metadata: ::Sequel.pg_json(metadata_hash)
50
+ )
51
+ end
57
52
 
58
- # Convert attributes to all be arrays to better enable querying and
59
- # "changing of minds" later on.
60
- # @return [Hash]
61
- def metadata_hash
62
- Hash[
63
- selected_resource_attributes.compact.map do |k, v|
64
- [k, Array.wrap(v)]
65
- end
66
- ]
67
- end
53
+ def resource_hash
54
+ @resource_hash ||= resource.__attributes__
55
+ end
68
56
 
69
- def selected_resource_attributes
70
- resource_hash.select do |k, _v|
71
- !PRIMARY_TERMS.include?(k) && !BLACKLIST_TERMS.include?(k)
57
+ # Convert attributes to all be arrays to better enable querying and
58
+ # "changing of minds" later on.
59
+ # @return [Hash]
60
+ def metadata_hash
61
+ Hash[
62
+ selected_resource_attributes.compact.map do |k, v|
63
+ [k, Array.wrap(v)]
72
64
  end
65
+ ]
66
+ end
67
+
68
+ def selected_resource_attributes
69
+ resource_hash.select do |k, _v|
70
+ !PRIMARY_TERMS.include?(k) && !DISALLOWED_TERMS.include?(k)
73
71
  end
72
+ end
74
73
  end
75
74
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Valkyrie
3
3
  module Sequel
4
- VERSION = "2.0.1"
4
+ VERSION = "3.0.0-beta.1"
5
5
  end
6
6
  end
@@ -20,16 +20,15 @@ Gem::Specification.new do |spec|
20
20
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
21
  spec.require_paths = ["lib"]
22
22
 
23
- spec.add_dependency "sequel"
24
- spec.add_dependency "sequel_pg"
25
- spec.add_dependency "valkyrie", '~> 2.0.0'
26
- spec.add_dependency "oj"
23
+ spec.add_dependency "sequel", "~> 5.0"
24
+ spec.add_dependency "sequel_pg", "~> 1.0"
25
+ spec.add_dependency "valkyrie", ">= 3.0.0-beta.1"
26
+ spec.add_dependency "oj", "~> 3.0"
27
27
  spec.add_development_dependency "bundler", "~> 2.0"
28
28
  spec.add_development_dependency "rake"
29
29
  spec.add_development_dependency "rspec", "~> 3.0"
30
30
  spec.add_development_dependency "bixby"
31
31
  spec.add_development_dependency "pry-byebug"
32
- spec.add_development_dependency "database_cleaner"
33
- spec.add_development_dependency "coveralls"
32
+ spec.add_development_dependency "database_cleaner", "< 2"
34
33
  spec.add_development_dependency "simplecov"
35
34
  end
metadata CHANGED
@@ -1,71 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: valkyrie-sequel
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 3.0.0.pre.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trey Pendragon
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-04 00:00:00.000000000 Z
11
+ date: 2021-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: '5.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sequel_pg
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '1.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '1.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: valkyrie
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 2.0.0
47
+ version: 3.0.0.pre.beta.1
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 2.0.0
54
+ version: 3.0.0.pre.beta.1
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: oj
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '3.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '3.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -140,30 +140,16 @@ dependencies:
140
140
  name: database_cleaner
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
- - - ">="
143
+ - - "<"
144
144
  - !ruby/object:Gem::Version
145
- version: '0'
145
+ version: '2'
146
146
  type: :development
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
- - - ">="
150
+ - - "<"
151
151
  - !ruby/object:Gem::Version
152
- version: '0'
153
- - !ruby/object:Gem::Dependency
154
- name: coveralls
155
- requirement: !ruby/object:Gem::Requirement
156
- requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: '0'
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - ">="
165
- - !ruby/object:Gem::Version
166
- version: '0'
152
+ version: '2'
167
153
  - !ruby/object:Gem::Dependency
168
154
  name: simplecov
169
155
  requirement: !ruby/object:Gem::Requirement
@@ -211,7 +197,7 @@ files:
211
197
  homepage: https://github.com/samvera-labs/valkyrie-sequel
212
198
  licenses: []
213
199
  metadata: {}
214
- post_install_message:
200
+ post_install_message:
215
201
  rdoc_options: []
216
202
  require_paths:
217
203
  - lib
@@ -222,12 +208,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
222
208
  version: '0'
223
209
  required_rubygems_version: !ruby/object:Gem::Requirement
224
210
  requirements:
225
- - - ">="
211
+ - - ">"
226
212
  - !ruby/object:Gem::Version
227
- version: '0'
213
+ version: 1.3.1
228
214
  requirements: []
229
215
  rubygems_version: 3.0.3
230
- signing_key:
216
+ signing_key:
231
217
  specification_version: 4
232
218
  summary: Valkyrie::MetadataAdapter for Postgres using Sequel.
233
219
  test_files: []