graffiti 2.1 → 2.3.1
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 +7 -0
- data/Rakefile +21 -0
- data/graffiti.gemspec +11 -5
- data/lib/graffiti/debug.rb +1 -1
- data/lib/graffiti/sql_mapper.rb +27 -22
- data/lib/graffiti/squish.rb +7 -7
- data/test/ts_graffiti.rb +53 -64
- metadata +88 -64
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d1a5980784c2cc78f9e23e4277110bfa3944e306
|
4
|
+
data.tar.gz: cf3450ef275dd472c8ef8df5d18ad473600188f9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c58ce00dabeb684334776062f94de2d2f79fd61eee9d89946643a0f0246bbe7c56b24b9325b119008e77eb2951f2763070b44c6996b51985affa2887203fc87
|
7
|
+
data.tar.gz: 67119fd8fd88ee3e50f57f969491958003d8ac8947e27cd01aa0bbb3f6a926d2b377a72242c7cb3a8643a69f1f1fd1131a56962182d1ee3fc50480a77663e5a0
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# Graffiti RDF Store
|
2
|
+
# (originally written for Samizdat project)
|
3
|
+
#
|
4
|
+
# Copyright (c) 2002-2012, 2016 Dmitry Borodaenko <angdraug@debian.org>
|
5
|
+
#
|
6
|
+
# This program is free software.
|
7
|
+
# You can distribute/modify this program under the terms of
|
8
|
+
# the GNU General Public License version 3 or later.
|
9
|
+
#
|
10
|
+
# see doc/rdf-storage.txt for introduction and Graffiti Squish definition;
|
11
|
+
# see doc/storage-impl.txt for explanation of implemented algorithms
|
12
|
+
#
|
13
|
+
# vim: et sw=2 sts=2 ts=8 tw=0
|
14
|
+
|
15
|
+
require "rake"
|
16
|
+
|
17
|
+
task :default => :test
|
18
|
+
|
19
|
+
task :test do
|
20
|
+
sh %{#{FileUtils::RUBY} -I. -Ilib test/ts_graffiti.rb}
|
21
|
+
end
|
data/graffiti.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'graffiti'
|
3
|
-
spec.version = '2.1'
|
3
|
+
spec.version = '2.3.1'
|
4
4
|
spec.author = 'Dmitry Borodaenko'
|
5
5
|
spec.email = 'angdraug@debian.org'
|
6
6
|
spec.homepage = 'https://github.com/angdraug/graffiti'
|
@@ -13,9 +13,15 @@ and vice versa, to store any RDF data in a relational database.
|
|
13
13
|
Graffiti uses Sequel to connect to database backend and provides a DBI-like
|
14
14
|
interface to run RDF queries in Squish query language from Ruby applications.
|
15
15
|
EOF
|
16
|
-
spec.files =
|
16
|
+
spec.files = %w(COPYING ChangeLog.mtn README.rdoc TODO
|
17
|
+
setup.rb Rakefile graffiti.gemspec) +
|
18
|
+
Dir['{lib,test}/**/*.rb'] +
|
19
|
+
Dir['doc/**/*.{txt,tex,yaml,sql,svg}']
|
17
20
|
spec.test_files = Dir['test/ts_*.rb']
|
18
|
-
spec.license = '
|
19
|
-
spec.add_dependency
|
20
|
-
spec.add_dependency
|
21
|
+
spec.license = 'GPL-3.0+'
|
22
|
+
spec.add_dependency 'syncache'
|
23
|
+
spec.add_dependency 'sequel'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'test-unit'
|
26
|
+
spec.add_development_dependency 'sqlite3'
|
21
27
|
end
|
data/lib/graffiti/debug.rb
CHANGED
data/lib/graffiti/sql_mapper.rb
CHANGED
@@ -211,9 +211,11 @@ class SqlMapper
|
|
211
211
|
refine_ambiguous_properties
|
212
212
|
|
213
213
|
debug do
|
214
|
-
@nodes.each do |node
|
215
|
-
|
214
|
+
@nodes.keys.sort.each do |node|
|
215
|
+
n = @nodes[node]
|
216
|
+
debug %{map_predicates #{node}: #{n[:bind_mode]} #{n[:colors].inspect}}
|
216
217
|
end
|
218
|
+
nil
|
217
219
|
end
|
218
220
|
end
|
219
221
|
|
@@ -386,14 +388,14 @@ class SqlMapper
|
|
386
388
|
# be refined based on other occurences of this node in other query clauses.
|
387
389
|
#
|
388
390
|
def refine_ambiguous_properties
|
389
|
-
@nodes.
|
390
|
-
map =
|
391
|
+
@nodes.keys.sort.each do |node|
|
392
|
+
map = @nodes[node][:positions]
|
391
393
|
|
392
394
|
map.each_with_index do |p, i|
|
393
395
|
big = @clauses[ p[:clause] ][ p[:role] ]
|
394
396
|
next if big.size <= 1 # no refining needed
|
395
397
|
|
396
|
-
debug {
|
398
|
+
debug { 'refine_ambiguous_properties ' + @nodes[node] + ': ' + big.inspect }
|
397
399
|
|
398
400
|
(i + 1).upto(map.size - 1) do |j|
|
399
401
|
small_p = map[j]
|
@@ -447,9 +449,9 @@ class SqlMapper
|
|
447
449
|
end
|
448
450
|
|
449
451
|
def define_relation_aliases
|
450
|
-
@nodes.each do |node
|
451
|
-
|
452
|
-
|
452
|
+
@nodes.keys.sort.each do |node|
|
453
|
+
positions = @nodes[node][:positions]
|
454
|
+
debug { 'define_relation_aliases ' + positions.inspect }
|
453
455
|
|
454
456
|
# go through all clauses with this node in subject position
|
455
457
|
positions.each_with_index do |p, i|
|
@@ -508,8 +510,8 @@ class SqlMapper
|
|
508
510
|
@jc = []
|
509
511
|
@bindings = {}
|
510
512
|
|
511
|
-
@nodes.each do |node
|
512
|
-
positions =
|
513
|
+
@nodes.keys.sort.each do |node|
|
514
|
+
positions = @nodes[node][:positions]
|
513
515
|
|
514
516
|
# node binding
|
515
517
|
first = positions.first
|
@@ -527,7 +529,7 @@ class SqlMapper
|
|
527
529
|
unless @bindings[node].include?(binding2)
|
528
530
|
@bindings[node].push(binding2)
|
529
531
|
@jc.push([binding, binding2, node])
|
530
|
-
|
532
|
+
@nodes[node][:ground] = true
|
531
533
|
end
|
532
534
|
end
|
533
535
|
|
@@ -561,6 +563,7 @@ class SqlMapper
|
|
561
563
|
end
|
562
564
|
|
563
565
|
@aliases[r][:filter].push SqlExpression.new(
|
566
|
+
# FIXME: replace 't' with database-specific boolean literal
|
564
567
|
SqlNodeBinding.new(r, 'uriref'), '=', "'t'", 'AND',
|
565
568
|
SqlNodeBinding.new(r, 'label'), '=', %{'#{node}'})
|
566
569
|
|
@@ -569,13 +572,14 @@ class SqlMapper
|
|
569
572
|
"Invalid node '#{node}' should never occur at this point"
|
570
573
|
end
|
571
574
|
|
572
|
-
|
575
|
+
@nodes[node][:ground] = true
|
573
576
|
end
|
574
577
|
end
|
575
578
|
|
576
579
|
debug do
|
577
|
-
@aliases.each {|
|
578
|
-
@jc.each {|jc| debug jc.inspect }
|
580
|
+
@aliases.keys.sort.each {|a| debug %{transform #{a}: #{@aliases[a].inspect}} }
|
581
|
+
@jc.each {|jc| debug 'transform ' + jc.inspect }
|
582
|
+
nil
|
579
583
|
end
|
580
584
|
end
|
581
585
|
|
@@ -583,7 +587,7 @@ class SqlMapper
|
|
583
587
|
#
|
584
588
|
def generate_tables_and_conditions
|
585
589
|
main_path, seen = jc_subgraph_path(:must_bind)
|
586
|
-
debug { main_path.inspect }
|
590
|
+
debug { 'generate_tables_and_conditions ' + main_path.inspect }
|
587
591
|
|
588
592
|
main_path and not main_path.empty? or raise RuntimeError,
|
589
593
|
'Failed to find table aliases for main query'
|
@@ -598,7 +602,7 @@ class SqlMapper
|
|
598
602
|
sub_path, new = jc_subgraph_path(bind_mode, seen)
|
599
603
|
break if sub_path.nil? or sub_path.empty?
|
600
604
|
|
601
|
-
debug { sub_path.inspect }
|
605
|
+
debug { 'generate_tables_and_conditions ' + sub_path.inspect }
|
602
606
|
|
603
607
|
sub_query, sub_join = sub_path.partition {|a,| main_path.assoc(a).nil? }
|
604
608
|
# fixme: make sure that sub_join is not empty
|
@@ -719,9 +723,9 @@ class SqlMapper
|
|
719
723
|
end
|
720
724
|
|
721
725
|
def find_alias(bind_mode, seen = {})
|
722
|
-
@aliases.each do |
|
723
|
-
next if seen[
|
724
|
-
return
|
726
|
+
@aliases.keys.sort.each do |a|
|
727
|
+
next if seen[a] or @aliases[a][:bind_mode] != bind_mode
|
728
|
+
return a
|
725
729
|
end
|
726
730
|
|
727
731
|
nil
|
@@ -734,7 +738,8 @@ class SqlMapper
|
|
734
738
|
conditions = []
|
735
739
|
ground_nodes = @global_filter.scan(SquishQuery::BN_SCAN)
|
736
740
|
|
737
|
-
@nodes.each do |node
|
741
|
+
@nodes.keys.sort.each do |node|
|
742
|
+
n = @nodes[node]
|
738
743
|
next if (n[:ground] or ground_nodes.include?(node))
|
739
744
|
|
740
745
|
expression =
|
@@ -800,7 +805,7 @@ class SqlMapper
|
|
800
805
|
wrapped = {}
|
801
806
|
sub_path.each {|a,| wrapped[a] = true }
|
802
807
|
|
803
|
-
@nodes.each do |node
|
808
|
+
@nodes.keys.sort.each do |node|
|
804
809
|
@bindings[node].each do |b|
|
805
810
|
if wrapped[b.alias] and rebind[b].nil?
|
806
811
|
field = '_field_' << field_count
|
@@ -822,7 +827,7 @@ class SqlMapper
|
|
822
827
|
select_nodes = {}
|
823
828
|
|
824
829
|
# update the global filter
|
825
|
-
@nodes.each do |node
|
830
|
+
@nodes.keys.sort.each do |node|
|
826
831
|
if r = rebind[ @bindings[node].first ]
|
827
832
|
@global_filter.gsub!(/#{Regexp.escape(node)}\b/) do
|
828
833
|
select_nodes[ @bindings[node].first ] = true
|
data/lib/graffiti/squish.rb
CHANGED
@@ -84,7 +84,7 @@ class SquishQuery
|
|
84
84
|
"Bad query initialization parameter class: #{query.class}"
|
85
85
|
end
|
86
86
|
|
87
|
-
debug { query }
|
87
|
+
debug { 'SquishQuery ' + query }
|
88
88
|
@query = query # keep original string
|
89
89
|
query = query.dup
|
90
90
|
|
@@ -391,7 +391,7 @@ class SquishAssert < SquishQuery
|
|
391
391
|
:strings => @strings
|
392
392
|
}
|
393
393
|
)
|
394
|
-
debug { db[s.to_sql, params].select_sql }
|
394
|
+
debug { 'resource_values ' + db[s.to_sql, params].select_sql }
|
395
395
|
found = db.fetch(s.to_sql, params).first
|
396
396
|
end
|
397
397
|
|
@@ -401,7 +401,7 @@ class SquishAssert < SquishQuery
|
|
401
401
|
else
|
402
402
|
table = @sql_mapper.clauses[ subject_position[:clause] ][:map].table
|
403
403
|
value = db[:resource].insert(:label => table)
|
404
|
-
debug { db[:resource].insert_sql(:label => table) }
|
404
|
+
debug { 'resource_values ' + db[:resource].insert_sql(:label => table) }
|
405
405
|
new = true unless 'resource' == table
|
406
406
|
end
|
407
407
|
end
|
@@ -413,16 +413,16 @@ class SquishAssert < SquishQuery
|
|
413
413
|
value = found[:id]
|
414
414
|
else
|
415
415
|
value = db[:resource].insert(uriref)
|
416
|
-
debug { db[:resource].insert_sql(uriref) }
|
416
|
+
debug { 'resource_values ' + db[:resource].insert_sql(uriref) }
|
417
417
|
end
|
418
418
|
end
|
419
419
|
|
420
|
-
debug { node + ' = ' + value.inspect }
|
420
|
+
debug { 'resource_values ' + node + ' = ' + value.inspect }
|
421
421
|
v = SquishAssertValue.new(value, new, @update.has_key?(node))
|
422
422
|
values[node] = v
|
423
423
|
end
|
424
424
|
|
425
|
-
debug { values.inspect }
|
425
|
+
debug { 'resource_values ' + 'resource_values ' + values.inspect }
|
426
426
|
values
|
427
427
|
end
|
428
428
|
|
@@ -523,7 +523,7 @@ class SquishAssertStatement
|
|
523
523
|
@filter = {:id => key.value}
|
524
524
|
end
|
525
525
|
|
526
|
-
debug { self.inspect }
|
526
|
+
debug { 'SquishAssertStatement ' + self.inspect }
|
527
527
|
end
|
528
528
|
|
529
529
|
attr_reader :key_node, :references, :action
|
data/test/ts_graffiti.rb
CHANGED
@@ -46,19 +46,19 @@ LITERAL ?rating >= -1
|
|
46
46
|
ORDER BY ?rating DESC
|
47
47
|
USING PRESET NS}
|
48
48
|
|
49
|
-
sql = "SELECT DISTINCT
|
50
|
-
FROM
|
51
|
-
INNER JOIN message AS
|
52
|
-
INNER JOIN
|
53
|
-
INNER JOIN
|
54
|
-
INNER JOIN resource AS e ON (
|
55
|
-
INNER JOIN resource AS f ON (
|
56
|
-
WHERE (
|
57
|
-
AND (
|
58
|
-
AND (
|
59
|
-
AND (
|
60
|
-
AND (
|
61
|
-
ORDER BY
|
49
|
+
sql = "SELECT DISTINCT b.id AS msg, b.title AS title, a.full_name AS name, c.published_date AS date, d.rating AS rating
|
50
|
+
FROM member AS a
|
51
|
+
INNER JOIN message AS b ON (b.creator = a.id)
|
52
|
+
INNER JOIN resource AS c ON (b.id = c.id)
|
53
|
+
INNER JOIN statement AS d ON (b.id = d.subject)
|
54
|
+
INNER JOIN resource AS e ON (d.predicate = e.id) AND (e.uriref = 't' AND e.label = 'http://purl.org/dc/elements/1.1/relation')
|
55
|
+
INNER JOIN resource AS f ON (d.object = f.id) AND (f.uriref = 't' AND f.label = 'http://www.nongnu.org/samizdat/rdf/schema#Quality')
|
56
|
+
WHERE (c.published_date IS NOT NULL)
|
57
|
+
AND (a.full_name IS NOT NULL)
|
58
|
+
AND (d.id IS NOT NULL)
|
59
|
+
AND (b.title IS NOT NULL)
|
60
|
+
AND (d.rating >= -1)
|
61
|
+
ORDER BY d.rating DESC"
|
62
62
|
|
63
63
|
test_squish_select(squish, sql) do |query|
|
64
64
|
assert_equal %w[?msg ?title ?name ?date ?rating], query.nodes
|
@@ -187,21 +187,21 @@ EXCEPT (s::inReplyTo ?msg ?parent)
|
|
187
187
|
(dc::creator ?version_of 1)
|
188
188
|
ORDER BY ?date DESC}
|
189
189
|
|
190
|
-
sql = "SELECT DISTINCT
|
191
|
-
FROM resource AS
|
190
|
+
sql = "SELECT DISTINCT a.id AS msg, a.published_date AS date
|
191
|
+
FROM resource AS a
|
192
192
|
LEFT JOIN (
|
193
|
-
SELECT
|
194
|
-
FROM message AS
|
195
|
-
INNER JOIN resource AS
|
196
|
-
INNER JOIN resource AS c ON (
|
197
|
-
WHERE (
|
198
|
-
) AS _subquery_a ON (
|
199
|
-
LEFT JOIN resource AS d ON (
|
200
|
-
WHERE (
|
201
|
-
AND (
|
202
|
-
AND (_subquery_a.
|
193
|
+
SELECT a.id AS _field_c
|
194
|
+
FROM message AS b
|
195
|
+
INNER JOIN resource AS a ON (a.part_of = b.id)
|
196
|
+
INNER JOIN resource AS c ON (a.part_of_subproperty = c.id) AND (c.uriref = 't' AND c.label = 'http://purl.org/dc/terms/isVersionOf')
|
197
|
+
WHERE (b.creator = 1)
|
198
|
+
) AS _subquery_a ON (a.id = _subquery_a._field_c)
|
199
|
+
LEFT JOIN resource AS d ON (a.part_of_subproperty = d.id) AND (d.uriref = 't' AND d.label = 'http://www.nongnu.org/samizdat/rdf/schema#inReplyTo')
|
200
|
+
WHERE (a.published_date IS NOT NULL)
|
201
|
+
AND (a.id IS NOT NULL)
|
202
|
+
AND (_subquery_a._field_c IS NULL)
|
203
203
|
AND (d.id IS NULL)
|
204
|
-
ORDER BY
|
204
|
+
ORDER BY a.published_date DESC"
|
205
205
|
|
206
206
|
test_squish_select(squish, sql)
|
207
207
|
end
|
@@ -219,20 +219,20 @@ EXCEPT (dct::isPartOf ?msg ?parent)
|
|
219
219
|
GROUP BY ?msg
|
220
220
|
ORDER BY max(?date) DESC}
|
221
221
|
|
222
|
-
sql = "SELECT DISTINCT
|
223
|
-
FROM
|
224
|
-
INNER JOIN
|
225
|
-
INNER JOIN
|
226
|
-
INNER JOIN resource AS d ON (
|
227
|
-
INNER JOIN resource AS e ON (
|
228
|
-
WHERE (
|
229
|
-
AND (
|
230
|
-
AND (
|
231
|
-
AND (
|
232
|
-
AND (
|
233
|
-
AND ((a.
|
234
|
-
GROUP BY
|
235
|
-
ORDER BY max(
|
222
|
+
sql = "SELECT DISTINCT c.subject AS msg, max(d.published_date)
|
223
|
+
FROM message AS a
|
224
|
+
INNER JOIN statement AS c ON (c.subject = a.id) AND (c.rating >= 1.5)
|
225
|
+
INNER JOIN resource AS b ON (c.subject = b.id)
|
226
|
+
INNER JOIN resource AS d ON (c.id = d.id)
|
227
|
+
INNER JOIN resource AS e ON (c.predicate = e.id) AND (e.uriref = 't' AND e.label = 'http://purl.org/dc/elements/1.1/relation')
|
228
|
+
WHERE (d.published_date IS NOT NULL)
|
229
|
+
AND (a.hidden IS NOT NULL)
|
230
|
+
AND (b.part_of IS NULL)
|
231
|
+
AND (c.rating IS NOT NULL)
|
232
|
+
AND (c.object IS NOT NULL)
|
233
|
+
AND ((a.hidden = 'f'))
|
234
|
+
GROUP BY c.subject
|
235
|
+
ORDER BY max(d.published_date) DESC"
|
236
236
|
|
237
237
|
test_squish_select(squish, sql)
|
238
238
|
end
|
@@ -272,18 +272,17 @@ OPTIONAL (dct::isPartOf ?tag ?supertag TRANSITIVE)
|
|
272
272
|
LITERAL ?tag = 1 OR ?supertag = 1
|
273
273
|
ORDER BY ?date DESC}
|
274
274
|
|
275
|
-
sql = "SELECT DISTINCT
|
276
|
-
FROM
|
277
|
-
INNER JOIN
|
278
|
-
INNER JOIN resource AS d ON (
|
279
|
-
LEFT JOIN part AS c ON (
|
280
|
-
WHERE (a.
|
281
|
-
AND (
|
282
|
-
AND (
|
283
|
-
AND (b.
|
284
|
-
AND (
|
285
|
-
|
286
|
-
ORDER BY b.published_date DESC"
|
275
|
+
sql = "SELECT DISTINCT b.subject AS msg, a.published_date AS date
|
276
|
+
FROM resource AS a
|
277
|
+
INNER JOIN statement AS b ON (b.subject = a.id) AND (b.rating > 0)
|
278
|
+
INNER JOIN resource AS d ON (b.predicate = d.id) AND (d.uriref = 't' AND d.label = 'http://purl.org/dc/elements/1.1/relation')
|
279
|
+
LEFT JOIN part AS c ON (b.object = c.id)
|
280
|
+
WHERE (a.published_date IS NOT NULL)
|
281
|
+
AND (a.part_of IS NULL)
|
282
|
+
AND (b.rating IS NOT NULL)
|
283
|
+
AND (b.id IS NOT NULL)
|
284
|
+
AND (b.object = 1 OR c.part_of = 1)
|
285
|
+
ORDER BY a.published_date DESC"
|
287
286
|
|
288
287
|
test_squish_select(squish, sql)
|
289
288
|
end
|
@@ -387,13 +386,11 @@ ORDER BY c.published_date DESC"
|
|
387
386
|
end
|
388
387
|
|
389
388
|
def normalize(sql)
|
390
|
-
|
391
|
-
# length should remain the same
|
392
|
-
sql.size
|
389
|
+
sql
|
393
390
|
end
|
394
391
|
|
395
392
|
def create_mock_db
|
396
|
-
db = Sequel.sqlite(:quote_identifiers => false)
|
393
|
+
db = Sequel.sqlite(:quote_identifiers => false, :integer_booleans => false)
|
397
394
|
|
398
395
|
db.create_table(:resource) do
|
399
396
|
primary_key :id
|
@@ -444,12 +441,4 @@ ORDER BY c.published_date DESC"
|
|
444
441
|
|
445
442
|
db
|
446
443
|
end
|
447
|
-
|
448
|
-
def create_mock_member(db)
|
449
|
-
db[:member].insert(
|
450
|
-
:login => 'test',
|
451
|
-
:full_name => 'test',
|
452
|
-
:email => 'test@localhost'
|
453
|
-
)
|
454
|
-
end
|
455
444
|
end
|
metadata
CHANGED
@@ -1,68 +1,101 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: graffiti
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 1
|
9
|
-
version: "2.1"
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.3.1
|
10
5
|
platform: ruby
|
11
|
-
authors:
|
6
|
+
authors:
|
12
7
|
- Dmitry Borodaenko
|
13
8
|
autorequire:
|
14
9
|
bindir: bin
|
15
10
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2016-04-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
20
14
|
name: syncache
|
21
|
-
|
22
|
-
|
23
|
-
none: false
|
24
|
-
requirements:
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
25
17
|
- - ">="
|
26
|
-
- !ruby/object:Gem::Version
|
27
|
-
|
28
|
-
segments:
|
29
|
-
- 0
|
30
|
-
version: "0"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
31
20
|
type: :runtime
|
32
|
-
version_requirements: *id001
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: sequel
|
35
21
|
prerelease: false
|
36
|
-
|
37
|
-
|
38
|
-
requirements:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
39
24
|
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sequel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
45
34
|
type: :runtime
|
46
|
-
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: test-unit
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: sqlite3
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
47
83
|
description: |
|
48
84
|
Graffiti is an RDF store based on dynamic translation of RDF queries into SQL.
|
49
85
|
Graffiti allows one to map any relational database schema into RDF semantics
|
50
86
|
and vice versa, to store any RDF data in a relational database.
|
51
|
-
|
87
|
+
|
52
88
|
Graffiti uses Sequel to connect to database backend and provides a DBI-like
|
53
89
|
interface to run RDF queries in Squish query language from Ruby applications.
|
54
|
-
|
55
90
|
email: angdraug@debian.org
|
56
91
|
executables: []
|
57
|
-
|
58
92
|
extensions: []
|
59
|
-
|
60
93
|
extra_rdoc_files: []
|
61
|
-
|
62
|
-
files:
|
94
|
+
files:
|
63
95
|
- COPYING
|
64
96
|
- ChangeLog.mtn
|
65
97
|
- README.rdoc
|
98
|
+
- Rakefile
|
66
99
|
- TODO
|
67
100
|
- doc/diagrams/graffiti-classes.svg
|
68
101
|
- doc/diagrams/graffiti-deployment.svg
|
@@ -86,37 +119,28 @@ files:
|
|
86
119
|
- setup.rb
|
87
120
|
- test/ts_graffiti.rb
|
88
121
|
homepage: https://github.com/angdraug/graffiti
|
89
|
-
licenses:
|
90
|
-
-
|
122
|
+
licenses:
|
123
|
+
- GPL-3.0+
|
124
|
+
metadata: {}
|
91
125
|
post_install_message:
|
92
126
|
rdoc_options: []
|
93
|
-
|
94
|
-
require_paths:
|
127
|
+
require_paths:
|
95
128
|
- lib
|
96
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
-
|
98
|
-
requirements:
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
99
131
|
- - ">="
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
version: "0"
|
105
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
|
-
requirements:
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
108
136
|
- - ">="
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
|
111
|
-
segments:
|
112
|
-
- 0
|
113
|
-
version: "0"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
114
139
|
requirements: []
|
115
|
-
|
116
140
|
rubyforge_project:
|
117
|
-
rubygems_version:
|
141
|
+
rubygems_version: 2.5.1
|
118
142
|
signing_key:
|
119
|
-
specification_version:
|
143
|
+
specification_version: 4
|
120
144
|
summary: Relational RDF store for Ruby
|
121
|
-
test_files:
|
145
|
+
test_files:
|
122
146
|
- test/ts_graffiti.rb
|