PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/arc2/store/ARC2_StoreTableManager.php

https://bitbucket.org/rhiaro/public-notices-as-georss
PHP | 290 lines | 234 code | 34 blank | 22 comment | 15 complexity | 453ad38e5a875dd51b7632d24d7397f5 MD5 | raw file
  1. <?php
  2. /**
  3. * ARC2 RDF Store Table Manager
  4. *
  5. * @license http://arc.semsol.org/license
  6. * @author Benjamin Nowack
  7. * @version 2010-11-16
  8. *
  9. */
  10. ARC2::inc('Store');
  11. class ARC2_StoreTableManager extends ARC2_Store {
  12. function __construct($a, &$caller) {
  13. parent::__construct($a, $caller);
  14. }
  15. function __init() {/* db_con */
  16. parent::__init();
  17. $this->engine_type = $this->v('store_engine_type', 'MyISAM', $this->a);
  18. }
  19. /* */
  20. function getTableOptionsCode() {
  21. $v = $this->getDBVersion();
  22. $r = "";
  23. $r .= (($v < '04-01-00') && ($v >= '04-00-18')) ? 'ENGINE' : (($v >= '04-01-02') ? 'ENGINE' : 'TYPE');
  24. $r .= "=" . $this->engine_type;
  25. $r .= ($v >= '04-00-00') ? " CHARACTER SET utf8" : "";
  26. $r .= ($v >= '04-01-00') ? " COLLATE utf8_unicode_ci" : "";
  27. $r .= " DELAY_KEY_WRITE = 1";
  28. return $r;
  29. }
  30. /* */
  31. function createTables() {
  32. $con = $this->getDBCon();
  33. if(!$this->createTripleTable()) {
  34. return $this->addError('Could not create "triple" table (' . mysql_error($con) . ').');
  35. }
  36. if(!$this->createG2TTable()) {
  37. return $this->addError('Could not create "g2t" table (' . mysql_error($con) . ').');
  38. }
  39. if(!$this->createID2ValTable()) {
  40. return $this->addError('Could not create "id2val" table (' . mysql_error($con) . ').');
  41. }
  42. if(!$this->createS2ValTable()) {
  43. return $this->addError('Could not create "s2val" table (' . mysql_error($con) . ').');
  44. }
  45. if(!$this->createO2ValTable()) {
  46. return $this->addError('Could not create "o2val" table (' . mysql_error($con) . ').');
  47. }
  48. if(!$this->createSettingTable()) {
  49. return $this->addError('Could not create "setting" table (' . mysql_error($con) . ').');
  50. }
  51. return 1;
  52. }
  53. /* */
  54. function createTripleTable($suffix = 'triple') {
  55. /* keep in sync with merge def in StoreQueryHandler ! */
  56. $indexes = $this->v('store_indexes', array('sp (s,p)', 'os (o,s)', 'po (p,o)'), $this->a);
  57. $index_code = $indexes ? 'KEY ' . join(', KEY ', $indexes) . ', ' : '';
  58. $sql = "
  59. CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . $suffix . " (
  60. t mediumint UNSIGNED NOT NULL,
  61. s mediumint UNSIGNED NOT NULL,
  62. p mediumint UNSIGNED NOT NULL,
  63. o mediumint UNSIGNED NOT NULL,
  64. o_lang_dt mediumint UNSIGNED NOT NULL,
  65. o_comp char(35) NOT NULL, /* normalized value for ORDER BY operations */
  66. s_type tinyint(1) NOT NULL default 0, /* uri/bnode => 0/1 */
  67. o_type tinyint(1) NOT NULL default 0, /* uri/bnode/literal => 0/1/2 */
  68. misc tinyint(1) NOT NULL default 0, /* temporary flags */
  69. UNIQUE KEY (t), " . $index_code . " KEY (misc)
  70. ) ". $this->getTableOptionsCode() . "
  71. ";
  72. return mysql_query($sql, $this->getDBCon());
  73. }
  74. function extendTripleTableColumns($suffix = 'triple') {
  75. $sql = "
  76. ALTER TABLE " . $this->getTablePrefix() . $suffix . "
  77. MODIFY t int(10) UNSIGNED NOT NULL,
  78. MODIFY s int(10) UNSIGNED NOT NULL,
  79. MODIFY p int(10) UNSIGNED NOT NULL,
  80. MODIFY o int(10) UNSIGNED NOT NULL,
  81. MODIFY o_lang_dt int(10) UNSIGNED NOT NULL
  82. ";
  83. return mysql_query($sql, $this->getDBCon());
  84. }
  85. /* */
  86. function createG2TTable() {
  87. $sql = "
  88. CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "g2t (
  89. g mediumint UNSIGNED NOT NULL,
  90. t mediumint UNSIGNED NOT NULL,
  91. UNIQUE KEY gt (g,t), KEY tg (t,g)
  92. ) ". $this->getTableOptionsCode() . "
  93. ";
  94. return mysql_query($sql, $this->getDBCon());
  95. }
  96. function extendG2tTableColumns($suffix = 'g2t') {
  97. $sql = "
  98. ALTER TABLE " . $this->getTablePrefix() . $suffix . "
  99. MODIFY g int(10) UNSIGNED NOT NULL,
  100. MODIFY t int(10) UNSIGNED NOT NULL
  101. ";
  102. return mysql_query($sql, $this->getDBCon());
  103. }
  104. /* */
  105. function createID2ValTable() {
  106. $sql = "
  107. CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "id2val (
  108. id mediumint UNSIGNED NOT NULL,
  109. misc tinyint(1) NOT NULL default 0,
  110. val text NOT NULL,
  111. val_type tinyint(1) NOT NULL default 0, /* uri/bnode/literal => 0/1/2 */
  112. UNIQUE KEY (id,val_type), KEY v (val(64))
  113. ) ". $this->getTableOptionsCode() . "
  114. ";
  115. return mysql_query($sql, $this->getDBCon());
  116. }
  117. function extendId2valTableColumns($suffix = 'id2val') {
  118. $sql = "
  119. ALTER TABLE " . $this->getTablePrefix() . $suffix . "
  120. MODIFY id int(10) UNSIGNED NOT NULL
  121. ";
  122. return mysql_query($sql, $this->getDBCon());
  123. }
  124. /* */
  125. function createS2ValTable() {
  126. //$indexes = 'UNIQUE KEY (id), KEY vh (val_hash), KEY v (val(64))';
  127. $indexes = 'UNIQUE KEY (id), KEY vh (val_hash)';
  128. $sql = "
  129. CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "s2val (
  130. id mediumint UNSIGNED NOT NULL,
  131. misc tinyint(1) NOT NULL default 0,
  132. val_hash char(32) NOT NULL,
  133. val text NOT NULL,
  134. " . $indexes . "
  135. ) " . $this->getTableOptionsCode() . "
  136. ";
  137. return mysql_query($sql, $this->getDBCon());
  138. }
  139. function extendS2valTableColumns($suffix = 's2val') {
  140. $sql = "
  141. ALTER TABLE " . $this->getTablePrefix() . $suffix . "
  142. MODIFY id int(10) UNSIGNED NOT NULL
  143. ";
  144. return mysql_query($sql, $this->getDBCon());
  145. }
  146. /* */
  147. function createO2ValTable() {
  148. /* object value index, e.g. "KEY v (val(64))" and/or "FULLTEXT KEY vft (val)" */
  149. $val_index = $this->v('store_object_index', 'KEY v (val(64))', $this->a);
  150. if ($val_index) $val_index = ', ' . ltrim($val_index, ',');
  151. $sql = "
  152. CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "o2val (
  153. id mediumint UNSIGNED NOT NULL,
  154. misc tinyint(1) NOT NULL default 0,
  155. val_hash char(32) NOT NULL,
  156. val text NOT NULL,
  157. UNIQUE KEY (id), KEY vh (val_hash)" . $val_index . "
  158. ) ". $this->getTableOptionsCode() . "
  159. ";
  160. return mysql_query($sql, $this->getDBCon());
  161. }
  162. function extendO2valTableColumns($suffix = 'o2val') {
  163. $sql = "
  164. ALTER TABLE " . $this->getTablePrefix() . $suffix . "
  165. MODIFY id int(10) UNSIGNED NOT NULL
  166. ";
  167. return mysql_query($sql, $this->getDBCon());
  168. }
  169. /* */
  170. function createSettingTable() {
  171. $sql = "
  172. CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "setting (
  173. k char(32) NOT NULL,
  174. val text NOT NULL,
  175. UNIQUE KEY (k)
  176. ) ". $this->getTableOptionsCode() . "
  177. ";
  178. return mysql_query($sql, $this->getDBCon());
  179. }
  180. /* */
  181. function extendColumns() {
  182. $con = $this->getDBCon();
  183. $tbl_prefix = $this->getTablePrefix();
  184. $tbls = $this->getTables();
  185. foreach ($tbls as $suffix) {
  186. if (preg_match('/^(triple|g2t|id2val|s2val|o2val)/', $suffix, $m)) {
  187. $mthd = 'extend' . ucfirst($m[1]) . 'TableColumns';
  188. $this->$mthd($suffix);
  189. }
  190. }
  191. }
  192. /* */
  193. function splitTables() {
  194. $old_ps = $this->getSetting('split_predicates', array());
  195. $new_ps = $this->retrieveSplitPredicates();
  196. $add_ps = array_diff($new_ps, $old_ps);
  197. $del_ps = array_diff($old_ps, $new_ps);
  198. $final_ps = array();
  199. foreach ($del_ps as $p) {
  200. if (!$this->unsplitPredicate($p)) $final_ps[] = $p;
  201. }
  202. foreach ($add_ps as $p) {
  203. if ($this->splitPredicate($p)) $final_ps[] = $p;
  204. }
  205. $this->setSetting('split_predicates', $new_ps);
  206. }
  207. function unsplitPredicate($p) {
  208. $suffix = 'triple_' . abs(crc32($p));
  209. $old_tbl = $this->getTablePrefix() . $suffix;
  210. $new_tbl = $this->getTablePrefix() . 'triple';
  211. $p_id = $this->getTermID($p, 'p');
  212. $con = $this->getDBCon();
  213. $sql = '
  214. INSERT IGNORE INTO ' . $new_tbl .'
  215. SELECT * FROM ' . $old_tbl . ' WHERE ' . $old_tbl . '.p = ' . $p_id . '
  216. ';
  217. if ($rs = mysql_query($sql, $con)) {
  218. mysql_query('DROP TABLE ' . $old_tbl, $con);
  219. return 1;
  220. }
  221. else {
  222. return 0;
  223. }
  224. }
  225. function splitPredicate($p) {
  226. $suffix = 'triple_' . abs(crc32($p));
  227. $this->createTripleTable($suffix);
  228. $old_tbl = $this->getTablePrefix() . 'triple';
  229. $new_tbl = $this->getTablePrefix() . $suffix;
  230. $p_id = $this->getTermID($p, 'p');
  231. $con = $this->getDBCon();
  232. $sql = '
  233. INSERT IGNORE INTO ' . $new_tbl .'
  234. SELECT * FROM ' . $old_tbl . ' WHERE ' . $old_tbl . '.p = ' . $p_id . '
  235. ';
  236. if ($rs = mysql_query($sql, $con)) {
  237. mysql_query('DELETE FROM ' . $old_tbl . ' WHERE ' . $old_tbl . '.p = ' . $p_id, $con);
  238. return 1;
  239. }
  240. else {
  241. mysql_query('DROP TABLE ' . $new_tbl, $con);
  242. return 0;
  243. }
  244. }
  245. function retrieveSplitPredicates() {
  246. $r = $this->split_predicates;
  247. $limit = $this->max_split_tables - count($r);
  248. $q = 'SELECT ?p COUNT(?p) AS ?pc WHERE { ?s ?p ?o } GROUP BY ?p ORDER BY DESC(?pc) LIMIT ' . $limit;
  249. $rows = $this->query($q, 'rows');
  250. foreach ($rows as $row) {
  251. $r[] = $row['p'];
  252. }
  253. return $r;
  254. }
  255. /* */
  256. }