-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f72805a
commit df64393
Showing
9 changed files
with
259 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module Gearbox | ||
|
||
# Understands how to construct CRUD queries from domain logic. | ||
# I.e., the attributes, attribute options, associations and context taught | ||
# in the domain logic are a necessary and complete description of the triples | ||
# as they should be handled in the Repository. | ||
module DomainQueryBuilder | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
module Gearbox | ||
class Repository < ::SPARQL::Client::Repository | ||
|
||
MAX_TRIES = 10 | ||
|
||
attr_reader :data_uri, :update_uri, :status_uri, :size_uri | ||
|
||
def initialize(endpoint="http://localhost:8000", options = {}) | ||
super | ||
assert_uris! | ||
end | ||
|
||
def each(&block) | ||
raise NotImplemented, "each is not yet implemented in Gearbox::Adapter" | ||
end | ||
|
||
# def insert_statement | ||
# raise NotImplemented, "insert_statement is not yet implemented in Gearbox::Adapter" | ||
# end | ||
|
||
# def delete_statement | ||
# raise NotImplemented, "delete_statement is not yet implemented in Gearbox::Adapter" | ||
# end | ||
|
||
# def load(filename, options = {}) | ||
# return super(filename, options) if /^https?:\/\//.match(filename) | ||
# | ||
# uri = nil | ||
# | ||
# if options[:context] | ||
# uri = @dataURI + options[:context] | ||
# else | ||
# uri = @dataURI + 'file://' + File.expand_path(filename) | ||
# end | ||
# | ||
# uri = URI.parse(uri) | ||
# content = open(filename).read | ||
# begin | ||
# req = Net::HTTP::Put.new(uri.path) | ||
# Net::HTTP.start(uri.host, uri.port) do |http| | ||
# http.request(req, content) | ||
# end | ||
# rescue Errno::ECONNREFUSED, Errno::ECONNRESET, TimeoutError | ||
# retry | ||
# end | ||
# end | ||
|
||
# alias_method :load!, :load | ||
|
||
attr_writer :load_handler | ||
def load_handler | ||
@load_handler ||= lambda do |*args| | ||
filename = args.shift | ||
options = args.shift | ||
options ||= {} | ||
uri = options[:context] ? File.join(data_uri, options[:context]) : File.join(data_uri, "file://#{File.expand_path(filename)}") | ||
content = open(filename).read | ||
begin | ||
request = Net::HTTP::Put.new(uri.path) | ||
Net::HTTP.start(uri.host, uri.port) do |http| | ||
http.request(request, content) | ||
end | ||
rescue Errno::ECONNRESET, Errno::ECONNREFUSED, TimeoutError | ||
retries ||= 0 | ||
retries += 1 | ||
retries <= MAX_TRIES ? retry : raise | ||
end | ||
end | ||
end | ||
|
||
def load(*args) | ||
load_handler.call(*args) | ||
end | ||
alias :load! :load | ||
|
||
private | ||
def assert_uris! | ||
uri = self.client.url.to_s | ||
@data_uri = File.join(uri, 'data', '/') | ||
@update_uri = File.join(uri, 'update', '/') | ||
@status_uri = File.join(uri, 'status', '/') | ||
@size_uri = File.join(uri, 'size', '/') | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
require_relative '../../spec_helper' | ||
|
||
include Gearbox | ||
|
||
describe DomainQueryBuilder do | ||
|
||
before do | ||
@class = Class.new do | ||
include DomainQueryBuilder | ||
end | ||
|
||
@omni_model = Class.new do | ||
include Resource | ||
|
||
attribute :name, :predicate => RDF::FOAF.name | ||
|
||
end | ||
end | ||
|
||
# let(:base_uri) { "http://example.com" } | ||
let(:omni) { @omni_model.new } | ||
subject { @class.new } | ||
|
||
it "just works" do | ||
omni | ||
end | ||
|
||
end | ||
|
||
=begin | ||
This is the good stuff. At this point, I start reading and writing data from the repository. | ||
I have been relying on 4Store locally to offer an endpoint. The concept is that this is standard- | ||
enough to be a good pattern for other SPARQL-endpoint-aware repositories. This is a departure from | ||
a lot of the RDF.rb libraries, where they are storing triples in various data stores (mongo, postgres, | ||
sqlite, redis, cassandra, couchdb, and probably others) and using query patterns to extract these | ||
triples. Here, we are allowing the SPARQL end points to understand their own architecture and deliverying | ||
our data as we need it. This is partly due to having a near-standardized SPARQL Update 1.1 which defines | ||
how the basic CRUD can be accomplished in these endpoints. That, and I need the SPIN to maintain the graph, | ||
rather than just assume the model got it right the first time. That, and SPARQL is more expressive than the | ||
query patterns as currently constituted in the RDF.rb world. That, and I want a knowledge base that is | ||
implementation agnostic once the data is stored in it. I should be able to write an application in any | ||
language I'd like and only have to rely on SPARQL to get the data in and out of the repository. | ||
OK, that needed to be said. There is quite a bit of big-picture assumptions that I've been gleaning from | ||
the source codes. | ||
Meanwhile, we have a task before us today: start getting data in and out of a repository. Tasks: | ||
* Read the query pattern codes, to make sure I'm not full of shit | ||
* Figure out how to mock this environment, I don't want tests to rely on a repository running. | ||
* Figure out the raw SPARQL for a single-model query | ||
* SPARQL for all instances of a model | ||
* SPARQL for a filtered list of instances | ||
* " + ordered | ||
* SPARQL to insert a model | ||
* SPARQL to insert a set of models | ||
* SPARQL to update a model | ||
* SPARQL to update a set of models | ||
* SPARQL to delete a model | ||
* SPARQL to delete a set of models | ||
At this point, it would probably be good to build a knowledge base regarding everything related to | ||
database design, transactions, principles of data integrity, and similar concepts. There will be more | ||
features once I understand some of these design principles better. Plus, building knowledge bases will | ||
tease out some of these same concerns empirically. | ||
RDF::Query | ||
========== | ||
* limited to select, ask, construct and describe | ||
* I didn't see support for union, and there may be other gaps | ||
* used to create SPARQL with a syntax like query.select.where(:variable => value).order([:v1, :v2]) | ||
* would have to be extended to be complete, even for today's work | ||
* probably an unnecessary nicety in the short-run, maybe generally | ||
=end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
require_relative '../spec_helper' | ||
|
||
include Gearbox | ||
|
||
describe Repository do | ||
|
||
subject { Repository.new } | ||
|
||
it "subclasses a SPARQL::Client::Repository" do | ||
Gearbox::Repository.ancestors.must_include ::SPARQL::Client::Repository | ||
end | ||
|
||
it "defaults the endpoint to http://localhost:8000" do | ||
subject.client.url.to_s.must_equal 'http://localhost:8000' | ||
end | ||
|
||
it "creates the data_uri as uri/data/" do | ||
uri = subject.client.url.to_s | ||
subject.data_uri.must_equal "#{uri}/data/" | ||
end | ||
|
||
it "creates the update_uri as uri/update/" do | ||
uri = subject.client.url.to_s | ||
subject.update_uri.must_equal "#{uri}/update/" | ||
end | ||
|
||
it "creates the status_uri as uri/status/" do | ||
uri = subject.client.url.to_s | ||
subject.status_uri.must_equal "#{uri}/status/" | ||
end | ||
|
||
it "creates the size_uri as uri/size/" do | ||
uri = subject.client.url.to_s | ||
subject.size_uri.must_equal "#{uri}/size/" | ||
end | ||
|
||
it "implements each" do | ||
subject.respond_to?(:each).must_equal true | ||
end | ||
|
||
it "implements insert_statement" do | ||
subject.respond_to?(:insert_statement).must_equal true | ||
end | ||
|
||
it "implements delete_statement" do | ||
subject.respond_to?(:delete_statement).must_equal true | ||
end | ||
|
||
it "uses a load_handler to abstract the load (testing and async would need a different load)" do | ||
subject.load_handler = lambda{:loaded} | ||
subject.load!.must_equal :loaded | ||
end | ||
|
||
# load, load_data, update, update_data, delete, insert... (possibly BGP can assemble these) | ||
# select, ask, describe, construct (possibly SPARQL client can do all of this) | ||
# has_statement?, dump_statement, has_triple? has_quad? | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters