valkyrie 2.0.0.RC5 → 2.0.0.RC6

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: 785deb077ba05ca2933bbb8696744609b8a870726b183e09e6a405c9a325360e
4
- data.tar.gz: 69af3b44c709c5b8cccdfdbeaa9bb0176fd17f3786d503262867e97df5ab4ff2
3
+ metadata.gz: 1336b38de11dafb9436b6f04cf20438f2bbdde2662a9f1e4fb17214b29b2628e
4
+ data.tar.gz: bf96fa3e361a65d700d01a293f149c62f27b48ea3a952b60bdc2e5907ab4a86d
5
5
  SHA512:
6
- metadata.gz: 77b7c6314d7c41ec81dd7b6b9c9efeebc98e5b870a97374d7bc4571137604a2b7f4b7c88cac58a717ea873dc48d3e64a8bad0f3f03ddd0fe08a5f5d4e8c70ea4
7
- data.tar.gz: e918e7516ace50406db02f8198eb87c0a7c29f531cc573aa0a8f9586ef6b20537abe9cb05f005d19ae1777d02a1a76ad4fc9efb3e7d89fa82830920a5b770e01
6
+ metadata.gz: 838ce2eda7f2966055f0b26d467ca92d567c90372b2a020b4eab64fc86d7cfdca7a9f7d0775885a101e19b1885682beeb1a49386e934a41eca2b6b7f23492878
7
+ data.tar.gz: 5a8567646b98d942e96582a0212b823f23d603c18fe25c5e78284bd5e73f9aed4867c7c1ab0559ce8f8235d452e7f3c23cc73ffc39ff6c4feeb83693fc2bf188
data/.circleci/config.yml CHANGED
@@ -10,7 +10,7 @@ jobs:
10
10
  type: "string"
11
11
  ruby:
12
12
  description: "Ruby version"
13
- default: "2.6.2"
13
+ default: "2.6.3"
14
14
  type: "string"
15
15
  environment:
16
16
  BUNDLE_GEMFILE: << parameters.gemfile >>
@@ -69,11 +69,11 @@ workflows:
69
69
  jobs:
70
70
  - build:
71
71
  gemfile: "gemfiles/activerecord_5_2.gemfile"
72
- ruby: 2.6.2
72
+ ruby: 2.6.3
73
73
  name: "Ruby2-6_Rails5-2"
74
74
  - build:
75
75
  gemfile: "gemfiles/activerecord_5_1.gemfile"
76
- ruby: 2.6.2
76
+ ruby: 2.6.3
77
77
  name: "Ruby2-6_Rails5-1"
78
78
  - build:
79
79
  gemfile: "gemfiles/activerecord_5_2.gemfile"
@@ -85,11 +85,11 @@ workflows:
85
85
  name: "Ruby2-5_Rails5-1"
86
86
  - build:
87
87
  gemfile: "gemfiles/activerecord_5_2.gemfile"
88
- ruby: 2.4.5
88
+ ruby: 2.4.6
89
89
  name: "Ruby2-4_Rails5-2"
90
90
  - build:
91
91
  gemfile: "gemfiles/activerecord_5_1.gemfile"
92
- ruby: 2.4.5
92
+ ruby: 2.4.6
93
93
  name: "Ruby2-4_Rails5-1"
94
94
  nightly:
95
95
  triggers:
@@ -102,11 +102,11 @@ workflows:
102
102
  jobs:
103
103
  - build:
104
104
  gemfile: "gemfiles/activerecord_5_2.gemfile"
105
- ruby: 2.6.2
105
+ ruby: 2.6.3
106
106
  name: "Ruby2-6_Rails5-2"
107
107
  - build:
108
108
  gemfile: "gemfiles/activerecord_5_1.gemfile"
109
- ruby: 2.6.2
109
+ ruby: 2.6.3
110
110
  name: "Ruby2-6_Rails5-1"
111
111
  - build:
112
112
  gemfile: "gemfiles/activerecord_5_2.gemfile"
@@ -118,9 +118,9 @@ workflows:
118
118
  name: "Ruby2-5_Rails5-1"
119
119
  - build:
120
120
  gemfile: "gemfiles/activerecord_5_2.gemfile"
121
- ruby: 2.4.5
121
+ ruby: 2.4.6
122
122
  name: "Ruby2-4_Rails5-2"
123
123
  - build:
124
124
  gemfile: "gemfiles/activerecord_5_1.gemfile"
125
- ruby: 2.4.5
125
+ ruby: 2.4.6
126
126
  name: "Ruby2-4_Rails5-1"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,75 @@
