/Erfurt/Store/Adapter/Mssql.php
PHP | 1570 lines | 1110 code | 287 blank | 173 comment | 168 complexity | b90729041084063ab0a90cd2ee082334 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- <?php
- require_once 'Erfurt/Store/Adapter/Interface.php';
- require_once 'Erfurt/Store/Sql/Interface.php';
- /**
- * Erfurt RDF Store - Adapter for the {@link http://www4.wiwiss.fu-berlin.de/bizer/rdfapi/ RAP} schema (modified) with
- * Zend_Db database abstraction layer.
- *
- * @package erfurt
- * @subpackage store
- * @author Philipp Frischmuth <pfrischmuth@googlemail.com>
- * @copyright Copyright (c) 2008 {@link http://aksw.org aksw}
- * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
- * @version $Id: RapZendDb.php 2532 2009-02-06 08:15:41Z pfrischmuth $
- */
- class Erfurt_Store_Adapter_Mssql implements Erfurt_Store_Adapter_Interface, Erfurt_Store_Sql_Interface
- {
- // ------------------------------------------------------------------------
- // --- Private properties -------------------------------------------------
- // ------------------------------------------------------------------------
- private $_modelCache = array();
- private $_modelInfoCache = null;
- private $_dbConn = false;
- /** @var array */
- private $_titleProperties = array(
- 'http://www.w3.org/2000/01/rdf-schema#label',
- 'http://purl.org/dc/elements/1.1/title'
- );
- // ------------------------------------------------------------------------
- // --- Magic methods ------------------------------------------------------
- // ------------------------------------------------------------------------
- /**
- * Constructor
- *
- * @param array $adapterOptions This adapter class needs the following parameters:
- * - 'host'
- * - 'username'
- * - 'password'
- * - 'dbname'
- */
- public function __construct($adapterOptions = array())
- {
- $adapter = $adapterOptions['dbtype'];
- $host = isset($adapterOptions['host']) ? $adapterOptions['host'] : 'localhost';
- $username = $adapterOptions['username'];
- $password = $adapterOptions['password'];
- $dbname = $adapterOptions['dbname'];
- $adapterOptions = array(
- 'host' => $host,
- 'username' => $username,
- 'password' => $password,
- 'dbname' => $dbname,
- 'profiler' => false
- );
- if (extension_loaded('sqlsrv')) {
- require_once 'Zend/Db/Adapter/Sqlsrv.php';
- $this->_dbConn = new Zend_Db_Adapter_Sqlsrv($adapterOptions);
- } else {
- require_once 'Erfurt/Exception.php';
- throw new Erfurt_Exception('Sqlsrv extension not found.', -1);
- }
- try {
- // try to initialize the connection
- $this->_dbConn->getConnection();
- } catch (Zend_Db_Adapter_Exception $e) {
- // maybe wrong login credentials or db-server not running?!
- require_once 'Erfurt/Exception.php';
- throw new Erfurt_Exception('Could not connect to database with name: "' . $dbname . '". Please check your credentials and whether the database exists and the server is running.', -1);
- } catch (Zend_Exception $e) {
- // maybe a needed php extension is not loaded?!
- require_once 'Erfurt/Exception.php';
- throw new Erfurt_Exception('An error with the specified database adapter occured.', -1);
- }
- // we want indexed results
- //$this->_dbConn->setFetchMode(Zend_Db::FETCH_NUM);
- // load title properties for model titles
- $config = Erfurt_App::getInstance()->getConfig();
- if (isset($config->properties->title)) {
- $this->_titleProperties = $config->properties->title->toArray();
- }
- }
- public function __destruct()
- {
- #$log = Erfurt_App::getInstance()->getLog();
- #$profiles = $this->_dbConn->getProfiler()->getQueryProfiles();
- #foreach ($profiles as $profile) {
- # $debugStr = 'Query: ' . $profile->getQuery() . PHP_EOL;
- # $debugStr .= 'Time: ' . $profile->getElapsedSecs() . PHP_EOL;
- #
- # $log->debug($debugStr);
- #}
- }
- // ------------------------------------------------------------------------
- // --- Public methods (derived from Erfurt_Store_Adapter_Abstract) --------
- // ------------------------------------------------------------------------
- /** @see Erfurt_Store_Adapter_Interface */
- public function addMultipleStatements($graphUri, array $statementsArray, array $options = array())
- {
- $modelInfoCache = $this->_getModelInfos();
- $graphId = $modelInfoCache[$graphUri]['modelId'];
- $sqlQuery = 'INSERT INTO ef_stmt (g,s,p,o,s_r,p_r,o_r,st,ot,ol,od,od_r) VALUES ';
- $insertArray = array();
- $counter = 0;
- foreach ($statementsArray as $subject => $predicatesArray) {
- foreach ($predicatesArray as $predicate => $objectsArray) {
- foreach ($objectsArray as $object) {
- $sqlString = '';
- $s = $subject;
- $p = $predicate;
- $o = $object;
- // check whether the subject is a blank node
- if (substr((string)$s, 0, 2) === '_:') {
- $s = substr((string)$s, 2);
- $subjectIs = '1';
- } else {
- $subjectIs = '0';
- }
- // check the type of the object
- if ($o['type'] === 'uri') {
- $objectIs = '0';
- $lang = false;
- $dType = false;
- } else if ($o['type'] === 'bnode') {
- if (substr((string)$o['value'], 0, 2) === '_:') {
- $o['value'] = substr((string)$o['value'], 2);
- }
- $objectIs = '1';
- $lang = false;
- $dType = false;
- } else {
- $objectIs = '2';
- $lang = isset($o['lang']) ? $o['lang'] : '';
- $dType = isset($o['datatype']) ? $o['datatype'] : '';
- }
- $sRef = false;
- if (strlen((string)$s) > $this->_getSchemaRefThreshold()) {
- $subjectHash = md5((string)$s);
- try {
- $sRef = $this->_insertValueInto('ef_uri', $graphId, $s, $subjectHash);
- } catch (Erfurt_Store_Adapter_Exception $e) {
- $this->_dbConn->rollback();
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception($e->getMessage());
- }
- $s = substr((string)$s, 0, 128) . $subjectHash;
- }
- $pRef = false;
- if (strlen((string)$p) > $this->_getSchemaRefThreshold()) {
- $predicateHash = md5((string)$p);
- try {
- $pRef = $this->_insertValueInto('ef_uri', $graphId, $p, $predicateHash);
- } catch (Erfurt_Store_Adapter_Exception $e) {
- $this->_dbConn->rollback();
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception($e->getMessage());
- }
- $p = substr((string)$p, 0, 128) . $predicateHash;
- }
- $oRef = false;
- if (strlen((string)$o['value']) > $this->_getSchemaRefThreshold()) {
- $objectHash = md5((string)$o['value']);
- if ($o['type'] === 'literal') {
- $tableName = 'ef_lit';
- } else {
- $tableName = 'ef_uri';
- }
- try {
- $oRef = $this->_insertValueInto($tableName, $graphId, $o['value'], $objectHash);
- } catch (Erfurt_Store_Adapter_Exception $e) {
- $this->_dbConn->rollback();
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception($e->getMessage());
- }
- $o['value'] = substr((string)$o['value'], 0, 128) . $objectHash;
- }
- $oValue = addslashes($o['value']);
- $sqlString .= "($graphId,'$s','$p','$oValue',";
- #$data = array(
- # 'g' => $graphId,
- # 's' => $subject,
- # 'p' => $predicate,
- # 'o' => $object['value'],
- # 'st' => $subjectIs,
- # 'ot' => $objectIs
- #);
- if ($sRef !== false) {
- $sqlString .= "$sRef,";
- } else {
- $sqlString .= "NULL,";
- }
- if ($pRef !== false) {
- $sqlString .= "$pRef,";
- } else {
- $sqlString .= "NULL,";
- }
- if ($oRef !== false) {
- $sqlString .= "$oRef,";
- } else {
- $sqlString .= "NULL,";
- }
- $sqlString .= "$subjectIs,$objectIs,'$lang',";
- #$data['ol'] = $lang;
- if (strlen((string)$dType) > $this->_getSchemaRefThreshold()) {
- $dTypeHash = md5((string)$dType);
- try {
- $dtRef = $this->_insertValueInto('ef_uri', $graphId, $dType, $dTypeHash);
- } catch (Erfurt_Store_Adapter_Exception $e) {
- $this->_dbConn->rollback();
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception($e->getMessage());
- }
- $dType = substr((string)$data['od'], 0, 128) . $dTypeHash;
- $data['od_r'] = $dtRef;
- $sqlString .= "'$dType',$dtRef)";
- } else {
- #$data['od'] = $dType;
- $sqlString .= "'$dType',NULL)";
- }
- // $insertArray[] = $sqlString;
- $counter++;
- $finalquery = 'IF NOT EXISTS(Select g, s, p, o, st, ot, ol, od from ef_stmt
- WHERE
- g = \''.$graphId.'\' AND
- s = \''.$s.'\' AND
- p = \''.$p.'\' AND
- o = \''.$oValue.'\' AND
- st = \''.$subjectIs.'\' AND
- ot = \''.$objectIs.'\' AND
- ol = \''.$lang.'\' AND
- od = \''.$dType.'\'
- )'.$sqlQuery. $sqlString;
- $this->sqlQuery((string)$finalquery);
-
- }
- }
- }
- if (defined('_EFDEBUG')) {
- $logger = Erfurt_App::getInstance()->getLog();
- $logger->info('ZendDb multiple statements added: ' . $counter);
- }
- if ($counter > 100) {
- $this->_optimizeTables();
- }
- }
- protected function _getNormalizedErrorCode()
- {
- if ($this->_dbConn instanceof Zend_Db_Adapter_Mysqli) {
- switch($this->_dbConn->getConnection()->errno) {
- case 1062:
- // duplicate entry
- return 1000;
- }
- } else {
- return -1;
- }
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function addStatement($graphUri, $subject, $predicate, $object, array $options = array())
- {
- $statementArray = array();
- $statementArray["$subject"] = array();
- $statementArray["$subject"]["$predicate"] = array();
- $statementArray["$subject"]["$predicate"][] = $object;
- try {
- $this->addMultipleStatements($graphUri, $statementArray);
- } catch (Erfurt_Store_Adapter_Exception $e) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Insertion of statement failed:' .
- $e->getMessage());
- }
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function countWhereMatches($graphIris, $whereSpec, $countSpec, $distinct = false)
- {
- $query = new Erfurt_Sparql_SimpleQuery();
- if(!$distinct){
- $query->setProloguePart("COUNT DISTINCT $countSpec"); // old way: distinct has no effect !!!
- } else {
- $query->setProloguePart("COUNT-DISTINCT $countSpec"); // i made a (unccol) hack to fix this, the "-" ist there because i didnt want to change tokenization
- }
- $query->setFrom($graphIris)
- ->setWherePart($whereSpec);
- $result = $this->sparqlQuery($query);
- if ($result) {
- return $result;
- }
- return 0;
- }
- /** @see Erfurt_Store_Sql_Interface */
- public function createTable($tableName, array $columns)
- {
- if ($this->_dbConn instanceof Zend_Db_Adapter_Mysqli) {
- return $this->_createTableMysql($tableName, $columns);
- }
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function createModel($graphUri, $type = Erfurt_Store::MODEL_TYPE_OWL)
- {
- $data = array(
- 'uri' => &$graphUri
- );
- $baseUri = $graphUri;
- if ($baseUri !== '') {
- $data['base'] = $baseUri;
- }
- // insert the new model into the database
- $this->_dbConn->insert('ef_graph', $data);
- $graphId = $this->lastInsertId();
- $uriRef = false;
- if (strlen($graphUri) > $this->_getSchemaRefThreshold()) {
- $uriHash = md5($uri);
- $uriData = array(
- 'g' => $graphid,
- 'v' => $uri,
- 'vh' => $uriHash);
- $uriRef = $this->_insertValueInto('ef_uri', $uriData);
- $updateData = array(
- 'uri' => $uriHash,
- 'uri_r' => $uriRef);
- $this->_dbConn->update('ef_graph', $updateData, "id = graphId");
- }
- $baseRef = false;
- if (strlen($baseUri) > $this->_getSchemaRefThreshold()) {
- $baseHash = md5($baseUri);
- $baseData = array(
- 'g' => $graphid,
- 'v' => $baseUri,
- 'vh' => $baseHash);
- $baseRef = $this->_insertValueInto('ef_uri', $baseData);
- $updateData = array(
- 'base' => $baseHash,
- 'base_r' => $baseRef);
- $this->_dbConn->update('ef_graph', $updateData, "id = graphId");
- }
- // invalidate the cache and fetch model infos again
- require_once 'Erfurt/App.php';
- $cache = Erfurt_App::getInstance()->getCache();
- $cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('model_info'));
- $this->_modelInfoCache = null;
- if ($type === Erfurt_Store::MODEL_TYPE_OWL) {
- $this->addStatement($graphUri, $graphUri, EF_RDF_TYPE, array('type' => 'uri', 'value' => EF_OWL_ONTOLOGY));
- $this->_modelInfoCache = null;
- }
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function deleteMatchingStatements($graphUri, $subject, $predicate, $object, array $options = array())
- {
- $modelInfoCache = $this->_getModelInfos();
- $modelId = $modelInfoCache[$graphUri]['modelId'];
- if ($subject !== null && strlen($subject) > $this->_getSchemaRefThreshold()) {
- $subject = substr($subject, 0, 128) . md5($subject);
- }
- if ($predicate !== null && strlen($predicate) > $this->_getSchemaRefThreshold()) {
- $predicate = substr($predicate, 0, 128) . md5($predicate);
- }
- if ($object !== null && strlen($object['value']) > $this->_getSchemaRefThreshold()) {
- $object = substr($object['value'], 0, 128) . md5($object['value']);
- }
- $operator = array('0' => '', '1' => 'AND');
- $firstparam = 0;
- // determine the rows, which should be deleted by the given parameters
- if ($subject !== null) {
- $whereString .= " $operator[$firstparam] s = '$subject'";
- $firstparam = 1;
- }
- if ($predicate !== null) {
- $whereString .= " $operator[$firstparam] p = '$predicate'";
- $firstparam = 1;
- }
- if (null !== $subject) {
- if (substr($subject, 0, 2) === '_:') {
- $whereString .= " $operator[$firstparam] st = 1";
- $firstparam = 1;
- } else {
- $whereString .= " $operator[$firstparam] st = 0";
- $firstparam = 1;
- }
- }
- if (null !== $object) {
- if (isset($object['value'])) {
- $whereString .= $operator[$firstparam]. 'o = \''.$object['value'].'\'';
- $firstparam = 1;
- }
- if (isset($object['type'])) {
- switch ($object['type']) {
- case 'uri':
- $whereString .= $operator[$firstparam].' ot = 0';
- $firstparam = 1;
- break;
- case 'literal':
- $whereString .= $operator[$firstparam].' ot = 2';
- $firstparam = 1;
- break;
- case 'bnode':
- $whereString .= $operator[$firstparam].' ot = 1';
- $firstparam = 1;
- break;
- }
- }
- if (isset($object['lang'])) {
- $whereString .= $operator[$firstparam].' ol = \''. $object['lang'] . '\'';
- $firstparam = 1;
- }
- if (isset($object['datatype'])) {
- if (strlen($object['datatype']) > $this->_getSchemaRefThreshold()) {
- $whereString .= $operator[$firstparam].' od = \'' . substr($object['datatype'], 0, 128) .
- md5($object['datatype']) . '\'';
- $firstparam = 1;
- } else {
- $whereString .= $operator[$firstparam].' od = \'' . $object['datatype'] . '\'';
- $firstparam = 1;
- }
- }
- }
- // remove the specified statements from the database
- $ret = $this->_dbConn->delete('ef_stmt', $whereString);
- // Clean up ef_uri and ef_lit table
- $this->_cleanUpValueTables($graphUri);
- // return number of affected rows (>0 means there were triples deleted)
- return $ret;
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function deleteMultipleStatements($graphUri, array $statementsArray)
- {
- $modelInfoCache = $this->_getModelInfos();
- $modelId = $modelInfoCache[$graphUri]['modelId'];
- $this->_dbConn->beginTransaction();
- try {
- foreach ($statementsArray as $subject => $predicatesArray) {
- foreach ($predicatesArray as $predicate => $objectsArray) {
- foreach ($objectsArray as $object) {
- $whereString = 'g = ' . $modelId . ' ';
- // check whether the subject is a blank node
- if (substr($subject, 0, 2) === '_:') {
- $subject = substr($subject, 2);
- $whereString .= 'AND st = 1 ';
- } else {
- $whereString .= 'AND st = 0 ';
- }
- // check the type of the object
- if ($object['type'] === 'uri') {
- $whereString .= 'AND ot = 0 ';
- } else if ($object['type'] === 'bnode') {
- $whereString .= 'AND ot = 1 ';
- } else {
- $whereString .= 'AND ot = 2 ';
- $whereString .= isset($object['lang']) ? 'AND ol = \'' . $object['lang'] . '\' ' : '';
- $whereString .= isset($object['datatype']) ? 'AND od = \'' . $object['datatype'] .
- '\' ' : '';
- }
- if (strlen((string)$subject) > $this->_getSchemaRefThreshold()) {
- $subjectHash = md5((string)$subject);
- $subject = substr((string)$subject, 0, 128) . $subjectHash;
- }
- if (strlen((string)$predicate) > $this->_getSchemaRefThreshold()) {
- $predicateHash = md5((string)$predicate);
- $predicate = substr((string)$predicate, 0, 128) . $predicateHash;
- }
- if (strlen((string)$object['value']) > $this->_getSchemaRefThreshold()) {
- $objectHash = md5((string)$object['value']);
- $object = substr((string)$object['value'], 0, 128) . $objectHash;
- } else {
- $object = $object['value'];
- }
- $whereString .= 'AND s = \'' . $subject . '\' ';
- $whereString .= 'AND p = \'' . $predicate . '\' ';
- $whereString .= 'AND o = \'' . str_replace('\'', '\\\'', $object) . '\' ';
- $this->_dbConn->delete('ef_stmt', $whereString);
- }
- }
- }
- // if everything went ok... commit the changes to the database
- $this->_dbConn->commit();
- $this->_cleanUpValueTables($graphUri);
- } catch (Exception $e) {
- // something went wrong... rollback
- $this->_dbConn->rollback();
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Bulk deletion of statements failed.'.$e->getMessage());
- }
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function deleteModel($graphUri)
- {
- $modelInfoCache = $this->_getModelInfos();
- if (isset($modelInfoCache[$graphUri]['modelId'])) {
- $graphId = $modelInfoCache[$graphUri]['modelId'];
- } else {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Model deletion failed: No db id found for model URL.');
- }
- // remove all rows with the specified modelID from the models, statements and namespaces tables
- $this->_dbConn->delete('ef_graph', "id = $graphId");
- $this->_dbConn->delete('ef_stmt', "g = $graphId");
- $this->_dbConn->delete('ef_uri', "g = $graphId");
- $this->_dbConn->delete('ef_lit', "g = $graphId");
- // invalidate the cache and fetch model infos again
- require_once 'Erfurt/App.php';
- $cache = Erfurt_App::getInstance()->getCache();
- $tags = array('model_info', $modelInfoCache[$graphUri]['modelId']);
- #$cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, $tags);
- $this->_modelCache = array();
- $this->_modelInfoCache = null;
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function exportRdf($modelIri, $serializationType = 'xml', $filename = false)
- {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Not implemented yet.');
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function getAvailableModels()
- {
- $modelInfoCache = $this->_getModelInfos();
- $models = array();
- foreach ($modelInfoCache as $mInfo) {
- $models[$mInfo['modelIri']] = true;
- }
- return $models;
- }
- public function getBackendName()
- {
- return 'ZendDb';
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function getBlankNodePrefix()
- {
- return 'bNode';
- }
- /**
- * Returns a list of graph uris, where each graph in the list contains at least
- * one statement where the given resource uri is subject.
- *
- * @param string $resourceUri
- * @return array
- */
- public function getGraphsUsingResource($resourceUri)
- {
- $sqlQuery = 'SELECT DISTINCT g.uri FROM ef_stmt s
- LEFT JOIN ef_graph g ON ( g.id = s.g)
- WHERE s.s = \'' . $resourceUri . '\'';
- $sqlResult = $this->sqlQuery($sqlQuery);
- $result = array();
- foreach ($sqlResult as $row) {
- $result[] = $row['uri'];
- }
- return $result;
- }
- /**
- * Recursively gets owl:imported model IRIs starting with $modelIri as root.
- *
- * @param string $modelIri
- */
- public function getImportsClosure($modelIri)
- {
- $modelInfoCache = $this->_getModelInfos();
- if (isset($modelInfoCache["$modelIri"]['imports'])) {
- return $modelInfoCache["$modelIri"]['imports'];
- } else {
- return array();
- }
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function getModel($modelIri)
- {
- // if model is already in cache return the cached value
- if (isset($this->_modelCache[$modelIri])) {
- return $this->_modelCache[$modelIri];
- }
- $modelInfoCache = $this->_getModelInfos();
- $baseUri = $modelInfoCache[$modelIri]['baseIri'];
- if ($baseUri === '') {
- $baseUri = null;
- }
- // choose the right type for the model instance and instanciate it
- if ($modelInfoCache[$modelIri]['type'] === 'owl') {
- require_once 'Erfurt/Owl/Model.php';
- $m = new Erfurt_Owl_Model($modelIri, $baseUri);
- } else if ($this->_modelInfoCache[$modelIri]['type'] === 'rdfs') {
- require_once 'Erfurt/Rdfs/Model.php';
- $m = new Erfurt_Rdfs_Model($modelIri, $baseUri);
- } else {
- require_once 'Erfurt/Rdf/Model.php';
- $m = new Erfurt_Rdf_Model($modelIri, $baseUri);
- }
- $this->_modelCache[$modelIri] = $m;
- return $m;
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function getNewModel($graphUri, $baseUri = '', $type = 'owl')
- {
- $data = array(
- 'uri' => &$graphUri
- );
- if ($baseUri !== '') {
- $data['base'] = $baseUri;
- }
- // insert the new model into the database
- $this->_dbConn->insert('ef_graph', $data);
- $graphId = $this->lastInsertId();
- $uriRef = false;
- if (strlen($graphUri) > $this->_getSchemaRefThreshold()) {
- $uriHash = md5($uri);
- $uriData = array(
- 'g' => $graphid,
- 'v' => $uri,
- 'vh' => $uriHash);
- $uriRef = $this->_insertValueInto('ef_uri', $uriData);
- $updateData = array(
- 'uri' => $uriHash,
- 'uri_r' => $uriRef);
- $this->_dbConn->update('ef_graph', $updateData, "id = graphId");
- }
- $baseRef = false;
- if (strlen($baseUri) > $this->_getSchemaRefThreshold()) {
- $baseHash = md5($baseUri);
- $baseData = array(
- 'g' => $graphid,
- 'v' => $baseUri,
- 'vh' => $baseHash);
- $baseRef = $this->_insertValueInto('ef_uri', $baseData);
- $updateData = array(
- 'base' => $baseHash,
- 'base_r' => $baseRef);
- $this->_dbConn->update('ef_graph', $updateData, "id = graphId");
- }
- // invalidate the cache and fetch model infos again
- require_once 'Erfurt/App.php';
- $cache = Erfurt_App::getInstance()->getCache();
- $cache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('model_info'));
- $this->_modelInfoCache = null;
- if ($type === 'owl') {
- $this->addStatement($graphUri, $graphUri, EF_RDF_TYPE, array('type' => 'uri', 'value' => EF_OWL_ONTOLOGY));
- $this->_modelInfoCache = null;
- }
- // instanciate the model
- $m = $this->getModel($graphUri);
- return $m;
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function getSupportedExportFormats()
- {
- return array();
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function getSupportedImportFormats()
- {
- return array();
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function importRdf($modelUri, $data, $type, $locator)
- {
- // TODO fix or remove
- if ($this->_dbConn instanceof Zend_Db_Adapter_Mysqli) {
- require_once 'Erfurt/Syntax/RdfParser.php';
- $parser = Erfurt_Syntax_RdfParser::rdfParserWithFormat($type);
- $parsedArray = $parser->parse($data, $locator, $modelUri, false);
- $modelInfoCache = $this->_getModelInfos();
- $modelId = $modelInfoCache["$modelUri"]['modelId'];
- // create file
- $tmpDir = Erfurt_App::getInstance()->getTmpDir();
- $filename = $tmpDir . 'import' . md5((string)time()) . '.csv';
- $fileHandle = fopen($filename, 'w');
- $count = 0;
- $longStatements = array();
- foreach ($parsedArray as $s => $pArray) {
- if (substr($s, 0, 2) === '_:') {
- $s = substr($s, 2);
- $sType = '1';
- } else {
- $sType = '0';
- }
- foreach ($pArray as $p => $oArray) {
- foreach ($oArray as $o) {
- // to long values need to be put in a different table, so we can't bulk insert these
- // values, for they need a foreign key
- if (strlen($s) > $this->_getSchemaRefThreshold() ||
- strlen($p) > $this->_getSchemaRefThreshold() ||
- strlen($o['value']) > $this->_getSchemaRefThreshold() ||
- (isset($o['datatype']) && strlen($o['datatype']) > $this->_getSchemaRefThreshold())) {
- $longStatements[] = array(
- 's' => $s,
- 'p' => $p,
- 'o' => $o
- );
- continue;
- }
- if ($o['type'] === 'literal') {
- $oType = '2';
- } else if ($o['type'] === 'bnode') {
- if (substr($o['value'], 0, 2) === '_:') {
- $o['value'] = substr($o['value'], 2);
- }
- $oType = '1';
- } else {
- $oType = '0';
- }
- $lineString = $modelId . ';' . $s . ';' . $p . ';' . $o['value'] . ';';
- $lineString .= "\N;\N;\N;";
- $lineString .= $sType . ';' . $oType . ';';
- if (isset($o['lang'])) {
- $lineString .= $o['lang'];
- } else {
- $lineString .= "\N";
- }
- $lineString .= ';';
- if (isset($o['datatype'])) {
- $lineString .= $o['datatype'] . ";\N";
- } else {
- $lineString .= "\N;\N";
- }
- $lineString .= PHP_EOL;
- $count++;
- fputs($fileHandle, $lineString);
- }
- }
- }
- fclose($fileHandle);
- if ($count > 10000) {
- $this->_dbConn->getConnection()->query('ALTER TABLE ef_stmt DISABLE KEYS');
- }
- $sql = "LOAD DATA INFILE '$filename' IGNORE INTO TABLE ef_stmt
- FIELDS TERMINATED BY ';'
- (g, s, p, o, s_r, p_r, o_r, st, ot, ol, od, od_r);";
- $this->_dbConn->getConnection()->query('START TRANSACTION;');
- $this->_dbConn->getConnection()->query($sql);
- $this->_dbConn->getConnection()->query('COMMIT');
- // Delete the temp file
- unlink($filename);
- // Now add the long-value-statements
- foreach($longStatements as $stm) {
- $sId = false;
- $pId = false;
- $oId = false;
- $dtId = false;
- $s = $stm['s'];
- $p = $stm['p'];
- $o = $stm['o']['value'];
- if (strlen($s) > $this->_getSchemaRefThreshold()) {
- $sHash = md5($s);
- $sId = $this->_insertValueInto('ef_uri', $modelId, $s, $sHash);
- $s = substr($s, 0, 128) . $sHash;
- }
- if (strlen($p) > $this->_getSchemaRefThreshold()) {
- $pHash = md5($p);
- $pId = $this->_insertValueInto('ef_uri', $modelId, $p, $pHash);
- $p = substr($p, 0, 128) . $pHash;
- }
- if (strlen($o) > $this->_getSchemaRefThreshold()) {
- $oHash = md5($o);
- if ($stm['o']['type'] === 'literal') {
- $oId = $this->_insertValueInto('ef_lit', $modelId, $o, $oHash);
- } else {
- $oId = $this->_insertValueInto('ef_uri', $modelId, $o, $oHash);
- }
- $o = substr($o, 0, 128) . $oHash;
- }
- if (isset($stm['o']['datatype']) && strlen($stm['o']['datatype']) > $this->_getSchemaRefThreshold()) {
- $oDtHash = md5($stm['o']['datatype']);
- $dtId = $this->_insertValueInto('ef_uri', $modelId, $stm['o']['datatype'], $oDtHash);
- $oDt = substr($oDt, 0, 128) . $oDtHash;
- }
- $sql = "INSERT INTO ef_stmt
- (g,s,p,o,s_r,p_r,o_r,st,ot,ol,od,od_r)
- VALUES ($modelId,'$s','$p','$o',";
- if ($sId !== false) {
- $sql .= $sId . ',';
- } else {
- $sql .= "NULL,";
- }
- if ($pId !== false) {
- $sql .= $pId . ',';
- } else {
- $sql .= "NULL,";
- }
- if ($oId !== false) {
- $sql .= $oId . ',';
- } else {
- $sql .= "NULL,";
- }
- if (substr($stm['s'], 0, 2) === '_:') {
- $sql .= '1,';
- } else {
- $sql .= '0,';
- }
- if ($stm['o']['type'] === 'literal') {
- $sql .= '2,';
- } else if ($stm['o']['type'] === 'uri') {
- $sql .= '0,';
- } else {
- $sql .= '1,';
- }
- if (isset($stm['o']['lang'])) {
- $sql .= '"' . $stm['o']['lang'] . '",';
- } else {
- $sql .= "NULL,";
- }
- if (isset($stm['o']['datatype'])) {
- if ($dtId !== false) {
- $sql .= '"' . $oDt . '",' . $dtId . ')';
- } else {
- $sql .= '"' . $stm['o']['datatype'] . '",' . "\N)";
- }
- } else {
- $sql .= "NULL,NULL)";
- }
- //$this->_dbConn->getConnection()->query($sql);
- }
- if ($count > 10000) {
- $this->_dbConn->getConnection()->query('ALTER TABLE ef_stmt ENABLE KEYS');
- }
- $this->_optimizeTables();
- } else {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('CSV import not supported for this database server.');
- }
- }
- public function init()
- {
- $this->_modelInfoCache = null;
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function isModelAvailable($modelIri)
- {
- $modelInfoCache = $this->_getModelInfos();
- if (isset($modelInfoCache[$modelIri])) {
- return true;
- } else {
- return false;
- }
- }
- /** @see Erfurt_Store_Sql_Interface */
- public function lastInsertId()
- {
- return $this->_dbConn->lastInsertId();
- }
- /** @see Erfurt_Store_Sql_Interface */
- public function listTables($prefix = '')
- {
- return $this->_dbConn->listTables();
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function sparqlAsk($query)
- {
- //TODO works for me...., why hasnt this be enabled earlier? is the same as sparqlQuery... looks like the engine supports it. but there is probably a reason for this not to be supported
- $start = microtime(true);
- require_once 'Erfurt/Sparql/EngineDb/Adapter/EfZendDb.php';
- $engine = new Erfurt_Sparql_EngineDb_Adapter_EfZendDb($this->_dbConn, $this->_getModelInfos());
- require_once 'Erfurt/Sparql/Parser.php';
- $parser = new Erfurt_Sparql_Parser();
- if(!($query instanceof Erfurt_Sparql_Query))
- $query = $parser->parse((string)$query);
- $result = $engine->queryModel($query);
- // Debug executed SPARQL queries in debug mode (7)
- $logger = Erfurt_App::getInstance()->getLog();
- $time = (microtime(true) - $start)*1000;
- $debugText = 'SPARQL Query (' . $time . ' ms)';
- $logger->debug($debugText);
- return $result;
- }
- /** @see Erfurt_Store_Adapter_Interface */
- public function sparqlQuery($query, $options=array())
- {
- $resultform =(isset($options[STORE_RESULTFORMAT]))?$options[STORE_RESULTFORMAT]:STORE_RESULTFORMAT_PLAIN;
- $start = microtime(true);
- require_once 'Erfurt/Sparql/EngineDb/Adapter/EfZendDb.php';
- $engine = new Erfurt_Sparql_EngineDb_Adapter_EfZendDb($this->_dbConn, $this->_getModelInfos());
- require_once 'Erfurt/Sparql/Parser.php';
- $parser = new Erfurt_Sparql_Parser();
- if(!($query instanceof Erfurt_Sparql_Query)) {
- $query = $parser->parse((string)$query);
- }
- $result = $engine->queryModel($query, $resultform);
- // Debug executed SPARQL queries in debug mode (7)
- $logger = Erfurt_App::getInstance()->getLog();
- $time = (microtime(true) - $start)*1000;
- $debugText = 'SPARQL Query (' . $time . ' ms)';
- $logger->debug($debugText);
- return $result;
- }
- /** @see Erfurt_Store_Sql_Interface */
- public function sqlQuery($sqlQuery, $limit = PHP_INT_MAX, $offset = 0)
- {
- $start = microtime(true);
- // add limit/offset
- if ($limit < PHP_INT_MAX) {
- $sqlQuery = sprintf('%s LIMIT %d OFFSET %d', (string)$sqlQuery, (int)$limit, (int)$offset);
- }
- $queryType = strtolower(substr($sqlQuery, 0, 6));
- if ( $queryType === 'insert' ||
- $queryType === 'update' ||
- $queryType === 'create' ||
- $queryType === 'if not' ||
- $queryType === 'delete') {
- // Handle without ZendDb
- $result = $this->_dbConn->query($sqlQuery);
- //SQLSRVCHANGE - Hack - result kommt immer falsch zurück - Queries werden aber ausgeführt....?
-
- if($result != NULL)
- {
- $result = true;
- }
- if ($result !== true) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception(/*var_dump($result).'<br>'.$sqlQuery.'<br>*/'SQL query failed: ' .
- $this->_dbConn->getConnection()->error);
- }
- } else {
- try {
- $result = $this->_dbConn->fetchAll($sqlQuery);
- //SQLSRV - Result ist immer true und es kommt keine Exception...
- } catch (Zend_Db_Exception $e) { #return false;
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception($e->getMessage());
- }
- }
- // Debug executed SQL queries in debug mode (7)
- $logger = Erfurt_App::getInstance()->getLog();
- $time = (microtime(true) - $start)*1000;
- $debugText = 'SQL Query (' . $time . ' ms)';
- $logger->debug($debugText);
- return $result;
- }
- // ------------------------------------------------------------------------
- // --- Private methods ----------------------------------------------------
- // ------------------------------------------------------------------------
- /**
- * @throws Erfurt_Exception Throws exception if something goes wrong while initialization of database.
- */
- private function _createTables()
- {
- return $this->_createTablesSqlsrv();
- }
- /**
- * This internal function creates the table structure for MS SQL Server databases.
- */
- private function _createTablesSqlsrv()
- {
- //#####################################################################
- // Create table ef_info if not existing
- $sqlsrv ='IF NOT EXISTS
- ( SELECT * FROM SysObjects WHERE [Name] = \'ef_info\')
- CREATE TABLE ef_info (
- id TINYINT NOT NULL IDENTITY(1,1),
- schema_id VARCHAR(10) COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL
- ) ON [PRIMARY]';
- $success = $this->_dbConn->query($sqlsrv);
- if (!$success) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Creation of table "ef_info" failed: ' .
- $this->_dbConn->getConnection()->error);
- }
- // Insert id of the current schema into the ef_info table.
- $sql = 'INSERT INTO ef_info (schema_id) VALUES (1.0)';
- $success = false;
- $success = $this->_dbConn->query($sql);
- if (!$success) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Insertion of "schema_id" into "ef_info" failed: ' .
- $this->_dbConn->getConnection()->error);
- }
- //#####################################################################
- // Create table ef_graph if not existing
- $sqlsrv ='IF NOT EXISTS
- ( SELECT * FROM SysObjects WHERE [Name] = \'ef_graph\')
- BEGIN
- CREATE TABLE ef_graph (
- id TINYINT NOT NULL IDENTITY(1,1),
- uri VARCHAR(160)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- uri_r INT NULL,
- base VARCHAR(160)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- base_r INT NULL
- ) ON [PRIMARY]
- CREATE UNIQUE INDEX unique_uri ON ef_graph (uri)
- END';
- $success = $this->_dbConn->query($sqlsrv);
- if (!$success) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Creation of table "ef_info" failed: ' .
- $this->_dbConn->getConnection()->error);
- }
- //#####################################################################
- // Create table ef_stmt if not existing
- $sqlsrv ='IF NOT EXISTS
- ( SELECT * FROM SysObjects WHERE [Name] = \'ef_stmt\')
- BEGIN
- CREATE TABLE ef_stmt (
- id TINYINT NOT NULL IDENTITY(1,1),
- g INT NOT NULL,
- s VARCHAR(160)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- p VARCHAR(160)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- o VARCHAR(160)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- s_r INT DEFAULT NULL,
- p_r INT DEFAULT NULL,
- o_r INT DEFAULT NULL,
- st TINYINT NOT NULL,
- ot TINYINT NOT NULL,
- ol VARCHAR(50)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- od VARCHAR(160)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- od_r INT DEFAULT NULL,
- ) ON [PRIMARY]
- CREATE UNIQUE NONCLUSTERED INDEX unique_stmt ON ef_stmt (g,s,p,o,st,ot,ol,od)
- CREATE NONCLUSTERED INDEX idx_g_p_o_ot ON ef_stmt (g, p, o, ot)
- CREATE NONCLUSTERED INDEX idx_g_o_ot ON ef_stmt (g, o, ot)
- END';
- $success = $this->_dbConn->query($sqlsrv);
- if (!$success) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Creation of table "ef_info" failed: ' .
- $this->_dbConn->getConnection()->error);
- }
- //#####################################################################
- // Create table ef_uri if not existing
- $sqlsrv ='IF NOT EXISTS
- ( SELECT * FROM SysObjects WHERE [Name] = \'ef_uri\')
- BEGIN
- CREATE TABLE ef_uri (
- id TINYINT NOT NULL IDENTITY(1,1),
- g INT NOT NULL,
- v TEXT COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- vh VARCHAR(32)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL
- ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
- CREATE UNIQUE NONCLUSTERED INDEX unique_uri ON ef_uri (g,vh)
- END';
- $success = $this->_dbConn->query($sqlsrv);
- if (!$success) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Creation of table "ef_uri" failed: ' .
- $this->_dbConn->getConnection()->error);
- }
- //#####################################################################
- // Create table ef_lit if not existing
- //v would b UTF8 - not shure if SQL_Latin1_general_CP850_bin is the right type
- $sqlsrv ='IF NOT EXISTS
- ( SELECT * FROM SysObjects WHERE [Name] = \'ef_lit\')
- BEGIN
- CREATE TABLE ef_lit (
- id TINYINT NOT NULL IDENTITY(1,1),
- g INT NOT NULL,
- v TEXT COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL,
- vh VARCHAR(32)COLLATE SQL_Latin1_General_CP1_CS_AS NOT NULL
- ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
- CREATE UNIQUE NONCLUSTERED INDEX unique_lit ON ef_lit (g,vh)
- END';
- $success = $this->_dbConn->query($sqlsrv);
- if (!$success) {
- require_once 'Erfurt/Store/Adapter/Exception.php';
- throw new Erfurt_Store_Adapter_Exception('Creation of table "ef_uri" failed: ' .
- $this->_dbConn->getConnection()->error);
- }
- }
- protected function _getModelInfos()
- {
- if (null === $this->_modelInfoCache) {
- try {
- // try to fetch model and namespace infos... if all tables are present this should not lead to an error.
- $this->_fetchModelInfos();
- } catch (Erfurt_Exception $e) {
- // error while fetching model and namespace infos... should only be the case if the tables aren't present,
- // for db connection is already established (in constructor)... so let's check for tables
- if (!$this->_isSetup()) {
- $this->_createTables();
- try {
- Erfurt_App::getInstance()->getStore()->checkSetup();
- …
Large files files are truncated, but you can click here to view the full file