active-triples 0.11.0 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|