rdf-virtuoso 0.0.15 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +5 -38
- data/lib/rdf/virtuoso/version.rb +1 -1
- metadata +7 -113
- data/lib/active_rdf.rb +0 -14
- data/lib/active_rdf/association_reflection.rb +0 -26
- data/lib/active_rdf/errors.rb +0 -9
- data/lib/active_rdf/exceptions.rb +0 -83
- data/lib/active_rdf/model.rb +0 -69
- data/lib/active_rdf/persistence.rb +0 -185
- data/lib/active_rdf/reflections.rb +0 -19
- data/lib/active_rdf/version.rb +0 -10
- data/spec/active_rdf/persistence_spec.rb +0 -31
data/README.md
CHANGED
@@ -18,7 +18,11 @@ This example assumes you have a local installation of Virtoso running at standar
|
|
18
18
|
|
19
19
|
uri = "http://localhost:8890/sparql"
|
20
20
|
update_uri = "http://localhost:8890/sparql-auth"
|
21
|
-
repo = RDF::Virtuoso::Repository.new(uri,
|
21
|
+
repo = RDF::Virtuoso::Repository.new(uri,
|
22
|
+
:update_uri => update_uri,
|
23
|
+
:username => 'admin',
|
24
|
+
:password => 'secret',
|
25
|
+
:auth_method => 'digest')
|
22
26
|
|
23
27
|
:auth_method can be 'digest' or 'basic'. a repository connection without auth requires only uri
|
24
28
|
|
@@ -60,40 +64,3 @@ or you can dynamically add RDF::Vocabulary objects
|
|
60
64
|
Results will be an array of RDF::Query::Solution that can be accessed by bindings or iterated
|
61
65
|
|
62
66
|
count = result.first[:count].to_i
|
63
|
-
|
64
|
-
## Rails specifics
|
65
|
-
Working on a prototype Rails application for negotiating and manipulating linked data in an RDF store, I discovered the lack of a reasonably current library to bridge the gap between the fairly well-established, modular RDF.rb library and a Rails 3 application. I wanted to be able to manipulate RDF data in a convenient, ActiveRecord/ActiveModel way. It turned out to be fairly non-trivial to mimic true AR/AM behavior and this is more or less the groundwork and result of my experimentation. I now have a much better idea of how to proceed, I just need the time to really go deep into this.
|
66
|
-
An example prototype that exercises this library can be found here: https://github.com/digibib/booky
|
67
|
-
|
68
|
-
It must be stressed that this is still early days, with lots of refactoring and abstraction to be done, along with very specific functionality targeted at the prototype I've been working on. So anyone wanting a more generalized approach would be well served by waiting until I'm further along.
|
69
|
-
|
70
|
-
Essentially, a model in a Rails 3 app subclasses ActiveRDF::Model, which in itself includes the following modules:
|
71
|
-
ActiveAttr::Model - https://github.com/cgriego/active_attr
|
72
|
-
ActiveModel::Dirty - http://api.rubyonrails.org/classes/ActiveModel/Dirty.html
|
73
|
-
ActiveRDF::Persistence - responsible for handling persistence, in this gem
|
74
|
-
|
75
|
-
In a nutshell:
|
76
|
-
|
77
|
-
ActiveRDF::Model provides common functionality for models along with some mixed-in 3rd-party modules
|
78
|
-
|
79
|
-
ActiveRDF::Persistence provides some of the functionality a Rails model may expect, along with some placeholder methods that are waiting for AR/Arel type implementations. All communication is done via the query language SPARQL, (version 1.1 as of this writing).
|
80
|
-
|
81
|
-
RDF::Virtuoso::Client provides a rudimentary connection class for interacting with a Virtuoso server. It is inspired by API Smith (https://github.com/filtersquad/api_smith) which has some nice features, such as a convenient way to specify a Parser class for a given mimetype. See RDF::Virtuoso::Parser for example, and the method RDF::Virtuoso::Client#api_get.
|
82
|
-
|
83
|
-
## Challenges
|
84
|
-
In no particular order:
|
85
|
-
|
86
|
-
* In RDF data, the equivalent of a primary key in a relational database is called the subject (part of each of a set of triples), which is represented by a URI which looks like an absolute URL. When Rails does its magic with routes and friends, it assumes by default that it's dealing with an Integer, which is fine for a relational database id column which is auto-generated by the RDBM, unique and very often an int. Under the covers, to_i is called on id. This does not work for URLs, obviously. Also, you can't just send unencoded URLs over the wire as part of a path in a route. Anyway, this whole issue needed to be solved quickly, so for now RDF subjects that are part of a path are encoded and then decoded before insertion.
|
87
|
-
* On the topic of unique ids, relational databases can be told to autogenerate unique primary keys on insert for you. Here, we have to use a library (UUID) to generate unique ids before insert.
|
88
|
-
* On the whole, when dealing with RDF subjects, care has to be taken how they are constructed. They can end with either a forward-slash or a hash, followed by some unique identifier. Seems like the hash-notation is preferred if the data is ever to be be exported as turtle files (suffix ttl) and the unique identifier potentially starts with an integer. Whether that is a bug in the writer implementation is unclear, but better safe than sorry.
|
89
|
-
* An update in an RDF store is a so-called modify and consists of one or more delete statements followed by one or more insert statements. Meaning that when a triple has changed, the original has to be deleted before the modified triple is inserted. There is a potential for leaving the data in an inconsistent state if, for instance, the delete directive isn't constructed correctly and the insert is. Or vice versa. With ActiveRecord, database writes are automatically wrapped in transactions that will roll back the data on failure. This too needed to be implemented explicitly, as seen in ActiveRDF::Persistence#update_attributes, using the SimpleTransaction libray.
|
90
|
-
|
91
|
-
## Notes
|
92
|
-
The following classes are not yet in use or will probably disapper:
|
93
|
-
|
94
|
-
* ActiveRDF::AssociationReflection
|
95
|
-
* ActiveRDF::Exceptions
|
96
|
-
* ActiveRDF::Reflections
|
97
|
-
|
98
|
-
|
99
|
-
|
data/lib/rdf/virtuoso/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdf-virtuoso
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-10-
|
13
|
+
date: 2012-10-24 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rspec
|
@@ -44,102 +44,6 @@ dependencies:
|
|
44
44
|
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 0.3.5
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: vcr
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ! '>='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
type: :development
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
|
-
requirements:
|
60
|
-
- - ! '>='
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '0'
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: webmock
|
65
|
-
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
|
-
requirements:
|
68
|
-
- - ! '>='
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: '0'
|
71
|
-
type: :development
|
72
|
-
prerelease: false
|
73
|
-
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
|
-
requirements:
|
76
|
-
- - ! '>='
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version: '0'
|
79
|
-
- !ruby/object:Gem::Dependency
|
80
|
-
name: activesupport
|
81
|
-
requirement: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
|
-
requirements:
|
84
|
-
- - ~>
|
85
|
-
- !ruby/object:Gem::Version
|
86
|
-
version: 3.2.3
|
87
|
-
type: :runtime
|
88
|
-
prerelease: false
|
89
|
-
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
|
-
requirements:
|
92
|
-
- - ~>
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
version: 3.2.3
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: active_attr
|
97
|
-
requirement: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
|
-
requirements:
|
100
|
-
- - ! '>='
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '0'
|
103
|
-
type: :runtime
|
104
|
-
prerelease: false
|
105
|
-
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
|
-
requirements:
|
108
|
-
- - ! '>='
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: uuid
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
none: false
|
115
|
-
requirements:
|
116
|
-
- - ~>
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
version: 2.3.5
|
119
|
-
type: :runtime
|
120
|
-
prerelease: false
|
121
|
-
version_requirements: !ruby/object:Gem::Requirement
|
122
|
-
none: false
|
123
|
-
requirements:
|
124
|
-
- - ~>
|
125
|
-
- !ruby/object:Gem::Version
|
126
|
-
version: 2.3.5
|
127
|
-
- !ruby/object:Gem::Dependency
|
128
|
-
name: transaction-simple
|
129
|
-
requirement: !ruby/object:Gem::Requirement
|
130
|
-
none: false
|
131
|
-
requirements:
|
132
|
-
- - ~>
|
133
|
-
- !ruby/object:Gem::Version
|
134
|
-
version: 1.4.0
|
135
|
-
type: :runtime
|
136
|
-
prerelease: false
|
137
|
-
version_requirements: !ruby/object:Gem::Requirement
|
138
|
-
none: false
|
139
|
-
requirements:
|
140
|
-
- - ~>
|
141
|
-
- !ruby/object:Gem::Version
|
142
|
-
version: 1.4.0
|
143
47
|
- !ruby/object:Gem::Dependency
|
144
48
|
name: rdf
|
145
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -188,8 +92,7 @@ dependencies:
|
|
188
92
|
- - ~>
|
189
93
|
- !ruby/object:Gem::Version
|
190
94
|
version: 1.2.0
|
191
|
-
description: An RDF.rb extension library for interacting with a Virtuoso rdf store
|
192
|
-
also with ActiveRDF Rails connector
|
95
|
+
description: An RDF.rb extension library for interacting with a Virtuoso rdf store
|
193
96
|
email:
|
194
97
|
- benjamin.rokseth@kul.oslo.kommune.no
|
195
98
|
executables: []
|
@@ -197,25 +100,16 @@ extensions: []
|
|
197
100
|
extra_rdoc_files: []
|
198
101
|
files:
|
199
102
|
- README.md
|
200
|
-
- lib/rdf/virtuoso.rb
|
201
103
|
- lib/rdf/virtuoso/version.rb
|
202
|
-
- lib/rdf/virtuoso/
|
104
|
+
- lib/rdf/virtuoso/query.rb
|
203
105
|
- lib/rdf/virtuoso/prefixes.rb
|
204
106
|
- lib/rdf/virtuoso/repository.rb
|
205
|
-
- lib/rdf/virtuoso/
|
206
|
-
- lib/
|
207
|
-
- lib/active_rdf/version.rb
|
208
|
-
- lib/active_rdf/reflections.rb
|
209
|
-
- lib/active_rdf/association_reflection.rb
|
210
|
-
- lib/active_rdf/persistence.rb
|
211
|
-
- lib/active_rdf/errors.rb
|
212
|
-
- lib/active_rdf/model.rb
|
213
|
-
- lib/active_rdf/exceptions.rb
|
107
|
+
- lib/rdf/virtuoso/parser.rb
|
108
|
+
- lib/rdf/virtuoso.rb
|
214
109
|
- spec/repository_spec.rb
|
110
|
+
- spec/prefixes_spec.rb
|
215
111
|
- spec/query_spec.rb
|
216
112
|
- spec/spec_helper.rb
|
217
|
-
- spec/active_rdf/persistence_spec.rb
|
218
|
-
- spec/prefixes_spec.rb
|
219
113
|
homepage: https://github.com/digibib/rdf-virtuoso
|
220
114
|
licenses: []
|
221
115
|
post_install_message:
|
data/lib/active_rdf.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'active_support'
|
2
|
-
require 'active_model'
|
3
|
-
require 'active_attr'
|
4
|
-
require 'active_rdf/exceptions'
|
5
|
-
require 'active_rdf/errors'
|
6
|
-
require 'active_rdf/version'
|
7
|
-
|
8
|
-
module ActiveRDF
|
9
|
-
extend ActiveSupport::Autoload
|
10
|
-
|
11
|
-
autoload :Model
|
12
|
-
autoload :Persistence
|
13
|
-
autoload :Reflection
|
14
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
class AssociationReflection
|
2
|
-
attr_reader :macro
|
3
|
-
attr_reader :name
|
4
|
-
attr_reader :options
|
5
|
-
|
6
|
-
def initialize(macro, name, options = {})
|
7
|
-
@macro = macro
|
8
|
-
@name = name
|
9
|
-
@options = options
|
10
|
-
end
|
11
|
-
|
12
|
-
def class_name
|
13
|
-
@class_name ||= (options[:type] || derive_class_name).to_s
|
14
|
-
end
|
15
|
-
|
16
|
-
def klass
|
17
|
-
@klass ||= class_name.constantize
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def derive_class_name
|
23
|
-
name.to_s.camelize
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
data/lib/active_rdf/errors.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
module ActiveRDF
|
2
|
-
|
3
|
-
class ConnectionError < StandardError # :nodoc:
|
4
|
-
attr_reader :response
|
5
|
-
|
6
|
-
def initialize(response, message = nil)
|
7
|
-
@response = response
|
8
|
-
@message = message
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_s
|
12
|
-
message = "Failed."
|
13
|
-
message << " Response code = #{response.code}." if response.respond_to?(:code)
|
14
|
-
message << " Response message = #{response.message}." if response.respond_to?(:message)
|
15
|
-
message
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Raised when a Timeout::Error occurs.
|
20
|
-
class TimeoutError < ConnectionError
|
21
|
-
def initialize(message)
|
22
|
-
@message = message
|
23
|
-
end
|
24
|
-
def to_s; @message ;end
|
25
|
-
end
|
26
|
-
|
27
|
-
# Raised when a OpenSSL::SSL::SSLError occurs.
|
28
|
-
class SSLError < ConnectionError
|
29
|
-
def initialize(message)
|
30
|
-
@message = message
|
31
|
-
end
|
32
|
-
def to_s; @message ;end
|
33
|
-
end
|
34
|
-
|
35
|
-
# 3xx Redirection
|
36
|
-
class Redirection < ConnectionError # :nodoc:
|
37
|
-
def to_s
|
38
|
-
response['Location'] ? "#{super} => #{response['Location']}" : super
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
class MissingPrefixParam < ArgumentError # :nodoc:
|
43
|
-
end
|
44
|
-
|
45
|
-
# 4xx Client Error
|
46
|
-
class ClientError < ConnectionError # :nodoc:
|
47
|
-
end
|
48
|
-
|
49
|
-
# 400 Bad Request
|
50
|
-
class BadRequest < ClientError # :nodoc:
|
51
|
-
end
|
52
|
-
|
53
|
-
# 401 Unauthorized
|
54
|
-
class UnauthorizedAccess < ClientError # :nodoc:
|
55
|
-
end
|
56
|
-
|
57
|
-
# 403 Forbidden
|
58
|
-
class ForbiddenAccess < ClientError # :nodoc:
|
59
|
-
end
|
60
|
-
|
61
|
-
# 404 Not Found
|
62
|
-
class ResourceNotFound < ClientError # :nodoc:
|
63
|
-
end
|
64
|
-
|
65
|
-
# 409 Conflict
|
66
|
-
class ResourceConflict < ClientError # :nodoc:
|
67
|
-
end
|
68
|
-
|
69
|
-
# 410 Gone
|
70
|
-
class ResourceGone < ClientError # :nodoc:
|
71
|
-
end
|
72
|
-
|
73
|
-
# 5xx Server Error
|
74
|
-
class ServerError < ConnectionError # :nodoc:
|
75
|
-
end
|
76
|
-
|
77
|
-
# 405 Method Not Allowed
|
78
|
-
class MethodNotAllowed < ClientError # :nodoc:
|
79
|
-
def allowed_methods
|
80
|
-
@response['Allow'].split(',').map { |verb| verb.strip.downcase.to_sym }
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
data/lib/active_rdf/model.rb
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'uuid'
|
2
|
-
require 'transaction/simple'
|
3
|
-
require 'rdf'
|
4
|
-
require 'active_rdf/reflections'
|
5
|
-
|
6
|
-
module ActiveRDF
|
7
|
-
|
8
|
-
class Model
|
9
|
-
include ActiveAttr::Model
|
10
|
-
include ActiveModel::Dirty
|
11
|
-
include ActiveRDF::Persistence
|
12
|
-
|
13
|
-
# All children should have these attributes
|
14
|
-
attribute :id, type: String
|
15
|
-
attribute :subject, type: String
|
16
|
-
|
17
|
-
|
18
|
-
class << self
|
19
|
-
attr_accessor :reflections
|
20
|
-
|
21
|
-
def graph
|
22
|
-
url = RDF::URI.new("http://data.deichman.no")
|
23
|
-
if defined?(Rails)
|
24
|
-
url = url.join Rails.env unless (Rails.env.production? || Rails.env.staging?)
|
25
|
-
end
|
26
|
-
url / self.name.downcase.pluralize
|
27
|
-
end
|
28
|
-
|
29
|
-
def encode(string)
|
30
|
-
[string].pack('m0')
|
31
|
-
end
|
32
|
-
|
33
|
-
def decode(string)
|
34
|
-
string.unpack('m')[0]
|
35
|
-
end
|
36
|
-
|
37
|
-
def from_param(param)
|
38
|
-
decode param
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def inherited(child)
|
44
|
-
child.instance_variable_set :@reflections, @reflections.dup
|
45
|
-
super
|
46
|
-
end
|
47
|
-
end # Class methods
|
48
|
-
|
49
|
-
def type
|
50
|
-
self.class.type
|
51
|
-
end
|
52
|
-
|
53
|
-
# When using an object's subject, which comes in the format http://example.org/object#123 as
|
54
|
-
# a query param, we must encode it first
|
55
|
-
def to_param
|
56
|
-
self.class.encode self.subject
|
57
|
-
end
|
58
|
-
|
59
|
-
def graph
|
60
|
-
self.class.graph
|
61
|
-
end
|
62
|
-
|
63
|
-
extend Reflections
|
64
|
-
|
65
|
-
@reflections = HashWithIndifferentAccess.new
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
@@ -1,185 +0,0 @@
|
|
1
|
-
module ActiveRDF
|
2
|
-
module Persistence
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
|
7
|
-
# Override ActiveAttr::Attributes.attribute=(name, value)
|
8
|
-
def attribute=(name, value)
|
9
|
-
@attributes ||= {}
|
10
|
-
# We'll assume that nil and "" are equivalent
|
11
|
-
unless (@attributes[name].blank? && value.blank?) || (@attributes[name] == value)
|
12
|
-
send("#{name}_will_change!")
|
13
|
-
end
|
14
|
-
@attributes[name] = value
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
module ClassMethods
|
19
|
-
def connection
|
20
|
-
# TODO: make this behave like AM/AR Connection
|
21
|
-
#CLIENT
|
22
|
-
REPOSITORY
|
23
|
-
end
|
24
|
-
|
25
|
-
def create(attrs = nil)
|
26
|
-
object = new(attrs)
|
27
|
-
object.save
|
28
|
-
object
|
29
|
-
end
|
30
|
-
|
31
|
-
def create!(attrs = nil)
|
32
|
-
object = new(attrs)
|
33
|
-
object.save!
|
34
|
-
object
|
35
|
-
end
|
36
|
-
|
37
|
-
def before_create(method)
|
38
|
-
# Placeholder until implemented in ActiveRDF::Callbacks
|
39
|
-
end
|
40
|
-
|
41
|
-
def before_save(method)
|
42
|
-
# Placeholder until implemented in ActiveRDF::Callbacks
|
43
|
-
end
|
44
|
-
|
45
|
-
# @see: http://rdf.rubyforge.org/RDF/Query/Solutions.html
|
46
|
-
def order(variable)
|
47
|
-
end
|
48
|
-
|
49
|
-
def where(conditions)
|
50
|
-
end
|
51
|
-
|
52
|
-
def scope(variable, conditions)
|
53
|
-
end
|
54
|
-
|
55
|
-
def scoped
|
56
|
-
end
|
57
|
-
|
58
|
-
def count
|
59
|
-
#query = "SELECT COUNT(DISTINCT ?s) WHERE { GRAPH <#{self.graph}> { ?s a <#{self.type}> }}"
|
60
|
-
query = RDF::Virtuoso::Query.select(:s).count(:s).distinct.where([:s, RDF.type, self.type ])
|
61
|
-
result = connection.select(query)
|
62
|
-
result.first[:count].to_i
|
63
|
-
end
|
64
|
-
|
65
|
-
def find(object_or_id, conditions = {})
|
66
|
-
|
67
|
-
subject = case object_or_id
|
68
|
-
when String then decode(object_or_id)
|
69
|
-
when self then object_or_id.subject
|
70
|
-
else raise ActiveModel::MissingAttributeError.new(object_or_id.inspect)
|
71
|
-
end
|
72
|
-
|
73
|
-
find_by_subject(subject, conditions = {})
|
74
|
-
end
|
75
|
-
|
76
|
-
def first
|
77
|
-
all(limit: 1).first
|
78
|
-
end
|
79
|
-
|
80
|
-
# What does this do?
|
81
|
-
def execute(sql)
|
82
|
-
results = []
|
83
|
-
solutions = connection.select(sql)
|
84
|
-
solutions.each do |solution|
|
85
|
-
record = new
|
86
|
-
solution.each_binding do |name, value|
|
87
|
-
record[name] = value.to_s
|
88
|
-
end
|
89
|
-
if record.subject.present?
|
90
|
-
record.id = id_for(record.subject)
|
91
|
-
record.changed_attributes.clear
|
92
|
-
end
|
93
|
-
results << record
|
94
|
-
end
|
95
|
-
results
|
96
|
-
end
|
97
|
-
|
98
|
-
# TODO: set baseurl via config
|
99
|
-
def subject_for(id)
|
100
|
-
RDF::URI('http://data.deichman.no') / self.name.downcase / "/id_" / id
|
101
|
-
end
|
102
|
-
|
103
|
-
def id_for(subject)
|
104
|
-
subject.to_s.split("/").last.gsub('id_', '')
|
105
|
-
end
|
106
|
-
|
107
|
-
def destroy_all
|
108
|
-
#query = "DELETE FROM <#{self.graph}> { ?s ?p ?o } WHERE { GRAPH <#{self.graph}> { ?s a <#{self.type}> . ?s ?p ?o } }"
|
109
|
-
query = RDF::Virtuoso::Query.delete([:s, :p, :o]).graph(self.graph).where([:s, RDF.type, self.type],[:s, :p, :o])
|
110
|
-
connection.delete(query)
|
111
|
-
end
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
# Instance methods
|
116
|
-
|
117
|
-
def connection
|
118
|
-
self.class.connection
|
119
|
-
end
|
120
|
-
|
121
|
-
def save
|
122
|
-
return false unless self.valid?
|
123
|
-
create_or_update
|
124
|
-
end
|
125
|
-
|
126
|
-
def save!
|
127
|
-
unless self.valid?
|
128
|
-
raise ActiveRecord::RecordInvalid.new(self)
|
129
|
-
end
|
130
|
-
create_or_update
|
131
|
-
end
|
132
|
-
|
133
|
-
def destroy
|
134
|
-
subject = subject_for(self.id)
|
135
|
-
#p subject
|
136
|
-
query = RDF::Virtuoso::Query.delete([subject, :p, :o]).graph(graph).where([subject, :p, :o])
|
137
|
-
result = connection.delete(query)
|
138
|
-
end
|
139
|
-
|
140
|
-
|
141
|
-
def update_attributes(attributes)
|
142
|
-
self.extend(::Transaction::Simple)
|
143
|
-
status = false
|
144
|
-
begin
|
145
|
-
self.start_transaction
|
146
|
-
self.assign_attributes(attributes)
|
147
|
-
status = save
|
148
|
-
self.commit_transaction
|
149
|
-
rescue Exception
|
150
|
-
self.rewind_transaction
|
151
|
-
self.abort_transaction
|
152
|
-
end
|
153
|
-
status
|
154
|
-
end
|
155
|
-
|
156
|
-
def reload
|
157
|
-
self.attributes = self.class.find(self).attributes
|
158
|
-
self
|
159
|
-
end
|
160
|
-
|
161
|
-
def new_record?
|
162
|
-
self.id.nil?
|
163
|
-
end
|
164
|
-
|
165
|
-
def persisted?
|
166
|
-
!new_record?
|
167
|
-
end
|
168
|
-
|
169
|
-
def subject_for(id)
|
170
|
-
self.class.subject_for(id)
|
171
|
-
end
|
172
|
-
|
173
|
-
private
|
174
|
-
|
175
|
-
def create_or_update
|
176
|
-
result = new_record? ? create : update
|
177
|
-
result != false
|
178
|
-
end
|
179
|
-
|
180
|
-
def guid
|
181
|
-
UUID.generate(:compact)
|
182
|
-
end
|
183
|
-
|
184
|
-
end
|
185
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'active_rdf/association_reflection'
|
2
|
-
|
3
|
-
module ActiveRDF
|
4
|
-
module Reflections
|
5
|
-
# Returns a hash containing all AssociationReflection objects for the current class
|
6
|
-
# Example:
|
7
|
-
#
|
8
|
-
# Invoice.reflections
|
9
|
-
# Account.reflections
|
10
|
-
#
|
11
|
-
def reflections
|
12
|
-
read_inheritable_attribute(:reflections) || write_inheritable_attribute(:reflections, {})
|
13
|
-
end
|
14
|
-
|
15
|
-
def reflect_on_association(association)
|
16
|
-
reflections[association].is_a?(AssociationReflection) ? reflections[association] : nil
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
data/lib/active_rdf/version.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class Resource < ActiveRDF::Model
|
4
|
-
end
|
5
|
-
|
6
|
-
describe ActiveRDF::Persistence do
|
7
|
-
|
8
|
-
let(:resource) { Resource.new }
|
9
|
-
|
10
|
-
before do
|
11
|
-
resource.stub(:id).and_return("some_unique_id")
|
12
|
-
client = double("client")
|
13
|
-
resource.stub(:connection).and_return client
|
14
|
-
end
|
15
|
-
|
16
|
-
describe :destroy do
|
17
|
-
|
18
|
-
it "formats the destroy query correctly" do
|
19
|
-
subject = resource.subject_for(resource.id)
|
20
|
-
# query =
|
21
|
-
#<<-q
|
22
|
-
#DELETE FROM <#{resource.graph}> { <#{subject}> ?p ?o }
|
23
|
-
#WHERE { <#{subject}> ?p ?o }
|
24
|
-
#q
|
25
|
-
query = RDF::Virtuoso::Query.delete([subject, :p, :o]).graph(resource.graph).where([subject, :p, :o])
|
26
|
-
resource.connection.should_receive(:delete).with(query)
|
27
|
-
resource.destroy
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|