valkyrie 0.0.0 → 0.1.0

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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -3
  3. data/.rubocop.yml +28 -0
  4. data/Gemfile +6 -1
  5. data/README.md +145 -10
  6. data/Rakefile +59 -1
  7. data/bin/console +1 -1
  8. data/config/valkyrie.yml +8 -0
  9. data/db/config.yml +17 -0
  10. data/db/migrate/20160111215816_enable_uuid_extension.rb +6 -0
  11. data/db/migrate/20161007101725_create_orm_resources.rb +10 -0
  12. data/db/migrate/20170124135846_add_model_type_to_orm_resources.rb +6 -0
  13. data/db/migrate/20170531004548_change_model_type_to_internal_model.rb +6 -0
  14. data/db/schema.rb +65 -0
  15. data/db/seeds.rb +8 -0
  16. data/lib/config/database_connection.rb +15 -0
  17. data/lib/generators/valkyrie/resource_generator.rb +27 -0
  18. data/lib/generators/valkyrie/templates/resource.rb.erb +9 -0
  19. data/lib/generators/valkyrie/templates/resource_spec.rb.erb +13 -0
  20. data/lib/valkyrie.rb +76 -1
  21. data/lib/valkyrie/adapter_container.rb +12 -0
  22. data/lib/valkyrie/change_set.rb +84 -0
  23. data/lib/valkyrie/decorators/decorator_list.rb +15 -0
  24. data/lib/valkyrie/decorators/decorator_with_arguments.rb +14 -0
  25. data/lib/valkyrie/derivative_service.rb +42 -0
  26. data/lib/valkyrie/engine.rb +10 -0
  27. data/lib/valkyrie/file_characterization_service.rb +42 -0
  28. data/lib/valkyrie/id.rb +32 -0
  29. data/lib/valkyrie/indexers/access_controls_indexer.rb +19 -0
  30. data/lib/valkyrie/local_file_service.rb +11 -0
  31. data/lib/valkyrie/metadata_adapter.rb +22 -0
  32. data/lib/valkyrie/persist_derivatives.rb +29 -0
  33. data/lib/valkyrie/persistence.rb +14 -0
  34. data/lib/valkyrie/persistence/buffered_persister.rb +28 -0
  35. data/lib/valkyrie/persistence/composite_persister.rb +29 -0
  36. data/lib/valkyrie/persistence/delete_tracking_buffer.rb +21 -0
  37. data/lib/valkyrie/persistence/fedora.rb +11 -0
  38. data/lib/valkyrie/persistence/fedora/list_node.rb +88 -0
  39. data/lib/valkyrie/persistence/fedora/metadata_adapter.rb +45 -0
  40. data/lib/valkyrie/persistence/fedora/ordered_list.rb +146 -0
  41. data/lib/valkyrie/persistence/fedora/ordered_reader.rb +28 -0
  42. data/lib/valkyrie/persistence/fedora/persister.rb +47 -0
  43. data/lib/valkyrie/persistence/fedora/persister/model_converter.rb +199 -0
  44. data/lib/valkyrie/persistence/fedora/persister/orm_converter.rb +338 -0
  45. data/lib/valkyrie/persistence/fedora/persister/resource_factory.rb +21 -0
  46. data/lib/valkyrie/persistence/fedora/query_service.rb +80 -0
  47. data/lib/valkyrie/persistence/memory.rb +8 -0
  48. data/lib/valkyrie/persistence/memory/metadata_adapter.rb +22 -0
  49. data/lib/valkyrie/persistence/memory/persister.rb +58 -0
  50. data/lib/valkyrie/persistence/memory/query_service.rb +86 -0
  51. data/lib/valkyrie/persistence/postgres.rb +6 -0
  52. data/lib/valkyrie/persistence/postgres/metadata_adapter.rb +20 -0
  53. data/lib/valkyrie/persistence/postgres/orm.rb +9 -0
  54. data/lib/valkyrie/persistence/postgres/orm/resource.rb +7 -0
  55. data/lib/valkyrie/persistence/postgres/orm_converter.rb +118 -0
  56. data/lib/valkyrie/persistence/postgres/persister.rb +33 -0
  57. data/lib/valkyrie/persistence/postgres/queries.rb +8 -0
  58. data/lib/valkyrie/persistence/postgres/queries/find_inverse_references_query.rb +31 -0
  59. data/lib/valkyrie/persistence/postgres/queries/find_members_query.rb +33 -0
  60. data/lib/valkyrie/persistence/postgres/queries/find_references_query.rb +33 -0
  61. data/lib/valkyrie/persistence/postgres/query_service.rb +53 -0
  62. data/lib/valkyrie/persistence/postgres/resource_converter.rb +18 -0
  63. data/lib/valkyrie/persistence/postgres/resource_factory.rb +30 -0
  64. data/lib/valkyrie/persistence/solr.rb +6 -0
  65. data/lib/valkyrie/persistence/solr/metadata_adapter.rb +42 -0
  66. data/lib/valkyrie/persistence/solr/model_converter.rb +270 -0
  67. data/lib/valkyrie/persistence/solr/orm_converter.rb +252 -0
  68. data/lib/valkyrie/persistence/solr/persister.rb +32 -0
  69. data/lib/valkyrie/persistence/solr/queries.rb +11 -0
  70. data/lib/valkyrie/persistence/solr/queries/default_paginator.rb +16 -0
  71. data/lib/valkyrie/persistence/solr/queries/find_all_query.rb +33 -0
  72. data/lib/valkyrie/persistence/solr/queries/find_by_id_query.rb +24 -0
  73. data/lib/valkyrie/persistence/solr/queries/find_inverse_references_query.rb +30 -0
  74. data/lib/valkyrie/persistence/solr/queries/find_members_query.rb +43 -0
  75. data/lib/valkyrie/persistence/solr/queries/find_references_query.rb +34 -0
  76. data/lib/valkyrie/persistence/solr/query_service.rb +48 -0
  77. data/lib/valkyrie/persistence/solr/repository.rb +36 -0
  78. data/lib/valkyrie/persistence/solr/resource_factory.rb +24 -0
  79. data/lib/valkyrie/rdf_patches.rb +17 -0
  80. data/lib/valkyrie/resource.rb +106 -0
  81. data/lib/valkyrie/resource/access_controls.rb +13 -0
  82. data/lib/valkyrie/specs/shared_specs.rb +10 -0
  83. data/lib/valkyrie/specs/shared_specs/change_set_persister.rb +60 -0
  84. data/lib/valkyrie/specs/shared_specs/derivative_service.rb +30 -0
  85. data/lib/valkyrie/specs/shared_specs/file.rb +12 -0
  86. data/lib/valkyrie/specs/shared_specs/file_characterization_service.rb +33 -0
  87. data/lib/valkyrie/specs/shared_specs/metadata_adapter.rb +10 -0
  88. data/lib/valkyrie/specs/shared_specs/persister.rb +154 -0
  89. data/lib/valkyrie/specs/shared_specs/queries.rb +128 -0
  90. data/lib/valkyrie/specs/shared_specs/resource.rb +71 -0
  91. data/lib/valkyrie/specs/shared_specs/storage_adapter.rb +44 -0
  92. data/lib/valkyrie/storage.rb +8 -0
  93. data/lib/valkyrie/storage/disk.rb +55 -0
  94. data/lib/valkyrie/storage/fedora.rb +71 -0
  95. data/lib/valkyrie/storage/memory.rb +31 -0
  96. data/lib/valkyrie/storage_adapter.rb +100 -0
  97. data/lib/valkyrie/types.rb +34 -0
  98. data/lib/valkyrie/value_mapper.rb +67 -0
  99. data/lib/valkyrie/version.rb +2 -1
  100. data/lib/valkyrie/vocab/pcdm_use.rb +73 -0
  101. data/valkyrie.gemspec +33 -7
  102. metadata +462 -7
  103. data/.travis.yml +0 -5
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr
3
+ ##
4
+ # Converts a solr hash to a {Valkyrie::Resource}
5
+ class ORMConverter
6
+ attr_reader :solr_document
7
+ def initialize(solr_document)
8
+ @solr_document = solr_document
9
+ end
10
+
11
+ def convert!
12
+ resource
13
+ end
14
+
15
+ def resource
16
+ resource_klass.new(attributes.symbolize_keys)
17
+ end
18
+
19
+ def resource_klass
20
+ internal_resource.constantize
21
+ end
22
+
23
+ def internal_resource
24
+ solr_document["internal_resource_ssim"].first
25
+ end
26
+
27
+ def attributes
28
+ attribute_hash.merge("id" => id, internal_resource: internal_resource, created_at: created_at, updated_at: updated_at)
29
+ end
30
+
31
+ def created_at
32
+ DateTime.parse(solr_document["created_at_dtsi"].to_s).utc
33
+ end
34
+
35
+ def updated_at
36
+ DateTime.parse(solr_document["timestamp"] || solr_document["created_at_dtsi"].to_s).utc
37
+ end
38
+
39
+ def id
40
+ solr_document["id"].gsub(/^id-/, '')
41
+ end
42
+
43
+ def attribute_hash
44
+ build_literals(strip_tsim(solr_document.select do |k, _v|
45
+ k.end_with?("tsim")
46
+ end))
47
+ end
48
+
49
+ def strip_tsim(hsh)
50
+ Hash[
51
+ hsh.map do |k, v|
52
+ [k.gsub("_tsim", ""), v]
53
+ end
54
+ ]
55
+ end
56
+
57
+ class Property
58
+ attr_reader :key, :value, :document
59
+ def initialize(key, value, document)
60
+ @key = key
61
+ @value = value
62
+ @document = document
63
+ end
64
+ end
65
+
66
+ def build_literals(hsh)
67
+ hsh.each_with_object({}) do |(key, value), output|
68
+ next if key.end_with?("_lang")
69
+ output[key] = SolrValue.for(Property.new(key, value, hsh)).result
70
+ end
71
+ end
72
+
73
+ class SolrValue < ::Valkyrie::ValueMapper
74
+ end
75
+
76
+ # Converts a stored language typed literal from two fields into one
77
+ # {RDF::Literal}
78
+ class LanguagePropertyValue < ::Valkyrie::ValueMapper
79
+ SolrValue.register(self)
80
+ def self.handles?(value)
81
+ value.is_a?(Property) && value.document["#{value.key}_lang"]
82
+ end
83
+
84
+ def result
85
+ value.value.zip(languages).map do |literal, language|
86
+ if language == "eng"
87
+ literal
88
+ else
89
+ RDF::Literal.new(literal, language: language)
90
+ end
91
+ end
92
+ end
93
+
94
+ def languages
95
+ value.document["#{value.key}_lang"]
96
+ end
97
+ end
98
+ class PropertyValue < ::Valkyrie::ValueMapper
99
+ SolrValue.register(self)
100
+ def self.handles?(value)
101
+ value.is_a?(Property)
102
+ end
103
+
104
+ def result
105
+ calling_mapper.for(value.value).result
106
+ end
107
+ end
108
+ class EnumerableValue < ::Valkyrie::ValueMapper
109
+ SolrValue.register(self)
110
+ def self.handles?(value)
111
+ value.respond_to?(:each)
112
+ end
113
+
114
+ def result
115
+ value.map do |element|
116
+ calling_mapper.for(element).result
117
+ end
118
+ end
119
+ end
120
+
121
+ # Converts a stored ID value in solr into a {Valkyrie::ID}
122
+ class IDValue < ::Valkyrie::ValueMapper
123
+ SolrValue.register(self)
124
+ def self.handles?(value)
125
+ value.to_s.start_with?("id-")
126
+ end
127
+
128
+ def result
129
+ Valkyrie::ID.new(value.gsub(/^id-/, ''))
130
+ end
131
+ end
132
+
133
+ # Converts a stored URI value in solr into a {RDF::URI}
134
+ class URIValue < ::Valkyrie::ValueMapper
135
+ SolrValue.register(self)
136
+ def self.handles?(value)
137
+ value.to_s.start_with?("uri-")
138
+ end
139
+
140
+ def result
141
+ ::RDF::URI.new(value.gsub(/^uri-/, ''))
142
+ end
143
+ end
144
+
145
+ # Converts a nested resource in solr into a {Valkyrie::Resource}
146
+ class NestedResourceValue < ::Valkyrie::ValueMapper
147
+ SolrValue.register(self)
148
+ def self.handles?(value)
149
+ value.to_s.start_with?("serialized-")
150
+ end
151
+
152
+ def result
153
+ NestedResourceConverter.for(JSON.parse(json, symbolize_names: true)).result
154
+ end
155
+
156
+ def json
157
+ value.gsub(/^serialized-/, '')
158
+ end
159
+ end
160
+
161
+ class NestedResourceConverter < ::Valkyrie::ValueMapper
162
+ end
163
+
164
+ class NestedEnumerable < ::Valkyrie::ValueMapper
165
+ NestedResourceConverter.register(self)
166
+ def self.handles?(value)
167
+ value.is_a?(Array)
168
+ end
169
+
170
+ def result
171
+ value.map do |v|
172
+ calling_mapper.for(v).result
173
+ end
174
+ end
175
+ end
176
+
177
+ class NestedResourceID < ::Valkyrie::ValueMapper
178
+ NestedResourceConverter.register(self)
179
+ def self.handles?(value)
180
+ value.is_a?(Hash) && value[:id] && !value[:internal_resource]
181
+ end
182
+
183
+ def result
184
+ Valkyrie::ID.new(value[:id])
185
+ end
186
+ end
187
+
188
+ class NestedResourceURI < ::Valkyrie::ValueMapper
189
+ NestedResourceConverter.register(self)
190
+ def self.handles?(value)
191
+ value.is_a?(Hash) && value[:@id]
192
+ end
193
+
194
+ def result
195
+ RDF::URI(value[:@id])
196
+ end
197
+ end
198
+
199
+ class NestedResourceLiteral < ::Valkyrie::ValueMapper
200
+ NestedResourceConverter.register(self)
201
+ def self.handles?(value)
202
+ value.is_a?(Hash) && value[:@value]
203
+ end
204
+
205
+ def result
206
+ RDF::Literal.new(value[:@value], language: value[:@language])
207
+ end
208
+ end
209
+
210
+ class NestedResourceHash < ::Valkyrie::ValueMapper
211
+ NestedResourceConverter.register(self)
212
+ def self.handles?(value)
213
+ value.is_a?(Hash)
214
+ end
215
+
216
+ def result
217
+ Hash[
218
+ value.map do |k, v|
219
+ [k, calling_mapper.for(v).result]
220
+ end
221
+ ]
222
+ end
223
+ end
224
+
225
+ # Converts an integer in solr into an {Integer}
226
+ class IntegerValue < ::Valkyrie::ValueMapper
227
+ SolrValue.register(self)
228
+ def self.handles?(value)
229
+ value.to_s.start_with?("integer-")
230
+ end
231
+
232
+ def result
233
+ value.gsub(/^integer-/, '').to_i
234
+ end
235
+ end
236
+
237
+ # Converts a datetime in Solr into a {DateTime}
238
+ class DateTimeValue < ::Valkyrie::ValueMapper
239
+ SolrValue.register(self)
240
+ def self.handles?(value)
241
+ return false unless value.to_s.start_with?("datetime-")
242
+ DateTime.iso8601(value.gsub(/^datetime-/, '')).utc
243
+ rescue
244
+ false
245
+ end
246
+
247
+ def result
248
+ DateTime.parse(value.gsub(/^datetime-/, '')).utc
249
+ end
250
+ end
251
+ end
252
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr
3
+ require 'valkyrie/persistence/solr/repository'
4
+ class Persister
5
+ attr_reader :adapter
6
+ delegate :connection, :resource_factory, to: :adapter
7
+ # @param adapter [Valkyrie::Persistence::Solr::MetadataAdapter] The adapter with the
8
+ # configured solr connection.
9
+ def initialize(adapter:)
10
+ @adapter = adapter
11
+ end
12
+
13
+ # (see Valkyrie::Persistence::Memory::Persister#save)
14
+ def save(resource:)
15
+ repository([resource]).persist.first
16
+ end
17
+
18
+ # (see Valkyrie::Persistence::Memory::Persister#save_all)
19
+ def save_all(resources:)
20
+ repository(resources).persist
21
+ end
22
+
23
+ # (see Valkyrie::Persistence::Memory::Persister#delete)
24
+ def delete(resource:)
25
+ repository([resource]).delete.first
26
+ end
27
+
28
+ def repository(resources)
29
+ Valkyrie::Persistence::Solr::Repository.new(resources: resources, connection: connection, resource_factory: resource_factory)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr
3
+ module Queries
4
+ require 'valkyrie/persistence/solr/queries/default_paginator'
5
+ require 'valkyrie/persistence/solr/queries/find_all_query'
6
+ require 'valkyrie/persistence/solr/queries/find_by_id_query'
7
+ require 'valkyrie/persistence/solr/queries/find_inverse_references_query'
8
+ require 'valkyrie/persistence/solr/queries/find_members_query'
9
+ require 'valkyrie/persistence/solr/queries/find_references_query'
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr::Queries
3
+ class DefaultPaginator
4
+ def next_page
5
+ 1
6
+ end
7
+
8
+ def per_page
9
+ 100
10
+ end
11
+
12
+ def has_next?
13
+ true
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr::Queries
3
+ class FindAllQuery
4
+ attr_reader :connection, :resource_factory, :model
5
+ def initialize(connection:, resource_factory:, model: nil)
6
+ @connection = connection
7
+ @resource_factory = resource_factory
8
+ @model = model
9
+ end
10
+
11
+ def run
12
+ enum_for(:each)
13
+ end
14
+
15
+ def each
16
+ docs = DefaultPaginator.new
17
+ while docs.has_next?
18
+ docs = connection.paginate(docs.next_page, docs.per_page, "select", params: { q: query })["response"]["docs"]
19
+ docs.each do |doc|
20
+ yield resource_factory.to_resource(object: doc)
21
+ end
22
+ end
23
+ end
24
+
25
+ def query
26
+ if !model
27
+ "*:*"
28
+ else
29
+ "internal_resource_ssim:#{model}"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr::Queries
3
+ class FindByIdQuery
4
+ attr_reader :id, :connection, :resource_factory
5
+ def initialize(id, connection:, resource_factory:)
6
+ @id = id
7
+ @connection = connection
8
+ @resource_factory = resource_factory
9
+ end
10
+
11
+ def run
12
+ raise ::Valkyrie::Persistence::ObjectNotFoundError unless resource
13
+ resource_factory.to_resource(object: resource)
14
+ end
15
+
16
+ def id
17
+ "id-#{@id}"
18
+ end
19
+
20
+ def resource
21
+ connection.get("select", params: { q: "id:\"#{id}\"", fl: "*", rows: 1 })["response"]["docs"].first
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr::Queries
3
+ class FindInverseReferencesQuery
4
+ attr_reader :resource, :property, :connection, :resource_factory
5
+ def initialize(resource:, property:, connection:, resource_factory:)
6
+ @resource = resource
7
+ @property = property
8
+ @connection = connection
9
+ @resource_factory = resource_factory
10
+ end
11
+
12
+ def run
13
+ enum_for(:each)
14
+ end
15
+
16
+ def each
17
+ docs = DefaultPaginator.new
18
+ while docs.has_next?
19
+ docs = connection.paginate(docs.next_page, docs.per_page, "select", params: { q: query })["response"]["docs"]
20
+ docs.each do |doc|
21
+ yield resource_factory.to_resource(object: doc)
22
+ end
23
+ end
24
+ end
25
+
26
+ def query
27
+ "#{property}_ssim:id-#{resource.id}"
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+ module Valkyrie::Persistence::Solr::Queries
3
+ class FindMembersQuery
4
+ attr_reader :resource, :connection, :resource_factory
5
+ def initialize(resource:, connection:, resource_factory:)
6
+ @resource = resource
7
+ @connection = connection
8
+ @resource_factory = resource_factory
9
+ end
10
+
11
+ def run
12
+ enum_for(:each)
13
+ end
14
+
15
+ def each
16
+ unordered_members.sort_by { |x| member_ids.index(x.id) }.each do |member|
17
+ yield member
18
+ end
19
+ end
20
+
21
+ def unordered_members
22
+ docs.map do |doc|
23
+ resource_factory.to_resource(object: doc)
24
+ end
25
+ end
26
+
27
+ def docs
28
+ connection.get("select", params: { q: query, rows: 1_000_000_000 })["response"]["docs"]
29
+ end
30
+
31
+ def member_ids
32
+ Array.wrap(resource.member_ids)
33
+ end
34
+
35
+ def query
36
+ "{!join from=member_ids_ssim to=id}id:#{id}"
37
+ end
38
+
39
+ def id
40
+ "id-#{resource.id}"
41
+ end
42
+ end
43
+ end