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.
Files changed (190) hide show
  1. data/CHANGELOG +79 -0
  2. data/LICENSE +504 -0
  3. data/README.rdoc +34 -0
  4. data/activerdf-jena/CHANGELOG +14 -0
  5. data/activerdf-jena/LICENSE +504 -0
  6. data/activerdf-jena/README +57 -0
  7. data/activerdf-jena/Rakefile +87 -0
  8. data/activerdf-jena/TODO +18 -0
  9. data/activerdf-jena/VERSION +1 -0
  10. data/activerdf-jena/ext/antlr-2.7.5.jar +0 -0
  11. data/activerdf-jena/ext/arq-extra.jar +0 -0
  12. data/activerdf-jena/ext/arq.jar +0 -0
  13. data/activerdf-jena/ext/aterm-java-1.6.jar +0 -0
  14. data/activerdf-jena/ext/commons-logging-1.1.jar +0 -0
  15. data/activerdf-jena/ext/concurrent.jar +0 -0
  16. data/activerdf-jena/ext/icu4j_3_4.jar +0 -0
  17. data/activerdf-jena/ext/iri.jar +0 -0
  18. data/activerdf-jena/ext/jena.jar +0 -0
  19. data/activerdf-jena/ext/jenatest.jar +0 -0
  20. data/activerdf-jena/ext/json.jar +0 -0
  21. data/activerdf-jena/ext/junit.jar +0 -0
  22. data/activerdf-jena/ext/log4j-1.2.12.jar +0 -0
  23. data/activerdf-jena/ext/lucene-core-2.0.0.jar +0 -0
  24. data/activerdf-jena/ext/ng4j.jar +0 -0
  25. data/activerdf-jena/ext/pellet.jar +0 -0
  26. data/activerdf-jena/ext/relaxngDatatype.jar +0 -0
  27. data/activerdf-jena/ext/stax-api-1.0.jar +0 -0
  28. data/activerdf-jena/ext/wstx-asl-3.0.0.jar +0 -0
  29. data/activerdf-jena/ext/xercesImpl.jar +0 -0
  30. data/activerdf-jena/ext/xml-apis.jar +0 -0
  31. data/activerdf-jena/ext/xsdlib.jar +0 -0
  32. data/activerdf-jena/lib/activerdf_jena/init.rb +26 -0
  33. data/activerdf-jena/lib/activerdf_jena/jena.rb +59 -0
  34. data/activerdf-jena/lib/activerdf_jena/jena_adapter.rb +515 -0
  35. data/activerdf-jena/lib/activerdf_jena/lucene.rb +22 -0
  36. data/activerdf-jena/lib/activerdf_jena/ng4j.rb +50 -0
  37. data/activerdf-jena/lib/activerdf_jena/ng4j_adapter.rb +379 -0
  38. data/activerdf-jena/lib/activerdf_jena/pellet.rb +25 -0
  39. data/activerdf-jena/test/bnode_org_rss.rdf +793 -0
  40. data/activerdf-jena/test/eyal-foaf.nt +39 -0
  41. data/activerdf-jena/test/fun_with_bnodes.nt +2 -0
  42. data/activerdf-jena/test/s1.n3 +18 -0
  43. data/activerdf-jena/test/test_data.nt +32 -0
  44. data/activerdf-jena/test/test_jena_adapter.rb +451 -0
  45. data/activerdf-jena/test/test_ng4j_adapter.rb +354 -0
  46. data/activerdf-rdflite/CHANGELOG +31 -0
  47. data/activerdf-rdflite/LICENSE +504 -0
  48. data/activerdf-rdflite/README +16 -0
  49. data/activerdf-rdflite/Rakefile +73 -0
  50. data/activerdf-rdflite/VERSION +1 -0
  51. data/activerdf-rdflite/lib/activerdf_rdflite/fetching.rb +34 -0
  52. data/activerdf-rdflite/lib/activerdf_rdflite/init.rb +13 -0
  53. data/activerdf-rdflite/lib/activerdf_rdflite/rdflite.rb +582 -0
  54. data/activerdf-rdflite/lib/activerdf_rdflite/suggesting.rb +87 -0
  55. data/activerdf-rdflite/test/test_bnode_data.nt +5 -0
  56. data/activerdf-rdflite/test/test_data.nt +32 -0
  57. data/activerdf-rdflite/test/test_escaped_data.nt +2 -0
  58. data/activerdf-rdflite/test/test_fetching.rb +33 -0
  59. data/activerdf-rdflite/test/test_rdflite.rb +277 -0
  60. data/activerdf-redland/CHANGELOG +12 -0
  61. data/activerdf-redland/LICENSE +504 -0
  62. data/activerdf-redland/README +9 -0
  63. data/activerdf-redland/Rakefile +72 -0
  64. data/activerdf-redland/VERSION +1 -0
  65. data/activerdf-redland/lib/activerdf_redland/init.rb +10 -0
  66. data/activerdf-redland/lib/activerdf_redland/redland.rb +362 -0
  67. data/activerdf-redland/test/test_person_data.nt +42 -0
  68. data/activerdf-redland/test/test_redland_adapter.rb +242 -0
  69. data/activerdf-sesame/CHANGELOG +6 -0
  70. data/activerdf-sesame/LICENSE +10 -0
  71. data/activerdf-sesame/LICENSE-aduna +10 -0
  72. data/activerdf-sesame/LICENSE-lgpl +504 -0
  73. data/activerdf-sesame/README +33 -0
  74. data/activerdf-sesame/Rakefile +77 -0
  75. data/activerdf-sesame/VERSION +1 -0
  76. data/activerdf-sesame/ext/commons-codec-1.3.jar +0 -0
  77. data/activerdf-sesame/ext/commons-dbcp-1.2.2.jar +0 -0
  78. data/activerdf-sesame/ext/commons-httpclient-3.1.jar +0 -0
  79. data/activerdf-sesame/ext/commons-logging-1.1.1.jar +0 -0
  80. data/activerdf-sesame/ext/commons-pool-1.3.jar +0 -0
  81. data/activerdf-sesame/ext/commons-pool-1.5.2.jar +0 -0
  82. data/activerdf-sesame/ext/junit-3.8.2.jar +0 -0
  83. data/activerdf-sesame/ext/openrdf-sesame-2.0-onejar.jar +0 -0
  84. data/activerdf-sesame/ext/openrdf-sesame-2.3-pr1-onejar.jar +0 -0
  85. data/activerdf-sesame/ext/slf4j-api-1.4.3.jar +0 -0
  86. data/activerdf-sesame/ext/slf4j-nop-1.4.3.jar +0 -0
  87. data/activerdf-sesame/ext/wrapper-sesame2.jar +0 -0
  88. data/activerdf-sesame/java/build.number +3 -0
  89. data/activerdf-sesame/java/build.xml +313 -0
  90. data/activerdf-sesame/java/javadoc/allclasses-frame.html +31 -0
  91. data/activerdf-sesame/java/javadoc/allclasses-noframe.html +31 -0
  92. data/activerdf-sesame/java/javadoc/constant-values.html +146 -0
  93. data/activerdf-sesame/java/javadoc/deprecated-list.html +146 -0
  94. data/activerdf-sesame/java/javadoc/help-doc.html +223 -0
  95. data/activerdf-sesame/java/javadoc/index-files/index-1.html +150 -0
  96. data/activerdf-sesame/java/javadoc/index-files/index-10.html +145 -0
  97. data/activerdf-sesame/java/javadoc/index-files/index-2.html +157 -0
  98. data/activerdf-sesame/java/javadoc/index-files/index-3.html +146 -0
  99. data/activerdf-sesame/java/javadoc/index-files/index-4.html +145 -0
  100. data/activerdf-sesame/java/javadoc/index-files/index-5.html +145 -0
  101. data/activerdf-sesame/java/javadoc/index-files/index-6.html +142 -0
  102. data/activerdf-sesame/java/javadoc/index-files/index-7.html +145 -0
  103. data/activerdf-sesame/java/javadoc/index-files/index-8.html +152 -0
  104. data/activerdf-sesame/java/javadoc/index-files/index-9.html +146 -0
  105. data/activerdf-sesame/java/javadoc/index.html +36 -0
  106. data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/WrapperForSesame2.html +665 -0
  107. data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/class-use/WrapperForSesame2.html +144 -0
  108. data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-frame.html +32 -0
  109. data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-summary.html +157 -0
  110. data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-tree.html +150 -0
  111. data/activerdf-sesame/java/javadoc/org/activerdf/wrapper/sesame2/package-use.html +144 -0
  112. data/activerdf-sesame/java/javadoc/overview-summary.html +156 -0
  113. data/activerdf-sesame/java/javadoc/overview-tree.html +152 -0
  114. data/activerdf-sesame/java/javadoc/package-list +1 -0
  115. data/activerdf-sesame/java/javadoc/resources/inherit.gif +0 -0
  116. data/activerdf-sesame/java/javadoc/stylesheet.css +29 -0
  117. data/activerdf-sesame/java/lib/commons-codec-1.3.jar +0 -0
  118. data/activerdf-sesame/java/lib/commons-dbcp-1.2.2.jar +0 -0
  119. data/activerdf-sesame/java/lib/commons-httpclient-3.1.jar +0 -0
  120. data/activerdf-sesame/java/lib/commons-logging-1.1.1.jar +0 -0
  121. data/activerdf-sesame/java/lib/commons-pool-1.3.jar +0 -0
  122. data/activerdf-sesame/java/lib/commons-pool-1.5.2.jar +0 -0
  123. data/activerdf-sesame/java/lib/junit-3.8.2.jar +0 -0
  124. data/activerdf-sesame/java/lib/openrdf-sesame-2.0-onejar.jar +0 -0
  125. data/activerdf-sesame/java/lib/openrdf-sesame-2.3-pr1-onejar.jar +0 -0
  126. data/activerdf-sesame/java/lib/slf4j-api-1.4.3.jar +0 -0
  127. data/activerdf-sesame/java/lib/slf4j-nop-1.4.3.jar +0 -0
  128. data/activerdf-sesame/java/manifest.mf +3 -0
  129. data/activerdf-sesame/java/settings.xml +135 -0
  130. data/activerdf-sesame/java/src/org/activerdf/wrapper/sesame2/WrapperForSesame2.java +145 -0
  131. data/activerdf-sesame/java/test-src/org/activerdf/wrapper/sesame2/TestWrapperForSesame2.java +41 -0
  132. data/activerdf-sesame/lib/activerdf_sesame/init.rb +11 -0
  133. data/activerdf-sesame/lib/activerdf_sesame/sesame.rb +400 -0
  134. data/activerdf-sesame/test/eyal-foaf.nt +39 -0
  135. data/activerdf-sesame/test/eyal-foaf.rdf +65 -0
  136. data/activerdf-sesame/test/test_sesame_adapter.rb +341 -0
  137. data/activerdf-sparql/CHANGELOG +35 -0
  138. data/activerdf-sparql/LICENSE +504 -0
  139. data/activerdf-sparql/README +10 -0
  140. data/activerdf-sparql/Rakefile +78 -0
  141. data/activerdf-sparql/VERSION +1 -0
  142. data/activerdf-sparql/lib/activerdf_sparql/init.rb +10 -0
  143. data/activerdf-sparql/lib/activerdf_sparql/sparql.rb +212 -0
  144. data/activerdf-sparql/lib/activerdf_sparql/sparql_result_parser.rb +55 -0
  145. data/activerdf-sparql/test/test_sparql_adapter.rb +108 -0
  146. data/activerdf-yars/LICENSE +504 -0
  147. data/activerdf-yars/README +10 -0
  148. data/activerdf-yars/Rakefile +38 -0
  149. data/activerdf-yars/lib/activerdf_yars/init.rb +10 -0
  150. data/activerdf-yars/lib/activerdf_yars/jars2.rb +119 -0
  151. data/lib/active_rdf.rb +85 -0
  152. data/lib/active_rdf/directaccess/direct_access.rb +49 -0
  153. data/lib/active_rdf/federation/active_rdf_adapter.rb +47 -0
  154. data/lib/active_rdf/federation/connection_pool.rb +156 -0
  155. data/lib/active_rdf/federation/federation_manager.rb +112 -0
  156. data/lib/active_rdf/instance_exec.rb +13 -0
  157. data/lib/active_rdf/objectmanager/bnode.rb +7 -0
  158. data/lib/active_rdf/objectmanager/literal.rb +71 -0
  159. data/lib/active_rdf/objectmanager/namespace.rb +106 -0
  160. data/lib/active_rdf/objectmanager/object_manager.rb +119 -0
  161. data/lib/active_rdf/objectmanager/ordered_set.rb +116 -0
  162. data/lib/active_rdf/objectmanager/property_list.rb +76 -0
  163. data/lib/active_rdf/objectmanager/resource.rb +609 -0
  164. data/lib/active_rdf/objectmanager/resource_like.rb +28 -0
  165. data/lib/active_rdf/queryengine/ntriples_parser.rb +90 -0
  166. data/lib/active_rdf/queryengine/query.rb +245 -0
  167. data/lib/active_rdf/queryengine/query2jars2.rb +22 -0
  168. data/lib/active_rdf/queryengine/query2sparql.rb +139 -0
  169. data/lib/active_rdf_helpers.rb +30 -0
  170. data/lib/active_rdf_log.rb +100 -0
  171. data/test/common.rb +119 -0
  172. data/test/directaccess/test_direct_access.rb +64 -0
  173. data/test/federation/test_connection_pool.rb +86 -0
  174. data/test/federation/test_federation_manager.rb +145 -0
  175. data/test/objectmanager/test_literal.rb +52 -0
  176. data/test/objectmanager/test_namespace.rb +83 -0
  177. data/test/objectmanager/test_object_manager.rb +96 -0
  178. data/test/objectmanager/test_ordered_set.rb +110 -0
  179. data/test/objectmanager/test_resource_reading.rb +150 -0
  180. data/test/objectmanager/test_resource_writing.rb +39 -0
  181. data/test/objectmanager/test_talia_syntax.rb +68 -0
  182. data/test/queryengine/my_external_resource.rb +24 -0
  183. data/test/queryengine/test_external_resource_class.rb +49 -0
  184. data/test/queryengine/test_ntriples_parser.rb +71 -0
  185. data/test/queryengine/test_query.rb +55 -0
  186. data/test/queryengine/test_query2jars2.rb +51 -0
  187. data/test/queryengine/test_query2sparql.rb +76 -0
  188. data/test/queryengine/test_query_engine.rb +52 -0
  189. data/test/test_adapters.rb +58 -0
  190. metadata +266 -0
