tripod 0.0.8 → 0.0.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/lib/tripod.rb +1 -0
- data/lib/tripod/persistence.rb +95 -12
- data/lib/tripod/version.rb +1 -1
- data/spec/tripod/persistence_spec.rb +70 -0
- data/tripod.gemspec +1 -0
- metadata +27 -16
data/lib/tripod.rb
CHANGED
data/lib/tripod/persistence.rb
CHANGED
@@ -3,6 +3,61 @@
|
|
3
3
|
# This module defines behaviour for persisting to the database.
|
4
4
|
module Tripod::Persistence
|
5
5
|
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
class Tripod::Persistence::Transaction
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
self.transaction_id = Guid.new.to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_accessor :transaction_id
|
14
|
+
attr_accessor :query
|
15
|
+
|
16
|
+
def commit
|
17
|
+
Tripod::SparqlClient::Update::update(self.query)
|
18
|
+
clear_transaction
|
19
|
+
end
|
20
|
+
|
21
|
+
def abort
|
22
|
+
clear_transaction
|
23
|
+
end
|
24
|
+
|
25
|
+
def clear_transaction
|
26
|
+
self.transaction_id = nil
|
27
|
+
self.query = ""
|
28
|
+
Tripod::Persistence.transactions.delete(self.transaction_id)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.valid_transaction(transaction)
|
32
|
+
transaction && transaction.class == Tripod::Persistence::Transaction
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.get_transcation(trans)
|
36
|
+
transaction = nil
|
37
|
+
|
38
|
+
if Tripod::Persistence::Transaction.valid_transaction(trans)
|
39
|
+
|
40
|
+
transaction_id = trans.transaction_id
|
41
|
+
|
42
|
+
Tripod::Persistence.transactions ||= {}
|
43
|
+
|
44
|
+
if Tripod::Persistence.transactions[transaction_id]
|
45
|
+
# existing transaction
|
46
|
+
transaction = Tripod::Persistence.transactions[transaction_id]
|
47
|
+
else
|
48
|
+
# new transaction
|
49
|
+
transaction = Tripod::Persistence.transactions[transaction_id] = trans
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
transaction
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
# hash of transactions against their ids.
|
59
|
+
mattr_accessor :transactions
|
60
|
+
|
6
61
|
# Save the resource.
|
7
62
|
# Note: regardless of whether it's a new_record or not, we always make the
|
8
63
|
# db match the contents of this resource's statements.
|
@@ -11,19 +66,30 @@ module Tripod::Persistence
|
|
11
66
|
# resource.save
|
12
67
|
#
|
13
68
|
# @return [ true, false ] True is success, false if not.
|
14
|
-
def save()
|
69
|
+
def save(opts={})
|
70
|
+
|
71
|
+
transaction = Tripod::Persistence::Transaction.get_transcation(opts[:transaction])
|
72
|
+
|
15
73
|
if self.valid?
|
74
|
+
|
16
75
|
query = "
|
17
76
|
DELETE {GRAPH ?g {<#{@uri.to_s}> ?p ?o}} WHERE {GRAPH ?g {<#{@uri.to_s}> ?p ?o}};
|
18
77
|
INSERT DATA {
|
19
78
|
GRAPH <#{@graph_uri}> {
|
20
79
|
#{ @repository.dump(:ntriples) }
|
21
80
|
}
|
22
|
-
}
|
81
|
+
};
|
23
82
|
"
|
24
|
-
|
25
|
-
|
26
|
-
|
83
|
+
|
84
|
+
if transaction
|
85
|
+
transaction.query ||= ""
|
86
|
+
transaction.query += query
|
87
|
+
else
|
88
|
+
Tripod::SparqlClient::Update::update(query)
|
89
|
+
end
|
90
|
+
|
91
|
+
@new_record = false # if running in a trans, just assume it worked. If the query is dodgy, it will throw an exception later.
|
92
|
+
true
|
27
93
|
else
|
28
94
|
false
|
29
95
|
end
|
@@ -39,26 +105,43 @@ module Tripod::Persistence
|
|
39
105
|
# @raise [Tripod::Errors::Validations] if invalid
|
40
106
|
#
|
41
107
|
# @return [ true ] True is success.
|
42
|
-
def save!()
|
108
|
+
def save!(opts={})
|
43
109
|
# try to save
|
44
|
-
unless self.save()
|
110
|
+
unless self.save(opts)
|
111
|
+
|
45
112
|
# if we get in here, save failed.
|
46
|
-
|
113
|
+
|
114
|
+
# abort the transaction
|
115
|
+
transaction = Tripod::Persistence::Transaction.get_transcation(opts[:transaction])
|
116
|
+
transaction.abort() if transaction
|
117
|
+
|
118
|
+
self.class.fail_validate!(self) # throw an exception
|
119
|
+
|
47
120
|
# TODO: similar stuff for callbacks?
|
48
121
|
end
|
49
122
|
return true
|
50
123
|
end
|
51
124
|
|
52
|
-
def destroy()
|
125
|
+
def destroy(opts={})
|
126
|
+
|
127
|
+
transaction = Tripod::Persistence::Transaction.get_transcation(opts[:transaction])
|
128
|
+
|
53
129
|
query = "
|
54
130
|
# delete from default graph:
|
55
131
|
DELETE {<#{@uri.to_s}> ?p ?o} WHERE {<#{@uri.to_s}> ?p ?o};
|
56
132
|
# delete from named graphs:
|
57
133
|
DELETE {GRAPH ?g {<#{@uri.to_s}> ?p ?o}} WHERE {GRAPH ?g {<#{@uri.to_s}> ?p ?o}};
|
58
134
|
"
|
59
|
-
|
60
|
-
|
61
|
-
|
135
|
+
|
136
|
+
if transaction
|
137
|
+
transaction.query ||= ""
|
138
|
+
transaction.query += query
|
139
|
+
else
|
140
|
+
Tripod::SparqlClient::Update::update(query)
|
141
|
+
end
|
142
|
+
|
143
|
+
@destroyed = true
|
144
|
+
true
|
62
145
|
end
|
63
146
|
|
64
147
|
module ClassMethods #:nodoc:
|
data/lib/tripod/version.rb
CHANGED
@@ -29,6 +29,7 @@ describe Tripod::Persistence do
|
|
29
29
|
p
|
30
30
|
end
|
31
31
|
|
32
|
+
|
32
33
|
describe "#save" do
|
33
34
|
|
34
35
|
context 'graph not set' do
|
@@ -100,4 +101,73 @@ describe Tripod::Persistence do
|
|
100
101
|
lambda {unsaved_person.save!}.should raise_error(Tripod::Errors::Validations)
|
101
102
|
end
|
102
103
|
end
|
104
|
+
|
105
|
+
describe "transactions" do
|
106
|
+
|
107
|
+
it "only save on commit" do
|
108
|
+
|
109
|
+
transaction = Tripod::Persistence::Transaction.new
|
110
|
+
|
111
|
+
unsaved_person.save(transaction: transaction)
|
112
|
+
saved_person['http://pred2'] = 'blah'
|
113
|
+
saved_person.save(transaction: transaction)
|
114
|
+
|
115
|
+
# nothing should have changed yet.
|
116
|
+
lambda {Person.find(unsaved_person.uri)}.should raise_error(Tripod::Errors::ResourceNotFound)
|
117
|
+
Person.find(saved_person.uri)['http://pred2'].first.to_s.should == RDF::URI.new('http://obj2').to_s
|
118
|
+
|
119
|
+
transaction.commit
|
120
|
+
|
121
|
+
# things should have changed now.
|
122
|
+
lambda {Person.find(unsaved_person.uri)}.should_not raise_error()
|
123
|
+
Person.find(saved_person.uri)['http://pred2'].first.should == 'blah'
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
it "silently ignore invalid saves" do
|
128
|
+
transaction = Tripod::Persistence::Transaction.new
|
129
|
+
|
130
|
+
unsaved_person.uri = nil
|
131
|
+
unsaved_person.save(transaction: transaction).should be_false
|
132
|
+
|
133
|
+
saved_person['http://pred2'] = 'blah'
|
134
|
+
saved_person.save(transaction: transaction).should be_true
|
135
|
+
|
136
|
+
transaction.commit
|
137
|
+
|
138
|
+
# transaction should be gone
|
139
|
+
Tripod::Persistence.transactions[transaction.transaction_id].should be_nil
|
140
|
+
|
141
|
+
# unsaved person still not there
|
142
|
+
lambda {Person.find(unsaved_person.uri)}.should raise_error(Tripod::Errors::ResourceNotFound)
|
143
|
+
|
144
|
+
# saved person SHOULD be updated
|
145
|
+
Person.find(saved_person.uri)['http://pred2'].first.should == 'blah'
|
146
|
+
end
|
147
|
+
|
148
|
+
it "can be aborted" do
|
149
|
+
transaction = Tripod::Persistence::Transaction.new
|
150
|
+
unsaved_person.save(transaction: transaction)
|
151
|
+
transaction.abort()
|
152
|
+
|
153
|
+
# unsaved person still not there
|
154
|
+
lambda {Person.find(unsaved_person.uri)}.should raise_error(Tripod::Errors::ResourceNotFound)
|
155
|
+
|
156
|
+
#transaction gone.
|
157
|
+
transaction.query.should be_blank
|
158
|
+
Tripod::Persistence.transactions[transaction.transaction_id].should be_nil
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should be removed once committed" do
|
162
|
+
transaction = Tripod::Persistence::Transaction.new
|
163
|
+
unsaved_person.save(transaction: transaction)
|
164
|
+
transaction.commit()
|
165
|
+
|
166
|
+
#transaction gone.
|
167
|
+
transaction.query.should be_blank
|
168
|
+
Tripod::Persistence.transactions[transaction.transaction_id].should be_nil
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
103
173
|
end
|
data/tripod.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tripod
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
16
|
-
requirement: &
|
16
|
+
requirement: &70271542059420 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70271542059420
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: activemodel
|
27
|
-
requirement: &
|
27
|
+
requirement: &70271542058760 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '3.1'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70271542058760
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: equivalent-xml
|
38
|
-
requirement: &
|
38
|
+
requirement: &70271542058220 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70271542058220
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rdf
|
49
|
-
requirement: &
|
49
|
+
requirement: &70271542057540 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0.3'
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70271542057540
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rdf-rdfxml
|
60
|
-
requirement: &
|
60
|
+
requirement: &70271542057020 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70271542057020
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rdf-n3
|
71
|
-
requirement: &
|
71
|
+
requirement: &70271542056460 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70271542056460
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: rdf-json
|
82
|
-
requirement: &
|
82
|
+
requirement: &70271542055920 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,18 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70271542055920
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: guid
|
93
|
+
requirement: &70271542055420 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
type: :runtime
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70271542055420
|
91
102
|
description: RDF ruby ORM
|
92
103
|
email:
|
93
104
|
- ric@swirrl.com
|