Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README: add syntax highlighting #69

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 83 additions & 67 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,50 @@ ActiveModel-style Ruby ORM for RDF Linked Data. Works with SPARQL 1.1 HTTP endpo

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
```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
```rb
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'
# 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
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
# 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!
```rb
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
people = Person.all.resources #=> returns all people as an array

ric = Person.find('http://example.com/ric') #=> returns a single Person object.
ric = Person.find('http://example.com/ric') #=> returns a single Person object.
```

## Note:

Expand All @@ -64,73 +70,83 @@ Tripod doesn't supply a database. You need to install one. I recommend [Fuseki](

## Some Other interesting features

## Eager Loading
### Eager Loading

asa = Person.find('http://example.com/asa')
ric = Person.find('http://example.com/ric')
ric.knows = asa.uri
```rb
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_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
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
## Defining a graph at instantiation-time

class Resource
include Tripod::Resource
field :label, RDF::RDFS.label
```rb
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
# 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
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.
# 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")]
```rb
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)
```rb
# 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
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)
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 #=> 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.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 #=> 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.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)
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
# 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.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).
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
```rb
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)")
Person.where("?uri <http://example.com/name> ?name").limit(1).offset(0).order("DESC(?name)")
```

## Running tests

Expand All @@ -140,4 +156,4 @@ Some tests require memcached to be set up and running. The tests that require me

[Full Documentation](http://rubydoc.info/gems/tripod/frames)

Copyright (c) 2012 [Swirrl IT Limited](http://swirrl.com). Released under MIT License
Copyright (c) 2012 [Swirrl IT Limited](http://swirrl.com). Released under MIT License