danielebarchiesi@4: engine_type = $this->v('store_engine_type', 'MyISAM', $this->a); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function getTableOptionsCode() { danielebarchiesi@4: $v = $this->getDBVersion(); danielebarchiesi@4: $r = ""; danielebarchiesi@4: $r .= (($v < '04-01-00') && ($v >= '04-00-18')) ? 'ENGINE' : (($v >= '04-01-02') ? 'ENGINE' : 'TYPE'); danielebarchiesi@4: $r .= "=" . $this->engine_type; danielebarchiesi@4: $r .= ($v >= '04-00-00') ? " CHARACTER SET utf8" : ""; danielebarchiesi@4: $r .= ($v >= '04-01-00') ? " COLLATE utf8_unicode_ci" : ""; danielebarchiesi@4: $r .= " DELAY_KEY_WRITE = 1"; danielebarchiesi@4: return $r; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function createTables() { danielebarchiesi@4: $con = $this->getDBCon(); danielebarchiesi@4: if(!$this->createTripleTable()) { danielebarchiesi@4: return $this->addError('Could not create "triple" table (' . mysql_error($con) . ').'); danielebarchiesi@4: } danielebarchiesi@4: if(!$this->createG2TTable()) { danielebarchiesi@4: return $this->addError('Could not create "g2t" table (' . mysql_error($con) . ').'); danielebarchiesi@4: } danielebarchiesi@4: if(!$this->createID2ValTable()) { danielebarchiesi@4: return $this->addError('Could not create "id2val" table (' . mysql_error($con) . ').'); danielebarchiesi@4: } danielebarchiesi@4: if(!$this->createS2ValTable()) { danielebarchiesi@4: return $this->addError('Could not create "s2val" table (' . mysql_error($con) . ').'); danielebarchiesi@4: } danielebarchiesi@4: if(!$this->createO2ValTable()) { danielebarchiesi@4: return $this->addError('Could not create "o2val" table (' . mysql_error($con) . ').'); danielebarchiesi@4: } danielebarchiesi@4: if(!$this->createSettingTable()) { danielebarchiesi@4: return $this->addError('Could not create "setting" table (' . mysql_error($con) . ').'); danielebarchiesi@4: } danielebarchiesi@4: return 1; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function createTripleTable($suffix = 'triple') { danielebarchiesi@4: /* keep in sync with merge def in StoreQueryHandler ! */ danielebarchiesi@4: $indexes = $this->v('store_indexes', array('sp (s,p)', 'os (o,s)', 'po (p,o)'), $this->a); danielebarchiesi@4: $index_code = $indexes ? 'KEY ' . join(', KEY ', $indexes) . ', ' : ''; danielebarchiesi@4: $sql = " danielebarchiesi@4: CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . $suffix . " ( danielebarchiesi@4: t mediumint UNSIGNED NOT NULL, danielebarchiesi@4: s mediumint UNSIGNED NOT NULL, danielebarchiesi@4: p mediumint UNSIGNED NOT NULL, danielebarchiesi@4: o mediumint UNSIGNED NOT NULL, danielebarchiesi@4: o_lang_dt mediumint UNSIGNED NOT NULL, danielebarchiesi@4: o_comp char(35) NOT NULL, /* normalized value for ORDER BY operations */ danielebarchiesi@4: s_type tinyint(1) NOT NULL default 0, /* uri/bnode => 0/1 */ danielebarchiesi@4: o_type tinyint(1) NOT NULL default 0, /* uri/bnode/literal => 0/1/2 */ danielebarchiesi@4: misc tinyint(1) NOT NULL default 0, /* temporary flags */ danielebarchiesi@4: UNIQUE KEY (t), " . $index_code . " KEY (misc) danielebarchiesi@4: ) ". $this->getTableOptionsCode() . " danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function extendTripleTableColumns($suffix = 'triple') { danielebarchiesi@4: $sql = " danielebarchiesi@4: ALTER TABLE " . $this->getTablePrefix() . $suffix . " danielebarchiesi@4: MODIFY t int(10) UNSIGNED NOT NULL, danielebarchiesi@4: MODIFY s int(10) UNSIGNED NOT NULL, danielebarchiesi@4: MODIFY p int(10) UNSIGNED NOT NULL, danielebarchiesi@4: MODIFY o int(10) UNSIGNED NOT NULL, danielebarchiesi@4: MODIFY o_lang_dt int(10) UNSIGNED NOT NULL danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function createG2TTable() { danielebarchiesi@4: $sql = " danielebarchiesi@4: CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "g2t ( danielebarchiesi@4: g mediumint UNSIGNED NOT NULL, danielebarchiesi@4: t mediumint UNSIGNED NOT NULL, danielebarchiesi@4: UNIQUE KEY gt (g,t), KEY tg (t,g) danielebarchiesi@4: ) ". $this->getTableOptionsCode() . " danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function extendG2tTableColumns($suffix = 'g2t') { danielebarchiesi@4: $sql = " danielebarchiesi@4: ALTER TABLE " . $this->getTablePrefix() . $suffix . " danielebarchiesi@4: MODIFY g int(10) UNSIGNED NOT NULL, danielebarchiesi@4: MODIFY t int(10) UNSIGNED NOT NULL danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function createID2ValTable() { danielebarchiesi@4: $sql = " danielebarchiesi@4: CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "id2val ( danielebarchiesi@4: id mediumint UNSIGNED NOT NULL, danielebarchiesi@4: misc tinyint(1) NOT NULL default 0, danielebarchiesi@4: val text NOT NULL, danielebarchiesi@4: val_type tinyint(1) NOT NULL default 0, /* uri/bnode/literal => 0/1/2 */ danielebarchiesi@4: UNIQUE KEY (id,val_type), KEY v (val(64)) danielebarchiesi@4: ) ". $this->getTableOptionsCode() . " danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function extendId2valTableColumns($suffix = 'id2val') { danielebarchiesi@4: $sql = " danielebarchiesi@4: ALTER TABLE " . $this->getTablePrefix() . $suffix . " danielebarchiesi@4: MODIFY id int(10) UNSIGNED NOT NULL danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function createS2ValTable() { danielebarchiesi@4: //$indexes = 'UNIQUE KEY (id), KEY vh (val_hash), KEY v (val(64))'; danielebarchiesi@4: $indexes = 'UNIQUE KEY (id), KEY vh (val_hash)'; danielebarchiesi@4: $sql = " danielebarchiesi@4: CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "s2val ( danielebarchiesi@4: id mediumint UNSIGNED NOT NULL, danielebarchiesi@4: misc tinyint(1) NOT NULL default 0, danielebarchiesi@4: val_hash char(32) NOT NULL, danielebarchiesi@4: val text NOT NULL, danielebarchiesi@4: " . $indexes . " danielebarchiesi@4: ) " . $this->getTableOptionsCode() . " danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function extendS2valTableColumns($suffix = 's2val') { danielebarchiesi@4: $sql = " danielebarchiesi@4: ALTER TABLE " . $this->getTablePrefix() . $suffix . " danielebarchiesi@4: MODIFY id int(10) UNSIGNED NOT NULL danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function createO2ValTable() { danielebarchiesi@4: /* object value index, e.g. "KEY v (val(64))" and/or "FULLTEXT KEY vft (val)" */ danielebarchiesi@4: $val_index = $this->v('store_object_index', 'KEY v (val(64))', $this->a); danielebarchiesi@4: if ($val_index) $val_index = ', ' . ltrim($val_index, ','); danielebarchiesi@4: $sql = " danielebarchiesi@4: CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "o2val ( danielebarchiesi@4: id mediumint UNSIGNED NOT NULL, danielebarchiesi@4: misc tinyint(1) NOT NULL default 0, danielebarchiesi@4: val_hash char(32) NOT NULL, danielebarchiesi@4: val text NOT NULL, danielebarchiesi@4: UNIQUE KEY (id), KEY vh (val_hash)" . $val_index . " danielebarchiesi@4: ) ". $this->getTableOptionsCode() . " danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function extendO2valTableColumns($suffix = 'o2val') { danielebarchiesi@4: $sql = " danielebarchiesi@4: ALTER TABLE " . $this->getTablePrefix() . $suffix . " danielebarchiesi@4: MODIFY id int(10) UNSIGNED NOT NULL danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function createSettingTable() { danielebarchiesi@4: $sql = " danielebarchiesi@4: CREATE TABLE IF NOT EXISTS " . $this->getTablePrefix() . "setting ( danielebarchiesi@4: k char(32) NOT NULL, danielebarchiesi@4: val text NOT NULL, danielebarchiesi@4: UNIQUE KEY (k) danielebarchiesi@4: ) ". $this->getTableOptionsCode() . " danielebarchiesi@4: "; danielebarchiesi@4: return mysql_query($sql, $this->getDBCon()); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function extendColumns() { danielebarchiesi@4: $con = $this->getDBCon(); danielebarchiesi@4: $tbl_prefix = $this->getTablePrefix(); danielebarchiesi@4: $tbls = $this->getTables(); danielebarchiesi@4: foreach ($tbls as $suffix) { danielebarchiesi@4: if (preg_match('/^(triple|g2t|id2val|s2val|o2val)/', $suffix, $m)) { danielebarchiesi@4: $mthd = 'extend' . ucfirst($m[1]) . 'TableColumns'; danielebarchiesi@4: $this->$mthd($suffix); danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: function splitTables() { danielebarchiesi@4: $old_ps = $this->getSetting('split_predicates', array()); danielebarchiesi@4: $new_ps = $this->retrieveSplitPredicates(); danielebarchiesi@4: $add_ps = array_diff($new_ps, $old_ps); danielebarchiesi@4: $del_ps = array_diff($old_ps, $new_ps); danielebarchiesi@4: $final_ps = array(); danielebarchiesi@4: foreach ($del_ps as $p) { danielebarchiesi@4: if (!$this->unsplitPredicate($p)) $final_ps[] = $p; danielebarchiesi@4: } danielebarchiesi@4: foreach ($add_ps as $p) { danielebarchiesi@4: if ($this->splitPredicate($p)) $final_ps[] = $p; danielebarchiesi@4: } danielebarchiesi@4: $this->setSetting('split_predicates', $new_ps); danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function unsplitPredicate($p) { danielebarchiesi@4: $suffix = 'triple_' . abs(crc32($p)); danielebarchiesi@4: $old_tbl = $this->getTablePrefix() . $suffix; danielebarchiesi@4: $new_tbl = $this->getTablePrefix() . 'triple'; danielebarchiesi@4: $p_id = $this->getTermID($p, 'p'); danielebarchiesi@4: $con = $this->getDBCon(); danielebarchiesi@4: $sql = ' danielebarchiesi@4: INSERT IGNORE INTO ' . $new_tbl .' danielebarchiesi@4: SELECT * FROM ' . $old_tbl . ' WHERE ' . $old_tbl . '.p = ' . $p_id . ' danielebarchiesi@4: '; danielebarchiesi@4: if ($rs = mysql_query($sql, $con)) { danielebarchiesi@4: mysql_query('DROP TABLE ' . $old_tbl, $con); danielebarchiesi@4: return 1; danielebarchiesi@4: } danielebarchiesi@4: else { danielebarchiesi@4: return 0; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function splitPredicate($p) { danielebarchiesi@4: $suffix = 'triple_' . abs(crc32($p)); danielebarchiesi@4: $this->createTripleTable($suffix); danielebarchiesi@4: $old_tbl = $this->getTablePrefix() . 'triple'; danielebarchiesi@4: $new_tbl = $this->getTablePrefix() . $suffix; danielebarchiesi@4: $p_id = $this->getTermID($p, 'p'); danielebarchiesi@4: $con = $this->getDBCon(); danielebarchiesi@4: $sql = ' danielebarchiesi@4: INSERT IGNORE INTO ' . $new_tbl .' danielebarchiesi@4: SELECT * FROM ' . $old_tbl . ' WHERE ' . $old_tbl . '.p = ' . $p_id . ' danielebarchiesi@4: '; danielebarchiesi@4: if ($rs = mysql_query($sql, $con)) { danielebarchiesi@4: mysql_query('DELETE FROM ' . $old_tbl . ' WHERE ' . $old_tbl . '.p = ' . $p_id, $con); danielebarchiesi@4: return 1; danielebarchiesi@4: } danielebarchiesi@4: else { danielebarchiesi@4: mysql_query('DROP TABLE ' . $new_tbl, $con); danielebarchiesi@4: return 0; danielebarchiesi@4: } danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: function retrieveSplitPredicates() { danielebarchiesi@4: $r = $this->split_predicates; danielebarchiesi@4: $limit = $this->max_split_tables - count($r); danielebarchiesi@4: $q = 'SELECT ?p COUNT(?p) AS ?pc WHERE { ?s ?p ?o } GROUP BY ?p ORDER BY DESC(?pc) LIMIT ' . $limit; danielebarchiesi@4: $rows = $this->query($q, 'rows'); danielebarchiesi@4: foreach ($rows as $row) { danielebarchiesi@4: $r[] = $row['p']; danielebarchiesi@4: } danielebarchiesi@4: return $r; danielebarchiesi@4: } danielebarchiesi@4: danielebarchiesi@4: /* */ danielebarchiesi@4: danielebarchiesi@4: }