valkyrie 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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