3 * ARC2 RDF Store DELETE Query Handler
5 * @author Benjamin Nowack <bnowack@semsol.com>
6 * @license http://arc.semsol.org/license
7 * @homepage <http://arc.semsol.org/>
12 ARC2::inc('StoreQueryHandler');
14 class ARC2_StoreDeleteQueryHandler extends ARC2_StoreQueryHandler {
16 function __construct($a = '', &$caller) {/* caller has to be a store */
17 parent::__construct($a, $caller);
20 function ARC2_StoreDeleteQueryHandler($a = '', &$caller) {
21 $this->__construct($a, $caller);
24 function __init() {/* db_con */
26 $this->store =& $this->caller;
27 $this->handler_type = 'delete';
32 function runQuery($infos) {
33 $this->infos = $infos;
34 $con = $this->store->getDBCon();
37 $this->refs_deleted = false;
39 if (!$this->v('construct_triples', array(), $this->infos['query'])) {
40 $tc = $this->deleteTargetGraphs();
42 /* graph(s) + explicit triples */
43 elseif (!$this->v('pattern', array(), $this->infos['query'])) {
44 $tc = $this->deleteTriples();
46 /* graph(s) + constructed triples */
48 $tc = $this->deleteConstructedGraph();
52 if ($tc && ($this->refs_deleted || (rand(1, 100) == 1))) $this->cleanTableReferences();
53 if ($tc && (rand(1, 100) == 1)) $this->store->optimizeTables();
54 if ($tc && (rand(1, 500) == 1)) $this->cleanValueTables();
56 $index_dur = round($t3 - $t2, 4);
57 $dur = round($t3 - $t1, 4);
60 'delete_time' => $dur,
61 'index_update_time' => $index_dur,
67 function deleteTargetGraphs() {
68 $tbl_prefix = $this->store->getTablePrefix();
70 $con = $this->store->getDBCon();
71 foreach ($this->infos['query']['target_graphs'] as $g) {
72 if ($g_id = $this->getTermID($g, 'g')) {
73 $rs = mysql_query('DELETE FROM ' . $tbl_prefix . 'g2t WHERE g = ' .$g_id, $con);
74 $r += mysql_affected_rows($con);
77 $this->refs_deleted = $r ? 1 : 0;
83 function deleteTriples() {
85 $dbv = $this->store->getDBVersion();
86 $tbl_prefix = $this->store->getTablePrefix();
87 $con = $this->store->getDBCon();
88 /* graph restriction */
89 $tgs = $this->infos['query']['target_graphs'];
91 foreach ($tgs as $g) {
92 if ($g_id = $this->getTermID($g, 'g')) {
93 $gq .= $gq ? ', ' . $g_id : $g_id;
96 $gq = $gq ? ' AND G.g IN (' . $gq . ')' : '';
98 foreach ($this->infos['query']['construct_triples'] as $t) {
101 foreach (array('s', 'p', 'o') as $term) {
102 if (isset($t[$term . '_type']) && preg_match('/(var)/', $t[$term . '_type'])) {
106 $term_id = $this->getTermID($t[$term], $term);
107 $q .= ($q ? ' AND ' : '') . 'T.' . $term . '=' . $term_id;
108 /* explicit lang/dt restricts the matching */
110 $o_lang = $this->v1('o_lang', '', $t);
111 $o_lang_dt = $this->v1('o_datatype', $o_lang, $t);
113 $q .= ($q ? ' AND ' : '') . 'T.o_lang_dt=' . $this->getTermID($o_lang_dt, 'lang_dt');
122 $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'g2t' : 'DELETE G';
124 FROM ' . $tbl_prefix . 'g2t G
125 JOIN ' . $this->getTripleTable() . ' T ON (T.t = G.t' . $gq . ')
128 $this->refs_deleted = 1;
130 else {/* triples only */
131 $sql = ($dbv < '04-01') ? 'DELETE ' . $this->getTripleTable() : 'DELETE T';
132 $sql .= ' FROM ' . $this->getTripleTable() . ' T WHERE ' . $q;
134 $rs = mysql_query($sql, $con);
135 if ($er = mysql_error($con)) {
136 $this->addError($er .' in ' . $sql);
138 $r += mysql_affected_rows($con);
145 function deleteConstructedGraph() {
146 ARC2::inc('StoreConstructQueryHandler');
147 $h =& new ARC2_StoreConstructQueryHandler($this->a, $this->store);
148 $sub_r = $h->runQuery($this->infos);
149 $triples = ARC2::getTriplesFromIndex($sub_r);
150 $tgs = $this->infos['query']['target_graphs'];
151 $this->infos = array('query' => array('construct_triples' => $triples, 'target_graphs' => $tgs));
152 return $this->deleteTriples();
157 function cleanTableReferences() {
159 if (!$this->store->getLock()) return $this->addError('Could not get lock in "cleanTableReferences"');
160 $con = $this->store->getDBCon();
161 $tbl_prefix = $this->store->getTablePrefix();
162 $dbv = $this->store->getDBVersion();
163 /* check for unconnected triples */
165 SELECT T.t FROM '. $tbl_prefix . 'triple T LEFT JOIN '. $tbl_prefix . 'g2t G ON ( G.t = T.t )
166 WHERE G.t IS NULL LIMIT 1
168 if (($rs = mysql_query($sql, $con)) && mysql_num_rows($rs)) {
169 /* delete unconnected triples */
170 $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'triple' : 'DELETE T';
172 FROM ' . $tbl_prefix . 'triple T
173 LEFT JOIN ' . $tbl_prefix . 'g2t G ON (G.t = T.t)
176 mysql_query($sql, $con);
178 /* check for unconnected graph refs */
179 if ((rand(1, 10) == 1)) {
181 SELECT G.g FROM '. $tbl_prefix . 'g2t G LEFT JOIN '. $tbl_prefix . 'triple T ON ( T.t = G.t )
182 WHERE T.t IS NULL LIMIT 1
184 if (($rs = mysql_query($sql, $con)) && mysql_num_rows($rs)) {
185 /* delete unconnected graph refs */
186 $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'g2t' : 'DELETE G';
188 FROM ' . $tbl_prefix . 'g2t G
189 LEFT JOIN ' . $tbl_prefix . 'triple T ON (T.t = G.t)
192 mysql_query($sql, $con);
196 $this->store->releaseLock();
201 function cleanValueTables() {
203 if (!$this->store->getLock()) return $this->addError('Could not get lock in "cleanValueTables"');
204 $con = $this->store->getDBCon();
205 $tbl_prefix = $this->store->getTablePrefix();
206 $dbv = $this->store->getDBVersion();
208 $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'o2val' : 'DELETE V';
210 FROM ' . $tbl_prefix . 'o2val V
211 LEFT JOIN ' . $tbl_prefix . 'triple T ON (T.o = V.id)
214 mysql_query($sql, $con);
216 $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 's2val' : 'DELETE V';
218 FROM ' . $tbl_prefix . 's2val V
219 LEFT JOIN ' . $tbl_prefix . 'triple T ON (T.s = V.id)
222 mysql_query($sql, $con);
224 $sql = ($dbv < '04-01') ? 'DELETE ' . $tbl_prefix . 'id2val' : 'DELETE V';
226 FROM ' . $tbl_prefix . 'id2val V
227 LEFT JOIN ' . $tbl_prefix . 'g2t G ON (G.g = V.id)
228 LEFT JOIN ' . $tbl_prefix . 'triple T1 ON (T1.p = V.id)
229 LEFT JOIN ' . $tbl_prefix . 'triple T2 ON (T2.o_lang_dt = V.id)
230 WHERE G.g IS NULL AND T1.t IS NULL AND T2.t IS NULL
232 //mysql_query($sql, $con);