valkyrie-sequel 2.0.0.RC1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.circleci/config.yml +4 -2
- data/.rubocop.yml +2 -1
- data/lib/valkyrie/sequel/metadata_adapter.rb +9 -9
- data/lib/valkyrie/sequel/persister.rb +23 -23
- data/lib/valkyrie/sequel/query_service.rb +148 -80
- data/lib/valkyrie/sequel/resource_factory/orm_converter.rb +42 -42
- data/lib/valkyrie/sequel/resource_factory/resource_converter.rb +36 -37
- data/lib/valkyrie/sequel/version.rb +1 -1
- data/valkyrie-sequel.gemspec +7 -8
- metadata +34 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 02c82c0908c1a17e60365ffe3b82936ffed1c168ccc40183d78fc60000b4e7da
|
4
|
+
data.tar.gz: 434ff68cfb53eab85acc6cbe6eefe691d27eea0e01e0249475b97675c0da5f68
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bf48b6add481dcd51d4f02f3a0454d8144f6d39106a264510e5f02c0764769344cdb343a8f05038b94614d79b3b16cc0430a25a683f5b0f047cca7d8c072768
|
7
|
+
data.tar.gz: 00a6c97708c6f3653497f158d1a0aded088a73908d9559c4f276ae02f2768826a2ddb7306fa41ed5a1d146062f196f63995b5a7f6f0f4bbcc39c4e569e695446
|
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.
|
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: ""
|
@@ -21,8 +22,9 @@ jobs:
|
|
21
22
|
- type: cache-restore
|
22
23
|
name: Restore bundle cache
|
23
24
|
key: valkyrie-sequel-{{ checksum "Gemfile" }}
|
25
|
+
- run: gem install bundler -v '~> 2.0'
|
24
26
|
# Bundle install dependencies
|
25
|
-
- run: bundle install
|
27
|
+
- run: bundle install
|
26
28
|
# Cache Dependencies
|
27
29
|
- type: cache-save
|
28
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
|
-
|
52
|
-
|
53
|
-
|
51
|
+
def host
|
52
|
+
connection.opts[:host]
|
53
|
+
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
55
|
+
def port
|
56
|
+
connection.opts[:port]
|
57
|
+
end
|
58
58
|
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
def database
|
60
|
+
connection.opts[:database]
|
61
|
+
end
|
62
62
|
end
|
63
63
|
end
|
@@ -121,32 +121,32 @@ module Valkyrie::Sequel
|
|
121
121
|
|
122
122
|
private
|
123
123
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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])
|
128
|
+
update(resource: resource, attributes: attributes)
|
129
|
+
end
|
130
130
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
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
|
135
135
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
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
|
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)
|
146
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
|
146
|
+
end
|
147
147
|
|
148
|
-
|
149
|
-
|
150
|
-
|
148
|
+
def exists?(id:)
|
149
|
+
resources.select(1).first(id: id).nil?
|
150
|
+
end
|
151
151
|
end
|
152
152
|
end
|
@@ -1,7 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Valkyrie::Sequel
|
3
3
|
class QueryService
|
4
|
-
ACCEPTABLE_UUID
|
4
|
+
# ACCEPTABLE_UUID is deprecated and unused.
|
5
|
+
# which IDs are acceptable is now decided by the database.
|
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
|
-
|
21
|
-
|
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
|
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
|
-
|
72
|
+
find_ordered_references_by(resource: resource, property: property, model: model)
|
52
73
|
else
|
53
|
-
|
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
|
-
|
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
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
-
|
144
|
+
end
|
120
145
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
-
|
163
|
+
end
|
139
164
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
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
|
-
|
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
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
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
|
-
|
171
|
-
|
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
|
-
|
219
|
+
end
|
178
220
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
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
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
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
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
202
|
-
|
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
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
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
|
-
|
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
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
55
|
-
|
56
|
-
|
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
|
-
|
59
|
-
|
60
|
-
|
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
|
-
|
70
|
-
|
71
|
-
|
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
|
data/valkyrie-sequel.gemspec
CHANGED
@@ -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",
|
26
|
-
spec.add_dependency "oj"
|
27
|
-
spec.add_development_dependency "bundler", "~>
|
28
|
-
spec.add_development_dependency "rake"
|
23
|
+
spec.add_dependency "sequel", "~> 5.0"
|
24
|
+
spec.add_dependency "sequel_pg", "~> 1.0"
|
25
|
+
spec.add_dependency "valkyrie", ">= 2.1", "< 2.3"
|
26
|
+
spec.add_dependency "oj", "~> 3.0"
|
27
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
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,105 +1,105 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: valkyrie-sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.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:
|
11
|
+
date: 2021-07-01 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.
|
47
|
+
version: '2.1'
|
48
48
|
- - "<"
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: 3
|
50
|
+
version: '2.3'
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
55
|
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: 2.
|
57
|
+
version: '2.1'
|
58
58
|
- - "<"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 3
|
60
|
+
version: '2.3'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: oj
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
|
-
- - "
|
65
|
+
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '0'
|
67
|
+
version: '3.0'
|
68
68
|
type: :runtime
|
69
69
|
prerelease: false
|
70
70
|
version_requirements: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- - "
|
72
|
+
- - "~>"
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version: '0'
|
74
|
+
version: '3.0'
|
75
75
|
- !ruby/object:Gem::Dependency
|
76
76
|
name: bundler
|
77
77
|
requirement: !ruby/object:Gem::Requirement
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: '
|
81
|
+
version: '2.0'
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '2.0'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: rake
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - ">="
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version: '
|
95
|
+
version: '0'
|
96
96
|
type: :development
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - "
|
100
|
+
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: '
|
102
|
+
version: '0'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: rspec
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,30 +146,16 @@ dependencies:
|
|
146
146
|
name: database_cleaner
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
148
148
|
requirements:
|
149
|
-
- - "
|
150
|
-
- !ruby/object:Gem::Version
|
151
|
-
version: '0'
|
152
|
-
type: :development
|
153
|
-
prerelease: false
|
154
|
-
version_requirements: !ruby/object:Gem::Requirement
|
155
|
-
requirements:
|
156
|
-
- - ">="
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
version: '0'
|
159
|
-
- !ruby/object:Gem::Dependency
|
160
|
-
name: coveralls
|
161
|
-
requirement: !ruby/object:Gem::Requirement
|
162
|
-
requirements:
|
163
|
-
- - ">="
|
149
|
+
- - "<"
|
164
150
|
- !ruby/object:Gem::Version
|
165
|
-
version: '
|
151
|
+
version: '2'
|
166
152
|
type: :development
|
167
153
|
prerelease: false
|
168
154
|
version_requirements: !ruby/object:Gem::Requirement
|
169
155
|
requirements:
|
170
|
-
- - "
|
156
|
+
- - "<"
|
171
157
|
- !ruby/object:Gem::Version
|
172
|
-
version: '
|
158
|
+
version: '2'
|
173
159
|
- !ruby/object:Gem::Dependency
|
174
160
|
name: simplecov
|
175
161
|
requirement: !ruby/object:Gem::Requirement
|
@@ -217,7 +203,7 @@ files:
|
|
217
203
|
homepage: https://github.com/samvera-labs/valkyrie-sequel
|
218
204
|
licenses: []
|
219
205
|
metadata: {}
|
220
|
-
post_install_message:
|
206
|
+
post_install_message:
|
221
207
|
rdoc_options: []
|
222
208
|
require_paths:
|
223
209
|
- lib
|
@@ -228,13 +214,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
228
214
|
version: '0'
|
229
215
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
230
216
|
requirements:
|
231
|
-
- - "
|
217
|
+
- - ">="
|
232
218
|
- !ruby/object:Gem::Version
|
233
|
-
version:
|
219
|
+
version: '0'
|
234
220
|
requirements: []
|
235
|
-
|
236
|
-
|
237
|
-
signing_key:
|
221
|
+
rubygems_version: 3.1.4
|
222
|
+
signing_key:
|
238
223
|
specification_version: 4
|
239
224
|
summary: Valkyrie::MetadataAdapter for Postgres using Sequel.
|
240
225
|
test_files: []
|