Skip to content
/ tripod Public
forked from Swirrl/tripod

ActiveModel-style Ruby ORM for RDF Linked Data. Works with SPARQL 1.1 HTTP endpoints. This version supports localized fields, ignore_graph parameter for links, virtuoso and openRDF's sesame endpoints.

License

Notifications You must be signed in to change notification settings

fonji/tripod

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About this fork

I forked tripod mainly to support openRDF Sesame and Virtuoso endpoints, and getters for localized fields. It also includes the links branch, with an added ignore-graph option. I use it only as read-only and never took the time to adapt the specs config for my endpoints. Please let me know if you use it successfully to update/delete content.

Quick help for localized fields

If you want to get data from localized fields (@lang xml attribute), first declare the field as localized:

field :title, 'http://example.com/title', :localized => true
field :greetings, 'http://example.com/greeting', :multivalued => true, :localized => true

By default, only the value(s) of the current locale (I18n.locale) will be returned. It is possible specify the locale when getting a value or get all set values.

barry = Person.find('http://example.com/id/barry')
I18n.locale = :en
barry.title == "Doctor"
barry.title(:locale => :fr) == "Docteur"
I18n.locale = :fr
barry.title == "Docteur"
barry.title(:locale => :all) # array, length = 2
I18n.locale = :es
barry.title? == false
barry.title == nil

#Tripod

ActiveModel-style Ruby ORM for RDF Linked Data. Works with SPARQL 1.1 HTTP endpoints.

Quick start, for using in a rails app.

  1. Add it to your Gemfile and bundle

     gem tripod
    
     $ bundle
    
  2. Configure it (in application.rb, or development.rb/production.rb/test.rb)

     # (values shown are the defaults)
     Tripod.configure do |config|
       config.update_endpoint = 'http://127.0.0.1:3030/tripod/update'
       config.query_endpoint = 'http://127.0.0.1:3030/tripod/sparql'
       config.timeout_seconds = 30
     end
    
  3. Include it in your model classes.

     class Person
       include Tripod::Resource
    
       # these are the default rdf-type and graph for resources of this class
       rdf_type 'http://example.com/person'
       graph_uri 'http://example.com/people'
    
       field :name, 'http://example.com/name'
       field :knows, 'http://example.com/knows', :multivalued => true, :is_uri => true
       field :aliases, 'http://example.com/alias', :multivalued => true
       field :age, 'http://example.com/age', :datatype => RDF::XSD.integer
       field :important_dates, 'http://example.com/importantdates', :datatype => RDF::XSD.date, :multivalued => true
     end
    
     # Note: Active Model validations are supported
    
  4. Use it

     uri = 'http://example.com/ric'
     p = Person.new(uri)
     p.name = 'Ric'
     p.age = 31
     p.aliases = ['Rich', 'Richard']
     p.important_dates = [Date.new(2011,1,1)]
     p.save!
    
     people = Person.all.resources #=> returns all people as an array
    
     ric = Person.find('http://example.com/ric') #=> returns a single Person object.
    

Note:

Tripod doesn't supply a database. You need to install one. I recommend Fuseki, which runs on port 3030 by default.

Some Other interesting features

## Eager Loading

    asa = Person.find('http://example.com/asa')
    ric = Person.find('http://example.com/ric')
    ric.knows = asa.uri

    ric.eager_load_predicate_triples! #does a big DESCRIBE statement behind the scenes
    knows = ric.get_related_resource('http://example.com/knows', Resource)
    knows.label # this won't cause another database lookup

    ric.eager_load_object_triples! #does a big DESCRIBE statement behind the scenes
    asa = ric.get_related_resource('http://example.com/asa', Person) # returns a fully hydrated Person object for asa, without an extra lookup

## Defining a graph at instantiation-time

    class Resource
      include Tripod::Resource
      field :label, RDF::RDFS.label

      # notice also that you don't need to supply an rdf type or graph here!
    end

    r = Resource.new('http://example.com/foo', 'http://example.com/mygraph')
    r.label = "example"
    r.save

    # Note: Tripod assumes you want to store all resources in named graphs.
    # So if you don't supply a graph at any point (i.e. class or instance level),
    # you will get an error when you try to persist the resource.

Reading and writing arbitrary predicates

    r.write_predicate(RDF.type, 'http://example.com/myresource/type')
    r.read_predicate(RDF.type) #=> [RDF::URI.new("http://example.com/myresource/type")]

Finders and criteria

    # A Tripod::Criteria object defines a set of constraints for a SPARQL query.
    # It doesn't actually do anything against the DB until you run resources, first, or count on it.
    # (from Tripod::CriteriaExecution)

    Person.all #=> returns a Tripod::Criteria object which selects all resources of rdf_type http://example.com/person, in the http://example.com/people graph

    Resource.all #=> returns a criteria object to return resources in the database (as no rdf_type or graph_uri specified at class level)

    Person.all.resources #=> returns all the actual resources for the criteria object, as an array-like object

    Person.all.resources(:return_graph => false) #=> returns the actual resources, but without returning the graph_uri in the select (helps avoid pagination issues). Note: doesn't set the graph uri on the instantiated resources.

    Person.first #=> returns the first person (by crafting a sparql query under the covers that only returns 1 result)

    Person.first(:return_graph => false) # as with resources, doesn't return / set the graph_uri.

    Person.count  #=> returns the count of all people (by crafting a count query under the covers that only returns a count)

    # note that you need to use ?uri as the variable for the subject.
    Person.where("?uri <http://example.com/name> 'Joe'") #=> returns a Tripod::Criteria object

    Resource.graph("http://example.com/mygraph") #=> Retruns a criteria object with a graph restriction (note: if graph_uri set on the class, it will default to using this)

    Resource.find_by_sparql('SELECT ?uri ?graph WHERE { GRAPH ?graph { ?uri ?p ?o } }') #=> allows arbitrary sparql. Again, use ?uri for the variable of the subjects (and ?graph for the graph).

Chainable criteria

    Person.all.where("?uri <http://example.com/name> 'Ric'").where("?uri <http://example.com/knows> <http://example.com/asa>).first

    Person.where("?uri <http://example.com/name> ?name").limit(1).offset(0).order("DESC(?name)")

Running tests

With a Fuseki instance ready and up, edit the config in spec/spec_helper.rb to reflect your settings. Make sure you bundle to pull in all dependencies before trying to run the tests.

Some tests require memcached to be set up and running. The tests that require memcached are tagged with :caching_tests => true; do with this information what you will.

Full Documentation

Copyright (c) 2012 Swirrl IT Limited. Released under MIT License

About

ActiveModel-style Ruby ORM for RDF Linked Data. Works with SPARQL 1.1 HTTP endpoints. This version supports localized fields, ignore_graph parameter for links, virtuoso and openRDF's sesame endpoints.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 100.0%