lightrdf 0.1.8 → 0.1.9

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.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ === 0.1.9 2011-02-18
2
+
3
+ * Simplified design with much better performance
4
+
1
5
  === 0.1.8 2011-02-09
2
6
 
3
7
  * Added support for RDF abbreviated syntax
data/Manifest CHANGED
@@ -8,6 +8,6 @@ lib/lightrdf/graph.rb
8
8
  lib/lightrdf/node.rb
9
9
  lib/lightrdf/parser.rb
10
10
  lib/lightrdf/repository.rb
11
- lib/lightrdf/quri.rb
11
+ lib/lightrdf/id.rb
12
12
  test/test_helper.rb
13
13
  test/test_lightrdf.rb
data/README.rdoc CHANGED
@@ -56,7 +56,7 @@ If you want to get the property, an array will be returned, as many foaf::name's
56
56
  Therefore, we can add multiple values to a property:
57
57
 
58
58
  user.foaf::weblog = Node('http://www.awesomeweblogfordummies.com')
59
- user.foaf::weblog << Node('http://www.anotherawesomeweblogfordummies.com')
59
+ user.foaf::weblog += [Node('http://www.anotherawesomeweblogfordummies.com')]
60
60
  user.foaf::weblog.size # => 2
61
61
  user.foaf::weblog?(Node('http://www.awesomeweblogfordummies.com')) # => true
62
62
 
@@ -10,7 +10,7 @@ module RDF
10
10
  end
11
11
 
12
12
  def << node
13
- self[node] = node
13
+ self[node.id] = node
14
14
  end
15
15
 
16
16
  def [] id
@@ -35,18 +35,31 @@ module RDF
35
35
  end
36
36
  def triples= triples
37
37
  self.clear
38
- triples.each { |s, p, o| self[s][p] = self[s][p] + [o] }
38
+ triples.each { |s, p, o| self[s][p] += [o] }
39
+ end
40
+ def select &block
41
+ values.select &block
39
42
  end
40
43
 
41
44
  def find subject, predicate, object
42
- matches = triples.select { |s,p,o| (subject.nil? or subject==[] or s==subject) and
45
+ # Convert nodes into IDs
46
+ subject = subject.id if subject.is_a?(Node)
47
+ predicate = predicate.id if predicate.is_a?(Node)
48
+ object = object.id if object.is_a?(Node)
49
+
50
+ # Find nodes
51
+ matches = triples.select { |s,p,o| (subject.nil? or subject ==[] or s==subject) and
43
52
  (predicate.nil? or predicate==[] or p==predicate) and
44
- (object.nil? or object==[] or o==object) }
53
+ (object.nil? or object ==[] or o==object) }
54
+
55
+ # Build results
45
56
  result = []
46
57
  result += matches.map {|t| t[0] } if subject.nil?
47
58
  result += matches.map {|t| t[1] } if predicate.nil?
48
59
  result += matches.map {|t| t[2] } if object.nil?
49
- result.uniq
60
+
61
+ # Return nodes, not IDs
62
+ result.uniq.map { |id| id.is_a?(Symbol) ? Node(id, self) : id }
50
63
  end
51
64
  end
52
65
  end
@@ -0,0 +1,47 @@
1
+ module RDF
2
+ module ID
3
+ @count = 0
4
+ @ns = { :rdf => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
5
+ :rdfs => 'http://www.w3.org/2000/01/rdf-schema#',
6
+ :dc => 'http://purl.org/dc/elements/1.1/',
7
+ :owl => 'http://www.w3.org/2002/07/owl#' }
8
+ def self.ns; @ns; end
9
+ def self.count; @count; end
10
+ def self.count=c; @count=c; end
11
+
12
+ def self.bnode? id
13
+ id.to_s[0..0] == '_'
14
+ end
15
+ def self.uri? id
16
+ !bnode?(id)
17
+ end
18
+
19
+ def self.parse id, ns={}
20
+ if id.to_s[0..6]!='http://' and id.to_s[0..7]!='https://' and id.to_s[0..0]!='_' and id.to_s =~ /(\w+):(\w.*)/
21
+ :"#{RDF::ID.ns.merge(ns)[$1.to_sym]}#{$2}"
22
+ elsif id == '*' or !id
23
+ :"_:bnode#{@count+=1}"
24
+ else
25
+ id.to_sym
26
+ end
27
+ end
28
+
29
+ def self.compress uri, ns={}
30
+ RDF::ID.ns.merge(ns).map.sort_by{|k,v| -v.to_s.size}.each do |k,v|
31
+ if uri.to_s.index(v) == 0
32
+ return "#{k}:#{uri.to_s[v.size..-1]}"
33
+ end
34
+ end
35
+ uri.to_s
36
+ end
37
+ end
38
+ end
39
+
40
+ # Shortcut to parse IDs
41
+ def ID id, ns={}
42
+ RDF::ID.parse id, ns
43
+ end
44
+ # Shortcut to declare namespaces
45
+ def Namespace prefix, uri
46
+ RDF::ID.ns[prefix.to_sym] = uri
47
+ end
data/lib/lightrdf/node.rb CHANGED
@@ -19,36 +19,36 @@ module RDF
19
19
  end
