Source for file DbStore.php

Documentation is available at DbStore.php

  1. <?php
  2.  
  3. // ----------------------------------------------------------------------------------
  4. // Class: DbStore
  5. // ----------------------------------------------------------------------------------
  6.  
  7.  
  8.  
  9. /**
  10. * DbStore is a persistent store of RDF data using relational database technology.
  11. * DbStore uses ADOdb Library for PHP V3.60 (http://php.weblogs.com/ADODB),
  12. * which allows to connect to multiple databases in a portable manner.
  13. * This class also provides methods for creating tables for MsAccess, MySQL, and MS SQL Server.
  14. * If you want to use other databases, you will have to create tables by yourself
  15. * according to the abstract database schema described in the API documentation.
  16. *
  17. * <BR><BR>History:<UL>
  18. * <LI>12-06-2004 : improved namespace handling added (tobias.gauss@web.de)</LI>
  19. * <LI>10-19-2004 : _isSetup_MSSQL() added. tobias.gauss@web.de</LI>
  20. * <LI>09-02-2004 : _isSetup_MySql() and _isSetupMsAccess() added. ggrimnes@csd.abdn.ac.uk/ tobias.gauss@web.de</LI>
  21. * <LI>06-17-2003 : First version of this class</LI>
  22. *
  23. *
  24. * @version V0.9.1
  25. * @author Radoslaw Oldakowski <radol@gmx.de>
  26. *
  27. * @package model
  28. * @access public
  29. */
  30.  
  31.  
  32. class DbStore extends Object{
  33.  
  34. /**
  35. * Database connection object
  36. *
  37. * @var object ADOConnection
  38. * @access private
  39. */
  40. var $dbConn;
  41.  
  42.  
  43. /**
  44. * Constructor:
  45. * Set the database connection with the given parameters.
  46. *
  47. * @param string $dbDriver
  48. * @param string $host
  49. * @param string $dbName
  50. * @param string $user
  51. * @param string $password
  52. * @access public
  53. */
  54. function DbStore ($dbDriver=ADODB_DB_DRIVER, $host=ADODB_DB_HOST, $dbName=ADODB_DB_NAME,
  55. $user=ADODB_DB_USER, $password=ADODB_DB_PASSWORD) {
  56. // include DBase Package
  57. require_once(RDFAPI_INCLUDE_DIR.PACKAGE_DBASE);
  58. // create a new connection object
  59. $this->dbConn =& ADONewConnection($dbDriver);
  60. // connect to database
  61. $this->dbConn->connect($host, $user, $password, $dbName);
  62. // optimized for speed
  63. $this->dbConn->setFetchMode(ADODB_FETCH_NUM);
  64. $ADODB_COUNTRECS = FALSE;
  65. //activate the ADOdb DEBUG mode
  66. if (ADODB_DEBUG_MODE =='1')
  67. $this->dbConn->debug = TRUE;
  68. }
  69.  
  70.  
  71. /**
  72. * Create tables and indexes for the given database type.
  73. * Currently supported: MsAccess and MySQL.
  74. * If you want to use other databases, you will have to create tables by yourself
  75. * according to the abstract <a href="database_schema.html">database schema</a>
  76. * described in the API documentation.
  77. *
  78. * @param string $databaseType
  79. * @throws PhpError
  80. * @access public
  81. */
  82. function createTables($databaseType) {
  83.  
  84. if (!strcasecmp($databaseType, 'MsAccess'))
  85. $this->_createTables_MsAccess();
  86. elseif (!strcasecmp($databaseType, 'MySQL'))
  87. $this->_createTables_MySql();
  88. elseif (!strcasecmp($databaseType, 'MSSQL'))
  89. $this->_createTables_mssql();
  90. else {
  91. $errmsg = RDFAPI_ERROR . "(class: DbStore; method: createTables('$databaseType')):
  92. Currently only MsAcces, MySQL and MSSQL supported.";
  93. trigger_error($errmsg, E_USER_ERROR);
  94. }
  95. }
  96.  
  97. /**
  98. * List all DbModels stored in the database.
  99. *
  100. * @return array
  101. * @throws SqlError
  102. * @access public
  103. */
  104. function listModels() {
  105.  
  106. $recordSet =& $this->dbConn->execute("SELECT modelURI, baseURI
  107. FROM models");
  108. if (!$recordSet)
  109. echo $this->dbConn->errorMsg();
  110. else {
  111. $models = array();
  112. $i=0;
  113. while (!$recordSet->EOF) {
  114.  
  115. $models[$i]['modelURI'] = $recordSet->fields[0];
  116. $models[$i]['baseURI'] = $recordSet->fields[1];
  117. ++$i;
  118. $recordSet->moveNext();
  119. }
  120. return $models;
  121. }
  122. }
  123. /**
  124. * Check if the DbModel with the given modelURI is already stored in the database
  125. *
  126. * @param string $modelURI
  127. * @return boolean
  128. * @throws SqlError
  129. * @access public
  130. */
  131. function modelExists($modelURI) {
  132.  
  133. $res =& $this->dbConn->execute("SELECT COUNT(*) FROM models
  134. WHERE modelURI = '" .$modelURI ."'");
  135. if (!$res)
  136. echo $this->dbConn->errorMsg();
  137. else {
  138. if (!$res->fields[0])
  139. return FALSE;
  140. return TRUE;
  141. }
  142. }
  143.  
  144.  
  145. /**
  146. * Create a new instance of DbModel with the given $modelURI and
  147. * load the corresponding values of modelID and baseURI from the database.
  148. * Return FALSE if the DbModel does not exist.
  149. *
  150. * @param string $modelURI
  151. * @return object DbModel
  152. * @access public
  153. */
  154. function getModel($modelURI) {
  155.  
  156. if (!$this->modelExists($modelURI))
  157. return FALSE;
  158. else {
  159. $modelVars =& $this->dbConn->execute("SELECT modelURI, modelID, baseURI
  160. FROM models
  161. WHERE modelURI='" .$modelURI ."'");
  162.  
  163. return new DbModel($this->dbConn, $modelVars->fields[0],
  164. $modelVars->fields[1], $modelVars->fields[2]);
  165. }
  166. }
  167.  
  168.  
  169. /**
  170. * Create a new instance of DbModel with the given $modelURI
  171. * and insert the DbModel variables into the database.
  172. * Return FALSE if there is already a model with the given URI.
  173. *
  174. * @param string $modelURI
  175. * @param string $baseURI
  176. * @return object DbModel
  177. * @throws SqlError
  178. * @access public
  179. */
  180. function getNewModel($modelURI, $baseURI=NULL) {
  181.  
  182. if ($this->modelExists($modelURI))
  183. return FALSE;
  184. else {
  185. $modelID = $this->_createUniqueModelID();
  186. $rs =& $this->dbConn->execute("INSERT INTO models
  187. VALUES ('" .$modelID ."',
  188. '" .$modelURI ."',
  189. '" .$baseURI ."')");
  190. if (!$rs)
  191. $this->dbConn->errorMsg();
  192. else
  193. return new DbModel($this->dbConn, $modelURI, $modelID, $baseURI);
  194. }
  195. }
  196.  
  197.  
  198. /**
  199. * Store a MemModel or another DbModel from a different DbStore in the database.
  200. * Return FALSE if there is already a model with modelURI matching the modelURI
  201. * of the given model.
  202. *
  203. * @param object Model &$model
  204. * @param string $modelURI
  205. * @return boolean
  206. * @access public
  207. */
  208. function putModel(&$model, $modelURI=NULL) {
  209.  
  210. if (!$modelURI) {
  211. if (is_a($model, 'MemModel'))
  212. $modelURI = 'DbModel-' .$this->_createUniqueModelID();
  213. else
  214. $modelURI = $model->modelURI;
  215. }else
  216. if ($this->modelExists($modelURI))
  217. return FALSE;
  218.  
  219. $newDbModel = $this->getNewModel($modelURI, $model->getBaseURI());
  220. $newDbModel->addModel($model);
  221. }
  222.  
  223.  
  224. /**
  225. * Close the DbStore.
  226. * !!! Warning: If you close the DbStore all active instances of DbModel from this
  227. * !!! DbStore will lose their database connection !!!
  228. *
  229. * @access public
  230. */
  231. function close() {
  232.  
  233. $this->dbConn->close();
  234. unset($this);
  235. }
  236.  
  237. // =============================================================================
  238. // **************************** private methods ********************************
  239. // =============================================================================
  240.  
  241.  
  242.  
  243.  
  244.  
  245. /**
  246. * Create a unique ID for the DbModel to be insert into the models table.
  247. * This method was implemented because some databases do not support auto-increment.
  248. *
  249. * @return integer
  250. * @access private
  251. */
  252. function _createUniqueModelID() {
  253. $maxModelID =& $this->dbConn->GetOne('SELECT MAX(modelID) FROM models');
  254. return ++$maxModelID;
  255. }
  256.  
  257.  
  258. /**
  259. * Create tables and indexes for MsAccess database
  260. *
  261. * @throws SqlError
  262. * @access private
  263. */
  264. function _createTables_MsAccess() {
  265.  
  266. $this->dbConn->startTrans();
  267. $this->dbConn->execute('CREATE TABLE models
  268. (modelID long primary key,
  269. modelURI varchar not null,
  270. baseURI varchar)');
  271.  
  272. $this->dbConn->execute('CREATE UNIQUE INDEX m_modURI_idx ON models (modelURI)');
  273.  
  274. $this->dbConn->execute('CREATE TABLE statements
  275. (modelID long,
  276. subject varchar,
  277. predicate varchar,
  278. object Memo,
  279. l_language varchar,
  280. l_datatype varchar,
  281. subject_is varchar(1),
  282. object_is varchar(1),
  283. primary key (modelID, subject, predicate, object,
  284. l_language, l_datatype))');
  285. $this->dbConn->execute('CREATE INDEX s_mod_idx ON statements (modelID)');
  286. $this->dbConn->execute('CREATE INDEX s_sub_idx ON statements (subject)');
  287. $this->dbConn->execute('CREATE INDEX s_pred_idx ON statements (predicate)');
  288. $this->dbConn->execute('CREATE INDEX s_obj_idx ON statements (object)');
  289.  
  290. $this->dbConn->execute('CREATE TABLE namespaces
  291. (modelID long,
  292. namespace varchar,
  293. prefix varchar,
  294. primary key (modelID, namespace, prefix))');
  295.  
  296. $this->dbConn->execute('CREATE INDEX n_name_idx ON namespaces (namespace)');
  297. $this->dbConn->execute('CREATE INDEX n_pref_idx ON namespaces (prefix)');
  298. if (!$this->dbConn->completeTrans())
  299. echo $this->dbConn->errorMsg();
  300. }
  301.  
  302.  
  303. /**
  304. * Create tables and indexes for MySQL database
  305. *
  306. * @throws SqlError
  307. * @access private
  308. */
  309. function _createTables_MySql() {
  310.  
  311. $this->dbConn->startTrans();
  312.  
  313. $this->dbConn->execute("CREATE TABLE models
  314. (modelID bigint NOT NULL,
  315. modelURI varchar(255) NOT NULL,
  316. baseURI varchar(255) DEFAULT '',
  317. primary key (modelID))");
  318. $this->dbConn->execute('CREATE UNIQUE INDEX m_modURI_idx ON models (modelURI)');
  319.  
  320. $this->dbConn->execute("CREATE TABLE statements
  321. (modelID bigint NOT NULL,
  322. subject varchar(255) NOT NULL,
  323. predicate varchar(255) NOT NULL,
  324. object text,
  325. l_language varchar(255) DEFAULT '',
  326. l_datatype varchar(255) DEFAULT '',
  327. subject_is varchar(1) NOT NULL,
  328. object_is varchar(1) NOT NULL)");
  329. $this->dbConn->execute("CREATE TABLE namespaces
  330. (modelID bigint NOT NULL,
  331. namespace varchar(255) NOT NULL,
  332. prefix varchar(255) NOT NULL,
  333. primary key (modelID,namespace))");
  334.  
  335. $this->dbConn->execute('CREATE INDEX s_mod_idx ON statements (modelID)');
  336. $this->dbConn->execute('CREATE INDEX n_mod_idx ON namespaces (modelID)');
  337. $this->dbConn->execute('CREATE INDEX s_sub_pred_idx ON statements
  338. (subject(200),predicate(200))');
  339. $this->dbConn->execute('CREATE INDEX s_obj_idx ON statements (object(250))');
  340.  
  341. if (!$this->dbConn->completeTrans())
  342. echo $this->dbConn->errorMsg();
  343. }
  344. /**
  345. * Create tables and indexes for MSSQL database
  346. *
  347. * @throws SqlError
  348. * @access private
  349. */
  350. function _createTables_mssql(){
  351. $this->dbConn->startTrans();
  352.  
  353. $this->dbConn->execute("CREATE TABLE [dbo].[models] (
  354. [modelID] [int] NOT NULL ,
  355. [modelURI] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  356. [baseURI] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
  357. ) ON [PRIMARY]");
  358. $this->dbConn->execute("CREATE TABLE [dbo].[statements] (
  359. [modelID] [int] NOT NULL ,
  360. [subject] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  361. [predicate] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  362. [object] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  363. [l_language] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  364. [l_datatype] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  365. [subject_is] [nchar] (1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  366. [object_is] [nchar] (1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
  367. ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]");
  368. $this->dbConn->execute("CREATE TABLE [dbo].[namespaces] (
  369. [modelID] [int] NOT NULL ,
  370. [namespace] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
  371. [prefix] [nvarchar] (200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
  372. ) ON [PRIMARY]");
  373.  
  374. $this->dbConn->execute("ALTER TABLE [dbo].[models] WITH NOCHECK ADD
  375. CONSTRAINT [PK_models] PRIMARY KEY CLUSTERED
  376. (
  377. [modelID]
  378. ) ON [PRIMARY] ");
  379. $this->dbConn->execute("ALTER TABLE [dbo].[namespaces] WITH NOCHECK ADD
  380. CONSTRAINT [PK_namespaces] PRIMARY KEY CLUSTERED
  381. (
  382. [modelID],[namespace]
  383. ) ON [PRIMARY] ");
  384. $this->dbConn->execute("CREATE INDEX [joint index on subject and predicate] ON [dbo].[statements]([subject], [predicate]) ON [PRIMARY]");
  385.  
  386. if (!$this->dbConn->completeTrans())
  387. echo $this->dbConn->errorMsg();
  388. }
  389. /**
  390. * Checks if tables are setup for RAP
  391. *
  392. * @param string $databaseType
  393. * @throws SqlError
  394. * @access public
  395. ***/
  396. function isSetup($databaseType="MySQL") {
  397. if ($databaseType=="MySQL")
  398. return $this->_isSetup_MySql();
  399. if ($databaseType=="MSSQL")
  400. return $this->_isSetup_MSSQL();
  401. else {
  402. if ($databaseType=='MsAccess'){
  403. return $this->_isSetup_MsAccess();
  404. }else{
  405. $errmsg=RDFAPI_ERROR."(class: DbStore; method isSetup('$databaseType')):\nCurrently only MySQL, MsAccess and MSSQL are supported!";
  406. trigger_error($errmsg, E_USER_ERROR);}
  407. }
  408. }
  409.  
  410. /**
  411. * Checks if tables are setup for RAP (MySql)
  412. *
  413. * @throws SqlError
  414. * @access private
  415. ***/
  416. function _isSetup_MySql() {
  417. $recordSet =& $this->dbConn->execute("SHOW TABLES");
  418. if (!$recordSet)
  419. echo $this->dbConn->errorMsg();
  420. else {
  421. $tables = array();
  422. while (!$recordSet->EOF) {
  423.  
  424. $tables[]= $recordSet->fields[0];
  425. if(isset($i)){++$i;}
  426. $recordSet->moveNext();
  427. }
  428. if (in_array("models",$tables) && in_array("statements",$tables)&& in_array("namespaces",$tables)) return true;
  429. }
  430. return false;
  431. }
  432. /**
  433. * Checks if tables are setup for RAP (MsAccess)
  434. *
  435. * @throws SqlError
  436. * @access private
  437. ***/
  438. function _isSetup_MsAccess() {
  439. $tables =& $this->dbConn->MetaTables();
  440. if (!$tables)
  441. echo $this->dbConn->errorMsg();
  442. if (count($tables)==0){
  443. return false;}
  444. else {
  445. if (in_array("models",$tables) && in_array("statements",$tables) && in_array("namespaces",$tables)){ return true;
  446. }else{return false;}
  447. }
  448. }
  449. /**
  450. * Checks if tables are setup for RAP (MSSQL)
  451. *
  452. * @throws SqlError
  453. * @access private
  454. ***/
  455. function _isSetup_MSSQL() {
  456. $tables =& $this->dbConn->MetaTables();
  457. if (!$tables)
  458. echo $this->dbConn->errorMsg();
  459. if (count($tables)==0){
  460. return false;}
  461. else {
  462. if (in_array("models",$tables) && in_array("statements",$tables) && in_array("namespaces",$tables)){ return true;
  463. }else{return false;}
  464. }
  465. }
  466.  
  467.  
  468. } // end: Class DbStore
  469. ?>

Documentation generated on Fri, 17 Dec 2004 16:14:39 +0100 by phpDocumentor 1.3.0RC3