rdf-ordered-repo 3.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f43439c8ba4d9d9cb2376e134f91ac477800433d3fdc035a84ad557ce8f93d78
4
+ data.tar.gz: 266350c62103ab7c4d32cc25602bb7aa14499222f2ea085c1918e5e6952e8925
5
+ SHA512:
6
+ metadata.gz: 3942cd5d98be5cc13ebdb26fa7c155788466e2ab0f5051677aa18553e20230325bb8eda2cc2983c472f745addded4d0d356627d6dad09abd5704bd51e0d0b932
7
+ data.tar.gz: 7f19953b673e3e571f2c6a997d8ab6c6a771f099b176238775f276223912668917f7cb78877daeb23e6dee47217250f0f0007fcfe1835e84fe8343396375cf80
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ * Gregg Kellogg <gregg@greggkellogg.net>
@@ -0,0 +1,57 @@
1
+ # RDF::OrderedRepo
2
+
3
+ An order-preserving repository for RDF.rb.
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/rdf-ordered-repo.png)](https://badge.fury.io/rb/rdf-ordered-repo)
6
+ [![Build Status](https://travis-ci.org/ruby-rdf/rdf-ordered-repo.png?branch=master)](https://travis-ci.org/ruby-rdf/rdf-ordered-repo)
7
+
8
+ ## Description
9
+
10
+ An in-memory implementation of RDF::Repository using native Ruby Hashes having insert-order preserving properties.
11
+
12
+ ## Examples
13
+
14
+ require 'rdf/ordered_repo'
15
+ require 'rdf/nquads'
16
+ repo = RDF::OrderedRepo.load("https://ruby-rdf.github.com/rdf/etc/doap.nq")
17
+
18
+ ## Dependencies
19
+
20
+ * [Ruby](https://ruby-lang.org/) (>= 2.4)
21
+ * [RDF.rb][] (~> 3.1)
22
+
23
+ ## Mailing List
24
+
25
+ * <https://lists.w3.org/Archives/Public/public-rdf-ruby/>
26
+
27
+ ## Author
28
+
29
+ * [Gregg Kellogg](https://github.com/gkellogg) - <https://greggkellogg.net/>
30
+
31
+ ## Contributing
32
+ This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange development and release activity. All submissions _must_ be on a feature branch based on the _develop_ branch to ease staging and integration.
33
+
34
+ * Do your best to adhere to the existing coding conventions and idioms.
35
+ * Don't use hard tabs, and don't leave trailing whitespace on any line.
36
+ Before committing, run `git diff --check` to make sure of this.
37
+ * Do document every method you add using [YARD][] annotations. Read the
38
+ [tutorial][YARD-GS] or just look at the existing code for examples.
39
+ * Don't touch the `.gemspec` or `VERSION` files. If you need to change them,
40
+ do so on your private branch only.
41
+ * Do feel free to add yourself to the `CREDITS` file and the
42
+ corresponding list in the the `README`. Alphabetical order applies.
43
+ * Don't touch the `AUTHORS` file. If your contributions are significant
44
+ enough, be assured we will eventually add you in there.
45
+ * Do note that in order for us to merge any non-trivial changes (as a rule
46
+ of thumb, additions larger than about 15 lines of code), we need an
47
+ explicit [public domain dedication][PDD] on record from you.
48
+
49
+ ## License
50
+
51
+ This is free and unencumbered public domain software. For more information,
52
+ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
53
+
54
+ [RDF.rb]: https://ruby-rdf.github.com/
55
+ [YARD]: https://yardoc.org/
56
+ [YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
57
+ [PDD]: https://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <https://unlicense.org>
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 3.1.0
@@ -0,0 +1,30 @@
1
+ @base <https://rubygems.org/gems/rdf-ordered-repo> .
2
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
3
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
4
+ @prefix dc: <http://purl.org/dc/terms/> .
5
+ @prefix foaf: <http://xmlns.com/foaf/0.1/> .
6
+ @prefix doap: <http://usefulinc.com/ns/doap#> .
7
+ @prefix ex: <http://example.org/> .
8
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
9
+
10
+ <> a doap:Project ;
11
+ doap:name "RDF::N3" ;
12
+ doap:homepage <https://github.com/ruby-rdf/rdf-ordered-repo> ;
13
+ doap:license <https://unlicense.org/1.0/> ;
14
+ doap:shortdesc "An order-preserving repository for RDF.rb."@en ;
15
+ doap:description "An in-memory implementation of RDF::Repository using native Ruby Hashes having insert-order preserving properties."@en ;
16
+ doap:created "2020-09-22"^^xsd:date;
17
+ doap:programming-language "Ruby" ;
18
+ doap:implements <http://www.w3.org/TR/rdf11-concepts/> ;
19
+ doap:category <http://dbpedia.org/resource/Resource_Description_Framework>,
20
+ <http://dbpedia.org/resource/Ruby_(programming_language)> ;
21
+ doap:download-page <> ;
22
+ doap:mailing-list <https://lists.w3.org/Archives/Public/public-rdf-ruby/> ;
23
+ doap:bug-database <https://github.com/ruby-rdf/rdf-ordered-repo/issues> ;
24
+ doap:blog <https://greggkellogg.net/> ;
25
+ doap:developer <https://greggkellogg.net/foaf#me> ;
26
+ doap:helper <http://njh.me/> ;
27
+ doap:maintainer <https://greggkellogg.net/foaf#me> ;
28
+ doap:documenter <https://greggkellogg.net/foaf#me> ;
29
+ foaf:maker <https://greggkellogg.net/foaf#me> ;
30
+ dc:creator <https://greggkellogg.net/foaf#me> .
@@ -0,0 +1,310 @@
1
+ require 'rdf'
2
+
3
+ module RDF
4
+ ##
5
+ # Sub-class of RDF::Repository with order-preserving properties.
6
+ class OrderedRepo < RDF::Repository
7
+ DEFAULT_GRAPH = false
8
+
9
+ ##
10
+ # Initializes this repository instance.
11
+ #
12
+ # @param [URI, #to_s] uri (nil)
13
+ # @param [String, #to_s] title (nil)
14
+ # @param [Hash{Symbol => Object}] options
15
+ # @option options [Boolean] :with_graph_name (true)
16
+ # Indicates that the repository supports named graphs, otherwise,
17
+ # only the default graph is supported.
18
+ # @option options [Boolean] :with_validity (true)
19
+ # Indicates that the repository supports named validation.
20
+ # @option options [Boolean] :transaction_class (DEFAULT_TX_CLASS)
21
+ # Specifies the RDF::Transaction implementation to use in this Repository.
22
+ # @yield [repository]
23
+ # @yieldparam [Repository] repository
24
+ def initialize(uri: nil, title: nil, **options, &block)
25
+ @data = options.delete(:data) || {}
26
+ super do
27
+ if block_given?
28
+ case block.arity
29
+ when 1 then block.call(self)
30
+ else instance_eval(&block)
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ ##
37
+ # Returns `true` if this respository supports the given `feature`.
38
+ #
39
+ # This repository supports list_terms.
40
+ def supports?(feature)
41
+ case feature.to_sym
42
+ when :rdfstar then true
43
+ when :snapshots then false
44
+ else super
45
+ end
46
+ end
47
+
48
+ ##
49
+ # Creates a query from the statements in this repository, turning blank nodes into non-distinguished variables. This can be used to determine if this repository is logically a subset of another repository.
50
+ #
51
+ # @return [RDF::Query]
52
+ def to_query
53
+ RDF::Query.new do |query|
54
+ each do |statement|
55
+ query.pattern RDF::Query::Pattern.from(statement, ndvars: true)
56
+ end
57
+ end
58
+ end
59
+
60
+ ##
61
+ # @private
62
+ # @see RDF::Countable#count
63
+ def count
64
+ count = 0
65
+ @data.each do |_, ss|
66
+ ss.each do |_, ps|
67
+ ps.each { |_, os| count += os.size }
68
+ end
69
+ end
70
+ count
71
+ end
72
+
73
+ ##
74
+ # @private
75
+ # @see RDF::Enumerable#has_graph?
76
+ def has_graph?(graph)
77
+ @data.has_key?(graph)
78
+ end
79
+
80
+ ##
81
+ # @private
82
+ # @see RDF::Enumerable#each_graph
83
+ def graph_names(options = nil, &block)
84
+ @data.keys.reject { |g| g == DEFAULT_GRAPH }.to_a
85
+ end
86
+
87
+ ##
88
+ # @private
89
+ # @see RDF::Enumerable#each_graph
90
+ def each_graph(&block)
91
+ if block_given?
92
+ @data.each_key do |gn|
93
+ yield RDF::Graph.new(graph_name: (gn == DEFAULT_GRAPH ? nil : gn), data: self)
94
+ end
95
+ end
96
+ enum_graph
97
+ end
98
+
99
+ ##
100
+ # @private
101
+ # @see RDF::Enumerable#has_statement?
102
+ def has_statement?(statement)
103
+ has_statement_in?(@data, statement)
104
+ end
105
+
106
+ ##
107
+ # @private
108
+ # @see RDF::Enumerable#each_statement
109
+ def each_statement(&block)
110
+ if block_given?
111
+ @data.each do |g, ss|
112
+ ss.each do |s, ps|
113
+ ps.each do |p, os|
114
+ os.each do |o, object_options|
115
+ yield RDF::Statement.new(s, p, o, object_options.merge(graph_name: g.equal?(DEFAULT_GRAPH) ? nil : g))
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ enum_statement
122
+ end
123
+ alias_method :each, :each_statement
124
+
125
+ ##
126
+ # @see Mutable#apply_changeset
127
+ def apply_changeset(changeset)
128
+ data = @data
129
+ changeset.deletes.each do |del|
130
+ if del.constant?
131
+ data = delete_from(data, del)
132
+ else
133
+ # we need this condition to handle wildcard statements
134
+ query_pattern(del) { |stmt| data = delete_from(data, stmt) }
135
+ end
136
+ end
137
+ changeset.inserts.each { |ins| data = insert_to(data, ins) }
138
+ @data = data
139
+ end
140
+
141
+ ##
142
+ # @see RDF::Dataset#isolation_level
143
+ def isolation_level
144
+ :serializable
145
+ end
146
+
147
+ protected
148
+
149
+ ##
150
+ # Match elements with `eql?`, not `==`
151
+ #
152
+ # `graph_name` of `false` matches default graph. Unbound variable matches
153
+ # non-false graph name.
154
+ #
155
+ # Matches terms which are native lists.
156
+ #
157
+ # @private
158
+ # @see RDF::Queryable#query_pattern
159
+ def query_pattern(pattern, **options, &block)
160
+ if block_given?
161
+ graph_name = pattern.graph_name
162
+ subject = pattern.subject
163
+ predicate = pattern.predicate
164
+ object = pattern.object
165
+
166
+ cs = @data.has_key?(graph_name) ? { graph_name => @data[graph_name] } : @data
167
+
168
+ cs.each do |c, ss|
169
+ next unless graph_name.nil? ||
170
+ graph_name == DEFAULT_GRAPH && !c ||
171
+ graph_name.eql?(c)
172
+
173
+ ss = if subject.nil? || subject.is_a?(RDF::Query::Variable)
174
+ ss
175
+ elsif subject.is_a?(RDF::Query::Pattern)
176
+ # Match subjects which are statements matching this pattern
177
+ ss.keys.select {|s| s.statement? && subject.eql?(s)}.inject({}) do |memo, st|
178
+ memo.merge(st => ss[st])
179
+ end
180
+ elsif ss.has_key?(subject)
181
+ { subject => ss[subject] }
182
+ else
183
+ []
184
+ end
185
+ ss.each do |s, ps|
186
+ ps = if predicate.nil? || predicate.is_a?(RDF::Query::Variable)
187
+ ps
188
+ elsif ps.has_key?(predicate)
189
+ { predicate => ps[predicate] }
190
+ else
191
+ []
192
+ end
193
+ ps.each do |p, os|
194
+ os.each do |o, object_options|
195
+ next unless object.nil? || object.eql?(o)
196
+ yield RDF::Statement.new(s, p, o, object_options.merge(graph_name: c.equal?(DEFAULT_GRAPH) ? nil : c))
197
+ end
198
+ end
199
+ end
200
+ end
201
+ else
202
+ enum_for(:query_pattern, pattern, **options)
203
+ end
204
+ end
205
+
206
+ ##
207
+ # @private
208
+ # @see RDF::Mutable#insert
209
+ def insert_statement(statement)
210
+ @data = insert_to(@data, statement)
211
+ end
212
+
213
+ ##
214
+ # @private
215
+ # @see RDF::Mutable#delete
216
+ def delete_statement(statement)
217
+ @data = delete_from(@data, statement)
218
+ end
219
+
220
+ ##
221
+ # @private
222
+ # @see RDF::Mutable#clear
223
+ def clear_statements
224
+ @data = @data.clear
225
+ end
226
+
227
+ ##
228
+ # @private
229
+ # @return [Hash]
230
+ def data
231
+ @data
232
+ end
233
+
234
+ ##
235
+ # @private
236
+ # @return [Hash]
237
+ def data=(hash)
238
+ @data = hash
239
+ end
240
+
241
+ private
242
+
243
+ ##
244
+ # @private
245
+ # @see #has_statement
246
+ def has_statement_in?(data, statement)
247
+ s, p, o, g = statement.to_quad
248
+ g ||= DEFAULT_GRAPH
249
+
250
+ data.has_key?(g) &&
251
+ data[g].has_key?(s) &&
252
+ data[g][s].has_key?(p) &&
253
+ data[g][s][p].has_key?(o)
254
+ end
255
+
256
+ ##
257
+ # @private
258
+ # @return [Hash] a new, updated hash
259
+ def insert_to(data, statement)
260
+ raise ArgumentError, "Statement #{statement.inspect} is incomplete" if statement.incomplete?
261
+
262
+ unless has_statement_in?(data, statement)
263
+ s, p, o, c = statement.to_quad
264
+ c ||= DEFAULT_GRAPH
265
+
266
+ data = data.has_key?(c) ? data.dup : data.merge(c => {})
267
+ data[c] = data[c].has_key?(s) ? data[c].dup : data[c].merge(s => {})
268
+ data[c][s] = data[c][s].has_key?(p) ? data[c][s].dup : data[c][s].merge(p => {})
269
+ data[c][s][p] = data[c][s][p].merge(o => statement.options)
270
+ end
271
+ data
272
+ end
273
+
274
+ ##
275
+ # @private
276
+ # @return [Hash] a new, updated hash
277
+ def delete_from(data, statement)
278
+ if has_statement_in?(data, statement)
279
+ s, p, o, g = statement.to_quad
280
+ g = DEFAULT_GRAPH unless supports?(:graph_name)
281
+ g ||= DEFAULT_GRAPH
282
+
283
+ os = data[g][s][p].dup.delete(o)
284
+ ps = os.empty? ? data[g][s].dup.delete_if {|k,v| k == p} : data[g][s].merge(p => os)
285
+ ss = ps.empty? ? data[g].dup.delete_if {|k,v| k == s} : data[g].merge(s => ps)
286
+ return ss.empty? ? data.dup.delete_if {|k,v| k == g} : data.merge(g => ss)
287
+ end
288
+ data
289
+ end
290
+
291
+ module VERSION
292
+ VERSION_FILE = File.expand_path("../../../VERSION", __FILE__)
293
+ MAJOR, MINOR, TINY, EXTRA = File.read(VERSION_FILE).chop.split(".")
294
+
295
+ STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
296
+
297
+ ##
298
+ # @return [String]
299
+ def self.to_s() STRING end
300
+
301
+ ##
302
+ # @return [String]
303
+ def self.to_str() STRING end
304
+
305
+ ##
306
+ # @return [Array(Integer, Integer, Integer)]
307
+ def self.to_a() STRING.split(".") end
308
+ end
309
+ end
310
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdf-ordered-repo
3
+ version: !ruby/object:Gem::Version
4
+ version: 3.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Gregg Kellogg
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rdf
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rdf-spec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.9'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.9'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.20
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.9.20
69
+ description: An in-memory implementation of RDF::Repository using native Ruby Hashes
70
+ having insert-order preserving properties.
71
+ email: public-rdf-ruby@w3.org
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - AUTHORS
77
+ - README.md
78
+ - UNLICENSE
79
+ - VERSION
80
+ - etc/doap.ttl
81
+ - lib/rdf/ordered_repo.rb
82
+ homepage: https://github.com/ruby-rdf/rdf-ordered-repo
83
+ licenses:
84
+ - Unlicense
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '2.4'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubygems_version: 3.1.3
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: An order-preserving repository for RDF.rb.
105
+ test_files: []