db.sql 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. --
  2. -- Copyright (c) 2014-2015, Marcus Rohrmoser mobile Software, http://mro.name/me
  3. -- All rights reserved.
  4. --
  5. -- Redistribution and use in source and binary forms, with or without modification, are permitted
  6. -- provided that the following conditions are met:
  7. --
  8. -- 1. Redistributions of source code must retain the above copyright notice, this list of conditions
  9. -- and the following disclaimer.
  10. --
  11. -- 2. The software must not be used for military or intelligence or related purposes nor
  12. -- anything that's in conflict with human rights as declared in http://www.un.org/en/documents/udhr/ .
  13. --
  14. -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  15. -- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  16. -- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  17. -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. -- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  19. -- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  20. -- IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  21. -- THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22. --
  23. PRAGMA foreign_keys = ON;
  24. PRAGMA recursive_triggers = ON;
  25. PRAGMA encoding = 'UTF-8';
  26. -- URIs for subjects and objects
  27. CREATE TABLE so_uris (
  28. id INTEGER PRIMARY KEY
  29. ,uri TEXT NOT NULL UNIQUE -- semantic constraint, could be dropped to save space
  30. );
  31. -- blank node IDs for subjects and objects
  32. CREATE TABLE so_blanks (
  33. id INTEGER PRIMARY KEY
  34. ,blank TEXT NOT NULL UNIQUE -- semantic constraint, could be dropped to save space
  35. );
  36. -- URIs for predicates
  37. CREATE TABLE p_uris (
  38. id INTEGER PRIMARY KEY
  39. ,uri TEXT NOT NULL UNIQUE -- semantic constraint, could be dropped to save space
  40. );
  41. -- URIs for literal types
  42. CREATE TABLE t_uris (
  43. id INTEGER PRIMARY KEY
  44. ,uri TEXT NOT NULL UNIQUE -- semantic constraint, could be dropped to save space
  45. );
  46. -- literal values
  47. CREATE TABLE o_literals (
  48. id INTEGER PRIMARY KEY
  49. ,datatype_id INTEGER NULL REFERENCES t_uris(id)
  50. ,language TEXT NULL
  51. ,text TEXT NOT NULL
  52. );
  53. CREATE UNIQUE INDEX o_literals_index ON o_literals (text,language,datatype_id); -- semantic constraint, could be dropped to save space
  54. -- URIs for context
  55. CREATE TABLE c_uris (
  56. id INTEGER PRIMARY KEY
  57. ,uri TEXT NOT NULL UNIQUE -- semantic constraint, could be dropped to save space
  58. );
  59. CREATE TABLE triple_relations (
  60. id INTEGER PRIMARY KEY
  61. ,s_uri_id INTEGER NULL REFERENCES so_uris(id)
  62. ,s_blank_id INTEGER NULL REFERENCES so_blanks(id)
  63. ,p_uri_id INTEGER NOT NULL REFERENCES p_uris(id)
  64. ,o_uri_id INTEGER NULL REFERENCES so_uris(id)
  65. ,o_blank_id INTEGER NULL REFERENCES so_blanks(id)
  66. ,o_lit_id INTEGER NULL REFERENCES o_literals(id)
  67. ,c_uri_id INTEGER NULL REFERENCES c_uris(id)
  68. , CONSTRAINT null_subject CHECK ( -- ensure uri/blank are mutually exclusively set
  69. (s_uri_id IS NOT NULL AND s_blank_id IS NULL) OR
  70. (s_uri_id IS NULL AND s_blank_id IS NOT NULL)
  71. )
  72. , CONSTRAINT null_object CHECK ( -- ensure uri/blank/literal are mutually exclusively set
  73. (o_uri_id IS NOT NULL AND o_blank_id IS NULL AND o_lit_id IS NULL) OR
  74. (o_uri_id IS NULL AND o_blank_id IS NOT NULL AND o_lit_id IS NULL) OR
  75. (o_uri_id IS NULL AND o_blank_id IS NULL AND o_lit_id IS NOT NULL)
  76. )
  77. );
  78. -- semantic constraint, could be dropped to save space:
  79. CREATE UNIQUE INDEX triple_relations_index ON triple_relations(s_uri_id,s_blank_id,p_uri_id,o_uri_id,o_blank_id,o_lit_id,c_uri_id);
  80. -- optional indexes for lookup performance, mostly on DELETE.
  81. CREATE INDEX triple_relations_index_s_uri_id ON triple_relations(s_uri_id); -- WHERE s_uri_id IS NOT NULL;
  82. CREATE INDEX triple_relations_index_s_blank_id ON triple_relations(s_blank_id); -- WHERE s_blank_id IS NOT NULL;
  83. CREATE INDEX triple_relations_index_p_uri_id ON triple_relations(p_uri_id); -- WHERE p_uri_id IS NOT NULL;
  84. CREATE INDEX triple_relations_index_o_uri_id ON triple_relations(o_uri_id); -- WHERE o_uri_id IS NOT NULL;
  85. CREATE INDEX triple_relations_index_o_blank_id ON triple_relations(o_blank_id); -- WHERE s_blank_id IS NOT NULL;
  86. CREATE INDEX triple_relations_index_o_lit_id ON triple_relations(o_lit_id); -- WHERE o_lit_id IS NOT NULL;
  87. CREATE INDEX o_literals_index_datatype_id ON o_literals(datatype_id); -- WHERE datatype_id IS NOT NULL;
  88. CREATE VIEW triples AS
  89. SELECT
  90. -- all *_id (hashes):
  91. triple_relations.id AS id
  92. ,s_uri_id
  93. ,s_blank_id
  94. ,p_uri_id
  95. ,o_uri_id
  96. ,o_blank_id
  97. ,o_lit_id
  98. ,o_literals.datatype_id AS o_datatype_id
  99. ,c_uri_id
  100. -- all joined values:
  101. ,s_uris.uri AS s_uri
  102. ,s_blanks.blank AS s_blank
  103. ,p_uris.uri AS p_uri
  104. ,o_uris.uri AS o_uri
  105. ,o_blanks.blank AS o_blank
  106. ,o_literals.text AS o_text
  107. ,o_literals.language AS o_language
  108. ,o_lit_uris.uri AS o_datatype
  109. ,c_uris.uri AS c_uri
  110. FROM triple_relations
  111. LEFT OUTER JOIN so_uris AS s_uris ON triple_relations.s_uri_id = s_uris.id
  112. LEFT OUTER JOIN so_blanks AS s_blanks ON triple_relations.s_blank_id = s_blanks.id
  113. INNER JOIN p_uris AS p_uris ON triple_relations.p_uri_id = p_uris.id
  114. LEFT OUTER JOIN so_uris AS o_uris ON triple_relations.o_uri_id = o_uris.id
  115. LEFT OUTER JOIN so_blanks AS o_blanks ON triple_relations.o_blank_id = o_blanks.id
  116. LEFT OUTER JOIN o_literals AS o_literals ON triple_relations.o_lit_id = o_literals.id
  117. LEFT OUTER JOIN t_uris AS o_lit_uris ON o_literals.datatype_id = o_lit_uris.id
  118. LEFT OUTER JOIN c_uris AS c_uris ON triple_relations.c_uri_id = c_uris.id
  119. ;
  120. CREATE TRIGGER triples_insert INSTEAD OF INSERT ON triples
  121. FOR EACH ROW BEGIN
  122. -- subject uri/blank
  123. INSERT OR IGNORE INTO so_uris (id,uri) VALUES (NEW.s_uri_id, NEW.s_uri);
  124. INSERT OR IGNORE INTO so_blanks (id,blank) VALUES (NEW.s_blank_id, NEW.s_blank);
  125. -- predicate uri
  126. INSERT OR IGNORE INTO p_uris (id,uri) VALUES (NEW.p_uri_id, NEW.p_uri);
  127. -- object uri/blank
  128. INSERT OR IGNORE INTO so_uris (id,uri) VALUES (NEW.o_uri_id, NEW.o_uri);
  129. INSERT OR IGNORE INTO so_blanks (id,blank) VALUES (NEW.o_blank_id, NEW.o_blank);
  130. -- object literal
  131. INSERT OR IGNORE INTO t_uris (id,uri) VALUES (NEW.o_datatype_id, NEW.o_datatype);
  132. INSERT OR IGNORE INTO o_literals(id,datatype_id,language,text) VALUES (NEW.o_lit_id, NEW.o_datatype_id, NEW.o_language, NEW.o_text);
  133. -- context uri
  134. INSERT OR IGNORE INTO c_uris (id,uri) VALUES (NEW.c_uri_id, NEW.c_uri);
  135. -- triple
  136. INSERT INTO triple_relations(id, s_uri_id, s_blank_id, p_uri_id, o_uri_id, o_blank_id, o_lit_id, c_uri_id)
  137. VALUES (NEW.id, NEW.s_uri_id, NEW.s_blank_id, NEW.p_uri_id, NEW.o_uri_id, NEW.o_blank_id, NEW.o_lit_id, NEW.c_uri_id);
  138. END;
  139. CREATE TRIGGER triples_delete INSTEAD OF DELETE ON triples
  140. FOR EACH ROW BEGIN
  141. -- triple
  142. DELETE FROM triple_relations WHERE id = OLD.id;
  143. -- subject uri/blank
  144. DELETE FROM so_uris WHERE (OLD.s_uri_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM triple_relations WHERE s_uri_id = OLD.s_uri_id)) AND (id = OLD.s_uri_id);
  145. DELETE FROM so_blanks WHERE (OLD.s_blank_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM triple_relations WHERE s_blank_id = OLD.s_blank_id)) AND (id = OLD.s_blank_id);
  146. -- predicate uri
  147. DELETE FROM p_uris WHERE (OLD.p_uri_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM triple_relations WHERE p_uri_id = OLD.p_uri_id)) AND (id = OLD.p_uri_id);
  148. -- object uri/blank
  149. DELETE FROM so_uris WHERE (OLD.o_uri_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM triple_relations WHERE o_uri_id = OLD.o_uri_id)) AND (id = OLD.o_uri_id);
  150. DELETE FROM so_blanks WHERE (OLD.o_blank_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM triple_relations WHERE o_blank_id = OLD.o_blank_id)) AND (id = OLD.o_blank_id);
  151. -- object literal
  152. DELETE FROM o_literals WHERE (OLD.o_lit_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM triple_relations WHERE o_lit_id = OLD.o_lit_id)) AND (id = OLD.o_lit_id);
  153. DELETE FROM t_uris WHERE (OLD.o_datatype_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM o_literals WHERE datatype_id = OLD.o_datatype_id)) AND (id = OLD.o_datatype_id);
  154. -- context uri
  155. DELETE FROM c_uris WHERE (OLD.c_uri_id IS NOT NULL) AND (0 == (SELECT COUNT(id) FROM triple_relations WHERE c_uri_id = OLD.c_uri_id)) AND (id = OLD.c_uri_id);
  156. END;
  157. PRAGMA user_version=1;
  158. -- spo URIs
  159. INSERT INTO triples(
  160. id,
  161. s_uri_id, s_uri,
  162. s_blank_id, s_blank,
  163. p_uri_id, p_uri,
  164. o_uri_id, o_uri,
  165. o_blank_id, o_blank,
  166. o_lit_id, o_text, o_language, o_datatype_id, o_datatype,
  167. c_uri_id, c_uri
  168. ) VALUES (
  169. 100,
  170. 1001, 's foo',
  171. NULL, NULL,
  172. 3001, 'p foo',
  173. 4001, 'o foo',
  174. NULL, NULL,
  175. NULL, NULL, NULL, NULL, NULL,
  176. NULL, NULL
  177. );
  178. -- so BLANKs, p URI
  179. INSERT INTO triples(
  180. id,
  181. s_uri_id, s_uri,
  182. s_blank_id, s_blank,
  183. p_uri_id, p_uri,
  184. o_uri_id, o_uri,
  185. o_blank_id, o_blank,
  186. o_lit_id, o_datatype_id, o_datatype, o_language, o_text,
  187. c_uri_id, c_uri
  188. ) VALUES (
  189. 101,
  190. NULL, NULL,
  191. 2001, 's -',
  192. 3002, 'p bar',
  193. NULL, NULL,
  194. 5001, 'o -',
  195. NULL, NULL, NULL, NULL, NULL,
  196. NULL, NULL
  197. );
  198. -- s BLANK, p URI, o LITERAL
  199. INSERT INTO triples(
  200. id,
  201. s_uri_id, s_uri,
  202. s_blank_id, s_blank,
  203. p_uri_id, p_uri,
  204. o_uri_id, o_uri,
  205. o_blank_id, o_blank,
  206. o_lit_id, o_datatype_id, o_datatype, o_language, o_text,
  207. c_uri_id, c_uri
  208. ) VALUES (
  209. 102,
  210. NULL, NULL,
  211. 2001, 's -',
  212. 3001, 'p foo',
  213. NULL, NULL,
  214. NULL, NULL,
  215. 6001, 7001, 'xsd:string', 'deu', 'Lorem ipsum',
  216. NULL, NULL
  217. );
  218. -- s BLANK, p URI, o LITERAL
  219. INSERT INTO triples(
  220. id,
  221. s_uri_id, s_uri,
  222. s_blank_id, s_blank,
  223. p_uri_id, p_uri,
  224. o_uri_id, o_uri,
  225. o_blank_id, o_blank,
  226. o_lit_id, o_datatype_id, o_datatype, o_language, o_text,
  227. c_uri_id, c_uri
  228. ) VALUES (
  229. 103,
  230. NULL, NULL,
  231. 2001, 's -',
  232. 3001, 'p foo',
  233. NULL, NULL,
  234. NULL, NULL,
  235. 6002, NULL, NULL, NULL, 'Lorem ipsum 2',
  236. NULL, NULL
  237. );
  238. -- DELETE FROM triples;