Skip to content

Instantly share code, notes, and snippets.

@emk
Created February 13, 2011 21:55
Show Gist options
  • Save emk/825185 to your computer and use it in GitHub Desktop.
Save emk/825185 to your computer and use it in GitHub Desktop.
Designing an RDF.rb query adapter for AllegroGraph

Many thanks to @bendiken and @bhuga for helping me get started with RDF.rb! Thanks to their tutorials and test suites, I was able to build a pretty good adapter in about 10 hours. The adapter already implements query_pattern, insert_statements and delete_statements.

My next challenge will be to support AllegroGraph queries. AllegroGraph has two server-side query languages: SPARQL, and a weird-but-powerful Prolog dialect using Lisp syntax. The Prolog dialect allows me to run graph algorithms and other funky queries on the server:

(select (?person ?name ?email)
  ;; Find everybody within one or two degrees of jsmith.
  (ego-group-member !people:jsmith 2 !foaf:knows ?person)
  (q ?person !foaf:name ?name)
  (q ?person !foaf:mbox ?email))

If I wanted to expose these kinds of queries to RDF.rb users, what approach would fit best into the RDF.rb ecosystem? Ideally, I'd like to do something that will work well with other RDF inference languages in the future.

1. Subclass RDF::Query

I could subclass RDF::Query and add support for custom query rules. This might look a bit like the following:

query = RDF::AllegroGraph::Query.new do
  ego_group_member People.jsmith, 2, FOAF.knows, :person
  pattern [:person, FOAF.name, :name]
  pattern [:person, FOAF.mbox, :email]
end
repository.query(query)

2. Reuse the SPARQL::Client interface

Alternatively, I could extend the existing SPARQL::Client interface, and build a new back end:

repository.select([:person, FOAF.name, :name],
                  [:person, FOAF.mbox, :email]).
  ego_group_member(People.jsmith, 2, FOAF.knows, :person)

There's a couple of ways to add ego_group_member to the syntax here. For example, here's another option:

repository.select(RDF::AllegroGraph.ego_group_member(People.jsmith, 2,
                                                     FOAF.knows, :person),
                  [:person, FOAF.name, :name],
                  [:person, FOAF.mbox, :email]).
  ego_group_member(People.jsmith, 2, FOAF.knows, :person)

Feel free to invent your own variations.

3. Build a new DSL from scratch

If none of the above seems appropriate, I could also build a new DSL from scratch.

What do people think? What would be most convenient to RDF.rb users? Thank you for your suggestions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment