active-triples 0.11.0 → 1.0.0.rc1
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 +4 -4
- data/README.md +1 -1
- data/active-triples.gemspec +2 -1
- data/lib/active_triples/configuration.rb +22 -11
- data/lib/active_triples/extension_strategy.rb +1 -1
- data/lib/active_triples/list.rb +0 -2
- data/lib/active_triples/node_config.rb +64 -8
- data/lib/active_triples/persistable.rb +2 -12
- data/lib/active_triples/persistence_strategies/parent_strategy.rb +16 -15
- data/lib/active_triples/property.rb +36 -11
- data/lib/active_triples/rdf_source.rb +86 -9
- data/lib/active_triples/relation.rb +61 -42
- data/lib/active_triples/schema.rb +20 -1
- data/lib/active_triples/version.rb +1 -1
- data/spec/active_triples/extension_strategy_spec.rb +12 -1
- data/spec/active_triples/node_config_spec.rb +54 -0
- data/spec/active_triples/persistence_strategies/parent_strategy_spec.rb +24 -17
- data/spec/active_triples/property_spec.rb +10 -0
- data/spec/active_triples/rdf_source_spec.rb +103 -122
- data/spec/active_triples/relation_spec.rb +199 -12
- data/spec/active_triples/resource_spec.rb +115 -0
- data/spec/active_triples/schema_spec.rb +6 -0
- metadata +21 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e4826fdb0493f209bf6b520769ce78254fa7821e
|
4
|
+
data.tar.gz: 44c6d5cb09faf8a94c3f6ae94ed42fafe09e6644
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 755c2a4fa05ad31bf96334673858c350ff361df74efe7bd592bb91a7e95f0f4e758a295c237d0f7f010b4baacbce0c836b7d174b3eda29fa60f490e4153525cb
|
7
|
+
data.tar.gz: 42293eeab490dd8b63d891a6b405da62776c77b700b9afd0e3bde636980b358cb102150e99a4d10c574198e5d0ad5f0addbfb52bd8701656ae1bfe9f1ef7e676
|
data/README.md
CHANGED
@@ -215,7 +215,7 @@ Contributing
|
|
215
215
|
|
216
216
|
Please observe the following guidelines:
|
217
217
|
|
218
|
-
- Do your work in a feature branch based on ```
|
218
|
+
- Do your work in a feature branch based on ```develop``` and rebase before submitting a pull request.
|
219
219
|
- Write tests for your contributions.
|
220
220
|
- Document every method you add using YARD annotations. (_Note: Annotations are sparse in the existing codebase, help us fix that!_)
|
221
221
|
- Organize your commits into logical units.
|
data/active-triples.gemspec
CHANGED
@@ -19,8 +19,9 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_dependency 'activemodel', '>= 3.0.0'
|
20
20
|
s.add_dependency 'activesupport', '>= 3.0.0'
|
21
21
|
|
22
|
-
s.add_development_dependency '
|
22
|
+
s.add_development_dependency 'yard'
|
23
23
|
s.add_development_dependency 'rspec'
|
24
|
+
s.add_development_dependency 'guard-rspec'
|
24
25
|
s.add_development_dependency 'rdf-spec', '~> 2.0'
|
25
26
|
s.add_development_dependency 'rdf-rdfxml', '~> 2.0'
|
26
27
|
s.add_development_dependency 'rdf-turtle', '~> 2.0'
|
@@ -3,15 +3,21 @@ module ActiveTriples
|
|
3
3
|
require_relative 'configuration/item'
|
4
4
|
require_relative 'configuration/merge_item'
|
5
5
|
require_relative 'configuration/item_factory'
|
6
|
+
|
6
7
|
##
|
7
8
|
# Class which contains configuration for RDFSources.
|
8
9
|
class Configuration
|
9
10
|
attr_accessor :inner_hash
|
11
|
+
|
12
|
+
##
|
13
|
+
# @param item_factory [ItemFactory]
|
10
14
|
# @param [Hash] options the configuration options.
|
11
|
-
def initialize(options
|
12
|
-
@
|
15
|
+
def initialize(item_factory: ItemFactory.new, **options)
|
16
|
+
@item_factory = item_factory
|
17
|
+
@inner_hash = Hash[options.to_a]
|
13
18
|
end
|
14
19
|
|
20
|
+
##
|
15
21
|
# Merges this configuration with other configuration options. This uses
|
16
22
|
# reflection setters to handle special cases like :type.
|
17
23
|
#
|
@@ -19,13 +25,17 @@ module ActiveTriples
|
|
19
25
|
# @return [ActiveTriples::Configuration] the configuration object which is a
|
20
26
|
# result of merging.
|
21
27
|
def merge(options)
|
22
|
-
|
28
|
+
options = options.to_h
|
29
|
+
new_config = self.class.new(**options)
|
30
|
+
|
23
31
|
new_config.items.each do |property, item|
|
24
32
|
build_configuration_item(property).set item.value
|
25
33
|
end
|
34
|
+
|
26
35
|
self
|
27
36
|
end
|
28
37
|
|
38
|
+
##
|
29
39
|
# Returns a hash with keys as the configuration property and values as
|
30
40
|
# reflections which know how to set a new value to it.
|
31
41
|
#
|
@@ -37,6 +47,7 @@ module ActiveTriples
|
|
37
47
|
end
|
38
48
|
end
|
39
49
|
|
50
|
+
##
|
40
51
|
# Returns the configured value for an option
|
41
52
|
#
|
42
53
|
# @return the configured value
|
@@ -44,30 +55,30 @@ module ActiveTriples
|
|
44
55
|
to_h[value]
|
45
56
|
end
|
46
57
|
|
58
|
+
##
|
47
59
|
# Returns the available configured options as a hash.
|
48
60
|
#
|
49
61
|
# This filters the options the class is initialized with.
|
50
62
|
#
|
51
63
|
# @return [Hash{Symbol => String, ::RDF::URI}]
|
52
64
|
def to_h
|
53
|
-
|
65
|
+
inner_hash.slice(*valid_config_options)
|
54
66
|
end
|
55
67
|
|
56
68
|
protected
|
57
69
|
|
58
70
|
def build_configuration_item(key)
|
59
|
-
|
71
|
+
item_factory.new(self, key)
|
60
72
|
end
|
61
73
|
|
62
74
|
private
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
75
|
+
|
76
|
+
CONFIG_OPTIONS = [:base_uri, :rdf_label, :type, :repository].freeze
|
77
|
+
|
78
|
+
attr_reader :item_factory
|
67
79
|
|
68
80
|
def valid_config_options
|
69
|
-
|
81
|
+
CONFIG_OPTIONS
|
70
82
|
end
|
71
83
|
end
|
72
|
-
|
73
84
|
end
|
@@ -10,7 +10,7 @@ module ActiveTriples
|
|
10
10
|
# the property to.
|
11
11
|
# @param [ActiveTriples::Property] property The property to copy.
|
12
12
|
def apply(resource, property)
|
13
|
-
resource.property
|
13
|
+
resource.property(property.name, property.to_h, &property.config)
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
data/lib/active_triples/list.rb
CHANGED
@@ -112,7 +112,6 @@ module ActiveTriples
|
|
112
112
|
values.delete key
|
113
113
|
end
|
114
114
|
end
|
115
|
-
persist!
|
116
115
|
super
|
117
116
|
end
|
118
117
|
|
@@ -176,7 +175,6 @@ module ActiveTriples
|
|
176
175
|
resource << value
|
177
176
|
value.set_persistence_strategy(ParentStrategy)
|
178
177
|
value.persistence_strategy.parent = resource
|
179
|
-
value.persist!
|
180
178
|
end
|
181
179
|
end
|
182
180
|
end
|
@@ -1,20 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module ActiveTriples
|
4
|
+
##
|
5
|
+
# Configuration for properties
|
3
6
|
class NodeConfig
|
7
|
+
##
|
8
|
+
# @!attribute class_name [rw]
|
9
|
+
# @return [Class, String]
|
10
|
+
# @!attribute predicate [rw]
|
11
|
+
# @return [RDF::URI]
|
12
|
+
# @!attribute term [rw]
|
13
|
+
# @return [Symbol]
|
14
|
+
# @!attribute type [rw]
|
15
|
+
# @return [Symbol]
|
16
|
+
# @!attribute behaviors [rw]
|
17
|
+
# @return [Enumerator<Symbol>]
|
18
|
+
# @!attribute cast [rw]
|
19
|
+
# @return [Boolean]
|
4
20
|
attr_accessor :predicate, :term, :class_name, :type, :behaviors, :cast
|
5
21
|
|
6
|
-
|
22
|
+
##
|
23
|
+
# @param term [Symbol]
|
24
|
+
# @param predicate [RDF::URI]
|
25
|
+
# @param opts [Hash<Symbol, Object>]
|
26
|
+
# @option opts [String, Class] :class_name
|
27
|
+
# @option opts [String, Class] :class_name
|
28
|
+
#
|
29
|
+
# @yield yields self to the block
|
30
|
+
# @yieldparam config [NodeConfig] self
|
31
|
+
def initialize(term, predicate, opts={})
|
7
32
|
self.term = term
|
8
33
|
self.predicate = predicate
|
9
|
-
self.class_name =
|
10
|
-
self.cast =
|
11
|
-
@opts =
|
34
|
+
self.class_name = opts.delete(:class_name) { nil }
|
35
|
+
self.cast = opts.delete(:cast) { true }
|
36
|
+
@opts = opts
|
12
37
|
yield(self) if block_given?
|
13
38
|
end
|
14
39
|
|
40
|
+
##
|
41
|
+
# @param value [#to_sym]
|
42
|
+
# @return [Object] the attribute or option represented by the symbol
|
15
43
|
def [](value)
|
16
44
|
value = value.to_sym
|
17
|
-
self.respond_to?(value) ? self.
|
45
|
+
self.respond_to?(value) ? self.public_send(value) : @opts[value]
|
18
46
|
end
|
19
47
|
|
20
48
|
def class_name
|
@@ -30,7 +58,10 @@ module ActiveTriples
|
|
30
58
|
@class_name
|
31
59
|
end
|
32
60
|
|
33
|
-
|
61
|
+
##
|
62
|
+
# @yield yields an index configuration object
|
63
|
+
# @yieldparam index [NodeConfig::IndexObject]
|
64
|
+
def with_index(&block)
|
34
65
|
# needed for solrizer integration
|
35
66
|
iobj = IndexObject.new
|
36
67
|
yield iobj
|
@@ -40,27 +71,52 @@ module ActiveTriples
|
|
40
71
|
|
41
72
|
private
|
42
73
|
|
74
|
+
##
|
75
|
+
# @deprecated Use `nil` instead.
|
43
76
|
def default_class_name
|
77
|
+
warn 'DEPRECATION: `ActiveTriples::NodeConfig#default_class_name` ' \
|
78
|
+
'will be removed in 1.0. Use `nil`.'
|
44
79
|
nil
|
45
80
|
end
|
46
81
|
|
47
82
|
# this enables a cleaner API for solr integration
|
48
83
|
class IndexObject
|
84
|
+
##
|
85
|
+
# @!attribute data_type [rw]
|
86
|
+
# @return [Symbol]
|
87
|
+
# @!attribute behaviors [rw]
|
88
|
+
# @return [Enumerator<Symbol>]
|
49
89
|
attr_accessor :data_type, :behaviors
|
90
|
+
|
50
91
|
def initialize
|
51
92
|
@behaviors = []
|
52
93
|
@data_type = :string
|
53
94
|
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# @param [Array<Symbol>] *args Behaviors for this index object
|
98
|
+
#
|
99
|
+
# @return [Array<Symbol>]
|
54
100
|
def as(*args)
|
55
101
|
@behaviors = args
|
56
102
|
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# @param sym [Symbol]
|
57
106
|
def type(sym)
|
58
107
|
@data_type = sym
|
59
108
|
end
|
60
|
-
|
109
|
+
|
110
|
+
##
|
111
|
+
# @deprecated Omit calls to this method; it has always been a no-op.
|
112
|
+
#
|
113
|
+
# @return [Symbol] :noop
|
114
|
+
def defaults # no-op
|
115
|
+
warn 'DEPRECATION: `ActiveTriples::NodeConfig::IndexObject#defaults` ' \
|
116
|
+
'will be removed in 1.0. If you are doing `index.defaults` in a ' \
|
117
|
+
'property config block, you can simply omit the call.'
|
61
118
|
:noop
|
62
119
|
end
|
63
120
|
end
|
64
121
|
end
|
65
122
|
end
|
66
|
-
|
@@ -27,13 +27,6 @@ module ActiveTriples
|
|
27
27
|
persistence_strategy.graph
|
28
28
|
end
|
29
29
|
|
30
|
-
##
|
31
|
-
# @see RDF::Enumerable.each
|
32
|
-
def each(*args)
|
33
|
-
graph.each(*args)
|
34
|
-
end
|
35
|
-
|
36
|
-
##
|
37
30
|
# @see RDF::Writable.insert_statement
|
38
31
|
def insert_statement(*args)
|
39
32
|
graph.send(:insert_statement, *args)
|
@@ -77,19 +70,16 @@ module ActiveTriples
|
|
77
70
|
end
|
78
71
|
|
79
72
|
##
|
80
|
-
# Sends a persistence message to the persistence_startegy
|
81
|
-
#
|
73
|
+
# Sends a persistence message to the `persistence_startegy`, saving the
|
74
|
+
# `Persistable`.
|
82
75
|
#
|
83
76
|
# @return [Boolean]
|
84
77
|
def persist!(opts={})
|
85
|
-
return if @persisting
|
86
78
|
result = false
|
87
79
|
return result if opts[:validate] && !valid?
|
88
|
-
@persisting = true
|
89
80
|
run_callbacks :persist do
|
90
81
|
result = persistence_strategy.persist!
|
91
82
|
end
|
92
|
-
@persisting = false
|
93
83
|
result
|
94
84
|
end
|
95
85
|
|
@@ -27,25 +27,25 @@ module ActiveTriples
|
|
27
27
|
# @see PeristenceStrategy#graph=
|
28
28
|
def graph=(graph)
|
29
29
|
final_parent.insert(graph || source.to_a)
|
30
|
-
@graph = BufferedTransaction.begin(parent,
|
30
|
+
@graph = BufferedTransaction.begin(parent,
|
31
31
|
mutable: true,
|
32
32
|
subject: source.to_term)
|
33
33
|
end
|
34
34
|
|
35
35
|
##
|
36
|
-
# @return [ActiveTriples::BufferedTransaction] a transaction on parent with
|
37
|
-
# buffered changes, with reads projected against an "Extended Bounded
|
36
|
+
# @return [ActiveTriples::BufferedTransaction] a transaction on parent with
|
37
|
+
# buffered changes, with reads projected against an "Extended Bounded
|
38
38
|
# Description" of the strategy's `#source`.
|
39
39
|
#
|
40
40
|
# @see ActiveTriples::ExtendedBoundedDescription
|
41
41
|
def graph
|
42
|
-
@graph ||= BufferedTransaction.begin(parent,
|
42
|
+
@graph ||= BufferedTransaction.begin(parent,
|
43
43
|
mutable: true,
|
44
44
|
subject: source.to_term)
|
45
45
|
end
|
46
46
|
|
47
47
|
##
|
48
|
-
# Resources using this strategy are persisted only if their parent is also
|
48
|
+
# Resources using this strategy are persisted only if their parent is also
|
49
49
|
# persisted.
|
50
50
|
#
|
51
51
|
# @see PersistenceStrategy#persisted?
|
@@ -66,8 +66,8 @@ module ActiveTriples
|
|
66
66
|
end
|
67
67
|
|
68
68
|
##
|
69
|
-
# @abstract Clear out any old assertions in the datastore / repository
|
70
|
-
# about this node or statement thus preparing to receive the updated
|
69
|
+
# @abstract Clear out any old assertions in the datastore / repository
|
70
|
+
# about this node or statement thus preparing to receive the updated
|
71
71
|
# assertions.
|
72
72
|
def erase_old_resource; end # noop
|
73
73
|
|
@@ -91,6 +91,7 @@ module ActiveTriples
|
|
91
91
|
# @param parent [RDFSource] source with a persistence strategy,
|
92
92
|
# must be mutable.
|
93
93
|
def parent=(parent)
|
94
|
+
raise NilParentError if parent.nil?
|
94
95
|
raise UnmutableParentError unless parent.is_a? RDF::Mutable
|
95
96
|
raise UnmutableParentError unless parent.mutable?
|
96
97
|
|
@@ -108,7 +109,7 @@ module ActiveTriples
|
|
108
109
|
|
109
110
|
graph.execute
|
110
111
|
|
111
|
-
parent.persist! if
|
112
|
+
parent.persist! if
|
112
113
|
ancestors.find { |a| a.is_a?(ActiveTriples::List::ListResource) }
|
113
114
|
|
114
115
|
reload
|
@@ -152,17 +153,17 @@ module ActiveTriples
|
|
152
153
|
#
|
153
154
|
# @raise [NilParentError] if `source` does not persist to a parent
|
154
155
|
def each
|
155
|
-
raise NilParentError if
|
156
|
-
!source.persistence_strategy.respond_to?(:parent) ||
|
156
|
+
raise NilParentError if
|
157
|
+
!source.persistence_strategy.respond_to?(:parent) ||
|
157
158
|
source.persistence_strategy.parent.nil?
|
158
|
-
|
159
|
+
|
159
160
|
current = source.persistence_strategy.parent
|
160
|
-
|
161
|
+
|
161
162
|
if block_given?
|
162
163
|
loop do
|
163
164
|
yield current
|
164
|
-
|
165
|
-
break unless (current.persistence_strategy.respond_to?(:parent) &&
|
165
|
+
|
166
|
+
break unless (current.persistence_strategy.respond_to?(:parent) &&
|
166
167
|
current.persistence_strategy.parent)
|
167
168
|
break if current.persistence_strategy.parent == current
|
168
169
|
|
@@ -172,7 +173,7 @@ module ActiveTriples
|
|
172
173
|
to_enum
|
173
174
|
end
|
174
175
|
end
|
175
|
-
|
176
|
+
|
176
177
|
class NilParentError < RuntimeError; end
|
177
178
|
class UnmutableParentError < ArgumentError; end
|
178
179
|
end
|
@@ -4,40 +4,65 @@ module ActiveTriples
|
|
4
4
|
# A value object to encapsulate what a Property is. Instantiate with a hash of
|
5
5
|
# options.
|
6
6
|
#
|
7
|
-
# @
|
7
|
+
# @example configuring a property in a schema
|
8
|
+
# title_prop = ActiveTriples::Property.new(name: :title,
|
9
|
+
# predicate: RDF::Vocab::DC.title)
|
8
10
|
class Property
|
9
|
-
|
10
|
-
|
11
|
+
##
|
12
|
+
# @param options [Hash] Options for the property
|
13
|
+
# @option options [RDF::URI] :name
|
14
|
+
# @option options [Boolean] :cast
|
15
|
+
# @option options [String, Class] :class_name
|
16
|
+
# @option options [RDF::URI] :predicate
|
17
|
+
def initialize(options = {}, &block)
|
18
|
+
self.name = options.fetch(:name)
|
11
19
|
self.attributes = options.except(:name)
|
20
|
+
self.config = block
|
12
21
|
end
|
13
22
|
|
14
|
-
|
15
|
-
|
23
|
+
##
|
24
|
+
# @!attribute [r] name
|
25
|
+
# @return [Symbol]
|
26
|
+
# @!attribute [r] config
|
27
|
+
# @return [Proc]
|
28
|
+
attr_reader :name, :config
|
16
29
|
|
17
|
-
|
30
|
+
##
|
31
|
+
# @return [Boolean]
|
18
32
|
def cast
|
19
33
|
attributes.fetch(:cast, false)
|
20
34
|
end
|
21
35
|
|
22
|
-
|
36
|
+
##
|
37
|
+
# @return [Class]
|
23
38
|
def class_name
|
24
39
|
attributes[:class_name]
|
25
40
|
end
|
26
41
|
|
27
|
-
|
42
|
+
##
|
43
|
+
# @return [RDF::Vocabulary::Term]
|
28
44
|
def predicate
|
29
45
|
attributes[:predicate]
|
30
46
|
end
|
31
47
|
|
32
48
|
private
|
33
49
|
|
34
|
-
|
50
|
+
##
|
51
|
+
# @!attribute [w] name
|
52
|
+
# @return [Symbol]
|
53
|
+
# @!attribute [w] config
|
54
|
+
# @return [Proc]
|
55
|
+
# @!attribute [rw] attributes
|
56
|
+
# @return [Hash<Symbol, Object>]
|
57
|
+
attr_writer :name, :config
|
35
58
|
attr_accessor :attributes
|
36
59
|
|
37
60
|
alias_method :to_h, :attributes
|
38
61
|
|
39
|
-
|
40
|
-
#
|
62
|
+
##
|
63
|
+
# Returns the property's configuration values. Will not return #name, which
|
64
|
+
# is meant to only be accessible via the accessor.
|
65
|
+
#
|
41
66
|
# @return [Hash] Configuration values for this property.
|
42
67
|
public :to_h
|
43
68
|
end
|