PageRenderTime 46ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/arc2/store/ARC2_StoreDeleteQueryHandler.php

https://bitbucket.org/rhiaro/public-notices-as-georss
PHP | 233 lines | 179 code | 18 blank | 36 comment | 32 complexity | 05e2565b37596bfc248d1eb9fd0d0f54 MD5 | raw file
  1. <?php
  2. /**
  3. * ARC2 RDF Store DELETE Query Handler
  4. *
  5. * @author Benjamin Nowack <bnowack@semsol.com>
  6. * @license http://arc.semsol.org/license
  7. * @homepage <http://arc.semsol.org/>
  8. * @package ARC2
  9. */
  10. ARC2::inc('StoreQueryHandler');
  11. class ARC2_StoreDeleteQueryHandler extends ARC2_StoreQueryHandler {
  12. function __construct($a, &$caller) {/* caller has to be a store */
  13. parent::__construct($a, $caller);
  14. }
  15. function __init() {/* db_con */
  16. parent::__init();
  17. $this->store = $this->caller;
  18. $this->handler_type = 'delete';
  19. }
  20. /* */
  21. function runQuery($infos) {
  22. $this->infos = $infos;
  23. $con = $this->store->getDBCon();
  24. $t1 = ARC2::mtime();
  25. /* delete */
  26. $this->refs_deleted = false;
  27. /* graph(s) only */
  28. if (!$this->v('construct_triples', array(), $this->infos['query'])) {
  29. $tc = $this->deleteTargetGraphs();
  30. }
  31. /* graph(s) + explicit triples */
  32. elseif (!$this->v('pattern', array(), $this->infos['query'])) {
  33. $tc = $this->deleteTriples();
  34. }
  35. /* graph(s) + constructed triples */
  36. else {
  37. $tc = $this->deleteConstructedGraph();
  38. }
  39. $t2 = ARC2::mtime();
  40. /* clean up */
  41. if ($tc && ($this->refs_deleted || (rand(1, 100) == 1))) $this->cleanTableReferences();
  42. if ($tc && (rand(1, 100) == 1)) $this->store->optimizeTables();
  43. if ($tc && (rand(1, 500) == 1)) $this->cleanValueTables();
  44. $t3 = ARC2::mtime();
  45. $index_dur = round($t3 - $t2, 4);
  46. $dur = round($t3 - $t1, 4);
  47. return array(
  48. 't_count' => $tc,
  49. 'delete_time' => $dur,
  50. 'index_update_time' => $index_dur,
  51. );
  52. }
  53. /* */
  54. function deleteTargetGraphs() {
  55. $tbl_prefix = $this->store->getTablePrefix();
  56. $r = 0;
  57. $con = $this->store->getDBCon();
  58. foreach ($this->infos['query']['target_graphs'] as $g) {
  59. if ($g_id = $this->getTermID($g, 'g')) {
  60. $rs = mysql_query('DELETE FROM ' . $tbl_prefix . 'g2t WHERE g = ' .$g_id, $con);
  61. $r += mysql_affected_rows($con);
  62. }
  63. }
  64. $this->refs_deleted = $r ? 1 : 0;
  65. return $r;
  66. }
  67. /* */
  68. function deleteTriples() {
  69. $r = 0;
  70. $dbv = $this->store->getDBVersion();
  71. $tbl_prefix = $this->store->getTablePrefix();
  72. $con = $this->store->getDBCon();
  73. /* graph restriction */
  74. $tgs = $this->infos['query']['target_graphs'];
  75. $gq = '';
  76. foreach ($tgs as $g) {
  77. if ($g_id = $this->getTermID($g, 'g')) {
  78. $gq .= $gq ? ', ' . $g_id : $g_id;
  79. }
  80. }
  81. $gq = $gq ? ' AND G.g IN (' . $gq . ')' : '';
  82. /* triples */
  83. foreach ($this->infos['query']['construct_triples'] as $t) {
  84. $q = '';
  85. $skip = 0;
  86. foreach (array('s', 'p', 'o') as $term) {
  87. if (isset($t[$term . '_type']) && preg_match('/(var)/', $t[$term . '_type'])) {
  88. //$skip = 1;
  89. }
  90. else {
  91. $term_id = $this->getTermID($t[$term], $term);
  92. $q .= ($q ? ' AND ' : '') . 'T.' . $term . '=' . $term_id;
  93. /* explicit lang/dt restricts the matching */
  94. if ($term == 'o') {
  95. $o_lang = $this->v1('o_lang', '', $t);
  96. $o_lang_dt = $this->v1('o_datatype', $o_lang, $t);
  97. if ($o_lang_dt) {
  98. $q .= ($q ? ' AND ' : '') . 'T.o_lang_dt=' . $this->getTermID($o_lang_dt, 'lang_dt');
  99. }
  100. }
  101. }
  102. }
  103. if ($skip) {
  104. continue;
  105. }
  106. if ($gq) {
  107. $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'g2t' : 'DELETE G';
  108. $sql .= '
  109. FROM ' . $tbl_prefix . 'g2t G
  110. JOIN ' . $this->getTripleTable() . ' T ON (T.t = G.t' . $gq . ')
  111. WHERE ' . $q . '
  112. ';
  113. $this->refs_deleted = 1;
  114. }
  115. else {/* triples only */
  116. $sql = ($dbv < '04-01') ? 'DELETE ' . $this->getTripleTable() : 'DELETE T';
  117. $sql .= ' FROM ' . $this->getTripleTable() . ' T WHERE ' . $q;
  118. }
  119. //$rs = mysql_query($sql, $con);
  120. $rs = $this->queryDB($sql, $con);
  121. if ($er = mysql_error($con)) {
  122. $this->addError($er .' in ' . $sql);
  123. }
  124. $r += mysql_affected_rows($con);
  125. }
  126. return $r;
  127. }
  128. /* */
  129. function deleteConstructedGraph() {
  130. ARC2::inc('StoreConstructQueryHandler');
  131. $h = new ARC2_StoreConstructQueryHandler($this->a, $this->store);
  132. $sub_r = $h->runQuery($this->infos);
  133. $triples = ARC2::getTriplesFromIndex($sub_r);
  134. $tgs = $this->infos['query']['target_graphs'];
  135. $this->infos = array('query' => array('construct_triples' => $triples, 'target_graphs' => $tgs));
  136. return $this->deleteTriples();
  137. }
  138. /* */
  139. function cleanTableReferences() {
  140. /* lock */
  141. if (!$this->store->getLock()) return $this->addError('Could not get lock in "cleanTableReferences"');
  142. $con = $this->store->getDBCon();
  143. $tbl_prefix = $this->store->getTablePrefix();
  144. $dbv = $this->store->getDBVersion();
  145. /* check for unconnected triples */
  146. $sql = '
  147. SELECT T.t FROM '. $tbl_prefix . 'triple T LEFT JOIN '. $tbl_prefix . 'g2t G ON ( G.t = T.t )
  148. WHERE G.t IS NULL LIMIT 1
  149. ';
  150. if (($rs = mysql_query($sql, $con)) && mysql_num_rows($rs)) {
  151. /* delete unconnected triples */
  152. $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'triple' : 'DELETE T';
  153. $sql .= '
  154. FROM ' . $tbl_prefix . 'triple T
  155. LEFT JOIN ' . $tbl_prefix . 'g2t G ON (G.t = T.t)
  156. WHERE G.t IS NULL
  157. ';
  158. mysql_query($sql, $con);
  159. }
  160. /* check for unconnected graph refs */
  161. if ((rand(1, 10) == 1)) {
  162. $sql = '
  163. SELECT G.g FROM '. $tbl_prefix . 'g2t G LEFT JOIN '. $tbl_prefix . 'triple T ON ( T.t = G.t )
  164. WHERE T.t IS NULL LIMIT 1
  165. ';
  166. if (($rs = mysql_query($sql, $con)) && mysql_num_rows($rs)) {
  167. /* delete unconnected graph refs */
  168. $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'g2t' : 'DELETE G';
  169. $sql .= '
  170. FROM ' . $tbl_prefix . 'g2t G
  171. LEFT JOIN ' . $tbl_prefix . 'triple T ON (T.t = G.t)
  172. WHERE T.t IS NULL
  173. ';
  174. mysql_query($sql, $con);
  175. }
  176. }
  177. /* release lock */
  178. $this->store->releaseLock();
  179. }
  180. /* */
  181. function cleanValueTables() {
  182. /* lock */
  183. if (!$this->store->getLock()) return $this->addError('Could not get lock in "cleanValueTables"');
  184. $con = $this->store->getDBCon();
  185. $tbl_prefix = $this->store->getTablePrefix();
  186. $dbv = $this->store->getDBVersion();
  187. /* o2val */
  188. $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'o2val' : 'DELETE V';
  189. $sql .= '
  190. FROM ' . $tbl_prefix . 'o2val V
  191. LEFT JOIN ' . $tbl_prefix . 'triple T ON (T.o = V.id)
  192. WHERE T.t IS NULL
  193. ';
  194. mysql_query($sql, $con);
  195. /* s2val */
  196. $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 's2val' : 'DELETE V';
  197. $sql .= '
  198. FROM ' . $tbl_prefix . 's2val V
  199. LEFT JOIN ' . $tbl_prefix . 'triple T ON (T.s = V.id)
  200. WHERE T.t IS NULL
  201. ';
  202. mysql_query($sql, $con);
  203. /* id2val */
  204. $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'id2val' : 'DELETE V';
  205. $sql .= '
  206. FROM ' . $tbl_prefix . 'id2val V
  207. LEFT JOIN ' . $tbl_prefix . 'g2t G ON (G.g = V.id)
  208. LEFT JOIN ' . $tbl_prefix . 'triple T1 ON (T1.p = V.id)
  209. LEFT JOIN ' . $tbl_prefix . 'triple T2 ON (T2.o_lang_dt = V.id)
  210. WHERE G.g IS NULL AND T1.t IS NULL AND T2.t IS NULL
  211. ';
  212. //mysql_query($sql, $con);
  213. }
  214. /* */
  215. }