activerdf_net7 1.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +79 -0
- data/LICENSE +504 -0
- data/README.rdoc +34 -0
- data/activerdf-jena/CHANGELOG +14 -0
- data/activerdf-jena/LICENSE +504 -0
- data/activerdf-jena/README +57 -0
- data/activerdf-jena/Rakefile +87 -0
- data/activerdf-jena/TODO +18 -0
- data/activerdf-jena/VERSION +1 -0
- data/activerdf-jena/ext/antlr-2.7.5.jar +0 -0
- data/activerdf-jena/ext/arq-extra.jar +0 -0
- data/activerdf-jena/ext/arq.jar +0 -0
- data/activerdf-jena/ext/aterm-java-1.6.jar +0 -0
- data/activerdf-jena/ext/commons-logging-1.1.jar +0 -0
- data/activerdf-jena/ext/concurrent.jar +0 -0
- data/activerdf-jena/ext/icu4j_3_4.jar +0 -0
- data/activerdf-jena/ext/iri.jar +0 -0
- data/activerdf-jena/ext/jena.jar +0 -0
- data/activerdf-jena/ext/jenatest.jar +0 -0
- data/activerdf-jena/ext/json.jar +0 -0
- data/activerdf-jena/ext/junit.jar +0 -0
- data/activerdf-jena/ext/log4j-1.2.12.jar +0 -0
- data/activerdf-jena/ext/lucene-core-2.0.0.jar +0 -0
- data/activerdf-jena/ext/ng4j.jar +0 -0
- data/activerdf-jena/ext/pellet.jar +0 -0
- data/activerdf-jena/ext/relaxngDatatype.jar +0 -0
- data/activerdf-jena/ext/stax-api-1.0.jar +0 -0
- data/activerdf-jena/ext/wstx-asl-3.0.0.jar +0 -0
- data/activerdf-jena/ext/xercesImpl.jar +0 -0
- data/activerdf-jena/ext/xml-apis.jar +0 -0
- data/activerdf-jena/ext/xsdlib.jar +0 -0
- data/activerdf-jena/lib/activerdf_jena/init.rb +26 -0
- data/activerdf-jena/lib/activerdf_jena/jena.rb +59 -0
- data/activerdf-jena/lib/activerdf_jena/jena_adapter.rb +515 -0
- data/activerdf-jena/lib/activerdf_jena/lucene.rb +22 -0
- data/activerdf-jena/lib/activerdf_jena/ng4j.rb +50 -0
- data/activerdf-jena/lib/activerdf_jena/ng4j_adapter.rb +379 -0
- data/activerdf-jena/lib/activerdf_jena/pellet.rb +25 -0
- data/activerdf-jena/test/bnode_org_rss.rdf +793 -0
- data/activerdf-jena/test/eyal-foaf.nt +39 -0
- data/activerdf-jena/test/fun_with_bnodes.nt +2 -0
- data/activerdf-jena/test/s1.n3 +18 -0
- data/activerdf-jena/test/test_data.nt +32 -0
- data/activerdf-jena/test/test_jena_adapter.rb +451 -0
- data/activerdf-jena/test/test_ng4j_adapter.rb +354 -0
- data/activerdf-rdflite/CHANGELOG +31 -0
- data/activerdf-rdflite/LICENSE +504 -0
- data/activerdf-rdflite/README +16 -0
- data/activerdf-rdflite/Rakefile +73 -0
- data/activerdf-rdflite/VERSION +1 -0
- data/activerdf-rdflite/lib/activerdf_rdflite/fetching.rb +34 -0
- data/activerdf-rdflite/lib/activerdf_rdflite/init.rb +13 -0
- data/activerdf-rdflite/lib/activerdf_rdflite/rdflite.rb +582 -0
- data/activerdf-rdflite/lib/activerdf_rdflite/suggesting.rb +87 -0
- data/activerdf-rdflite/test/test_bnode_data.nt +5 -0
- data/activerdf-rdflite/test/test_data.nt +32 -0
- data/activerdf-rdflite/test/test_escaped_data.nt +2 -0
- data/activerdf-rdflite/test/test_fetching.rb +33 -0
- data/activerdf-rdflite/test/test_rdflite.rb +277 -0
- data/activerdf-redland/CHANGELOG +12 -0
- data/activerdf-redland/LICENSE +504 -0
- data/activerdf-redland/README +9 -0
- data/activerdf-redland/Rakefile +72 -0
- data/activerdf-redland/VERSION +1 -0
- data/activerdf-redland/lib/activerdf_redland/init.rb +10 -0
- data/activerdf-redland/lib/activerdf_redland/redland.rb +362 -0
- data/activerdf-redland/test/test_person_data.nt +42 -0
- data/activerdf-redland/test/test_redland_adapter.rb +242 -0
- data/activerdf-sesame/CHANGELOG +6 -0
- data/activerdf-sesame/LICENSE +10 -0
- data/activerdf-sesame/LICENSE-aduna +10 -0
- data/activerdf-sesame/LICENSE-lgpl +504 -0
- data/activerdf-sesame/README +33 -0
- data/activerdf-sesame/Rakefile +77 -0
- data/activerdf-sesame/VERSION +1 -0
- data/activerdf-sesame/ext/commons-codec-1.3.jar +0 -0
- data/activerdf-sesame/ext/commons-dbcp-1.2.2.jar +0 -0
- data/activerdf-sesame/ext/commons-httpclient-3.1.jar +0 -0
- data/activerdf-sesame/ext/commons-logging-1.1.1.jar +0 -0
- data/activerdf-sesame/ext/commons-pool-1.3.jar +0 -0
- data/activerdf-sesame/ext/commons-pool-1.5.2.jar +0 -0
- data/activerdf-sesame/ext/junit-3.8.2.jar +0 -0
- data/activerdf-sesame/ext/openrdf-sesame-2.0-onejar.jar +0 -0
- data/activerdf-sesame/ext/openrdf-sesame-2.3-pr1-onejar.jar +0 -0
- data/activerdf-sesame/ext/slf4j-api-1.4.3.jar +0 -0
- data/activerdf-sesame/ext/slf4j-nop-1.4.3.jar +0 -0
- data/activerdf-sesame/ext/wrapper-sesame2.jar +0 -0
- data/activerdf-sesame/java/build.number +3 -0
- data/activerdf-sesame/java/build.xml +313 -0
- data/activerdf-sesame/java/javadoc/allclasses-frame.html +31 -0
- data/activerdf-sesame/java/javadoc/allclasses-noframe.html +31 -0
- data/activerdf-sesame/java/javadoc/constant-values.html +146 -0
- data/activerdf-sesame/java/javadoc/deprecated-list.html +146 -0
- data/activerdf-sesame/java/javadoc/help-doc.html +223 -0
- data/activerdf-sesame/java/javadoc/index-files/index-1.html +150 -0
- data/activerdf-sesame/java/javadoc/index-files/index-10.html +145 -0
- data/activerdf-sesame/java/javadoc/index-files/index-2.html +157 -0
- data/activerdf-sesame/java/javadoc/index-files/index-3.html +146 -0
- data/activerdf-sesame/java/javadoc/index-files/index-4.html +145 -0
- data/activerdf-sesame/java/javadoc/index-files/index-5.html +145 -0
- data/activerdf-sesame/java/javadoc/index-files/index-6.html +142 -0
- data/activerdf-sesame/java/javadoc/index-files/index-7.html +145 -0
- data/activerdf-sesame/java/javadoc/index-files/index-8.html +152 -0
- data/activerdf-sesame/java/javadoc/index-files/index-9.html +146 -0
- data/activerdf-sesame/java/javadoc/index.html +36 -0
- data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/WrapperForSesame2.html +665 -0
- data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/class-use/WrapperForSesame2.html +144 -0
- data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-frame.html +32 -0
- data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-summary.html +157 -0
- data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-tree.html +150 -0
- data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-use.html +144 -0
- data/activerdf-sesame/java/javadoc/overview-summary.html +156 -0
- data/activerdf-sesame/java/javadoc/overview-tree.html +152 -0
- data/activerdf-sesame/java/javadoc/package-list +1 -0
- data/activerdf-sesame/java/javadoc/resources/inherit.gif +0 -0
- data/activerdf-sesame/java/javadoc/stylesheet.css +29 -0
- data/activerdf-sesame/java/lib/commons-codec-1.3.jar +0 -0
- data/activerdf-sesame/java/lib/commons-dbcp-1.2.2.jar +0 -0
- data/activerdf-sesame/java/lib/commons-httpclient-3.1.jar +0 -0
- data/activerdf-sesame/java/lib/commons-logging-1.1.1.jar +0 -0
- data/activerdf-sesame/java/lib/commons-pool-1.3.jar +0 -0
- data/activerdf-sesame/java/lib/commons-pool-1.5.2.jar +0 -0
- data/activerdf-sesame/java/lib/junit-3.8.2.jar +0 -0
- data/activerdf-sesame/java/lib/openrdf-sesame-2.0-onejar.jar +0 -0
- data/activerdf-sesame/java/lib/openrdf-sesame-2.3-pr1-onejar.jar +0 -0
- data/activerdf-sesame/java/lib/slf4j-api-1.4.3.jar +0 -0
- data/activerdf-sesame/java/lib/slf4j-nop-1.4.3.jar +0 -0
- data/activerdf-sesame/java/manifest.mf +3 -0
- data/activerdf-sesame/java/settings.xml +135 -0
- data/activerdf-sesame/java/src/org/activerdf/wrapper/sesame2/WrapperForSesame2.java +145 -0
- data/activerdf-sesame/java/test-src/org/activerdf/wrapper/sesame2/TestWrapperForSesame2.java +41 -0
- data/activerdf-sesame/lib/activerdf_sesame/init.rb +11 -0
- data/activerdf-sesame/lib/activerdf_sesame/sesame.rb +400 -0
- data/activerdf-sesame/test/eyal-foaf.nt +39 -0
- data/activerdf-sesame/test/eyal-foaf.rdf +65 -0
- data/activerdf-sesame/test/test_sesame_adapter.rb +341 -0
- data/activerdf-sparql/CHANGELOG +35 -0
- data/activerdf-sparql/LICENSE +504 -0
- data/activerdf-sparql/README +10 -0
- data/activerdf-sparql/Rakefile +78 -0
- data/activerdf-sparql/VERSION +1 -0
- data/activerdf-sparql/lib/activerdf_sparql/init.rb +10 -0
- data/activerdf-sparql/lib/activerdf_sparql/sparql.rb +212 -0
- data/activerdf-sparql/lib/activerdf_sparql/sparql_result_parser.rb +55 -0
- data/activerdf-sparql/test/test_sparql_adapter.rb +108 -0
- data/activerdf-yars/LICENSE +504 -0
- data/activerdf-yars/README +10 -0
- data/activerdf-yars/Rakefile +38 -0
- data/activerdf-yars/lib/activerdf_yars/init.rb +10 -0
- data/activerdf-yars/lib/activerdf_yars/jars2.rb +119 -0
- data/lib/active_rdf.rb +85 -0
- data/lib/active_rdf/directaccess/direct_access.rb +49 -0
- data/lib/active_rdf/federation/active_rdf_adapter.rb +47 -0
- data/lib/active_rdf/federation/connection_pool.rb +156 -0
- data/lib/active_rdf/federation/federation_manager.rb +112 -0
- data/lib/active_rdf/instance_exec.rb +13 -0
- data/lib/active_rdf/objectmanager/bnode.rb +7 -0
- data/lib/active_rdf/objectmanager/literal.rb +71 -0
- data/lib/active_rdf/objectmanager/namespace.rb +106 -0
- data/lib/active_rdf/objectmanager/object_manager.rb +119 -0
- data/lib/active_rdf/objectmanager/ordered_set.rb +116 -0
- data/lib/active_rdf/objectmanager/property_list.rb +76 -0
- data/lib/active_rdf/objectmanager/resource.rb +609 -0
- data/lib/active_rdf/objectmanager/resource_like.rb +28 -0
- data/lib/active_rdf/queryengine/ntriples_parser.rb +90 -0
- data/lib/active_rdf/queryengine/query.rb +245 -0
- data/lib/active_rdf/queryengine/query2jars2.rb +22 -0
- data/lib/active_rdf/queryengine/query2sparql.rb +139 -0
- data/lib/active_rdf_helpers.rb +30 -0
- data/lib/active_rdf_log.rb +100 -0
- data/test/common.rb +119 -0
- data/test/directaccess/test_direct_access.rb +64 -0
- data/test/federation/test_connection_pool.rb +86 -0
- data/test/federation/test_federation_manager.rb +145 -0
- data/test/objectmanager/test_literal.rb +52 -0
- data/test/objectmanager/test_namespace.rb +83 -0
- data/test/objectmanager/test_object_manager.rb +96 -0
- data/test/objectmanager/test_ordered_set.rb +110 -0
- data/test/objectmanager/test_resource_reading.rb +150 -0
- data/test/objectmanager/test_resource_writing.rb +39 -0
- data/test/objectmanager/test_talia_syntax.rb +68 -0
- data/test/queryengine/my_external_resource.rb +24 -0
- data/test/queryengine/test_external_resource_class.rb +49 -0
- data/test/queryengine/test_ntriples_parser.rb +71 -0
- data/test/queryengine/test_query.rb +55 -0
- data/test/queryengine/test_query2jars2.rb +51 -0
- data/test/queryengine/test_query2sparql.rb +76 -0
- data/test/queryengine/test_query_engine.rb +52 -0
- data/test/test_adapters.rb +58 -0
- metadata +266 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
== Welcome to rdflite
|
|
2
|
+
|
|
3
|
+
rdflite is a small RDF datastore, based on sqlite3. It can be used as a
|
|
4
|
+
datastore for ActiveRDF: it acts as a gemplugin for ActiveRDF. rdflite does not
|
|
5
|
+
scale well for large datasets, but is very fast for small ones. It supports the
|
|
6
|
+
full ActiveRDF query grammar (basically, select/distinct/count with arbitrary
|
|
7
|
+
joins in the where clauses) and offers full-text search over the literals if
|
|
8
|
+
ferret is installed.
|
|
9
|
+
|
|
10
|
+
See http://www.activerdf.org/ for more information.
|
|
11
|
+
|
|
12
|
+
== License
|
|
13
|
+
rdflite is distributed under the LGPL license.
|
|
14
|
+
|
|
15
|
+
== Authors
|
|
16
|
+
* Eyal Oren
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'meta_project'
|
|
2
|
+
require 'rake'
|
|
3
|
+
require 'rake/testtask'
|
|
4
|
+
require 'rake/clean'
|
|
5
|
+
require 'rake/gempackagetask'
|
|
6
|
+
require 'rake/rdoctask'
|
|
7
|
+
require 'rake/contrib/xforge'
|
|
8
|
+
require 'rubygems'
|
|
9
|
+
require 'fileutils'
|
|
10
|
+
require '../tools/rakehelp'
|
|
11
|
+
|
|
12
|
+
$version = IO.read('VERSION').strip
|
|
13
|
+
$name = 'activerdf_rdflite'
|
|
14
|
+
$project = MetaProject::Project::XForge::RubyForge.new('activerdf')
|
|
15
|
+
|
|
16
|
+
# setup tests
|
|
17
|
+
setup_tests
|
|
18
|
+
setup_clean ["pkg", "lib/*.bundle", "*.gem", ".config"]
|
|
19
|
+
|
|
20
|
+
# setup rdoc
|
|
21
|
+
Rake::RDocTask.new do |rdoc|
|
|
22
|
+
rdoc.rdoc_dir = 'doc/rdoc'
|
|
23
|
+
rdoc.options << '--line-numbers'
|
|
24
|
+
rdoc.rdoc_files.add ['README', 'LICENSE', 'lib/**/*.rb', 'doc/**/*.rdoc']
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
desc "Does a full compile, test run"
|
|
28
|
+
task :default => [:test, :package]
|
|
29
|
+
|
|
30
|
+
setup_gem($name, $version) do |spec|
|
|
31
|
+
spec.summary = "an RDF database for usage in ActiveRDF (based on sqlite3)"
|
|
32
|
+
spec.description = spec.summary
|
|
33
|
+
spec.author="Eyal Oren <eyal.oren@deri.org"
|
|
34
|
+
spec.add_dependency('gem_plugin', '>= 0.2.1')
|
|
35
|
+
spec.add_dependency('uuidtools')
|
|
36
|
+
spec.add_dependency('activerdf', '>= 1.6.4')
|
|
37
|
+
spec.add_dependency('mime-types')
|
|
38
|
+
spec.add_dependency('sqlite3-ruby', '>= 1.2.1')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
task :verify_rubyforge do
|
|
42
|
+
raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
|
|
43
|
+
raise "RUBYFORGE_PASSWORD environment variable not set!" unless ENV['RUBYFORGE_PASSWORD']
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
desc "Release files on RubyForge."
|
|
47
|
+
task :release => [:clean, :verify_rubyforge, :package ] do
|
|
48
|
+
release_files = FileList["pkg/#$name-#$version.gem"]
|
|
49
|
+
|
|
50
|
+
Rake::XForge::Release.new($project) do |release|
|
|
51
|
+
release.user_name = ENV['RUBYFORGE_USER']
|
|
52
|
+
release.password = ENV['RUBYFORGE_PASSWORD']
|
|
53
|
+
release.files = release_files.to_a
|
|
54
|
+
release.release_name = "#$name #$version"
|
|
55
|
+
release.package_name = "activerdf-rdflite"
|
|
56
|
+
release.release_notes = ""
|
|
57
|
+
|
|
58
|
+
changes = []
|
|
59
|
+
File.open("CHANGELOG") do |file|
|
|
60
|
+
current = true
|
|
61
|
+
|
|
62
|
+
file.each do |line|
|
|
63
|
+
line.chomp!
|
|
64
|
+
if current and line =~ /^==/
|
|
65
|
+
current = false; next
|
|
66
|
+
end
|
|
67
|
+
break if line.empty? and not current
|
|
68
|
+
changes << line
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
release.release_changes = changes.join("\n")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.4.1
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Author:: Eyal Oren
|
|
2
|
+
# Copyright:: (c) 2005-2006 Eyal Oren
|
|
3
|
+
# License:: LGPL
|
|
4
|
+
|
|
5
|
+
# FetchingAdapter is an extension to rdflite for fetching RDF from online sources.
|
|
6
|
+
class FetchingAdapter < RDFLite
|
|
7
|
+
ConnectionPool.register_adapter(:fetching, self)
|
|
8
|
+
|
|
9
|
+
# TODO: check that rapper is installed
|
|
10
|
+
|
|
11
|
+
# fetches RDF/XML data from given url and adds it to the datastore, using the
|
|
12
|
+
# source url as context identifier.
|
|
13
|
+
def fetch url
|
|
14
|
+
# check if url starts with http://
|
|
15
|
+
return unless url.match(/http:\/\/(.*)/)
|
|
16
|
+
|
|
17
|
+
ActiveRdfLogger::log_debug(self) { "Fetching from #{url}" }
|
|
18
|
+
|
|
19
|
+
#model = Redland::Model.new
|
|
20
|
+
#parser = Redland::Parser.new('rdfxml')
|
|
21
|
+
#scan = Redland::Uri.new('http://feature.librdf.org/raptor-scanForRDF')
|
|
22
|
+
#enable = Redland::Literal.new('1')
|
|
23
|
+
#Redland::librdf_parser_set_feature(parser, scan.uri, enable.node)
|
|
24
|
+
#parser.parse_into_model(model, url)
|
|
25
|
+
#triples = Redland::Serializer.ntriples.model_to_string(nil, model)
|
|
26
|
+
|
|
27
|
+
triples = `rapper --scan --quiet "#{url}"`
|
|
28
|
+
lines = triples.split($/)
|
|
29
|
+
ActiveRdfLogger::log_debug(self) { "Found #{lines.size} triples" }
|
|
30
|
+
|
|
31
|
+
context = Query.resource_class.new(url)
|
|
32
|
+
add_ntriples(triples, context)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
|
|
2
|
+
# add the directory in which this file is located to the ruby loadpath
|
|
3
|
+
file =
|
|
4
|
+
if File.symlink?(__FILE__)
|
|
5
|
+
File.readlink(__FILE__)
|
|
6
|
+
else
|
|
7
|
+
__FILE__
|
|
8
|
+
end
|
|
9
|
+
$: << File.dirname(File.expand_path(file))
|
|
10
|
+
|
|
11
|
+
require 'rdflite'
|
|
12
|
+
require 'fetching'
|
|
13
|
+
require 'suggesting'
|
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
# Author:: Eyal Oren
|
|
2
|
+
# Copyright:: (c) 2005-2006 Eyal Oren
|
|
3
|
+
# License:: LGPL
|
|
4
|
+
|
|
5
|
+
require 'sqlite3'
|
|
6
|
+
require 'active_rdf'
|
|
7
|
+
require 'federation/connection_pool'
|
|
8
|
+
require 'uuidtools'
|
|
9
|
+
require 'queryengine/ntriples_parser'
|
|
10
|
+
require 'open-uri'
|
|
11
|
+
require 'mime/types'
|
|
12
|
+
|
|
13
|
+
ActiveRdfLogger::log_info "Loading RDFLite adapter", self
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# RDFLite is a lightweight RDF database on top of sqlite3. It can act as adapter
|
|
18
|
+
# in ActiveRDF. It supports on-disk and in-memory usage, and allows keyword
|
|
19
|
+
# search if ferret is installed.
|
|
20
|
+
class RDFLite < ActiveRdfAdapter
|
|
21
|
+
|
|
22
|
+
class << self
|
|
23
|
+
begin
|
|
24
|
+
require 'ferret'
|
|
25
|
+
@have_ferret = true
|
|
26
|
+
rescue LoadError
|
|
27
|
+
ActiveRdfLogger::log_info "Keyword search is disabled since we could not load Ferret. To
|
|
28
|
+
enable, please do \"gem install ferret\"", self
|
|
29
|
+
@have_ferret = false
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def has_ferret?
|
|
33
|
+
@have_ferret
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
ConnectionPool.register_adapter(:rdflite,self)
|
|
38
|
+
bool_accessor :keyword_search, :reasoning
|
|
39
|
+
|
|
40
|
+
# instantiates RDFLite database
|
|
41
|
+
# available parameters:
|
|
42
|
+
# * :location => filepath (defaults to memory)
|
|
43
|
+
# * :keyword => true/false (defaults to false)
|
|
44
|
+
# * :pidx, :oidx, etc. => true/false (enable/disable these indices)
|
|
45
|
+
def initialize(params = {})
|
|
46
|
+
super()
|
|
47
|
+
ActiveRdfLogger::log_info(self) { "Initialised rdflite with params #{params.to_s}" }
|
|
48
|
+
|
|
49
|
+
@reads = true
|
|
50
|
+
@writes = true
|
|
51
|
+
|
|
52
|
+
# if no file-location given, we use in-memory store
|
|
53
|
+
file = params[:location] || ':memory:'
|
|
54
|
+
@db = SQLite3::Database.new(file)
|
|
55
|
+
|
|
56
|
+
# disable keyword search by default, enable only if ferret is found
|
|
57
|
+
@keyword_search = params[:keyword].nil? ? false : params[:keyword]
|
|
58
|
+
@keyword_search &= self.class.has_ferret?
|
|
59
|
+
|
|
60
|
+
@reasoning = params[:reasoning] || false
|
|
61
|
+
@subprops = {} if @reasoning
|
|
62
|
+
|
|
63
|
+
if keyword_search?
|
|
64
|
+
# we initialise the ferret index, either as a file or in memory
|
|
65
|
+
infos = Ferret::Index::FieldInfos.new
|
|
66
|
+
|
|
67
|
+
# we setup the fields not to store object's contents
|
|
68
|
+
infos.add_field(:subject, :store => :yes, :index => :no, :term_vector => :no)
|
|
69
|
+
infos.add_field(:object, :store => :no) #, :index => :omit_norms)
|
|
70
|
+
|
|
71
|
+
@ferret = if params[:location]
|
|
72
|
+
Ferret::I.new(:path => params[:location] + '.ferret', :field_infos => infos)
|
|
73
|
+
else
|
|
74
|
+
Ferret::I.new(:field_infos => infos)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# turn off filesystem synchronisation for speed
|
|
79
|
+
@db.synchronous = 'off'
|
|
80
|
+
|
|
81
|
+
# create triples table. ignores duplicated triples
|
|
82
|
+
@db.execute('create table if not exists triple(s,p,o,c, unique(s,p,o,c) on conflict ignore)')
|
|
83
|
+
|
|
84
|
+
create_indices(params)
|
|
85
|
+
@db
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# returns the number of triples in the datastore (incl. possible duplicates)
|
|
89
|
+
def size
|
|
90
|
+
@db.execute('select count(*) from triple')[0][0].to_i
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# returns all triples in the datastore
|
|
94
|
+
def dump
|
|
95
|
+
@db.execute('select s,p,o,c from triple').collect do |s,p,o,c|
|
|
96
|
+
[s,p,o,c].join(' ')
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# deletes all triples from datastore
|
|
101
|
+
def clear
|
|
102
|
+
@db.execute('delete from triple')
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# close adapter and remove it from the ConnectionPool
|
|
106
|
+
def close
|
|
107
|
+
ConnectionPool.remove_data_source(self)
|
|
108
|
+
@db.close
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# deletes triple(s,p,o,c) from datastore
|
|
112
|
+
# symbol parameters match anything: delete(:s,:p,:o) will delete all triples
|
|
113
|
+
# you can specify a context to limit deletion to that context:
|
|
114
|
+
# delete(:s,:p,:o, 'http://context') will delete all triples with that context
|
|
115
|
+
def delete(s, p, o, c=nil)
|
|
116
|
+
# convert non-nil input to internal format
|
|
117
|
+
quad = [s,p,o,c].collect {|r| r.nil? ? nil : internalise(r) }
|
|
118
|
+
|
|
119
|
+
# construct where clause for deletion (for all non-nil input)
|
|
120
|
+
where_clauses = []
|
|
121
|
+
conditions = []
|
|
122
|
+
quad.each_with_index do |r,i|
|
|
123
|
+
unless r.nil?
|
|
124
|
+
conditions << r
|
|
125
|
+
where_clauses << "#{SPOC[i]} = ?"
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# construct delete string
|
|
130
|
+
ds = 'delete from triple'
|
|
131
|
+
ds << " where #{where_clauses.join(' and ')}" unless where_clauses.empty?
|
|
132
|
+
|
|
133
|
+
# execute delete string with possible deletion conditions (for each
|
|
134
|
+
# non-empty where clause)
|
|
135
|
+
ActiveRdfLogger::log_debug(self) { "Deleting #{[s,p,o,c].join(' ')}" }
|
|
136
|
+
@db.execute(ds, *conditions)
|
|
137
|
+
|
|
138
|
+
# delete literal from ferret index
|
|
139
|
+
@ferret.search_each("subject:\"#{s}\", object:\"#{o}\"") do |idx, score|
|
|
140
|
+
@ferret.delete(idx)
|
|
141
|
+
end if keyword_search?
|
|
142
|
+
|
|
143
|
+
@db
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# adds triple(s,p,o) to datastore
|
|
147
|
+
# s,p must be resources, o can be primitive data or resource
|
|
148
|
+
def add(s,p,o,c=nil)
|
|
149
|
+
# check illegal input
|
|
150
|
+
raise(ActiveRdfError, "adding non-resource #{s} while adding (#{s},#{p},#{o},#{c})") unless s.respond_to?(:uri)
|
|
151
|
+
raise(ActiveRdfError, "adding non-resource #{p} while adding (#{s},#{p},#{o},#{c})") unless p.respond_to?(:uri)
|
|
152
|
+
|
|
153
|
+
triple = [s, p, o].collect{|r| serialise(r) }
|
|
154
|
+
add_ntriples(triple.join(' ') + " .\n", serialise(c) )
|
|
155
|
+
|
|
156
|
+
## get internal representation (array)
|
|
157
|
+
#quad = [s,p,o,c].collect {|r| internalise(r) }
|
|
158
|
+
|
|
159
|
+
## insert the triple into the datastore
|
|
160
|
+
#@db.execute('insert into triple values (?,?,?,?)', *quad)
|
|
161
|
+
|
|
162
|
+
## if keyword-search available, insert the object into keyword search
|
|
163
|
+
#@ferret << {:subject => s, :object => o} if keyword_search?
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# flushes openstanding changes to underlying sqlite3
|
|
167
|
+
def flush
|
|
168
|
+
# since we always write changes into sqlite3 immediately, we don't do
|
|
169
|
+
# anything here
|
|
170
|
+
true
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# loads triples from file in ntriples format
|
|
174
|
+
def load(location)
|
|
175
|
+
context = if URI.parse(location).host
|
|
176
|
+
location
|
|
177
|
+
else
|
|
178
|
+
internalise(RDFS::Resource.new("file:#{location}"))
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
case MIME::Types.of(location)
|
|
182
|
+
when MIME::Types['application/rdf+xml']
|
|
183
|
+
# check if rapper available
|
|
184
|
+
begin
|
|
185
|
+
# can only parse rdf/xml with redland
|
|
186
|
+
# die otherwise
|
|
187
|
+
require 'rdf/redland'
|
|
188
|
+
model = Redland::Model.new
|
|
189
|
+
Redland::Parser.new.parse_into_model(model, location)
|
|
190
|
+
add_ntriples(model.to_string('ntriples'), location)
|
|
191
|
+
rescue LoadError
|
|
192
|
+
raise ActiveRdfError, "cannot parse remote rdf/xml file without Redland: please install Redland (librdf.org) and its Ruby bindings"
|
|
193
|
+
end
|
|
194
|
+
else
|
|
195
|
+
data = open(location).read
|
|
196
|
+
add_ntriples(data, context)
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# adds ntriples from given context into datastore
|
|
201
|
+
def add_ntriples(ntriples, context)
|
|
202
|
+
# add each triple to db
|
|
203
|
+
@db.transaction
|
|
204
|
+
insert = @db.prepare('insert into triple values (?,?,?,?);')
|
|
205
|
+
|
|
206
|
+
ntriples = NTriplesParser.parse(ntriples)
|
|
207
|
+
ntriples.each do |s,p,o|
|
|
208
|
+
# convert triples into internal db format
|
|
209
|
+
subject, predicate, object = [s,p,o].collect {|r| internalise(r) }
|
|
210
|
+
|
|
211
|
+
# insert triple into database
|
|
212
|
+
insert.execute(subject, predicate, object, context)
|
|
213
|
+
|
|
214
|
+
# if keyword-search available, insert the object into keyword search
|
|
215
|
+
@ferret << {:subject => subject, :object => object} if keyword_search?
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
@db.commit
|
|
219
|
+
@db
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# executes ActiveRDF query on datastore
|
|
223
|
+
def query(query)
|
|
224
|
+
# construct query clauses
|
|
225
|
+
sql, conditions = translate(query)
|
|
226
|
+
|
|
227
|
+
# executing query, passing all where-clause values as parameters (so that
|
|
228
|
+
# sqlite will encode quotes correctly)
|
|
229
|
+
results = @db.execute(sql, *conditions)
|
|
230
|
+
|
|
231
|
+
# if ASK query, we check whether we received a positive result count
|
|
232
|
+
if query.ask?
|
|
233
|
+
return [[results[0][0].to_i > 0]]
|
|
234
|
+
elsif query.count?
|
|
235
|
+
return [[results[0][0].to_i]]
|
|
236
|
+
else
|
|
237
|
+
# otherwise we convert results to ActiveRDF nodes and return them
|
|
238
|
+
return wrap(results, query.resource_class)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# translates ActiveRDF query into internal sqlite query string
|
|
243
|
+
def translate(query)
|
|
244
|
+
where, conditions = construct_where(query)
|
|
245
|
+
[construct_select(query) + construct_join(query) + where + construct_sort(query) + construct_limit(query), conditions]
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
private
|
|
249
|
+
# constants for extracting resources/literals from sql results
|
|
250
|
+
SPOC = ['s','p','o','c']
|
|
251
|
+
|
|
252
|
+
# construct select clause
|
|
253
|
+
def construct_select(query)
|
|
254
|
+
# ASK queries counts the results, and return true if results > 0
|
|
255
|
+
return "select count(*)" if query.ask?
|
|
256
|
+
|
|
257
|
+
# add select terms for each selectclause in the query
|
|
258
|
+
# the term names depend on the join conditions, e.g. t0.s or t1.p
|
|
259
|
+
select = query.select_clauses.collect do |term|
|
|
260
|
+
variable_name(query, term)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
# add possible distinct and count functions to select clause
|
|
264
|
+
select_clause = ''
|
|
265
|
+
select_clause << 'distinct ' if query.distinct?
|
|
266
|
+
select_clause << select.join(', ')
|
|
267
|
+
select_clause = "count(#{select_clause})" if query.count?
|
|
268
|
+
|
|
269
|
+
"select " + select_clause
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# construct (optional) limit and offset clauses
|
|
273
|
+
def construct_limit(query)
|
|
274
|
+
clause = ""
|
|
275
|
+
|
|
276
|
+
# if no limit given, use limit -1 (no limit)
|
|
277
|
+
limit = query.limits.nil? ? -1 : query.limits
|
|
278
|
+
|
|
279
|
+
# if no offset given, use offset 0
|
|
280
|
+
offset = query.offsets.nil? ? 0 : query.offsets
|
|
281
|
+
|
|
282
|
+
clause << " limit #{limit} offset #{offset}"
|
|
283
|
+
clause
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
# sort query results on variable clause (optionally)
|
|
287
|
+
def construct_sort(query)
|
|
288
|
+
if not query.sort_clauses.empty?
|
|
289
|
+
sort = query.sort_clauses.collect { |term| variable_name(query, term) }
|
|
290
|
+
" order by (#{sort.join(',')})"
|
|
291
|
+
elsif not query.reverse_sort_clauses.empty?
|
|
292
|
+
sort = query.reverse_sort_clauses.collect { |term| variable_name(query, term) }
|
|
293
|
+
" order by (#{sort.join(',')}) DESC"
|
|
294
|
+
else
|
|
295
|
+
""
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# construct join clause
|
|
300
|
+
# TODO: joins don't work this way, they have to be linear (in one direction
|
|
301
|
+
# only, and we should only alias tables we didnt alias yet)
|
|
302
|
+
# we should only look for one join clause in each where-clause: when we find
|
|
303
|
+
# one, we skip the rest of the variables in this clause.
|
|
304
|
+
def construct_join(query)
|
|
305
|
+
join_stmt = ''
|
|
306
|
+
|
|
307
|
+
# no join necessary if only one where clause given
|
|
308
|
+
return ' from triple as t0 ' if query.where_clauses.size == 1
|
|
309
|
+
|
|
310
|
+
where_clauses = query.where_clauses.flatten
|
|
311
|
+
considering = where_clauses.uniq.select{|w| w.is_a?(Symbol)}
|
|
312
|
+
|
|
313
|
+
# constructing hash with indices for all terms
|
|
314
|
+
# e.g. {?s => [1,3,5], ?p => [2], ... }
|
|
315
|
+
term_occurrences = Hash.new()
|
|
316
|
+
where_clauses.each_with_index do |term, index|
|
|
317
|
+
ary = (term_occurrences[term] ||= [])
|
|
318
|
+
ary << index
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
aliases = {}
|
|
322
|
+
|
|
323
|
+
where_clauses.each_with_index do |term, index|
|
|
324
|
+
# if the term has been joined with his buddy already, we can skip it
|
|
325
|
+
next unless considering.include?(term)
|
|
326
|
+
|
|
327
|
+
# we find all (other) occurrences of this term
|
|
328
|
+
indices = term_occurrences[term]
|
|
329
|
+
|
|
330
|
+
# if the term doesnt have a join-buddy, we can skip it
|
|
331
|
+
next if indices.size == 1
|
|
332
|
+
|
|
333
|
+
# construct t0,t1,... as aliases for term
|
|
334
|
+
# and construct join condition, e.g. t0.s
|
|
335
|
+
termalias = "t#{index / 4}"
|
|
336
|
+
termjoin = "#{termalias}.#{SPOC[index % 4]}"
|
|
337
|
+
|
|
338
|
+
join = if join_stmt.include?(termalias)
|
|
339
|
+
""
|
|
340
|
+
else
|
|
341
|
+
"triple as #{termalias}"
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
indices.each do |i|
|
|
345
|
+
# skip the current term itself
|
|
346
|
+
next if i==index
|
|
347
|
+
|
|
348
|
+
# construct t0,t1, etc. as aliases for buddy,
|
|
349
|
+
# and construct join condition, e.g. t0.s = t1.p
|
|
350
|
+
buddyalias = "t#{i/4}"
|
|
351
|
+
buddyjoin = "#{buddyalias}.#{SPOC[i%4]}"
|
|
352
|
+
|
|
353
|
+
# TODO: fix reuse of same table names as aliases, e.g.
|
|
354
|
+
# "from triple as t1 join triple as t2 on ... join t1 on ..."
|
|
355
|
+
# is not allowed as such by sqlite
|
|
356
|
+
# but on the other hand, restating the aliases gives ambiguity:
|
|
357
|
+
# "from triple as t1 join triple as t2 on ... join triple as t1 ..."
|
|
358
|
+
# is ambiguous
|
|
359
|
+
if join_stmt.include?(buddyalias)
|
|
360
|
+
join << "and #{termjoin} = #{buddyjoin}"
|
|
361
|
+
else
|
|
362
|
+
join << " join triple as #{buddyalias} on #{termjoin} = #{buddyjoin} "
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
join_stmt << join
|
|
366
|
+
|
|
367
|
+
# remove term from 'todo' list of still-considered terms
|
|
368
|
+
considering.delete(term)
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
if join_stmt == ''
|
|
372
|
+
return " from triple as t0 "
|
|
373
|
+
else
|
|
374
|
+
return " from #{join_stmt} "
|
|
375
|
+
end
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
# construct where clause
|
|
379
|
+
def construct_where(query)
|
|
380
|
+
# collecting where clauses, these will be added to the sql string later
|
|
381
|
+
where = []
|
|
382
|
+
|
|
383
|
+
# collecting all the right-hand sides of where clauses (e.g. where name =
|
|
384
|
+
# 'abc'), to add to query string later using ?-notation, because then
|
|
385
|
+
# sqlite will automatically encode quoted literals correctly
|
|
386
|
+
right_hand_sides = []
|
|
387
|
+
|
|
388
|
+
# convert each where clause to SQL:
|
|
389
|
+
# add where clause for each subclause, except if it's a variable
|
|
390
|
+
query.where_clauses.each_with_index do |clause,level|
|
|
391
|
+
raise ActiveRdfError, "where clause #{clause} is not a triple" unless clause.is_a?(Array)
|
|
392
|
+
clause.each_with_index do |subclause, i|
|
|
393
|
+
# dont add where clause for variables
|
|
394
|
+
unless subclause.is_a?(Symbol) || subclause.nil?
|
|
395
|
+
conditions = compute_where_condition(i, subclause, query.reasoning? && reasoning?)
|
|
396
|
+
if conditions.size == 1
|
|
397
|
+
where << "t#{level}.#{SPOC[i]} = ?"
|
|
398
|
+
right_hand_sides << conditions.first
|
|
399
|
+
else
|
|
400
|
+
conditions = conditions.collect {|c| "'#{c}'"}
|
|
401
|
+
where << "t#{level}.#{SPOC[i]} in (#{conditions.join(',')})"
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
# if keyword clause given, convert it using keyword index
|
|
408
|
+
if query.keyword? && keyword_search?
|
|
409
|
+
subjects = []
|
|
410
|
+
select_subject = query.keywords.collect {|subj,key| subj}.uniq
|
|
411
|
+
raise ActiveRdfError, "cannot do keyword search over multiple subjects" if select_subject.size > 1
|
|
412
|
+
|
|
413
|
+
keywords = query.keywords.collect {|subj,key| key}
|
|
414
|
+
@ferret.search_each("object:#{keywords}") do |idx,score|
|
|
415
|
+
subjects << @ferret[idx][:subject]
|
|
416
|
+
end
|
|
417
|
+
subjects.uniq! if query.distinct?
|
|
418
|
+
where << "#{variable_name(query,select_subject.first)} in (#{subjects.collect {'?'}.join(',')})"
|
|
419
|
+
right_hand_sides += subjects
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
if where.empty?
|
|
423
|
+
['',[]]
|
|
424
|
+
else
|
|
425
|
+
["where " + where.join(' and '), right_hand_sides]
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
def compute_where_condition(index, subclause, reasoning)
|
|
430
|
+
conditions = [subclause]
|
|
431
|
+
|
|
432
|
+
# expand conditions with rdfs rules if reasoning enabled
|
|
433
|
+
if reasoning
|
|
434
|
+
case index
|
|
435
|
+
when 0: ;
|
|
436
|
+
# no rule for subjects
|
|
437
|
+
when 1:
|
|
438
|
+
# expand properties to include all subproperties
|
|
439
|
+
conditions = subproperties(subclause) if subclause.respond_to?(:uri)
|
|
440
|
+
when 2:
|
|
441
|
+
# no rule for objects
|
|
442
|
+
when 3:
|
|
443
|
+
# no rule for contexts
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# convert conditions into internal format
|
|
448
|
+
#conditions.collect { |c| c.respond_to?(:uri) ? "<#{c.uri}>" : c.to_s }
|
|
449
|
+
conditions.collect { |c| internalise(c) }
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
def subproperties(resource)
|
|
453
|
+
# compute and store subproperties of this resource
|
|
454
|
+
# or use earlier computed value if available
|
|
455
|
+
unless @subprops[resource]
|
|
456
|
+
subproperty = Namespace.lookup(:rdfs,:subPropertyOf)
|
|
457
|
+
children_query = Query.new.distinct(:sub).where(:sub, subproperty, resource)
|
|
458
|
+
children_query.reasoning = false
|
|
459
|
+
children = children_query.execute
|
|
460
|
+
|
|
461
|
+
if children.empty?
|
|
462
|
+
@subprops[resource] = [resource]
|
|
463
|
+
else
|
|
464
|
+
@subprops[resource] = [resource] + children.collect{|c| subproperties(c)}.flatten.compact
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
@subprops[resource]
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
# returns sql variable name for a queryterm
|
|
471
|
+
def variable_name(query,term)
|
|
472
|
+
# look up the first occurence of this term in the where clauses, and compute
|
|
473
|
+
# the level and s/p/o position of it
|
|
474
|
+
index = query.where_clauses.flatten.index(term)
|
|
475
|
+
|
|
476
|
+
if index.nil?
|
|
477
|
+
# term does not appear in where clause
|
|
478
|
+
# but maybe it appears in a keyword clause
|
|
479
|
+
|
|
480
|
+
# index would not be nil if we had:
|
|
481
|
+
# select(:o).where(knud, knows, :o).where(:o, :keyword, 'eyal')
|
|
482
|
+
#
|
|
483
|
+
# the only possibility that index is nil is if we have:
|
|
484
|
+
# select(:o).where(:o, :keyword, :eyal) (selecting subject)
|
|
485
|
+
# or if we use a select clause that does not appear in any where clause
|
|
486
|
+
|
|
487
|
+
# so we check if we find the term in the keyword clauses, otherwise we throw
|
|
488
|
+
# an error
|
|
489
|
+
if query.keywords.keys.include?(term)
|
|
490
|
+
return "t0.s"
|
|
491
|
+
else
|
|
492
|
+
raise ActiveRdfError, "unbound variable :#{term.to_s} in select of #{query.to_sp}"
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
termtable = "t#{index / 4}"
|
|
497
|
+
termspo = SPOC[index % 4]
|
|
498
|
+
return "#{termtable}.#{termspo}"
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
# wrap resources into ActiveRDF resources, literals into Strings. result_type
|
|
502
|
+
# is the type that should be used for ActiveRDF resources
|
|
503
|
+
def wrap(results, result_type)
|
|
504
|
+
results.collect do |row|
|
|
505
|
+
row.collect { |result| parse(result, result_type) }
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
# Return the result as a correct type. result_type is the type that should
|
|
510
|
+
# be used for "resouce" elements
|
|
511
|
+
def parse(result, result_type = RDFS::Resource)
|
|
512
|
+
NTriplesParser.parse_node(result, result_type) || result
|
|
513
|
+
# case result
|
|
514
|
+
# when Literal
|
|
515
|
+
# # replace special characters to allow string interpolation for e.g. 'test\nbreak'
|
|
516
|
+
# $1.double_quote
|
|
517
|
+
# when Resource
|
|
518
|
+
# result_type.new($1)
|
|
519
|
+
# else
|
|
520
|
+
# # when we do a count(*) query we get a number, not a resource/literal
|
|
521
|
+
# result
|
|
522
|
+
# end
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
def create_indices(params)
|
|
526
|
+
sidx = params[:sidx] || false
|
|
527
|
+
pidx = params[:pidx] || false
|
|
528
|
+
oidx = params[:oidx] || false
|
|
529
|
+
spidx = params[:spidx] || true
|
|
530
|
+
soidx = params[:soidx] || false
|
|
531
|
+
poidx = params[:poidx] || true
|
|
532
|
+
opidx = params[:opidx] || false
|
|
533
|
+
|
|
534
|
+
# creating lookup indices
|
|
535
|
+
@db.transaction do
|
|
536
|
+
@db.execute('create index if not exists sidx on triple(s)') if sidx
|
|
537
|
+
@db.execute('create index if not exists pidx on triple(p)') if pidx
|
|
538
|
+
@db.execute('create index if not exists oidx on triple(o)') if oidx
|
|
539
|
+
@db.execute('create index if not exists spidx on triple(s,p)') if spidx
|
|
540
|
+
@db.execute('create index if not exists soidx on triple(s,o)') if soidx
|
|
541
|
+
@db.execute('create index if not exists poidx on triple(p,o)') if poidx
|
|
542
|
+
@db.execute('create index if not exists opidx on triple(o,p)') if opidx
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
# transform triple into internal format <uri> and "literal"
|
|
547
|
+
def internalise(r)
|
|
548
|
+
if r.nil? or r.is_a? Symbol
|
|
549
|
+
nil
|
|
550
|
+
else
|
|
551
|
+
r.to_ntriple
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
# transform resource/literal into ntriples format
|
|
556
|
+
def serialise(r)
|
|
557
|
+
# Fixme: r is most likely NOT a resource
|
|
558
|
+
if r.nil?
|
|
559
|
+
nil
|
|
560
|
+
else
|
|
561
|
+
r.to_ntriple
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
Resource = /<([^>]*)>/
|
|
566
|
+
Literal = /"((?:\\"|[^"])*)"/
|
|
567
|
+
|
|
568
|
+
public :subproperties
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
class String
|
|
572
|
+
def double_quote
|
|
573
|
+
Thread.new do
|
|
574
|
+
$SAFE = 12
|
|
575
|
+
begin
|
|
576
|
+
eval('"%s"' % self)
|
|
577
|
+
rescue Exception => e
|
|
578
|
+
self
|
|
579
|
+
end
|
|
580
|
+
end.value
|
|
581
|
+
end
|
|
582
|
+
end
|