rdf-agraph 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +1 -0
- data/README.md +305 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/lib/rdf/allegro_graph/abstract_repository.rb +484 -0
- data/lib/rdf/allegro_graph/functors/sna_functors.rb +148 -0
- data/lib/rdf/allegro_graph/functors.rb +4 -0
- data/lib/rdf/allegro_graph/query/functor_expression.rb +56 -0
- data/lib/rdf/allegro_graph/query/prolog_literal.rb +29 -0
- data/lib/rdf/allegro_graph/query.rb +124 -0
- data/lib/rdf/allegro_graph/repository.rb +81 -0
- data/lib/rdf/allegro_graph/server.rb +93 -0
- data/lib/rdf/allegro_graph/session.rb +78 -0
- data/lib/rdf/allegro_graph/sna_generator.rb +37 -0
- data/lib/rdf/allegro_graph.rb +14 -0
- data/lib/rdf-agraph.rb +2 -0
- metadata +227 -0
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* Eric Kidd <git@randomhacks.net>
|
data/README.md
ADDED
@@ -0,0 +1,305 @@
|
|
1
|
+
# rdf-agraph: Ruby AllegroGraph adapter for RDF.rb
|
2
|
+
|
3
|
+
[RDF.rb][rdfrb] is an excellent Ruby library for working with RDF.
|
4
|
+
[AllegroGraph][allegrograph]® is a commercial RDF data store written
|
5
|
+
in Lisp. AllegroGraph supports advanced graph queries and social network
|
6
|
+
analysis.
|
7
|
+
|
8
|
+
This gem provides an optimized implementaton of RDF.rb's `Repository`
|
9
|
+
interface. It supports bulk loads, bulk deletes, optimized statement
|
10
|
+
queries and even optimized Basic Graph Pattern queries. At the time of
|
11
|
+
writing, I'm not aware of any other RDF.rb `Repository` that optimizes all
|
12
|
+
of the above.
|
13
|
+
|
14
|
+
Note, however, that this gem exposes only a small fraction of
|
15
|
+
AllegroGraph's features. To help add more features, see
|
16
|
+
[Contributing](#Contributing_to_rdf-agraph) below.
|
17
|
+
|
18
|
+
* [`rdf-agraph` documentation][doc]
|
19
|
+
* [`rdf-agraph` GitHub project][src]
|
20
|
+
|
21
|
+
This code is a wrapper around [phifty's `agraph` gem][agraph_gem], which
|
22
|
+
provides a low-level interface to AllegroGraph over HTTP.
|
23
|
+
|
24
|
+
<small>AllegroGraph® is a registered trademark of Franz, Inc.</small>
|
25
|
+
|
26
|
+
[rdfrb]: http://rdf.rubyforge.org/
|
27
|
+
[allegrograph]: http://www.franz.com/agraph/allegrograph/
|
28
|
+
[doc]: http://rdf-agraph.rubyforge.org/
|
29
|
+
[src]: https://github.com/emk/rdf-agraph
|
30
|
+
[agraph_gem]: https://github.com/phifty/agraph
|
31
|
+
|
32
|
+
## Installing
|
33
|
+
|
34
|
+
To install the `rdf-agraph` gem, run:
|
35
|
+
|
36
|
+
sudo gem install rdf-agraph
|
37
|
+
|
38
|
+
To use it from a script, you'll need to require it as follows:
|
39
|
+
|
40
|
+
require 'rubygems'
|
41
|
+
gem 'rdf-agraph'
|
42
|
+
require 'rdf-agraph'
|
43
|
+
|
44
|
+
### Installing with Bundler
|
45
|
+
|
46
|
+
If you're using Rails 3 or [Bundler][bundler], add the following line to
|
47
|
+
your Gemfile:
|
48
|
+
|
49
|
+
gem 'rdf-agraph'
|
50
|
+
|
51
|
+
And run:
|
52
|
+
|
53
|
+
bundle install
|
54
|
+
|
55
|
+
[bundler]: http://gembundler.com/
|
56
|
+
|
57
|
+
## Examples
|
58
|
+
|
59
|
+
### Connecting to a repository
|
60
|
+
|
61
|
+
To connect to an AllegroGraph repository, call:
|
62
|
+
|
63
|
+
url = "http://user:passwd@localhost:10035/repositories/example"
|
64
|
+
repo = RDF::AllegroGraph::Repository.new(url, :create => true)
|
65
|
+
|
66
|
+
### Loading data
|
67
|
+
|
68
|
+
You may now load an entire file of RDF statements:
|
69
|
+
|
70
|
+
require 'rdf/ntriples'
|
71
|
+
repo.load('triples.nt')
|
72
|
+
|
73
|
+
You may also insert statements manually with `insert`:
|
74
|
+
|
75
|
+
# Define some useful RDF vocabularies.
|
76
|
+
FOAF = RDF::FOAF # Standard "friend of a friend" vocabulary.
|
77
|
+
EX = RDF::Vocabulary.new("http://example.com/")
|
78
|
+
|
79
|
+
# Insert triples into AllegroGraph.
|
80
|
+
repo.insert(
|
81
|
+
# Information about Sam.
|
82
|
+
[EX.sam, RDF.type, FOAF.Person],
|
83
|
+
[EX.sam, FOAF.name, 'Sam Smith'],
|
84
|
+
[EX.sam, FOAF.mbox, 'mailto:sam@example.com'],
|
85
|
+
|
86
|
+
# Information about Susan.
|
87
|
+
[EX.susan, RDF.type, FOAF.Person],
|
88
|
+
[EX.susan, FOAF.name, 'Susan Jones'],
|
89
|
+
|
90
|
+
# Some more people so we have a nice graph.
|
91
|
+
[EX.rachel, RDF.type, FOAF.Person],
|
92
|
+
[EX.richard, RDF.type, FOAF.Person],
|
93
|
+
[EX.mike, RDF.type, FOAF.Person],
|
94
|
+
|
95
|
+
# Who knows who?
|
96
|
+
[EX.sam, FOAF.knows, EX.susan],
|
97
|
+
[EX.susan, FOAF.knows, EX.rachel],
|
98
|
+
[EX.susan, FOAF.knows, EX.richard],
|
99
|
+
[EX.rachel, FOAF.knows, EX.mike],
|
100
|
+
[EX.sam, FOAF.knows, EX.richard]
|
101
|
+
)
|
102
|
+
|
103
|
+
### Basic queries
|
104
|
+
|
105
|
+
To query for all statements about a subject, try:
|
106
|
+
|
107
|
+
repo.query(:subject => EX.susan) do |statement|
|
108
|
+
puts statement
|
109
|
+
end
|
110
|
+
|
111
|
+
# This prints:
|
112
|
+
# <http://example.com/susan> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://xmlns.com/foaf/0.1/Person> .
|
113
|
+
# <http://example.com/susan> <http://xmlns.com/foaf/0.1/name> Susan Jones .
|
114
|
+
# <http://example.com/susan> <http://xmlns.com/foaf/0.1/knows> <http://example.com/rachel> .
|
115
|
+
# <http://example.com/susan> <http://xmlns.com/foaf/0.1/knows> <http://example.com/richard> .
|
116
|
+
|
117
|
+
AllegroGraph also supports fully-optimized queries using RDF.rb's Basic
|
118
|
+
Graph Patterns. For example, to query for all people with known names:
|
119
|
+
|
120
|
+
repo.build_query do |q|
|
121
|
+
q.pattern [:person, RDF.type, FOAF.Person]
|
122
|
+
q.pattern [:person, FOAF.name, :name]
|
123
|
+
end.run do |solution|
|
124
|
+
puts "#{solution.name}: #{solution.person}"
|
125
|
+
end
|
126
|
+
|
127
|
+
# This prints:
|
128
|
+
# Sam Smith: http://example.com/sam
|
129
|
+
# Susan Jones: http://example.com/susan
|
130
|
+
|
131
|
+
### Advanced AllegroGraph queries
|
132
|
+
|
133
|
+
AllegroGraph has a number of more advanced features, including Prolog-style
|
134
|
+
queries and support for graph algorithms. To use these features, you'll
|
135
|
+
need to open up a dedicated AllegoGraph session. This requires the
|
136
|
+
AllegroGraph user privileges *Start sessions* and *Evaluate arbitrary code*.
|
137
|
+
|
138
|
+
repo.session do |session|
|
139
|
+
|
140
|
+
# Create a generator. This will be used to traverse links between
|
141
|
+
# nodes. It's possible to define a generator using multiple
|
142
|
+
# predicates, backwards links, and other options.
|
143
|
+
knows = session.generator(:object_of => FOAF.knows)
|
144
|
+
|
145
|
+
# Find everybody within two degrees of Sam.
|
146
|
+
session.build_query do |q|
|
147
|
+
q.ego_group_member EX.sam, 2, knows, :person
|
148
|
+
end.run do |solution|
|
149
|
+
puts solution.person
|
150
|
+
end
|
151
|
+
|
152
|
+
# This prints:
|
153
|
+
# http://example.com/sam
|
154
|
+
# http://example.com/rachel
|
155
|
+
# http://example.com/richard
|
156
|
+
# http://example.com/susan
|
157
|
+
|
158
|
+
# Find a path from Sam to Mike.
|
159
|
+
session.build_query do |q|
|
160
|
+
q.breadth_first_search_paths EX.sam, EX.mike, knows, :path
|
161
|
+
end.run do |solution|
|
162
|
+
puts "Found path:"
|
163
|
+
solution.path.each {|p| puts " #{p}" }
|
164
|
+
end
|
165
|
+
|
166
|
+
# This prints:
|
167
|
+
# Found path:
|
168
|
+
# http://example.com/sam
|
169
|
+
# http://example.com/susan
|
170
|
+
# http://example.com/rachel
|
171
|
+
# http://example.com/mike
|
172
|
+
end
|
173
|
+
|
174
|
+
## Related Projects & Documentation
|
175
|
+
|
176
|
+
For more ideas, check out the following websites:
|
177
|
+
|
178
|
+
* [AllegroGraph documentation][agraph_doc]: Documentation index for
|
179
|
+
AllegroGraph.
|
180
|
+
* [AllegroGraph Social Network Analysis][sna]: A Python tutorial showing
|
181
|
+
how to analyze the social networks in *Les Miserables*.
|
182
|
+
* [RDF.rb][rdfrb]: The RDF.rb API.
|
183
|
+
* [Spira][spira]: Define Ruby model objects for RDF data.
|
184
|
+
|
185
|
+
[agraph_doc]: http://www.franz.com/agraph/support/documentation/v4/
|
186
|
+
[sna]: http://www.franz.com/agraph/support/documentation/v4/python-tutorial/python-tutorial-40.html#Social Network Analysis
|
187
|
+
[spira]: http://spira.rubyforge.org/
|
188
|
+
|
189
|
+
## Comparisons with Other Gems
|
190
|
+
|
191
|
+
These comparisons were correct (to the best of my knowledge) at the time of
|
192
|
+
writing. However, things are moving quickly in the RDF.rb community, so
|
193
|
+
this information may be out of date!
|
194
|
+
|
195
|
+
### agraph vs. rdf-agraph
|
196
|
+
|
197
|
+
`rdf-agraph` is a wrapper around [phifty's `agraph` gem][agraph_gem], which
|
198
|
+
provides a low-level interface to AllegroGraph over HTTP.
|
199
|
+
|
200
|
+
* `agraph` provides a richer API for working with geometric primitives,
|
201
|
+
which we don't yet export.
|
202
|
+
* `rdf-agraph` provides bulk loads, bulk deletes, a Ruby-based query
|
203
|
+
builder, and better support for Social Network Analysis.
|
204
|
+
* `agraph` works with raw, serialized RDF values. URLs, for example are
|
205
|
+
represented as `"<http://example.com/>"` and strings are represented as
|
206
|
+
`"\"Hello\""`. The `rdf-agraph` gem uses high-level Ruby objects defined
|
207
|
+
by RDF.rb.
|
208
|
+
* `rdf-agraph` is compatible with the huge range of RDF formats and
|
209
|
+
repositories supported by RDF.rb.
|
210
|
+
|
211
|
+
### rdf-sesame vs. rdf-agraph
|
212
|
+
|
213
|
+
`rdf-sesame` is the standard RDF.rb Sesame driver. At the time of writing,
|
214
|
+
it has very few optimizations.
|
215
|
+
|
216
|
+
* `rdf-sesame` does not support bulk inserts, bulk deletes, or optimized
|
217
|
+
queries. `rdf-agraph` supports all of these.
|
218
|
+
* `rdf-sesame` tends to silently ignore network errors and return default
|
219
|
+
values.
|
220
|
+
* At the time of writing, `rdf-sesame` sends HTTP requests of the form `GET
|
221
|
+
http://example.com/path HTTP/1.1`, which do not work with AllegroGraph.
|
222
|
+
|
223
|
+
### sparql-client vs. rdf-agraph
|
224
|
+
|
225
|
+
`sparql-client` is the standard RDF.rb SPARQL client.
|
226
|
+
|
227
|
+
* `sparql-client` does not implement the `RDF::Repository` interface.
|
228
|
+
Instead, it implements a custom SPARQL DSL (domain-specific language).
|
229
|
+
This means that it can perform sophisticated queries, but it can't update
|
230
|
+
the contents of the repository.
|
231
|
+
* `rdf-agraph` can run raw SPARQL and queries, but does not provide a
|
232
|
+
complete DSL for building either kind of query.
|
233
|
+
|
234
|
+
## Installing AllegroGraph
|
235
|
+
|
236
|
+
AllegroGraph runs on 64-bit Intel Linux systems. Mac and Windows users may
|
237
|
+
be able to run it inside a virtual machine using [supplied images][vm] and
|
238
|
+
either VMware Player or VMware Fusion.
|
239
|
+
|
240
|
+
You may [download AllegroGraph Free Edition][free] from Franz's web site.
|
241
|
+
AllegroGraph Free Edition supports up to 50 million triples. For modern
|
242
|
+
Linux systems, I recommend installing it from a `*.tar.gz` file, as
|
243
|
+
described in the [installation instructions][install].
|
244
|
+
|
245
|
+
If you install AllegroGraph in `/opt/agraph`, you can control it using the
|
246
|
+
following script:
|
247
|
+
|
248
|
+
#!/bin/bash
|
249
|
+
#
|
250
|
+
# Call this script as either 'agraph-service start' or
|
251
|
+
# 'agraph-service stop'.
|
252
|
+
/opt/agraph/bin/agraph-control --config /opt/agraph/lib/agraph.cfg $1
|
253
|
+
|
254
|
+
Save this as `/usr/local/bin/agraph-service` and run:
|
255
|
+
|
256
|
+
chmod +x /usr/local/bin/agraph-service
|
257
|
+
|
258
|
+
[vm]: http://www.franz.com/agraph/allegrograph/vm.lhtml
|
259
|
+
[free]: http://www.franz.com/downloads/clp/ag_survey
|
260
|
+
[install]: http://www.franz.com/agraph/support/documentation/v4/server-installation.html
|
261
|
+
|
262
|
+
## A Warning About `fork`
|
263
|
+
|
264
|
+
If you use insert statements containing blank nodes into an
|
265
|
+
RDF::AllegroGraph::Repository, the repository will generate and store a
|
266
|
+
list of blank node IDs. If you later call `fork` (perhaps because you are
|
267
|
+
running Unicorn or Spork), you may cause this cache of unused blank node
|
268
|
+
IDs to be shared between two different processes. This may result in blank
|
269
|
+
node IDs being reused for multiple resources.
|
270
|
+
|
271
|
+
To avoid this problem, do not insert statements containing blank nodes
|
272
|
+
until after you have made any `fork` calls.
|
273
|
+
|
274
|
+
## Contributing to rdf-agraph
|
275
|
+
|
276
|
+
Your patches are welcome! You may contribute patches to `rdf-agraph` by
|
277
|
+
forking the [GitHub repository][src] and sending a pull request to `emk`.
|
278
|
+
|
279
|
+
If you're like to get your patches merged very quickly, here's some advice
|
280
|
+
on constructing the ideal patch:
|
281
|
+
|
282
|
+
* Start with something small, if you can: A bug fix, some new Prolog
|
283
|
+
functors, or a missing AllegroGraph feature.
|
284
|
+
* [Format your commit messages][git_commit_message] using the standard
|
285
|
+
format used by the Linux kernel, Rails and many other projects. This
|
286
|
+
keeps things tidy and makes your patch easy to review!
|
287
|
+
* Use the commit message to describe the problem that you're fixing. Make
|
288
|
+
sure that I can understand the problem and why your fix is correct.
|
289
|
+
You'd think this was obvious, but I've seen some very mysterious patches
|
290
|
+
in the past. :-)
|
291
|
+
* Provide [RSpec][rspec] specifications for the fix. This may feel like a
|
292
|
+
nuisance, but it ensures that your new feature will still work correctly
|
293
|
+
two releases from now! I can help you with this if you're not familiar
|
294
|
+
with RSpec.
|
295
|
+
* Document any new APIs using [yard][yard].
|
296
|
+
|
297
|
+
If you do these things (or at least try), I can merge your patch in about
|
298
|
+
20 seconds. If you don't know how to do these things, just do your best,
|
299
|
+
and I'll be happy to help you through the process.
|
300
|
+
|
301
|
+
Thank you for contributing to `rdf-agraph`!
|
302
|
+
|
303
|
+
[git_commit_message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
|
304
|
+
[rspec]: http://relishapp.com/rspec
|
305
|
+
[yard]: http://yardoc.org/
|
data/UNLICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
2
|
+
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
4
|
+
distribute this software, either in source code form or as a compiled
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
6
|
+
means.
|
7
|
+
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
9
|
+
of this software dedicate any and all copyright interest in the
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
11
|
+
of the public at large and to the detriment of our heirs and
|
12
|
+
successors. We intend this dedication to be an overt act of
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
14
|
+
software under copyright law.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
For more information, please refer to <http://unlicense.org/>
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|