PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/lv2-c++-tools-1.0.4/libraries/paq/query.hpp

#
C++ Header | 433 lines | 226 code | 109 blank | 98 comment | 0 complexity | afb1a41e484957a2deb07377ed65ce4e MD5 | raw file
Possible License(s): GPL-3.0
  1. /****************************************************************************
  2. query.hpp - Query engine for RDF data
  3. Copyright (C) 2006-2007 Lars Luthman <lars.luthman@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
  15. ****************************************************************************/
  16. #ifndef QUERY_HPP
  17. #define QUERY_HPP
  18. #include <map>
  19. #include <string>
  20. #include <vector>
  21. #include "rdf.hpp"
  22. namespace PAQ {
  23. class Pattern;
  24. /** This class contains a query result, i.e. a single matching subgraph. */
  25. class QueryResult {
  26. public:
  27. /** Return the bound node for the variable mentioned in place @c var. */
  28. RDFTerm* operator[](size_t var);
  29. /** Return the bound node for the variable @c var. */
  30. RDFTerm* operator[](Variable& var);
  31. protected:
  32. friend class QueryEngine;
  33. std::map<Variable*, size_t> m_variables;
  34. std::vector<RDFTerm*> m_data;
  35. };
  36. class Query;
  37. class QueryEngine;
  38. /** A filter is a constraint on a bound node. If a candidate for binding
  39. does not match the constraint that particular result is discarded.
  40. All member functions are for internal use only. */
  41. class Filter {
  42. public:
  43. virtual ~Filter() { }
  44. virtual void set_variable_indices(Query& query) = 0;
  45. virtual bool execute(QueryEngine& engine) = 0;
  46. };
  47. /** A filter that matches the language of a string literal against a
  48. language code. */
  49. class LangMatches : public Filter {
  50. public:
  51. LangMatches(Variable& var, const std::string& lang);
  52. void set_variable_indices(Query& query);
  53. bool execute(QueryEngine& engine);
  54. protected:
  55. Variable* m_var;
  56. size_t m_index;
  57. std::string m_lang;
  58. };
  59. /** Creates a filter that matches the language of a string literal against a
  60. language code. */
  61. Filter* lang_matches(Variable& var, const std::string& lang);
  62. /** A filter that matches the values of two bound nodes. */
  63. class TermEquality : public Filter {
  64. public:
  65. TermEquality(Variable& var1, Variable& var2);
  66. void set_variable_indices(Query& query);
  67. bool execute(QueryEngine& engine);
  68. protected:
  69. Variable* m_var1;
  70. Variable* m_var2;
  71. size_t m_index1;
  72. size_t m_index2;
  73. };
  74. /** Creates a filter that matches the values of two bound nodes. */
  75. Filter* operator==(Variable& var1, Variable& var2);
  76. /** Abstract base class for all unary filters. */
  77. class UnaryFilter : public Filter {
  78. public:
  79. UnaryFilter(Variable& var);
  80. virtual void set_variable_indices(Query& query);
  81. protected:
  82. Variable* m_var;
  83. size_t m_index;
  84. };
  85. /** A filter that checks if a bound node is an URI reference. */
  86. class IsURI : public UnaryFilter {
  87. public:
  88. IsURI(Variable& var) : UnaryFilter(var) { }
  89. bool execute(QueryEngine& engine);
  90. };
  91. /** Creates a filter that checks if a bound node is an URI reference. */
  92. Filter* is_uriref(Variable& var);
  93. /** A filter that checks if a bound node is a literal. */
  94. class IsLiteral : public UnaryFilter {
  95. public:
  96. IsLiteral(Variable& var) : UnaryFilter(var) { }
  97. bool execute(QueryEngine& engine);
  98. };
  99. /** Creates a filter that checks if a bound node is a literal. */
  100. Filter* is_literal(Variable& var);
  101. /** A filter that checks if a bound node is a numeric literal. */
  102. class IsNumeric : public UnaryFilter {
  103. public:
  104. IsNumeric(Variable& var) : UnaryFilter(var) { }
  105. bool execute(QueryEngine& engine);
  106. };
  107. /** Creates a filter that checks if a bound node is a numeric literal. */
  108. Filter* is_numeric(Variable& var);
  109. /** A filter that checks if a bound node is an integer literal. */
  110. class IsInteger : public UnaryFilter {
  111. public:
  112. IsInteger(Variable& var) : UnaryFilter(var) { }
  113. bool execute(QueryEngine& engine);
  114. };
  115. /** Creates a filter that checks if a bound node is an integer literal. */
  116. Filter* is_integer(Variable& var);
  117. /** A filter that checks for the inverse of another filter. */
  118. class Negation : public Filter {
  119. public:
  120. Negation(Filter* f);
  121. ~Negation();
  122. void set_variable_indices(Query& q);
  123. bool execute(QueryEngine& engine);
  124. protected:
  125. Filter* m_filter;
  126. };
  127. /** Creates a filter that checks for the inverse of another filter. */
  128. Filter* no(Filter* filter);
  129. /** A filter that is built from two other filters. */
  130. class Aggregate : public Filter {
  131. public:
  132. Aggregate(Filter* f1, Filter* f2);
  133. ~Aggregate();
  134. void set_variable_indices(Query& q);
  135. protected:
  136. Filter* m_f1;
  137. Filter* m_f2;
  138. };
  139. /** A filter that checks if one filter OR another is true. */
  140. class Or : public Aggregate {
  141. public:
  142. Or(Filter* f1, Filter* f2);
  143. bool execute(QueryEngine& engine);
  144. };
  145. /** Creates a filter that checks if at least one of two other
  146. filters is true. */
  147. Filter* or_filter(Filter* f1, Filter* f2);
  148. /** A filter that checks if one filter AND another is true. */
  149. class And : public Aggregate {
  150. public:
  151. And(Filter* f1, Filter* f2);
  152. bool execute(QueryEngine& engine);
  153. };
  154. /** Creates a filter that checks if two other filters is true. */
  155. Filter* and_filter(Filter* f1, Filter* f2);
  156. /** A filter that compares the numeric value of a node to a constant. */
  157. class NumericCompare : public Filter {
  158. public:
  159. NumericCompare(Variable& var, double value);
  160. virtual void set_variable_indices(Query& q);
  161. protected:
  162. Variable* m_var;
  163. double m_value;
  164. size_t m_index;
  165. };
  166. /** A filter that checks if the node's value is less than a constant. */
  167. class NumericLess : public NumericCompare {
  168. public:
  169. NumericLess(Variable& var, double value) : NumericCompare(var, value) { }
  170. bool execute(QueryEngine& engine);
  171. };
  172. /** Creates a filter that checks if the node's value is less
  173. than a constant. */
  174. Filter* operator<(Variable& var, double value);
  175. /** Creates a filter that checks if the node's value is less
  176. than a constant. */
  177. Filter* operator>=(double value, Variable& var);
  178. /** A filter that checks if the node's value is less than or equal to
  179. a constant. */
  180. class NumericLessEqual : public NumericCompare {
  181. public:
  182. NumericLessEqual(Variable& var, double value) : NumericCompare(var, value) {}
  183. bool execute(QueryEngine& engine);
  184. };
  185. /** Creates a filter that checks if the node's value is less than or equal to
  186. a constant. */
  187. Filter* operator<=(Variable& var, double value);
  188. /** Creates a filter that checks if the node's value is less than or equal to
  189. a constant. */
  190. Filter* operator>(double value, Variable& var);
  191. /** A filter that checks if the node's value is greater than a constant. */
  192. class NumericGreater : public NumericCompare {
  193. public:
  194. NumericGreater(Variable& var, double value) : NumericCompare(var, value) { }
  195. bool execute(QueryEngine& engine);
  196. };
  197. /** Creates a filter that checks if the node's value is greater than
  198. a constant. */
  199. Filter* operator>(Variable& var, double value);
  200. /** Creates a filter that checks if the node's value is greater than
  201. a constant. */
  202. Filter* operator<=(double value, Variable& var);
  203. /** A filter that checks if the node's value is greater than or equal to
  204. a constant. */
  205. class NumericGreaterEqual : public NumericCompare {
  206. public:
  207. NumericGreaterEqual(Variable& var, double value)
  208. : NumericCompare(var, value) { }
  209. bool execute(QueryEngine& engine);
  210. };
  211. /** Creates a filter that checks if the node's value is greater than
  212. or equal to a constant. */
  213. Filter* operator>=(Variable& var, double value);
  214. /** Creates a filter that checks if the node's value is greater than
  215. or equal to a constant. */
  216. Filter* operator<(double value, Variable& var);
  217. /** A filter that checks if the node's value is equal to a numeric
  218. constant. */
  219. class NumericEquality : public NumericCompare {
  220. public:
  221. NumericEquality(Variable& var, double value) : NumericCompare(var, value) { }
  222. bool execute(QueryEngine& engine);
  223. };
  224. /** Creates a filter that checks if the node's value is equal to a constant.*/
  225. Filter* operator==(Variable& var, double value);
  226. /** Creates a filter that checks if the node's value is equal to a constant.*/
  227. Filter* operator==(double value, Variable& var);
  228. /** Creates a filter that checks if the node's value is different from
  229. a constant. */
  230. Filter* operator!=(Variable& var, double value);
  231. /** Creates a filter that checks if the node's value is different from
  232. a constant. */
  233. Filter* operator!=(double value, Variable& var);
  234. /** A filter that checks if the node's value is equal to a string
  235. constant. */
  236. class StringEquality : public Filter {
  237. public:
  238. StringEquality(Variable& var, const std::string& value);
  239. virtual void set_variable_indices(Query& q);
  240. bool execute(QueryEngine& engine);
  241. protected:
  242. Variable* m_var;
  243. std::string m_value;
  244. size_t m_index;
  245. };
  246. /** Creates a filter that checks if the node's value is equal to a constant.*/
  247. Filter* operator==(Variable& var, const std::string& value);
  248. /** Creates a filter that checks if the node's value is equal to a constant.*/
  249. Filter* operator==(const std::string& value, Variable& var);
  250. /** Creates a filter that checks if the node's value is different from
  251. a constant. */
  252. Filter* operator!=(Variable& var, const std::string& value);
  253. /** Creates a filter that checks if the node's value is different from
  254. a constant. */
  255. Filter* operator!=(const std::string& value, Variable& var);
  256. /** Abstract base class for all binary filters. */
  257. class BinaryFilter : public Filter {
  258. public:
  259. BinaryFilter(Variable& var1, Variable& var2);
  260. virtual void set_variable_indices(Query& query);
  261. protected:
  262. Variable* m_var1;
  263. Variable* m_var2;
  264. size_t m_index1;
  265. size_t m_index2;
  266. };
  267. /** A class that holds queries. A query can be executed many times on
  268. different data sets. */
  269. class Query {
  270. public:
  271. Query();
  272. /** Add a new triple pattern to the query. */
  273. Query& where(Variable& s, Variable& p, Variable& o);
  274. Query& where(const std::string& s, Variable& p, Variable& o);
  275. Query& where(Variable& s, const std::string& p, Variable& o);
  276. Query& where(Variable& s, Variable& p, const std::string& o);
  277. Query& where(Variable& s, const std::string& p, const std::string& o);
  278. Query& where(const std::string& s, Variable& p, const std::string& o);
  279. Query& where(const std::string& s, const std::string& p, Variable& o);
  280. Query& where(const std::string& s, const std::string& p,
  281. const std::string& o);
  282. /** Add a filter to the query. */
  283. Query& filter(Filter* f);
  284. /** Run the query on a dataset. */
  285. std::vector<QueryResult> run(RDFData& data);
  286. RDFData data;
  287. protected:
  288. friend class QueryEngine;
  289. friend Query select(Variable& var1, Variable& var2,
  290. Variable& var3, Variable& var4);
  291. Query(Variable& var1, Variable& var2, Variable& var3, Variable& var4);
  292. RDFTerm* add_term(const std::string& str);
  293. std::vector<Filter*> filters;
  294. std::map<Variable*, size_t> selected;
  295. };
  296. /** Create a new query with some selected variables. */
  297. Query select(Variable& var1, Variable& var2 = Variable::nil,
  298. Variable& var3 = Variable::nil, Variable& var4 = Variable::nil);
  299. /** This is the class that does all the subgraph matching work. It is for
  300. internal use only. */
  301. class QueryEngine {
  302. public:
  303. QueryEngine(Query& q, RDFData& d);
  304. std::vector<QueryResult> run();
  305. std::vector<size_t> mapping;
  306. const std::vector<RDFTerm*>& N1;
  307. const std::vector<RDFTerm*>& N2;
  308. const std::vector<Triple*>& T1;
  309. const std::vector<Triple*>& T2;
  310. protected:
  311. const Query& query;
  312. void match(size_t depth);
  313. bool match_node(RDFTerm* p, RDFTerm* t, size_t& bound);
  314. size_t NULL_NODE;
  315. std::vector<QueryResult> result;
  316. };
  317. }
  318. #endif