1
+ # v2.0.0 2018-04-27
2
+
3
+ ## Changes since last release
4
+
5
+ * Make LDP optional (Add `gem ldp` to Gemfile if using Fedora)
6
+ * Make ActiveRecord optional (Add `gem activerecord` to Gemfile if using
7
+ Postgres)
8
+ * Make RSolr optional (Add `gem rsolr` to Gemfile if using Solr)
9
+ * Remove deprecated `standardize_query_result` argument.
10
+ * Remove deprecated `Valkyrie::ID#to_uri`
11
+ * Remove ActiveFedora as a dependency.
12
+ * Remove deprecated `Valkyrie::Persistence::Fedora::PermissiveSchema.alternate_ids`
13
+ * Remove deprecated `Valkyrie::Persistence::Fedora::PermissiveSchema.references`
14
+ * Upgrade `dry-types` to `0.13.x`
15
+ * Fedora Adapter default is now version 5.
16
+ * Require a symbol key when instantiating a Valkyrie::Resource (string keys are no longer valid)
17
+ * Remove deprecated `type.member()` method (use `type.of()`)
18
+ * Remove deprecated `Valkyrie::Types::Int` (use `Valkyrie::Types::Integer`)
19
+
20
+ ## Changes Without Deprecations in `1.6.0`
21
+
22
+ 1. Overriding an attribute getter no longer changes the output of `to_h`. If
23
+ you've overridden something via `def title; "overwritten"; end`, then `to_h`
24
+ will now have what was set via the setter or initializer, not `overwritten`.
25
+ 2. Setting attribute values via overriding instance variables no longer works.
26
+ Please use `#set_value` if you need dynamic setting, as this will be a stable
27
+ API.
28
+ 3. `Valkyrie::Resource#to_h` no longer includes keys with `nil` values.
29
+
30
+ ## Upgrade Guide
31
+
32
+ 1. Upgrade Valkyrie to `1.6.0` in your application, run tests, and fix all
33
+ deprecations output to console.
34
+ 2. Upgrade Valkyrie to `2.0.0` in your application.
35
+ 3. Failing tests at this point are likely due to behavior in the "Changes
36
+ Without Deprecations" section above. If you have any trouble, please contact
37
+ us in the #valkyrie channel in [Samvera Slack](http://slack.samvera.org/).
38
+
39
+ ## New Product Owner
40
+
41
+ All of us who have been part of the Valkyrie project so far would like to thank
42
+ [Carolyn Cole](https://github.com/carolyncole) for her role so far as Product Owner.
43
+ We'd like to welcome [Kate Lynch](https://github.com/kelynch), who will be
44
+ taking over effective immediately!
45
+
46
+ ## Special Thanks
47
+
48
+ This is the first major version of Valkyrie since 1.0 over a year ago. A lot of
49
+ work has gone into it, and I'd like to take the chance to thank everyone
50
+ involved for their contributions in the last year:
51
+
52
+
53
+ [DanCoughlin](https://github.com/DanCoughlin)
54
+ [awead](https://github.com/awead)
55
+ [cam156](https://github.com/cam156)
56
+ [carolyncole](https://github.com/carolyncole)
57
+ [cjcolvar](https://github.com/cjcolvar)
58
+ [dgcliff](https://github.com/dgcliff)
59
+ [escowles](https://github.com/escowles)
60
+ [hackmastera](https://github.com/hackmastera)
61
+ [jeremyf](https://github.com/jeremyf)
62
+ [jrgriffiniii](https://github.com/jrgriffiniii)
63
+ [kelynch](https://github.com/kelynch)
64
+ [mbklein](https://github.com/mbklein)
65
+ [mjgiarlo](https://github.com/mjgiarlo)
66
+ [mtribone](https://github.com/mtribone)
67
+ [no-reply](https://github.com/no-reply)
68
+ [ojlyytinen](https://github.com/ojlyytinen)
69
+ [revgum](https://github.com/revgum)
70
+ [stkenny](https://github.com/stkenny)
71
+ [tpendragon](https://github.com/tpendragon)
72
+
1
73
  # v1.6.0 2018-04-17
2
74
 
3
75
  ## Changes since last release
data/README.md CHANGED
@@ -17,7 +17,7 @@ Jump in: [![Slack Status](http://slack.samvera.org/badge.svg)](http://slack.samv
17
17
  ## Primary Contacts
18
18
 
19
19
  ### Product Owner
20
- [Carolyn Cole](https://github.com/cam156)
20
+ [Kate Lynch](https://github.com/kelynch)
21
21
 
22
22
  ### Technical Lead
23
23
  [Trey Pendragon](https://github.com/tpendragon)
@@ -103,11 +103,11 @@ end
103
103
  ```
104
104
 
105
105
  The initializer registers four `Valkyrie::MetadataAdapter` instances for storing metadata:
106
- * `:postgres` which stores metadata in a PostgreSQL database
107
- * `:solr` which stores metadata in a Solr Index
108
106
  * `:fedora` which stores metadata in a Fedora server.
109
107
  * `:memory` which stores metadata in an in-memory cache (this cache is not persistent, so it is only
110
- appropriate for testing)
108
+ appropriate for testing).
109
+ * `:postgres` which stores metadata in a PostgreSQL database.
110
+ * `:solr` which stores metadata in a Solr Index.
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
data/lib/valkyrie.rb CHANGED
@@ -6,9 +6,7 @@ require 'active_support/core_ext'
6
6
  require 'dry-types'
7
7
  require 'dry-struct'
8
8
  require 'draper'
9
- require 'active_record'
10
9
  require 'reform'
11
- require 'reform/active_record'
12
10
  require 'rdf'
13
11
  require 'valkyrie/rdf_patches'
14
12
  require 'json/ld'
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
  require 'reform/form/coercion'
3
+ require 'reform/form/orm'
4
+ require 'reform/form/active_model'
3
5
  require 'reform/form/active_model/validations'
6
+ require 'reform/form/active_model/model_reflections'
7
+ require 'reform/form/active_model/form_builder_methods'
4
8
  module Valkyrie
5
9
  ##
6
10
  # Standard change set object for Valkyrie.
@@ -16,7 +20,9 @@ module Valkyrie
16
20
  class ChangeSet < Reform::Form
17
21
  include Reform::Form::ORM
18
22
  include Reform::Form::ModelReflections
23
+ include Reform::Form::ActiveModel
19
24
  include Reform::Form::ActiveModel::Validations
25
+ include Reform::Form::ActiveModel::FormBuilderMethods
20
26
  feature Coercion
21
27
  class_attribute :fields
22
28
  self.fields = []
@@ -62,6 +68,9 @@ module Valkyrie
62
68
  fields
63
69
  end
64
70
 
71
+ # Override reflect_on_association so SimpleForm can work.
72
+ def self.reflect_on_association(*_args); end
73
+
65
74
  # Returns value for a given property.
66
75
  # @param key [Symbol]
67
76
  def [](key)
@@ -31,6 +31,7 @@ module Valkyrie
31
31
  require 'valkyrie/persistence/composite_persister'
32
32
  require 'valkyrie/persistence/delete_tracking_buffer'
33
33
  require 'valkyrie/persistence/buffered_persister'
34
+ require 'valkyrie/persistence/shared'
34
35
  autoload :Postgres, 'valkyrie/persistence/postgres'
35
36
  autoload :Solr, 'valkyrie/persistence/solr'
36
37
  autoload :Fedora, 'valkyrie/persistence/fedora'
@@ -201,8 +201,8 @@ module Valkyrie::Persistence::Fedora
201
201
  end
202
202
 
203
203
  def self.ordered?(value)
204
- return false unless value.resource.class.schema[value.key]
205
- value.resource.class.schema[value.key].meta.try(:[], :ordered)
204
+ return false unless value.resource.class.attribute_names.include?(value.key)
205
+ value.resource.ordered_attribute?(value.key)
206
206
  end
207
207
 
208
208
  delegate :subject, to: :value
@@ -171,7 +171,7 @@ module Valkyrie::Persistence::Fedora
171
171
  end
172
172
 
173
173
  def ordered_property?(resource:, property:)
174
- resource.class.schema[property].meta.try(:[], :ordered)
174
+ resource.ordered_attribute?(property)
175
175
  end
176
176
  end
177
177
  end
@@ -157,7 +157,7 @@ module Valkyrie::Persistence::Memory
157
157
  end
158
158
 
159
159
  def ordered_property?(resource:, property:)
160
- resource.class.schema[property].meta.try(:[], :ordered)
160
+ resource.ordered_attribute?(property)
161
161
  end
162
162
  end
163
163
  end
@@ -79,157 +79,7 @@ module Valkyrie::Persistence::Postgres
79
79
  # Responsible for converting `metadata` JSON-B field in
80
80
  # {Valkyrie::Persistence::Postgres::ORM::Resource} into an acceptable hash
81
81
  # for {Valkyrie::Resource}
82
- class RDFMetadata
83
- attr_reader :metadata
84
-
85
- # @param [Hash] metadata
86
- def initialize(metadata)
87
- # nil hash values are handled by the default state in dry-types
88
- # anyways, so don't bother processing them here.
89
- @metadata = metadata.compact
90
- end
91
-
92
- # Convert the database attribute values and map these to the existing keys in the Valkyrie Resource metadata
93
- # @return [Hash]
94
- def result
95
- Hash[
96
- metadata.map do |key, value|
97
- [key, PostgresValue.for(value).result]
98
- end
99
- ]
100
- end
101
-
102
- # Abstract base class for mapping PostgreSQL database field values to Valkyrie Resource attributes
103
- class PostgresValue < ::Valkyrie::ValueMapper
104
- end
105
-
106
- # Converts {RDF::Literal} typed-literals from JSON-LD stored into an
107
- # {RDF::Literal}
108
- class HashValue < ::Valkyrie::ValueMapper
109
- PostgresValue.register(self)
110
-
111
- # Determines whether or not a value is a Hash containing the key "@value"
112
- # @param [Object] value
113
- # @return [Boolean]
114
- def self.handles?(value)
115
- value.is_a?(Hash) && value["@value"]
116
- end
117
-
118
- # Constructs a RDF::Literal object using the Object keyed to "@value"
119
- # in the value Hash, as well as the language keyed to "@language" and
120
- # datatype keyed to "@type"
121
- # @return [RDF::Literal]
122
- def result
123
- RDF::Literal.new(value["@value"],
124
- language: value["@language"],
125
- datatype: value["@type"])
126
- end
127
- end
128
-
129
- # Converts stored IDs into {Valkyrie::ID}s
130
- class IDValue < ::Valkyrie::ValueMapper
131
- PostgresValue.register(self)
132
-
133
- # Determines whether or not a value is a Hash containing the key "id" (excluding those storing the Valkyrie Resource type)
134
- # @param [Object] value
135
- # @return [Boolean]
136
- def self.handles?(value)
137
- value.is_a?(Hash) && value["id"] && !value["internal_resource"]
138
- end
139
-
140
- # Constructs a Valkyrie::ID object using the String keyed to "id" in the value
141
- # @return [Valkyrie::ID]
142
- def result
143
- Valkyrie::ID.new(value["id"])
144
- end
145
- end
146
-
147
- # Converts stored URIs into {RDF::URI}s
148
- class URIValue < ::Valkyrie::ValueMapper
149
- PostgresValue.register(self)
150
-
151
- # Determines whether or not a value is a Hash containing the key "@id"
152
- # @param [Object] value
153
- # @return [Boolean]
154
- def self.handles?(value)
155
- value.is_a?(Hash) && value["@id"]
156
- end
157
-
158
- # Constructs a RDF::URI object using the URI keyed to @id in the value
159
- # @return [RDF::URI]
160
- def result
161
- ::RDF::URI.new(value["@id"])
162
- end
163
- end
164
-
165
- # Converts nested records into {Valkyrie::Resource}s
166
- class NestedRecord < ::Valkyrie::ValueMapper
167
- PostgresValue.register(self)
168
-
169
- # Determines whether or not a value is a Hash containing multiple keys
170
- # @param [Object] value
171
- # @return [Boolean]
172
- def self.handles?(value)
173
- value.is_a?(Hash) && value.keys.length > 1
174
- end
175
-
176
- # Generates a Hash derived from the RDFMetadata for the value
177
- # @return [Hash]
178
- def result
179
- RDFMetadata.new(value).result.symbolize_keys
180
- end
181
- end
182
-
183
- # Handles iterating over arrays of values and converting each value.
184
- class EnumeratorValue < ::Valkyrie::ValueMapper
185
- PostgresValue.register(self)
186
-
187
- # Determines whether or not a value has enumerable behavior
188
- # @param [Object] value
189
- # @return [Boolean]
190
- def self.handles?(value)
191
- value.respond_to?(:each)
192
- end
193
-
194
- # Convert the elements in the enumerable value in Valkyrie attribute values
195
- # Casts single-valued arrays to the first value, letting Types::Set and
196
- # Types::Array handle converting it back.
197
- # @return [Array<Object>]
198
- def result
199
- if value.length == 1
200
- calling_mapper.for(value.first).result
201
- else
202
- value.map do |value|
203
- calling_mapper.for(value).result
204
- end
205
- end
206
- end
207
- end
208
-
209
- # Converts Date strings to `DateTime`
210
- class DateValue < ::Valkyrie::ValueMapper
211
- PostgresValue.register(self)
212
-
213
- # Determines whether or not a value is an ISO 8601 datestamp String
214
- # e. g. 1970-01-01
215
- # @param [Object] value
216
- # @return [Boolean]
217
- def self.handles?(value)
218
- return false unless value.is_a?(String)
219
- return false unless value[4] == "-"
220
- year = value.to_s[0..3]
221
- return false unless year.length == 4 && year.to_i.to_s == year
222
- DateTime.iso8601(value)
223
- rescue
224
- false
225
- end
226
-
227
- # Generates a Time object in the UTC from the datestamp string value
228
- # @return [Time]
229
- def result
230
- DateTime.iso8601(value).utc
231
- end
232
- end
82
+ class RDFMetadata < ::Valkyrie::Persistence::Shared::JSONValueMapper
233
83
  end
234
84
  end
235
85
  end
@@ -237,7 +237,7 @@ module Valkyrie::Persistence::Postgres
237
237
  end
238
238
 
239
239
  def ordered_property?(resource:, property:)
240
- resource.class.schema[property].meta.try(:[], :ordered)
240
+ resource.ordered_attribute?(property)
241
241
  end
242
242
  end
243
243
  end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence
3
+ module Shared
4
+ require 'valkyrie/persistence/shared/json_value_mapper'
5
+ end
6
+ end
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Shared
3
+ # Converts a hash representation of a Resource back into a Resource.
4
+ # Often useful for converting back from JSON.
5
+ class JSONValueMapper
6
+ attr_reader :metadata
7
+
8
+ # @param [Hash] metadata
9
+ def initialize(metadata)
10
+ # nil hash values are handled by the default state in dry-types
11
+ # anyways, so don't bother processing them here.
12
+ @metadata = metadata.compact
13
+ end
14
+
15
+ # Convert the database attribute values and map these to the existing keys in the Valkyrie Resource metadata
16
+ # @return [Hash]
17
+ def result
18
+ Hash[
19
+ metadata.map do |key, value|
20
+ [key, PostgresValue.for(value).result]
21
+ end
22
+ ]
23
+ end
24
+
25
+ # Abstract base class for mapping PostgreSQL database field values to Valkyrie Resource attributes
26
+ class PostgresValue < ::Valkyrie::ValueMapper
27
+ end
28
+
29
+ # Converts {RDF::Literal} typed-literals from JSON-LD stored into an
30
+ # {RDF::Literal}
31
+ class HashValue < ::Valkyrie::ValueMapper
32
+ PostgresValue.register(self)
33
+
34
+ # Determines whether or not a value is a Hash containing the key "@value"
35
+ # @param [Object] value
36
+ # @return [Boolean]
37
+ def self.handles?(value)
38
+ value.is_a?(Hash) && value["@value"]
39
+ end
40
+
41
+ # Constructs a RDF::Literal object using the Object keyed to "@value"
42
+ # in the value Hash, as well as the language keyed to "@language" and
43
+ # datatype keyed to "@type"
44
+ # @return [RDF::Literal]
45
+ def result
46
+ RDF::Literal.new(value["@value"],
47
+ language: value["@language"],
48
+ datatype: value["@type"])
49
+ end
50
+ end
51
+
52
+ # Converts stored IDs into {Valkyrie::ID}s
53
+ class IDValue < ::Valkyrie::ValueMapper
54
+ PostgresValue.register(self)
55
+
56
+ # Determines whether or not a value is a Hash containing the key "id" (excluding those storing the Valkyrie Resource type)
57
+ # @param [Object] value
58
+ # @return [Boolean]
59
+ def self.handles?(value)
60
+ value.is_a?(Hash) && value["id"] && !value["internal_resource"]
61
+ end
62
+
63
+ # Constructs a Valkyrie::ID object using the String keyed to "id" in the value
64
+ # @return [Valkyrie::ID]
65
+ def result
66
+ Valkyrie::ID.new(value["id"])
67
+ end
68
+ end
69
+
70
+ # Converts stored URIs into {RDF::URI}s
71
+ class URIValue < ::Valkyrie::ValueMapper
72
+ PostgresValue.register(self)
73
+
74
+ # Determines whether or not a value is a Hash containing the key "@id"
75
+ # @param [Object] value
76
+ # @return [Boolean]
77
+ def self.handles?(value)
78
+ value.is_a?(Hash) && value["@id"]
79
+ end
80
+
81
+ # Constructs a RDF::URI object using the URI keyed to @id in the value
82
+ # @return [RDF::URI]
83
+ def result
84
+ ::RDF::URI.new(value["@id"])
85
+ end
86
+ end
87
+
88
+ # Converts nested records into {Valkyrie::Resource}s
89
+ class NestedRecord < ::Valkyrie::ValueMapper
90
+ PostgresValue.register(self)
91
+
92
+ # Determines whether or not a value is a Hash containing multiple keys
93
+ # @param [Object] value
94
+ # @return [Boolean]
95
+ def self.handles?(value)
96
+ value.is_a?(Hash) && value.keys.length > 1
97
+ end
98
+
99
+ # Generates a Hash derived from the JSON for the value
100
+ # @return [Hash]
101
+ def result
102
+ Valkyrie::Persistence::Shared::JSONValueMapper.new(value).result.symbolize_keys
103
+ end
104
+ end
105
+
106
+ # Handles iterating over arrays of values and converting each value.
107
+ class EnumeratorValue < ::Valkyrie::ValueMapper
108
+ PostgresValue.register(self)
109
+
110
+ # Determines whether or not a value has enumerable behavior
111
+ # @param [Object] value
112
+ # @return [Boolean]
113
+ def self.handles?(value)
114
+ value.respond_to?(:each)
115
+ end
116
+
117
+ # Convert the elements in the enumerable value in Valkyrie attribute values
118
+ # Casts single-valued arrays to the first value, letting Types::Set and
119
+ # Types::Array handle converting it back.
120
+ # @return [Array<Object>]
121
+ def result
122
+ if value.length == 1
123
+ calling_mapper.for(value.first).result
124
+ else
125
+ value.map do |value|
126
+ calling_mapper.for(value).result
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+ # Converts Date strings to `DateTime`
133
+ class DateValue < ::Valkyrie::ValueMapper
134
+ PostgresValue.register(self)
135
+
136
+ # Determines whether or not a value is an ISO 8601 datestamp String
137
+ # e. g. 1970-01-01
138
+ # @param [Object] value
139
+ # @return [Boolean]
140
+ def self.handles?(value)
141
+ return false unless value.is_a?(String)
142
+ return false unless value[4] == "-"
143
+ year = value.to_s[0..3]
144
+ return false unless year.length == 4 && year.to_i.to_s == year
145
+ DateTime.iso8601(value)
146
+ rescue
147
+ false
148
+ end
149
+
150
+ # Generates a Time object in the UTC from the datestamp string value
151
+ # @return [Time]
152
+ def result
153
+ DateTime.iso8601(value).utc
154
+ end
155
+ end
156
+ end
157
+ end
@@ -120,7 +120,7 @@ module Valkyrie::Persistence::Solr
120
120
  end
121
121
 
122
122
  def ordered_property?(resource:, property:)
123
- resource.class.schema[property].meta.try(:[], :ordered)
123
+ resource.ordered_attribute?(property)
124
124
  end
125
125
  end
126
126
  end
@@ -19,15 +19,7 @@ module Valkyrie
19
19
  # available key, and makes sure the defaults are set up if no value is
20
20
  # given.
21
21
  def self.allow_nonexistent_keys
22
- nil_2_undef = ->(v) { v.nil? ? Dry::Types::Undefined : v }
23
- transform_types do |type|
24
- current_meta = type.meta.merge(omittable: true)
25
- if type.default?
26
- type.constructor(nil_2_undef).meta(current_meta)
27
- else
28
- type.meta(current_meta)
29
- end
30
- end
22
+ transform_types(&:omittable)
31
23
  end
32
24
 
33
25
  # Overridden to provide default attributes.
@@ -36,7 +28,7 @@ module Valkyrie
36
28
  super(subclass)
37
29
  subclass.allow_nonexistent_keys
38
30
  subclass.attribute :id, Valkyrie::Types::ID.optional, internal: true
39
- subclass.attribute :internal_resource, Valkyrie::Types::Any.default(subclass.to_s), internal: true
31
+ subclass.attribute :internal_resource, Valkyrie::Types::Any.default(subclass.to_s.freeze), internal: true
40
32
  subclass.attribute :created_at, Valkyrie::Types::DateTime.optional, internal: true
41
33
  subclass.attribute :updated_at, Valkyrie::Types::DateTime.optional, internal: true
42
34
  subclass.attribute :new_record, Types::Bool.default(true), internal: true
@@ -44,7 +36,7 @@ module Valkyrie
44
36
 
45
37
  # @return [Array<Symbol>] Array of fields defined for this class.
46
38
  def self.fields
47
- schema.keys.without(:new_record)
39
+ attribute_names.without(:new_record)
48
40
  end
49
41
 
50
42
  # Define an attribute. Attributes are used to describe resources.
@@ -53,7 +45,9 @@ module Valkyrie
53
45
  # @note Overridden from {Dry::Struct} to make the default type
54
46
  # {Valkyrie::Types::Set}
55
47
  def self.attribute(name, type = Valkyrie::Types::Set.optional, internal: false)
56
- raise ReservedAttributeError, "#{name} is a reserved attribute and defined by Valkyrie::Resource, do not redefine it." if reserved_attributes.include?(name.to_sym) && schema[name] && !internal
48
+ raise ReservedAttributeError, "#{name} is a reserved attribute and defined by Valkyrie::Resource, do not redefine it." if reserved_attributes.include?(name.to_sym) &&
49
+ attribute_names.include?(name.to_sym) &&
50
+ !internal
57
51
  define_method("#{name}=") do |value|
58
52
  set_value(name, value)
59
53
  end
@@ -94,7 +88,11 @@ module Valkyrie
94
88
  end
95
89
 
96
90
  def attributes
97
- super.dup.freeze
91
+ Hash[self.class.attribute_names.map { |x| [x, nil] }].merge(super).freeze
92
+ end
93
+
94
+ def __attributes__
95
+ Hash[@attributes].freeze
98
96
  end
99
97
 
100
98
  def dup
@@ -158,7 +156,12 @@ module Valkyrie
158
156
  # @param key [#to_sym] the name of the attribute to set
159
157
  # @param value [] the value to set key to.
160
158
  def set_value(key, value)
161
- @attributes[key.to_sym] = self.class.schema[key.to_sym].call(value)
159
+ @attributes[key.to_sym] = self.class.schema.key(key.to_sym).type.call(value)
160
+ end
161
+
162
+ # Returns if an attribute is set as ordered.
163
+ def ordered_attribute?(key)
164
+ self.class.schema.key(key).type.meta.try(:[], :ordered)
162
165
  end
163
166
 
164
167
  class ReservedAttributeError < StandardError; end
@@ -76,7 +76,6 @@ RSpec.shared_examples 'a Valkyrie::Resource' do
76
76
  resource.my_property = "test"
77
77
 
78
78
  expect(resource[:my_property]).to eq ["test"]
79
- resource_klass.schema.delete(:my_property)
80
79
  end
81
80
  it "returns nil for non-existent properties" do
82
81
  resource = resource_klass.new
@@ -90,10 +89,17 @@ RSpec.shared_examples 'a Valkyrie::Resource' do
90
89
  resource.other_property = "test"
91
90
 
92
91
  expect(resource["other_property"]).to eq ["test"]
93
- resource_klass.schema.delete(:other_property)
92
+
93
+ unset_key(resource_klass, :other_property)
94
94
  end
95
95
  end
96
96
 
97
+ def unset_key(resource_klass, property)
98
+ resource_klass.schema(Dry::Types::Schema.new(Hash, **resource_klass.schema.options, keys: resource_klass.schema.keys.select { |x| x.name != property }, meta: resource_klass.schema.meta))
99
+ resource_klass.instance_variable_set(:@attribute_names, nil)
100
+ resource_klass.allow_nonexistent_keys
101
+ end
102
+
97
103
  describe "#set_value" do
98
104
  it "can set a value" do
99
105
  resource_klass.attribute :set_value_property unless resource_klass.schema.key?(:set_value_property)
@@ -104,7 +110,7 @@ RSpec.shared_examples 'a Valkyrie::Resource' do
104
110
  expect(resource.set_value_property).to eq ["test"]
105
111
  resource.set_value("set_value_property", "testing")
106
112
  expect(resource.set_value_property).to eq ["testing"]
107
- resource_klass.schema.delete(:set_value_property)
113
+ unset_key(resource_klass, :set_value_property)
108
114
  end
109
115
  end
110
116
 
@@ -115,14 +121,14 @@ RSpec.shared_examples 'a Valkyrie::Resource' do
115
121
  resource = resource_klass.new(symbol_property: "bla")
116
122
 
117
123
  expect(resource.symbol_property).to eq ["bla"]
118
- resource_klass.schema.delete(:symbol_property)
124
+ unset_key(resource_klass, :symbol_property)
119
125
  end
120
126
  it "can not set values with string properties" do
121
127
  resource_klass.attribute :string_property unless resource_klass.schema.key?(:string_property)
122
128
 
123
129
  resource = nil
124
130
  expect(resource).not_to respond_to :string_property
125
- resource_klass.schema.delete(:string_property)
131
+ unset_key(resource_klass, :string_property)
126
132
  end
127
133
  end
128
134
 
@@ -137,7 +143,22 @@ RSpec.shared_examples 'a Valkyrie::Resource' do
137
143
  expect(resource.attributes[:internal_resource]).to eq resource_klass.to_s
138
144
  expect { resource.attributes.dup[:internal_resource] = "bla" }.not_to output.to_stderr
139
145
 
140
- resource_klass.schema.delete(:bla)
146
+ unset_key(resource_klass, :bla)
147
+ resource = resource_klass.new
148
+ expect(resource.attributes).not_to have_key(:bla)
149
+ end
150
+ end
151
+
152
+ describe "#__attributes__" do
153
+ it "returns all defined attributes, but doesn't add nil keys" do
154
+ resource_klass.attribute :bla unless resource_klass.schema.key?(:bla)
155
+
156
+ resource = resource_klass.new
157
+ expect(resource.__attributes__).to be_frozen
158
+ expect(resource.__attributes__).not_to have_key :bla
159
+ expect(resource.__attributes__).to have_key :internal_resource
160
+
161
+ unset_key(resource_klass, :bla)
141
162
  end
142
163
  end
143
164
  end
@@ -15,10 +15,10 @@ module Valkyrie
15
15
  # @note Not all Dry::Types built-in types are supported in Valkyrie
16
16
  # @see https://github.com/samvera-labs/valkyrie/wiki/Supported-Data-Types List of types supported in Valkyrie
17
17
  module Types
18
- include Dry::Types.module
18
+ include Dry.Types(default: :nominal)
19
19
 
20
20
  # Valkyrie::ID
21
- ID = Dry::Types::Definition
21
+ ID = Dry::Types::Nominal
22
22
  .new(Valkyrie::ID)
23
23
  .constructor do |input|
24
24
  if input.respond_to?(:each)
@@ -40,7 +40,7 @@ module Valkyrie
40
40
  end
41
41
 
42
42
  # Valkyrie::URI
43
- URI = Dry::Types::Definition
43
+ URI = Dry::Types::Nominal
44
44
  .new(RDF::URI)
45
45
  .constructor do |input|
46
46
  if input.present?
@@ -52,7 +52,7 @@ module Valkyrie
52
52
 
53
53
  # Optimistic Lock Token
54
54
  OptimisticLockToken =
55
- Dry::Types::Definition
55
+ Dry::Types::Nominal
56
56
  .new(::Valkyrie::Persistence::OptimisticLockToken)
57
57
  .constructor do |input|
58
58
  Valkyrie::Persistence::OptimisticLockToken.deserialize(input)
@@ -96,13 +96,6 @@ module Valkyrie
96
96
  def of(type)
97
97
  super.default([].freeze)
98
98
  end
99
-
100
- # Override optional to provide a default because without it an
101
- # instantiated Valkyrie::Resource's internal hash does not have values for
102
- # every possible attribute, resulting in `MissingAttributeError`.
103
- def optional
104
- super.default(nil)
105
- end
106
99
  end
107
100
  Array.singleton_class.include(ArrayDefault)
108
101
  Set.singleton_class.include(ArrayDefault)
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Valkyrie
3
- VERSION = "2.0.0.RC5"
3
+ VERSION = "2.0.0.RC6"
4
4
  end
data/valkyrie.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency 'dry-struct'
23
23
  spec.add_dependency 'draper'
24
24
  spec.add_dependency 'activemodel'
25
- spec.add_dependency 'dry-types', '~> 0.13.0'
25
+ spec.add_dependency 'dry-types', '~> 1.0'
26
26
  spec.add_dependency 'rdf'
27
27
  spec.add_dependency 'activesupport'
28
28
  spec.add_dependency 'railties' # To use generators and engines
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
31
31
  spec.add_dependency 'json-ld'
32
32
  spec.add_dependency 'json'
33
33
  spec.add_dependency 'rdf-vocab'
34
+ spec.add_dependency 'disposable', '~> 0.4.5'
34
35
 
35
36
  spec.add_development_dependency "bundler", "~> 1.16"
36
37
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: valkyrie
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.RC5
4
+ version: 2.0.0.RC6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trey Pendragon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-23 00:00:00.000000000 Z
11
+ date: 2019-05-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-struct
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.13.0
61
+ version: '1.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.13.0
68
+ version: '1.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rdf
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +178,20 @@ dependencies:
178
178
  - - ">="
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0'
181
+ - !ruby/object:Gem::Dependency
182
+ name: disposable
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 0.4.5
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 0.4.5
181
195
  - !ruby/object:Gem::Dependency
182
196
  name: bundler
183
197
  requirement: !ruby/object:Gem::Requirement
@@ -474,6 +488,8 @@ files:
474
488
  - lib/valkyrie/persistence/postgres/query_service.rb
475
489
  - lib/valkyrie/persistence/postgres/resource_converter.rb
476
490
  - lib/valkyrie/persistence/postgres/resource_factory.rb
491
+ - lib/valkyrie/persistence/shared.rb
492
+ - lib/valkyrie/persistence/shared/json_value_mapper.rb
477
493
  - lib/valkyrie/persistence/solr.rb
478
494
  - lib/valkyrie/persistence/solr/composite_indexer.rb
479
495
  - lib/valkyrie/persistence/solr/metadata_adapter.rb