20
20
  end
21
21
  end
22
-
22
+
23
23
  class Node < Hash
24
24
  include Parser
25
25
  attr_accessor :graph, :id
26
26
 
27
27
  def initialize id=nil, graph=nil
28
- @id = ID::parse(id)
28
+ @id = ID(id)
29
29
  @graph = graph || Graph.new
30
30
  @graph << self
31
31
  end
32
32
 
33
33
  def method_missing method, *args
34
- QURI.ns[method] ? NsProxy.new(method, self) : super
34
+ ID.ns[method] ? NsProxy.new(method, self) : super
35
35
  end
36
36
  def inspect; "<#{self.class} #{id} #{super}>"; end
37
- def to_s; id.to_s; end
37
+ def to_s; id.to_s; end
38
+ def to_sym; id; end
38
39
 
39
40
  def [] name
40
- self[Node(name)] = [] if super(Node(name)).nil?
41
- super(Node(name)).map! {|n| n.is_a?(Node) ? @graph[n] : n}
41
+ ( super(ID(name)) || [] ).clone
42
42
  end
43
43
  def []= name, values
44
- super(Node(name), [values].flatten.map { |node| node.is_a?(Node) ? @graph[node] : node })
44
+ super(ID(name), [values].flatten.map { |node| node.is_a?(Node) ? @graph[node] : node })
45
45
  end
46
46
 
47
- def == b
48
- eql? b
47
+ def == node
48
+ eql? node
49
49
  end
50
- def eql? b
51
- b.is_a?(Node) and self.id == b.id
50
+ def eql? node
51
+ self.class == node.class and self.id == node.id
52
52
  end
53
53
  def hash # Hack for Ruby 1.8.6
54
54
  id.hash ^ self.class.hash
@@ -59,7 +59,7 @@ module RDF
59
59
  end
60
60
 
61
61
  def triples
62
- triples = []; each { |k, v| v.each { |o| triples << [self, Node(k), o] } }
62
+ triples = []; each { |p, v| v.each { |o| triples << [id, p, o.is_a?(Node) ? o.id : o] } }
63
63
  triples
64
64
  end
65
65
 
@@ -76,11 +76,11 @@ module RDF
76
76
  end
77
77
 
78
78
  def bnode?
79
- id.is_a?(BNodeID)
79
+ ID.bnode?(id)
80
80
  end
81
81
  end
82
82
  end
83
83
 
84
84
  def Node id, graph=nil
85
- graph.nil? ? RDF::Node.new(id, graph) : graph[id]
85
+ graph ? graph[id] : RDF::Node.new(id)
86
86
  end
@@ -11,9 +11,9 @@ module RDF
11
11
 
12
12
  case format.to_sym
13
13
  when :ntriples
14
- triples.map { |s,p,o| "#{serialize_chunk_ntriples(s)} #{serialize_chunk_ntriples(p)} #{serialize_chunk_ntriples(o)} ." } * "\n"
14
+ triples.map { |s,p,o| "#{serialize_chunk_ntriples(s)} #{serialize_chunk_ntriples(p)} #{serialize_chunk_ntriples(o)} .\n" } * ''
15
15
  when :yarf
16
- ns = respond_to?(:ns) ? QURI.ns.merge(self.ns) : QURI.ns
16
+ ns = respond_to?(:ns) ? ID.ns.merge(self.ns) : ID.ns
17
17
  if header
18
18
  (ns.map{|k,v| "#{k}: #{v}\n"} * '') + serialize_yarf(nodes, ns)
19
19
  else
@@ -26,7 +26,7 @@ module RDF
26
26
  stdout.read
27
27
  when :png
28
28
  dot = serialize(:dot)
29
- ns = respond_to?(:ns) ? QURI.ns.merge(self.ns) : QURI.ns
29
+ ns = respond_to?(:ns) ? ID.ns.merge(self.ns) : ID.ns
30
30
  ns.each { |k,v| dot.gsub!(v, "#{k}:") }
