source: pmb4.2/trunk/fuentes/pmb/classes/rdf/arc2/store/ARC2_StoreTableManager.php @ 815

Last change on this file since 815 was 815, checked in by jrpelegrina, 4 years ago

Initial release of pmb 4.2

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