@@ -0,0 +1,28 @@
1
+ module RDFS
2
+
3
+ # Helper Module that contains same additional methods that
4
+ # are expected from classes that want to behave like
5
+ # RDFS::Resource.
6
+ #
7
+ # The module expects that the including class has an uri
8
+ # method or property.
9
+ module ResourceLike
10
+
11
+ # returns uri of resource, can be overridden in subclasses
12
+ def to_s
13
+ "<#{uri}>"
14
+ end
15
+
16
+ # overriding sort based on uri
17
+ def <=>(other)
18
+ uri <=> other.uri
19
+ end
20
+
21
+ # NTriple representation of element
22
+ def to_ntriple
23
+ "<#{uri}>"
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,90 @@
1
+ # Author:: Eyal Oren
2
+ # Copyright:: (c) 2005-2006 Eyal Oren
3
+ # License:: LGPL
4
+ # require 'active_rdf'
5
+ require 'uuidtools'
6
+ require 'strscan'
7
+
8
+ # ntriples parser
9
+ class NTriplesParser
10
+ def self.parse_node(input, resource_class = RDFS::Resource)
11
+ case input
12
+ when MatchBNode
13
+ resource_class.new("http://www.activerdf.org/bnode/#{UUID.random_create}/#$1")
14
+ when MatchLiteral
15
+ value = fix_unicode($1)
16
+ if $2
17
+ Literal.typed(value, resource_class.new($2))
18
+ else
19
+ value
20
+ end
21
+ when MatchResource
22
+ resource_class.new($1)
23
+ else
24
+ nil
25
+ end
26
+ end
27
+
28
+ # parses an input string of ntriples and returns a nested array of [s, p, o]
29
+ # (which are in turn ActiveRDF objects)
30
+ def self.parse(input)
31
+ # need unique identifier for this batch of triples (to detect occurence of
32
+ # same bnodes _:#1
33
+ uuid = UUID.random_create.to_s
34
+
35
+ input.collect do |triple|
36
+ nodes = []
37
+ scanner = StringScanner.new(triple)
38
+ scanner.skip(/\s+/)
39
+ while not scanner.eos?
40
+ nodes << scanner.scan(MatchNode)
41
+ scanner.skip(/\s+/)
42
+ scanner.terminate if nodes.size == 3
43
+ end
44
+
45
+ # handle bnodes if necessary (bnodes need to have uri generated)
46
+ subject = case nodes[0]
47
+ when MatchBNode
48
+ RDFS::Resource.new("http://www.activerdf.org/bnode/#{uuid}/#$1")
49
+ when MatchResource
50
+ RDFS::Resource.new($1)
51
+ end
52
+
53
+ predicate = case nodes[1]
54
+ when MatchResource
55
+ RDFS::Resource.new($1)
56
+ end
57
+
58
+ # handle bnodes and literals if necessary (literals need unicode fixing)
59
+ object = case nodes[2]
60
+ when MatchBNode
61
+ RDFS::Resource.new("http://www.activerdf.org/bnode/#{uuid}/#$1")
62
+ when MatchLiteral
63
+ value = fix_unicode($1)
64
+ if $2
65
+ Literal.typed(value, RDFS::Resource.new($2))
66
+ else
67
+ value
68
+ end
69
+ when MatchResource
70
+ RDFS::Resource.new($1)
71
+ end
72
+
73
+ # collect s, p, o into array to be returned
74
+ [subject, predicate, object]
75
+ end
76
+ end
77
+
78
+ private
79
+ # constants for extracting resources/literals from sql results
80
+ MatchNode = Regexp.union(/"(?:\\"|[^"])*"(?:\^\^\S+)?/,/_:\S*/,/<[^>]*>/)
81
+ MatchBNode = /_:(\S*)/
82
+ MatchResource = /<([^>]*)>/
83
+ MatchLiteral = /"((?:\\"|[^"])*)"(?:\^\^<(\S+)>)?/
84
+
85
+ # fixes unicode characters in literals (because we parse them wrongly somehow)
86
+ def self.fix_unicode(str)
87
+ tmp = str.gsub(/\\\u([0-9a-fA-F]{4,4})/u){ "U+#$1" }
88
+ tmp.gsub(/U\+([0-9a-fA-F]{4,4})/u){["#$1".hex ].pack('U*')}
89
+ end
90
+ end
@@ -0,0 +1,245 @@
1
+ # require 'active_rdf'
2
+ require 'federation/federation_manager'
3
+ require 'queryengine/query2sparql'
4
+
5
+ require 'rubygems'
6
+
7
+ # Represents a query on a datasource, abstract representation of SPARQL
8
+ # features. Query is passed to federation manager or adapter for execution on
9
+ # data source. In all clauses symbols represent variables:
10
+ # Query.new.select(:s).where(:s,:p,:o).
11
+ class Query
12
+ attr_reader :select_clauses, :where_clauses, :sort_clauses, :keywords, :limits, :offsets, :reverse_sort_clauses, :filter_clauses
13
+
14
+ bool_accessor :distinct, :ask, :select, :count, :keyword, :reasoning
15
+
16
+ # Creates a new query. You may pass a different class that is used for "resource"
17
+ # type objects instead of RDFS::Resource
18
+ def initialize(resource_type = RDFS::Resource)
19
+ @distinct = false
20
+ @limits = nil
21
+ @offsets = nil
22
+ @select_clauses = []
23
+ @where_clauses = []
24
+ @sort_clauses = []
25
+ @filter_clauses = []
26
+ @keywords = {}
27
+ @reasoning = true
28
+ @reverse_sort_clauses = []
29
+ set_resource_class(resource_type)
30
+ end
31
+
32
+ # This returns the class that is be used for resources, by default this
33
+ # is RDFS::Resource
34
+ def resource_class
35
+ @resource_class ||= RDFS::Resource
36
+ end
37
+
38
+ # Sets the resource_class. Any class may be used, however it is required
39
+ # that it can be created using the uri of the resource as it's only
40
+ # parameter and that it has an 'uri' property
41
+ def set_resource_class(resource_class)
42
+ raise(ArgumentError, "resource_class must be a class") unless(resource_class.is_a?(Class))
43
+
44
+ test = resource_class.new("http://uri")
45
+ raise(ArgumentError, "Must have an uri property") unless(test.respond_to?(:uri))
46
+ @resource_class = resource_class
47
+ end
48
+
49
+ # Clears the select clauses
50
+ def clear_select
51
+ ActiveRdfLogger::log_debug "Cleared select clause"
52
+ @select_clauses = []
53
+ @distinct = false
54
+ end
55
+
56
+ # Adds variables to select clause
57
+ def select *s
58
+ @select = true
59
+ s.each do |e|
60
+ @select_clauses << parametrise(e)
61
+ end
62
+ # removing duplicate select clauses
63
+ @select_clauses.uniq!
64
+ self
65
+ end
66
+
67
+ # Adds variables to ask clause (see SPARQL specification)
68
+ def ask
69
+ @ask = true
70
+ self
71
+ end
72
+
73
+ # Adds variables to select distinct clause
74
+ def distinct *s
75
+ @distinct = true
76
+ select(*s)
77
+ end
78
+ alias_method :select_distinct, :distinct
79
+
80
+ # Adds variables to count clause
81
+ def count *s
82
+ @count = true
83
+ select(*s)
84
+ end
85
+
86
+ # Adds sort predicates
87
+ def sort *s
88
+ # add sort clauses without duplicates
89
+ s.each { |clause| @sort_clauses << parametrise(clause) }
90
+ @sort_clauses.uniq!
91
+
92
+ self
93
+ end
94
+
95
+ # adds one or more generic filters
96
+ # NOTE: you have to use SPARQL syntax for variables, eg. regex(?s, 'abc')
97
+ def filter *s
98
+ # add filter clauses
99
+ @filter_clauses << s
100
+ @filter_clauses.uniq!
101
+
102
+ self
103
+ end
104
+
105
+ # adds regular expression filter on one variable
106
+ # variable is Ruby symbol that appears in select/where clause, regex is Ruby
107
+ # regular expression
108
+ def filter_regexp(variable, regexp)
109
+ raise(ActiveRdfError, "variable must be a symbol") unless variable.is_a? Symbol
110
+ raise(ActiveRdfError, "regexp must be a ruby regexp") unless regexp.is_a? Regexp
111
+
112
+ filter "regex(str(?#{variable}), #{regexp.inspect.gsub('/','"')})"
113
+ end
114
+ alias :filter_regex :filter_regexp
115
+
116
+ # adds operator filter one one variable
117
+ # variable is a Ruby symbol that appears in select/where clause, operator is a
118
+ # SPARQL operator (e.g. '>'), operand is a SPARQL value (e.g. 15)
119
+ def filter_operator(variable, operator, operand)
120
+ raise(ActiveRdfError, "variable must be a Symbol") unless variable.is_a? Symbol
121
+
122
+ filter "?#{variable} #{operator} #{operand}"
123
+ end
124
+
125
+ # filter variable on specified language tag, e.g. lang(:o, 'en')
126
+ # optionally matches exactly on language dialect, otherwise only
127
+ # language-specifier is considered
128
+ def lang variable, tag, exact=false
129
+ if exact
130
+ filter "lang(?#{variable} = '#{tag}'"
131
+ else
132
+ filter "regex(lang(?#{variable}), '^#{tag.gsub(/_.*/,'')}$')"
133
+ end
134
+ end
135
+
136
+ # adds reverse sorting predicates
137
+ def reverse_sort *s
138
+ # add sort clauses without duplicates
139
+ s.each { |clause| @reverse_sort_clauses << parametrise(clause) }
140
+ @reverse_sort_clauses.uniq!
141
+
142
+ self
143
+ end
144
+
145
+ # Adds limit clause (maximum number of results to return)
146
+ def limit(i)
147
+ @limits = i.to_i
148
+ self
149
+ end
150
+
151
+ # Add offset clause (ignore first n results)
152
+ def offset(i)
153
+ @offsets = i.to_i
154
+ self
155
+ end
156
+
157
+ # Adds where clauses (s,p,o) where each constituent is either variable (:s) or
158
+ # an RDFS::Resource (or equivalent class). Keyword queries are specified with the special :keyword
159
+ # symbol: Query.new.select(:s).where(:s, :keyword, 'eyal')
160
+ def where s,p,o,c=nil
161
+ case p
162
+ when :keyword
163
+ # treat keywords in where-clauses specially
164
+ keyword_where(s,o)
165
+ else
166
+ # remove duplicate variable bindings, e.g.
167
+ # where(:s,type,:o).where(:s,type,:oo) we should remove the second clause,
168
+ # since it doesn't add anything to the query and confuses the query
169
+ # generator.
170
+ # if you construct this query manually, you shouldn't! if your select
171
+ # variable happens to be in one of the removed clauses: tough luck.
172
+
173
+ unless (s.respond_to?(:uri) or s.is_a?(Symbol)) and (!s.is_a?(RDFS::BNode))
174
+ raise(ActiveRdfError, "Cannot add a where clause with s #{s}: s must be a resource or a variable")
175
+ end
176
+ unless (p.respond_to?(:uri) or p.is_a?(Symbol)) and (!s.is_a?(RDFS::BNode))
177
+ raise(ActiveRdfError, "Cannot add a where clause with p #{p}: p must be a resource or a variable, is a #{p.class.name}")
178
+ end
179
+ raise(ActiveRdfErrror, "Cannot add a where clause where o is a blank node") if(o.is_a?(RDFS::BNode))
180
+
181
+ @where_clauses << [s,p,o,c].collect{|arg| parametrise(arg)}
182
+ end
183
+ self
184
+ end
185
+
186
+ # Adds keyword constraint to the query. You can use all Ferret query syntax in
187
+ # the constraint (e.g. keyword_where(:s,'eyal|benjamin')
188
+ def keyword_where s,o
189
+ @keyword = true
190
+ s = parametrise(s)
191
+ if @keywords.include?(s)
192
+ @keywords[s] = @keywords[s] + ' ' + o
193
+ else
194
+ @keywords[s] = o
195
+ end
196
+ self
197
+ end
198
+
199
+ # Executes query on data sources. Either returns result as array
200
+ # (flattened into single value unless specified otherwise)
201
+ # or executes a block (number of block variables should be
202
+ # same as number of select variables)
203
+ #
204
+ # usage:: results = query.execute
205
+ # usage:: query.execute do |s,p,o| ... end
206
+ def execute(options={:flatten => false}, &block)
207
+ options = {:flatten => true} if options == :flatten
208
+
209
+ if block_given?
210
+ for result in FederationManager.query(self, options)
211
+ yield result
212
+ end
213
+ else
214
+ FederationManager.query(self, options)
215
+ end
216
+ end
217
+
218
+ # Returns query string depending on adapter (e.g. SPARQL, N3QL, etc.)
219
+ def to_s
220
+ if ConnectionPool.read_adapters.empty?
221
+ inspect
222
+ else
223
+ ConnectionPool.read_adapters.first.translate(self)
224
+ end
225
+ end
226
+
227
+ # Returns SPARQL serialisation of query
228
+ def to_sp
229
+ Query2SPARQL.translate(self)
230
+ end
231
+
232
+ private
233
+ def parametrise s
234
+ case s
235
+ when Symbol, Literal, Class, nil
236
+ s
237
+ else
238
+ if(s.respond_to?(:uri))
239
+ s
240
+ else
241
+ '"' + s.to_s + '"'
242
+ end
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,22 @@
1
+ # require 'active_rdf'
2
+
3
+ # Translates abstract query into jars2 query.
4
+ # (ignores ASK queries)
5
+ class Query2Jars2
6
+ def self.translate(query)
7
+ str = ""
8
+ if query.select?
9
+ # concatenate each where clause using space: s p o
10
+ # and then concatenate the clauses using dot: s p o . s2 p2 o2 .
11
+ str << "#{query.where_clauses.collect{|w| w.collect{|w| '?'+w.to_s}.join(' ')}.join(" .\n")} ."
12
+ # TODO: should we maybe reverse the order on the where_clauses? it depends
13
+ # on Andreas' answer of the best order to give to jars2. Users would
14
+ # probably put the most specific stuff first, and join to get the
15
+ # interesting information. Maybe we should not touch it and let the user
16
+ # figure it out.
17
+ end
18
+
19
+ ActiveRdfLogger::log_debug(self) { "Query2Jars2: translated #{query} to #{str}" }
20
+ return str
21
+ end
22
+ end
@@ -0,0 +1,139 @@
1
+ # require 'active_rdf'
2
+
3
+ # TODO: support limit and offset
4
+
5
+ # Translates abstract query into SPARQL that can be executed on SPARQL-compliant
6
+ # data source.
7
+ class Query2SPARQL
8
+ Engines_With_Keyword = [:yars2, :virtuoso]
9
+ def self.translate(query, engine=nil)
10
+ str = ""
11
+ if query.select?
12
+ distinct = query.distinct? ? "DISTINCT " : ""
13
+ select_clauses = query.select_clauses.collect{|s| construct_clause(s)}
14
+
15
+ str << "SELECT #{distinct}#{select_clauses.join(' ')} "
16
+ str << "WHERE { #{where_clauses(query)} #{filter_clauses(query)}} "
17
+ str << "LIMIT #{query.limits} " if query.limits
18
+ str << "OFFSET #{query.offsets} " if query.offsets
19
+ if (!query.sort_clauses.empty? || !query.reverse_sort_clauses.empty?)
20
+ str << "ORDER BY "
21
+ str << "#{sort_clauses(query)} " if !query.sort_clauses.empty?
22
+ str << "#{reverse_sort_clauses(query)} " if !query.reverse_sort_clauses.empty?
23
+ end
24
+ elsif query.ask?
25
+ str << "ASK { #{where_clauses(query)} } "
26
+ end
27
+
28
+ return str
29
+ end
30
+
31
+ # concatenate each from clause using space
32
+ def self.from_clauses(query)
33
+ params = []
34
+ # construct single context clauses if context is present
35
+ query.where_clauses.each {|s,p,o,c|
36
+ params << "FROM #{construct_clause(c)}" unless c.nil?
37
+ }
38
+
39
+ # return FROM sintax or "" if no context is speficied
40
+ if (params.empty?)
41
+ ""
42
+ else
43
+ "#{params.join(' ')} "
44
+ end
45
+ end
46
+
47
+ # concatenate filters in query
48
+ def self.filter_clauses(query)
49
+ "FILTER (#{query.filter_clauses.join(" && ")})" unless query.filter_clauses.empty?
50
+ end
51
+
52
+ def self.sort_clauses(query)
53
+ sort_clauses = query.sort_clauses.collect do |term|
54
+ "ASC(#{construct_clause(term)})"
55
+ end
56
+
57
+ sort_clauses.join(' ')
58
+ end
59
+
60
+ def self.reverse_sort_clauses(query)
61
+ reverse_sort_clauses = query.reverse_sort_clauses.collect do |term|
62
+ "DESC(#{construct_clause(term)})"
63
+ end
64
+
65
+ "#{reverse_sort_clauses.join(' ')}"
66
+ end
67
+
68
+ # concatenate each where clause using space (e.g. 's p o')
69
+ # and concatenate the clauses using dot, e.g. 's p o . s2 p2 o2 .'
70
+ def self.where_clauses(query)
71
+ if query.keyword?
72
+ case sparql_engine
73
+ when :yars2
74
+ query.keywords.each do |term, keyword|
75
+ query.where(term, keyword_predicate, keyword)
76
+ end
77
+ when :virtuoso
78
+ query.keywords.each do |term, keyword|
79
+ query.filter("#{keyword_predicate}(#{construct_clause(term)}, '#{keyword}')")
80
+ end
81
+ end
82
+ end
83
+
84
+ where_clauses = query.where_clauses.collect do |s,p,o,c|
85
+ # does there where clause use a context ?
86
+ if c.nil?
87
+ [s,p,o].collect {|term| construct_clause(term) }.join(' ')
88
+ else
89
+ "GRAPH #{construct_clause(c)} { #{construct_clause(s)} #{construct_clause(p)} #{construct_clause(o)} }"
90
+ end
91
+ end
92
+
93
+ "#{where_clauses.join(' . ')} ."
94
+ end
95
+
96
+ def self.construct_clause(term)
97
+ if term.is_a?(Symbol)
98
+ "?#{term}"
99
+ else
100
+ term.to_ntriple
101
+ end
102
+ end
103
+
104
+ def self.sparql_engine
105
+ sparql_adapters = ConnectionPool.read_adapters.select{|adp| adp.is_a? SparqlAdapter}
106
+ engines = sparql_adapters.collect {|adp| adp.engine}.uniq
107
+
108
+ unless engines.all?{|eng| Engines_With_Keyword.include?(eng)}
109
+ raise ActiveRdfError, "one or more of the specified SPARQL engines do not support keyword queries"
110
+ end
111
+
112
+ if engines.size > 1
113
+ raise ActiveRdfError, "we currently only support keyword queries for one type of SPARQL engine (e.g. Yars2 or Virtuoso) at a time"
114
+ end
115
+
116
+ return engines.first
117
+ end
118
+
119
+ def self.keyword_predicate
120
+ case sparql_engine
121
+ when :yars, :yars2
122
+ RDFS::Resource.new("http://sw.deri.org/2004/06/yars#keyword")
123
+ when :virtuoso
124
+ VirtuosoBIF.new("bif:contains")
125
+ else
126
+ raise ActiveRdfError, "default SPARQL does not support keyword queries, remove the keyword clause or specify the type of SPARQL engine used"
127
+ end
128
+ end
129
+
130
+ private_class_method :where_clauses, :construct_clause, :keyword_predicate, :sparql_engine
131
+ end
132
+
133
+ # treat virtuoso built-ins slightly different: they are URIs but without <>
134
+ # surrounding them
135
+ class VirtuosoBIF < RDFS::Resource
136
+ def to_s
137
+ uri
138
+ end
139
+ end