31
31
  dot.gsub!(/label=\"\\n\\nModel:.*\)\";/, '')
32
32
  stdin, stdout, stderr = Open3.popen3("dot -o/dev/stdout -Tpng")
@@ -37,7 +37,7 @@ module RDF
37
37
  serialize(:'rdfxml-abbrev')
38
38
  else
39
39
  namespaces = if [:rdfxml, :'rdfxml-abbrev'].include?(format)
40
- QURI.ns.map {|k,v| "-f 'xmlns:#{k}=#{v.inspect}'" } * " "
40
+ ID.ns.map {|k,v| "-f 'xmlns:#{k}=#{v.inspect}'" } * " "
41
41
  end
42
42
  tmpfile = File.join(Dir.tmpdir, "rapper#{$$}#{Thread.current.object_id}")
43
43
  File.open(tmpfile, 'w') { |f| f.write(serialize(:ntriples)) }
@@ -134,7 +134,7 @@ module RDF
134
134
  [i, relations]
135
135
  end
136
136
 
137
- def serialize_yarf nodes, ns=QURI.ns, level=0, already_serialized=[]
137
+ def serialize_yarf nodes, ns=ID.ns, level=0, already_serialized=[]
138
138
  text = ""
139
139
 
140
140
  for node in nodes
@@ -148,7 +148,7 @@ module RDF
148
148
  text += ":\n"
149
149
  node.predicates.each do |p, o| # Predicate and object
150
150
  text += " " *(level+1)*2
151
- text += p.id.compressed(ns)
151
+ text += ID.compress(p.id, ns)
152
152
  text += ":"
153
153
  if o.size == 1 and (already_serialized.include?(o.first) or !o.first.is_a?(Node) or o.first.triples.size==0)
154
154
  text += " " + serialize_chunk_yarf(o.first, ns)
@@ -162,7 +162,7 @@ module RDF
162
162
  text
163
163
  end
164
164
 
165
- def serialize_chunk_yarf node, ns=QURI.ns
165
+ def serialize_chunk_yarf node, ns=ID.ns
166
166
  if node.is_a?(Node)
167
167
  if node.bnode?
168
168
  if node.graph.find(nil, [], node).size > 1 # Only use a bnode-id if it appears again as object
@@ -171,7 +171,7 @@ module RDF
171
171
  "*"
172
172
  end
173
173
  else
174
- node.id.compressed ns
174
+ ID.compress(node.id, ns)
175
175
  end
176
176
  else
177
177
  ActiveSupport::JSON.encode(node)
@@ -202,8 +202,8 @@ module RDF
202
202
  end
203
203
 
204
204
  def serialize_chunk_ntriples n
205
- if n.is_a? Node
206
- n.bnode? ? n.to_s : "<#{n}>"
205
+ if n.is_a? Symbol
206
+ ID.bnode?(n) ? n.to_s : "<#{n}>"
207
207
  else
208
208
  ActiveSupport::JSON.encode(n)
209
209
  end
data/lib/lightrdf.rb CHANGED
@@ -2,7 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  module RDF
5
- VERSION = '0.1.8'
5
+ VERSION = '0.1.9'
6
6
  end
7
7
 
8
8
  require 'rubygems'
@@ -16,7 +16,7 @@ require 'yaml'
16
16
  require 'monitor'
17
17
  require 'nokogiri'
18
18
 
19
- require "lightrdf/quri"
19
+ require "lightrdf/id"
20
20
  require "lightrdf/parser"
21
21
  require "lightrdf/graph"
22
22
  require "lightrdf/node"
data/lightrdf.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{lightrdf}
5
- s.version = "0.1.8"
5
+ s.version = "0.1.9"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Jose Ignacio"]
9
- s.date = %q{2011-02-09}
9
+ s.date = %q{2011-02-18}
10
10
  s.default_executable = %q{yarfp}
11
11
  s.description = %q{RDF library}
12
12
  s.email = %q{joseignacio.fernandez@gmail.com}
13
13
  s.executables = ["yarfp"]
14
- s.extra_rdoc_files = ["README.rdoc", "bin/yarfp", "lib/lightrdf.rb", "lib/lightrdf/graph.rb", "lib/lightrdf/node.rb", "lib/lightrdf/parser.rb", "lib/lightrdf/repository.rb", "lib/lightrdf/quri.rb"]
15
- s.files = ["History.txt", "Manifest", "README.rdoc", "Rakefile", "bin/yarfp", "lib/lightrdf.rb", "lib/lightrdf/graph.rb", "lib/lightrdf/node.rb", "lib/lightrdf/parser.rb", "lib/lightrdf/repository.rb", "lib/lightrdf/quri.rb", "test/test_helper.rb", "test/test_lightrdf.rb", "lightrdf.gemspec"]
14
+ s.extra_rdoc_files = ["README.rdoc", "bin/yarfp", "lib/lightrdf.rb", "lib/lightrdf/graph.rb", "lib/lightrdf/node.rb", "lib/lightrdf/parser.rb", "lib/lightrdf/repository.rb", "lib/lightrdf/id.rb"]
15
+ s.files = ["History.txt", "Manifest", "README.rdoc", "Rakefile", "bin/yarfp", "lib/lightrdf.rb", "lib/lightrdf/graph.rb", "lib/lightrdf/node.rb", "lib/lightrdf/parser.rb", "lib/lightrdf/repository.rb", "lib/lightrdf/id.rb", "test/test_helper.rb", "test/test_lightrdf.rb", "lightrdf.gemspec"]
16
16
  s.homepage = %q{http://github.com/josei/lighrdf}
17
17
  s.post_install_message = %q{**Remember to install raptor RDF tools and (optionally for RDF PNG output) Graphviz**}
18
18
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Lightrdf", "--main", "README.rdoc"]
@@ -14,14 +14,19 @@ class TestLightRDF < Test::Unit::TestCase
14
14
  assert Node('_:2') == Node('_:2')
15
15
  end
16
16
 
17
- def test_type
18
- assert ID('rdf:type').is_a?(RDF::ID)
19
- assert ID('_:bnode').is_a?(RDF::ID)
20
- assert ID('http://www.google.com').is_a?(RDF::ID)
21
- assert URI.parse('http://www.google.com').is_a?(RDF::ID)
22
- assert ID('*').is_a?(RDF::ID)
17
+ def test_ids
18
+ assert ID('rdf:type') == :'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'
19
+ assert ID('_:bnode') == :'_:bnode'
20
+ assert ID('http://www.google.com') == :'http://www.google.com'
23
21
  end
24
22
 
23
+ def test_type
24
+ assert RDF::ID.uri?(ID('rdf:type'))
25
+ assert RDF::ID.uri?(ID('http://www.google.com'))
26
+ assert RDF::ID.bnode?(ID('*'))
27
+ assert RDF::ID.bnode?(ID('_:bnode'))
28
+ end
29
+
25
30
  def test_random_node
26
31
  assert Node(nil).is_a?(RDF::Node)
27
32
  end
@@ -58,14 +63,14 @@ class TestLightRDF < Test::Unit::TestCase
58
63
  g << a
59
64
  g << b
60
65
 
61
- assert_equal 1, g.find(nil, Node('foaf:age'), "22").size
62
- assert_equal 2, g.find(Node('ex:bob'), nil, []).size
66
+ assert_equal [Node('ex:alice')], g.find(nil, Node('foaf:age'), "22")
67
+ assert_equal [Node('foaf:age'), Node('foaf:name')], g.find(Node('ex:bob'), nil, []).sort_by {|node| node.to_s}
63
68
  end
64
69
 
65
70
  def test_addition
66
71
  a = Node('ex:bob')
67
72
  a.foaf::weblog = Node('http://www.awesomeweblogfordummies.com')
68
- a.foaf::weblog << Node('http://www.anotherawesomeweblogfordummies.com')
73
+ a.foaf::weblog += [Node('http://www.anotherawesomeweblogfordummies.com')]
69
74
  assert_equal 2, a.foaf::weblog.size
70
75
  assert a.foaf::weblog?(Node('http://www.awesomeweblogfordummies.com'))
71
76
  end
@@ -108,7 +113,6 @@ foaf: http://xmlns.com/foaf/0.1/
108
113
  end
109
114
 
110
115
  def test_parsing_raptor
111
- # Very naive testing -- it only helps to check that rapper is being executed
112
116
  assert RDF::Parser.parse(:rdf, open('http://planetrdf.com/guide/rss.rdf').read).serialize(:ntriples).split("\n").size > 10
113
117
  end
114
118
 
@@ -123,6 +127,20 @@ foaf: http://xmlns.com/foaf/0.1/
123
127
  assert 2, g.to_ntriples.split("\n").size
124
128
  end
125
129
 
130
+ def test_serialization_raptor
131
+ a = Node('ex:bob')
132
+ a.foaf::name = "Bob"
133
+ a.foaf::age = "23"
134
+ a.ex::location = Node(nil)
135
+
136
+ g = RDF::Graph.new
137
+ g << a
138
+
139
+ assert_equal 3, RDF::Parser.parse(:yarf, g.serialize(:yarf) ).triples.size
140
+ assert_equal 3, RDF::Parser.parse(:rdfxml, g.serialize(:rdfxml)).triples.size
141
+ assert_equal 3, RDF::Parser.parse(:rdf, g.serialize(:rdf) ).triples.size
142
+ end
143
+
126
144
  def test_repository
127
145
  repository = RDF::Repository.new
128
146
  triple = [Node("http://testuri.org"), Node('rdf:type'), Node('rdf:Class')]
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 1
8
- - 8
9
- version: 0.1.8
8
+ - 9
9
+ version: 0.1.9
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jose Ignacio
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-02-09 00:00:00 +01:00
17
+ date: 2011-02-18 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -73,7 +73,7 @@ extra_rdoc_files:
73
73
  - lib/lightrdf/node.rb
74
74
  - lib/lightrdf/parser.rb
75
75
  - lib/lightrdf/repository.rb
76
- - lib/lightrdf/quri.rb
76
+ - lib/lightrdf/id.rb
77
77
  files:
78
78
  - History.txt
79
79
  - Manifest
@@ -85,7 +85,7 @@ files:
85
85
  - lib/lightrdf/node.rb
86
86
  - lib/lightrdf/parser.rb
87
87
  - lib/lightrdf/repository.rb
88
- - lib/lightrdf/quri.rb
88
+ - lib/lightrdf/id.rb
89
89
  - test/test_helper.rb
90
90
  - test/test_lightrdf.rb
91
91
  - lightrdf.gemspec
data/lib/lightrdf/quri.rb DELETED
@@ -1,81 +0,0 @@
1
- module RDF
2
- module QURI
3
- @ns = { :rdf => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
4
- :rdfs => 'http://www.w3.org/2000/01/rdf-schema#',
5
- :dc => 'http://purl.org/dc/elements/1.1/',
6
- :owl => 'http://www.w3.org/2002/07/owl#' }
7
- def self.ns; @ns; end
8
-
9
- def self.parse uri, ns={}
10
- URI.parse( (uri.to_s =~ /(\w+):(.*)/ and uri.to_s[0..6]!='http://' and uri.to_s[0..7]!='https://') ?
11
- "#{QURI.ns.merge(ns)[$1.to_sym]}#{$2}" :
12
- uri.to_s )
13
- end
14
-
15
- def self.compress uri, ns={}
16
- QURI.ns.merge(ns).map.sort_by{|k,v| -v.to_s.size}.each do |k,v|
17
- if uri.to_s.index(v) == 0
18
- return "#{k}:#{uri.to_s[v.size..-1]}"
19
- end
20
- end
21
- uri.to_s
22
- end
23
- end
24
-
25
- module ID
26
- def self.ns; QURI.ns; end
27
-
28
- def compressed ns={}
29
- RDF::ID.compress self, ns
30
- end
31
-
32
- def self.compress id, ns={}
33
- bnode?(id) ? id.to_s : RDF::QURI.compress(id, ns)
34
- end
35
-
36
- def self.parse id, ns={}
37
- bnode?(id) ? RDF::BNodeID.parse(id) : RDF::QURI.parse(id, ns)
38
- end
39
-
40
- def self.bnode?(id)
41
- id.nil? or id == '*' or id.to_s[0..0] == '_'
42
- end
43
- end
44
-
45
- class BNodeID
46
- include RDF::ID
47
- @count = 0
48
- def self.count; @count; end
49
- def self.count=c; @count=c; end
50
-
51
- attr_reader :id
52
- def initialize id=nil
53
- @id = (id || "_:bnode#{RDF::BNodeID.count+=1}").to_s
54
- end
55
- def self.parse id
56
- new(id=='*' ? nil : id)
57
- end
58
- def to_s; id.to_s; end
59
-
60
- def == b
61
- eql? b
62
- end
63
- def eql? b
64
- b.is_a?(BNodeID) and self.id == b.id
65
- end
66
- def hash # Hack for Ruby 1.8.6
67
- id.hash + self.class.hash
68
- end
69
- end
70
- end
71
-
72
- class URI::Generic
73
- include RDF::ID # URIs are RDF IDs
74
- end
75
-
76
- def ID uri, ns={} # Shortcut to parse IDs
77
- RDF::ID.parse uri, ns
78
- end
79
- def Namespace prefix, uri
80
- RDF::QURI.ns[prefix.to_sym] = uri
81
- end