graffiti 2.1 → 2.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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 = `git ls-files`.split "\n"
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 = 'GPL3+'
19
- spec.add_dependency('syncache')
20
- spec.add_dependency('sequel')
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
@@ -22,8 +22,8 @@ module Debug
22
22
  def debug(message = nil)
23
23
  return unless DEBUG
24
24
 
25
+ message = yield if block_given?
25
26
  log message if message
26
- log yield if block_given?
27
27
  end
28
28
 
29
29
  def log(message)
@@ -211,9 +211,11 @@ class SqlMapper
211
211
  refine_ambiguous_properties
212
212
 
213
213
  debug do
214
- @nodes.each do |node, n|
215
- debug %{#{node}: #{n[:bind_mode]} #{n[:colors].inspect}}
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.each_value do |n|
390
- map = n[:positions]
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 { n + ': ' + big.inspect }
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, n|
451
-
452
- positions = n[:positions]
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, n|
512
- positions = n[: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
- n[:ground] = true
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
- n[:ground] = true
575
+ @nodes[node][:ground] = true
573
576
  end
574
577
  end
575
578
 
576
579
  debug do
577
- @aliases.each {|alias_name, a| debug %{#{alias_name}: #{a.inspect}} }
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 |alias_name, a|
723
- next if seen[alias_name] or a[:bind_mode] != bind_mode
724
- return alias_name
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, n|
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, n|
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, n|
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
@@ -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
@@ -46,19 +46,19 @@ LITERAL ?rating >= -1
46
46
  ORDER BY ?rating DESC
47
47
  USING PRESET NS}
48
48
 
49
- sql = "SELECT DISTINCT c.id AS msg, c.title AS title, b.full_name AS name, d.published_date AS date, a.rating AS rating
50
- FROM statement AS a
51
- INNER JOIN message AS c ON (c.id = a.subject)
52
- INNER JOIN member AS b ON (c.creator = b.id)
53
- INNER JOIN resource AS d ON (c.id = d.id)
54
- INNER JOIN resource AS e ON (a.object = e.id) AND (e.uriref = 't' AND e.label = 'http://www.nongnu.org/samizdat/rdf/schema#Quality')
55
- INNER JOIN resource AS f ON (a.predicate = f.id) AND (f.uriref = 't' AND f.label = 'http://purl.org/dc/elements/1.1/relation')
56
- WHERE (a.id IS NOT NULL)
57
- AND (d.published_date IS NOT NULL)
58
- AND (b.full_name IS NOT NULL)
59
- AND (c.title IS NOT NULL)
60
- AND (a.rating >= -1)
61
- ORDER BY a.rating DESC"
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 b.id AS msg, b.published_date AS date
191
- FROM resource AS b
190
+ sql = "SELECT DISTINCT a.id AS msg, a.published_date AS date
191
+ FROM resource AS a
192
192
  LEFT JOIN (
193
- SELECT b.id AS _field_f
194
- FROM message AS a
195
- INNER JOIN resource AS b ON (b.part_of = a.id)
196
- INNER JOIN resource AS c ON (b.part_of_subproperty = c.id) AND (c.uriref = 't' AND c.label = 'http://purl.org/dc/terms/isVersionOf')
197
- WHERE (a.creator = 1)
198
- ) AS _subquery_a ON (b.id = _subquery_a._field_f)
199
- LEFT JOIN resource AS d ON (b.part_of_subproperty = d.id) AND (d.uriref = 't' AND d.label = 'http://www.nongnu.org/samizdat/rdf/schema#inReplyTo')
200
- WHERE (b.published_date IS NOT NULL)
201
- AND (b.id IS NOT NULL)
202
- AND (_subquery_a._field_f IS NULL)
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 b.published_date DESC"
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 a.subject AS msg, max(b.published_date)
223
- FROM statement AS a
224
- INNER JOIN resource AS b ON (a.id = b.id)
225
- INNER JOIN message AS c ON (a.subject = c.id) AND (c.hidden = 'f')
226
- INNER JOIN resource AS d ON (a.subject = d.id)
227
- INNER JOIN resource AS e ON (a.predicate = e.id) AND (e.uriref = 't' AND e.label = 'http://purl.org/dc/elements/1.1/relation')
228
- WHERE (c.hidden IS NOT NULL)
229
- AND (b.published_date IS NOT NULL)
230
- AND (a.object IS NOT NULL)
231
- AND (a.rating IS NOT NULL)
232
- AND (d.part_of IS NULL)
233
- AND ((a.rating >= 1.5))
234
- GROUP BY a.subject
235
- ORDER BY max(b.published_date) DESC"
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 a.subject AS msg, b.published_date AS date
276
- FROM statement AS a
277
- INNER JOIN resource AS b ON (a.subject = b.id)
278
- INNER JOIN resource AS d ON (a.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 (a.object = c.id)
280
- WHERE (a.id IS NOT NULL)
281
- AND (b.published_date IS NOT NULL)
282
- AND (a.rating IS NOT NULL)
283
- AND (b.part_of IS NULL)
284
- AND ((a.rating > 0))
285
- AND (a.object = 1 OR c.part_of = 1)
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
- # alias labels and where conditions may be reordered, but the query string
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
- hash: 1
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
- date: 2012-04-17 00:00:00 Z
18
- dependencies:
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
- prerelease: false
22
- requirement: &id001 !ruby/object:Gem::Requirement
23
- none: false
24
- requirements:
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
25
17
  - - ">="
26
- - !ruby/object:Gem::Version
27
- hash: 3
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
- requirement: &id002 !ruby/object:Gem::Requirement
37
- none: false
38
- requirements:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
39
24
  - - ">="
40
- - !ruby/object:Gem::Version
41
- hash: 3
42
- segments:
43
- - 0
44
- version: "0"
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
- version_requirements: *id002
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
- - GPL3+
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
- none: false
98
- requirements:
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
99
131
  - - ">="
100
- - !ruby/object:Gem::Version
101
- hash: 3
102
- segments:
103
- - 0
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
- hash: 3
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: 1.8.15
141
+ rubygems_version: 2.5.1
118
142
  signing_key:
119
- specification_version: 3
143
+ specification_version: 4
120
144
  summary: Relational RDF store for Ruby
121
- test_files:
145
+ test_files:
122
146
  - test/ts_graffiti.rb