Permalink
Browse files

added transactions interface

  • Loading branch information...
1 parent f5d67ab commit d621397de6eb5c655c394ee7013576f74688e116 @phifty committed Mar 28, 2010
@@ -5,16 +5,14 @@ module Proxy
class Geo
- attr_reader :server
- attr_reader :repository
+ attr_reader :repository_or_session
- def initialize(repository)
- @repository = repository
- @server = @repository.server
+ def initialize(repository_or_session)
+ @repository_or_session = repository_or_session
end
def path
- "#{@repository.path}/geo"
+ "#{@repository_or_session.path}/geo"
end
def cartesian_type(strip_width, x_min, y_min, x_max, y_max)
@@ -25,7 +23,7 @@ def cartesian_type(strip_width, x_min, y_min, x_max, y_max)
:xmax => x_max.to_s,
:ymax => y_max.to_s
}
- type = @server.request :post, self.path + "/types/cartesian", :parameters => parameters, :expected_status_code => 200
+ type = @repository_or_session.request :post, self.path + "/types/cartesian", :parameters => parameters, :expected_status_code => 200
type.sub! /^.*</, "<"
type.sub! />.*$/, ">"
type
@@ -40,7 +38,7 @@ def spherical_type(strip_width, unit, latitude_min, longitude_min, latitude_max,
:latmax => latitude_max.to_s,
:longmax => longitude_max.to_s
}
- type = @server.request :post, self.path + "/types/spherical", :parameters => parameters, :expected_status_code => 200
+ type = @repository_or_session.request :post, self.path + "/types/spherical", :parameters => parameters, :expected_status_code => 200
type.sub! /^.*</, "<"
type.sub! />.*$/, ">"
type
@@ -52,7 +50,7 @@ def create_polygon(name, type, points)
:resource => "\"#{name}\"",
:point => points.map{ |point| "\"%+g%+g\"^^%s" % [ point[0], point[1], type ] }
}
- @server.request :put, self.path + "/polygon", :parameters => parameters, :expected_status_code => 204
+ @repository_or_session.request :put, self.path + "/polygon", :parameters => parameters, :expected_status_code => 204
true
end
@@ -65,7 +63,7 @@ def inside_box(type, predicate, x_min, y_min, x_max, y_max)
:xmax => x_max.to_s,
:ymax => y_max.to_s
}
- @server.request :get, self.path + "/box", :parameters => parameters, :expected_status_code => 200
+ @repository_or_session.request :get, self.path + "/box", :parameters => parameters, :expected_status_code => 200
end
def inside_circle(type, predicate, x, y, radius)
@@ -76,7 +74,7 @@ def inside_circle(type, predicate, x, y, radius)
:y => y.to_s,
:radius => radius.to_s
}
- @server.request :get, self.path + "/circle", :parameters => parameters, :expected_status_code => 200
+ @repository_or_session.request :get, self.path + "/circle", :parameters => parameters, :expected_status_code => 200
end
def inside_haversine(type, predicate, latitude, longitude, radius, unit = :km)
@@ -88,7 +86,7 @@ def inside_haversine(type, predicate, latitude, longitude, radius, unit = :km)
:radius => radius.to_s,
:unit => unit.to_s
}
- @server.request :get, self.path + "/haversine", :parameters => parameters, :expected_status_code => 200
+ @repository_or_session.request :get, self.path + "/haversine", :parameters => parameters, :expected_status_code => 200
end
def inside_polygon(type, predicate, name)
@@ -97,7 +95,7 @@ def inside_polygon(type, predicate, name)
:predicate => predicate,
:polygon => "\"#{name}\""
}
- @server.request :get, self.path + "/polygon", :parameters => parameters, :expected_status_code => 200
+ @repository_or_session.request :get, self.path + "/polygon", :parameters => parameters, :expected_status_code => 200
end
private
@@ -8,17 +8,16 @@ class Query
LANGUAGES = [ :sparql, :prolog ].freeze unless defined?(LANGUAGES)
attr_reader :server
- attr_reader :repository
+ attr_reader :repository_or_session
attr_reader :language
- def initialize(repository)
- @repository = repository
- @server = @repository.server
+ def initialize(repository_or_session)
+ @repository_or_session = repository_or_session
@language = :sparql
end
def path
- @repository.path
+ @repository_or_session.path
end
def language=(value)
@@ -28,7 +27,7 @@ def language=(value)
def perform(query)
parameters = { :query => query, :queryLn => @language.to_s }
- @server.request :get, self.path, :parameters => parameters, :expected_status_code => 200
+ @repository_or_session.request :get, self.path, :parameters => parameters, :expected_status_code => 200
end
end
@@ -5,22 +5,20 @@ module Proxy
class Statements
- attr_reader :server
- attr_reader :repository
+ attr_reader :repository_or_session
- def initialize(repository)
- @repository = repository
- @server = @repository.server
+ def initialize(repository_or_session)
+ @repository_or_session = repository_or_session
end
def path
- "#{@repository.path}/statements"
+ "#{@repository_or_session.path}/statements"
end
def create(subject, predicate, object, context = nil)
statement = [ subject, predicate, object ]
statement << context if context
- @server.request :post, self.path, :body => [ statement ], :expected_status_code => 204
+ @repository_or_session.request :post, self.path, :body => [ statement ], :expected_status_code => 204
true
end
@@ -40,11 +38,11 @@ def find(options = { })
parameters = nil if parameters.empty?
- @server.request :get, self.path, :parameters => parameters, :expected_status_code => 200
+ @repository_or_session.request :get, self.path, :parameters => parameters, :expected_status_code => 200
end
def delete
- @server.request :delete, self.path, :expected_status_code => 200
+ @repository_or_session.request :delete, self.path, :expected_status_code => 200
end
end
@@ -1,4 +1,5 @@
require File.join(File.dirname(__FILE__), "server")
+require File.join(File.dirname(__FILE__), "session")
require File.join(File.dirname(__FILE__), "proxy", "statements")
require File.join(File.dirname(__FILE__), "proxy", "query")
require File.join(File.dirname(__FILE__), "proxy", "geo")
@@ -10,6 +11,7 @@ class Repository
attr_reader :server
attr_reader :catalog
attr_accessor :name
+
attr_reader :statements
attr_reader :query
attr_reader :geo
@@ -31,6 +33,10 @@ def path
"#{@catalog.path}/repositories/#{@name}"
end
+ def request(http_method, path, options = { })
+ @server.request http_method, path, options
+ end
+
def exists?
@catalog.repositories.include? self
end
@@ -64,6 +70,17 @@ def size
response.to_i
end
+ def transaction(&block)
+ session = Session.create self
+ begin
+ session.instance_eval &block
+ rescue Object => error
+ session.rollback
+ raise error
+ end
+ session.commit
+ end
+
end
-end
+end
@@ -0,0 +1,61 @@
+require File.join(File.dirname(__FILE__), "transport")
+require File.join(File.dirname(__FILE__), "proxy", "statements")
+require File.join(File.dirname(__FILE__), "proxy", "query")
+require File.join(File.dirname(__FILE__), "proxy", "geo")
+
+module AllegroGraph
+
+ class Session
+
+ attr_reader :url
+ attr_reader :username
+ attr_reader :password
+
+ attr_reader :statements
+ attr_reader :query
+ attr_reader :geo
+
+ def initialize(options = { })
+ @url = options[:url]
+ @username = options[:username]
+ @password = options[:password]
+
+ @statements = Proxy::Statements.new self
+ @query = Proxy::Query.new self
+ @geo = Proxy::Geo.new self
+ end
+
+ def path
+ ""
+ end
+
+ def request(http_method, path, options = { })
+ ExtendedTransport.request http_method, self.url + path, credentials.merge(options)
+ end
+
+ def commit
+ self.request :post, "/commit", :expected_status_code => 204
+ true
+ end
+
+ def rollback
+ self.request :post, "/rollback", :expected_status_code => 204
+ true
+ end
+
+ def self.create(repository)
+ url = repository.request :post, repository.path + "/session", :expected_status_code => 200
+ url.sub! /^"/, ""
+ url.sub! /"$/, ""
+ new :url => url, :username => repository.server.username, :password => repository.server.password
+ end
+
+ private
+
+ def credentials
+ { :auth_type => :basic, :username => @username, :password => @password }
+ end
+
+ end
+
+end
View
@@ -1,4 +1,16 @@
-
+ :http_method: "post"
+ :url: "http://session:5555/commit"
+ :response:
+ :code: "204"
+ :body: ""
+-
+ :http_method: "post"
+ :url: "http://session:5555/rollback"
+ :response:
+ :code: "204"
+ :body: ""
+-
:http_method: "get"
:url: "http://localhost:10035/version"
:response:
@@ -244,4 +244,37 @@
end
+ describe "transactions" do
+
+ before :each do
+ @repository.statements.delete
+ end
+
+ it "should commit all changes at once" do
+ @repository.transaction do
+ statements.create "\"test_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"test_object\""
+ statements.create "\"another_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"another_object\""
+ end
+
+ result = @repository.statements.find
+ result.should include([ "\"test_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"test_object\"" ])
+ result.should include([ "\"another_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"another_object\"" ])
+ end
+
+ it "should rollback on error" do
+ lambda do
+ @repository.transaction do
+ statements.create "\"test_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"test_object\""
+ statements.create "\"another_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"another_object\""
+ invalid
+ end
+ end.should raise_error(NameError)
+
+ result = @repository.statements.find
+ result.should_not include([ "\"test_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"test_object\"" ])
+ result.should_not include([ "\"another_subject\"", "<http://xmlns.com/foaf/0.1/knows>", "\"another_object\"" ])
+ end
+
+ end
+
end
@@ -31,6 +31,19 @@
end
+ describe "request" do
+
+ before :each do
+ @server.stub!(:request)
+ end
+
+ it "should call the server's request method" do
+ @server.should_receive(:request).with(:get, "/", { })
+ @repository.request :get, "/"
+ end
+
+ end
+
describe "exists?" do
context "for a repository that already exists" do
@@ -171,4 +184,41 @@
end
+ describe "transaction" do
+
+ before :each do
+ @session = AllegroGraph::Session.new :url => "http://session:5555", :username => "test", :password => "test"
+ AllegroGraph::Session.stub!(:create).and_return(@session)
+
+ @session.statements.stub!(:create)
+ end
+
+ it "should use the session proxies" do
+ @session.statements.should_receive(:create)
+ @repository.transaction do
+ statements.create
+ end
+ end
+
+ it "should commit the session after block execution" do
+ @session.statements.should_receive(:create).ordered
+ @session.should_receive(:commit).ordered
+ @repository.transaction do
+ statements.create
+ end
+ end
+
+ it "should rollback the session on error" do
+ @session.statements.should_receive(:create).ordered
+ @session.should_receive(:rollback).ordered
+ lambda do
+ @repository.transaction do
+ statements.create
+ invalid
+ end
+ end.should raise_error(NameError)
+ end
+
+ end
+
end
Oops, something went wrong.

0 comments on commit d621397

Please sign in to comment.