valkyrie 2.0.0.RC5 → 2.0.0.RC6

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 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