xpdomanager.class.php 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. <?php
  2. /*
  3. * Copyright 2010-2015 by MODX, LLC.
  4. *
  5. * This file is part of xPDO.
  6. *
  7. * xPDO is free software; you can redistribute it and/or modify it under the
  8. * terms of the GNU General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option) any later
  10. * version.
  11. *
  12. * xPDO is distributed in the hope that it will be useful, but WITHOUT ANY
  13. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  14. * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along with
  17. * xPDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
  18. * Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. /**
  21. * The sqlsrv implementation of the xPDOManager class.
  22. *
  23. * @package xpdo
  24. * @subpackage om.sqlsrv
  25. */
  26. /**
  27. * Include the parent {@link xPDOManager} class.
  28. */
  29. require_once (dirname(__DIR__) . '/xpdomanager.class.php');
  30. /**
  31. * Provides sqlsrv data source management for an xPDO instance.
  32. *
  33. * These are utility functions that only need to be loaded under special
  34. * circumstances, such as creating tables, adding indexes, altering table
  35. * structures, etc. xPDOManager class implementations are specific to a
  36. * database driver and this instance is implemented for sqlsrv.
  37. *
  38. * @package xpdo
  39. * @subpackage om.sqlsrv
  40. */
  41. class xPDOManager_sqlsrv extends xPDOManager {
  42. public function createSourceContainer($dsnArray = null, $username= null, $password= null, $containerOptions= array ()) {
  43. $created = false;
  44. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  45. if ($dsnArray === null) $dsnArray = xPDO::parseDSN($this->xpdo->getOption('dsn'));
  46. if ($username === null) $username = $this->xpdo->getOption('username', null, '');
  47. if ($password === null) $password = $this->xpdo->getOption('password', null, '');
  48. if (is_array($dsnArray) && is_string($username) && is_string($password)) {
  49. $sql= 'CREATE DATABASE ' . $this->xpdo->escape($dsnArray['dbname']);
  50. if (isset ($containerOptions['collation'])) {
  51. $sql.= ' COLLATE ' . $containerOptions['collation'];
  52. }
  53. try {
  54. $pdo = new PDO("sqlsrv:server={$dsnArray['server']}", $username, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
  55. $result = $pdo->exec($sql);
  56. if ($result !== false) {
  57. $created = true;
  58. } else {
  59. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not create source container:\n{$sql}\nresult = " . var_export($result, true));
  60. }
  61. } catch (PDOException $pe) {
  62. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not connect to database server: " . $pe->getMessage());
  63. } catch (Exception $e) {
  64. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not create source container: " . $e->getMessage());
  65. }
  66. }
  67. } else {
  68. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  69. }
  70. return $created;
  71. }
  72. public function removeSourceContainer($dsnArray = null, $username= null, $password= null) {
  73. $removed= false;
  74. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  75. if ($dsnArray === null) $dsnArray = xPDO::parseDSN($this->xpdo->getOption('dsn'));
  76. if ($username === null) $username = $this->xpdo->getOption('username', null, '');
  77. if ($password === null) $password = $this->xpdo->getOption('password', null, '');
  78. if (is_array($dsnArray) && is_string($username) && is_string($password)) {
  79. $sql= 'DROP DATABASE ' . $this->xpdo->escape($dsnArray['dbname']);
  80. try {
  81. $pdo = new PDO("sqlsrv:server={$dsnArray['server']}", $username, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
  82. $pdo->exec("ALTER DATABASE {$this->xpdo->escape($dsnArray['dbname'])} SET single_user WITH ROLLBACK IMMEDIATE");
  83. $result = $pdo->exec($sql);
  84. if ($result !== false) {
  85. $removed = true;
  86. } else {
  87. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not remove source container:\n{$sql}\nresult = " . var_export($result, true));
  88. }
  89. } catch (PDOException $pe) {
  90. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not connect to database server: " . $pe->getMessage());
  91. } catch (Exception $e) {
  92. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not remove source container: " . $e->getMessage());
  93. }
  94. }
  95. } else {
  96. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  97. }
  98. return $removed;
  99. }
  100. public function removeObjectContainer($className) {
  101. $removed= false;
  102. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  103. $instance= $this->xpdo->newObject($className);
  104. if ($instance) {
  105. $sql= 'DROP TABLE ' . $this->xpdo->getTableName($className);
  106. $removed= $this->xpdo->exec($sql);
  107. if ($removed === false && $this->xpdo->errorCode() !== '' && $this->xpdo->errorCode() !== PDO::ERR_NONE) {
  108. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not drop table ' . $className . "\nSQL: {$sql}\nERROR: " . print_r($this->xpdo->pdo->errorInfo(), true));
  109. } else {
  110. $removed= true;
  111. $this->xpdo->log(xPDO::LOG_LEVEL_INFO, 'Dropped table' . $className . "\nSQL: {$sql}\n");
  112. }
  113. }
  114. } else {
  115. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  116. }
  117. return $removed;
  118. }
  119. public function createObjectContainer($className) {
  120. $created= false;
  121. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  122. $instance= $this->xpdo->newObject($className);
  123. if ($instance) {
  124. $tableName= $this->xpdo->getTableName($className);
  125. $existsStmt = $this->xpdo->query("SELECT COUNT(*) FROM {$tableName}");
  126. if ($existsStmt && $existsStmt->fetchAll()) {
  127. return true;
  128. }
  129. $tableMeta= $this->xpdo->getTableMeta($className);
  130. $sql= 'CREATE TABLE ' . $tableName . ' (';
  131. $fieldMeta = $this->xpdo->getFieldMeta($className, true);
  132. $nativeGen = false;
  133. $columns = array();
  134. foreach ($fieldMeta as $key => $meta) {
  135. $columns[] = $this->getColumnDef($className, $key, $meta);
  136. if (array_key_exists('generated', $meta) && $meta['generated'] == 'native') $nativeGen = true;
  137. }
  138. $sql .= implode(', ', $columns);
  139. $indexes = $this->xpdo->getIndexMeta($className);
  140. $createIndices = array();
  141. $tableConstraints = array();
  142. if (!empty ($indexes)) {
  143. foreach ($indexes as $indexkey => $indexdef) {
  144. $indexType = ($indexdef['primary'] ? 'PRIMARY KEY' : ($indexdef['unique'] ? 'UNIQUE' : 'INDEX'));
  145. $indexset = $this->getIndexDef($className, $indexkey, $indexdef);
  146. switch ($indexType) {
  147. case 'INDEX':
  148. $createIndices[$indexkey] = "CREATE INDEX {$this->xpdo->escape($indexkey)} ON {$tableName} ({$indexset})";
  149. break;
  150. case 'PRIMARY KEY':
  151. if ($nativeGen) break;
  152. $tableConstraints[]= "{$indexType} ({$indexset})";
  153. break;
  154. case 'UNIQUE':
  155. default:
  156. $tableConstraints[]= "CONSTRAINT {$this->xpdo->escape($className . '_' . $indexkey)} {$indexType} ({$indexset})";
  157. break;
  158. }
  159. }
  160. }
  161. if (!empty($tableConstraints)) {
  162. $sql .= ', ' . implode(', ', $tableConstraints);
  163. }
  164. $sql .= ")";
  165. $created= $this->xpdo->exec($sql);
  166. if ($created === false && $this->xpdo->errorCode() !== '' && $this->xpdo->errorCode() !== PDO::ERR_NONE) {
  167. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Could not create table ' . $tableName . "\nSQL: {$sql}\nERROR: " . print_r($this->xpdo->errorInfo(), true));
  168. } else {
  169. $created= true;
  170. $this->xpdo->log(xPDO::LOG_LEVEL_INFO, 'Created table ' . $tableName . "\nSQL: {$sql}\n");
  171. }
  172. if ($created === true && !empty($createIndices)) {
  173. foreach ($createIndices as $createIndexKey => $createIndex) {
  174. $indexCreated = $this->xpdo->exec($createIndex);
  175. if ($indexCreated === false && $this->xpdo->errorCode() !== '' && $this->xpdo->errorCode() !== PDO::ERR_NONE) {
  176. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not create index {$createIndexKey}: {$createIndex} " . print_r($this->xpdo->errorInfo(), true));
  177. } else {
  178. $this->xpdo->log(xPDO::LOG_LEVEL_INFO, "Created index {$createIndexKey} on {$tableName}: {$createIndex}");
  179. }
  180. }
  181. }
  182. }
  183. } else {
  184. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  185. }
  186. return $created;
  187. }
  188. public function alterObjectContainer($className, array $options = array()) {
  189. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  190. // TODO: Implement alterObjectContainer() method.
  191. } else {
  192. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  193. }
  194. }
  195. public function addConstraint($class, $name, array $options = array()) {
  196. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  197. // TODO: Implement addConstraint() method.
  198. } else {
  199. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  200. }
  201. }
  202. public function addField($class, $name, array $options = array()) {
  203. $result = false;
  204. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  205. $className = $this->xpdo->loadClass($class);
  206. if ($className) {
  207. $meta = $this->xpdo->getFieldMeta($className, true);
  208. if (is_array($meta) && array_key_exists($name, $meta)) {
  209. $colDef = $this->getColumnDef($className, $name, $meta[$name]);
  210. if (!empty($colDef)) {
  211. $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} ADD {$colDef}";
  212. if ($this->xpdo->exec($sql) !== false) {
  213. $result = true;
  214. } else {
  215. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error adding field {$class}->{$name}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__);
  216. }
  217. } else {
  218. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error adding field {$class}->{$name}: Could not get column definition");
  219. }
  220. } else {
  221. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error adding field {$class}->{$name}: No metadata defined");
  222. }
  223. }
  224. } else {
  225. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  226. }
  227. return $result;
  228. }
  229. public function addIndex($class, $name, array $options = array()) {
  230. $result = false;
  231. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  232. $className = $this->xpdo->loadClass($class);
  233. if ($className) {
  234. $meta = $this->xpdo->getIndexMeta($className);
  235. if (is_array($meta) && array_key_exists($name, $meta)) {
  236. $idxDef = $this->getIndexDef($className, $name, $meta[$name]);
  237. if (!empty($idxDef)) {
  238. $indexType = ($meta[$name]['primary'] ? 'PRIMARY KEY' : ($meta[$name]['unique'] ? 'UNIQUE' : 'INDEX'));
  239. switch ($indexType) {
  240. case 'PRIMARY KEY':
  241. case 'UNIQUE':
  242. $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} ADD CONSTRAINT {$this->xpdo->escape($name)} {$indexType} ({$idxDef})";
  243. break;
  244. default:
  245. $sql = "CREATE {$indexType} {$this->xpdo->escape($name)} ON {$this->xpdo->getTableName($className)} ({$idxDef})";
  246. break;
  247. }
  248. if ($this->xpdo->exec($sql) !== false) {
  249. $result = true;
  250. } else {
  251. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error adding index {$name} to {$class}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__);
  252. }
  253. } else {
  254. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error adding index {$name} to {$class}: Could not get index definition");
  255. }
  256. } else {
  257. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error adding index {$name} to {$class}: No metadata defined");
  258. }
  259. }
  260. } else {
  261. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  262. }
  263. return $result;
  264. }
  265. public function alterField($class, $name, array $options = array()) {
  266. $result = false;
  267. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  268. $className = $this->xpdo->loadClass($class);
  269. if ($className) {
  270. $meta = $this->xpdo->getFieldMeta($className, true);
  271. if (is_array($meta) && array_key_exists($name, $meta)) {
  272. $colDef = $this->getColumnDef($className, $name, $meta[$name]);
  273. if (!empty($colDef)) {
  274. $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} ALTER COLUMN {$colDef}";
  275. if ($this->xpdo->exec($sql) !== false) {
  276. $result = true;
  277. } else {
  278. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$name}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__);
  279. }
  280. } else {
  281. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$name}: Could not get column definition");
  282. }
  283. } else {
  284. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error altering field {$class}->{$name}: No metadata defined");
  285. }
  286. }
  287. } else {
  288. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  289. }
  290. return $result;
  291. }
  292. public function removeConstraint($class, $name, array $options = array()) {
  293. $result = false;
  294. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  295. $className = $this->xpdo->loadClass($class);
  296. if ($className) {
  297. $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} DROP CONSTRAINT {$this->xpdo->escape($name)}";
  298. $result = $this->xpdo->exec($sql);
  299. if ($result !== false || (!$result && $this->xpdo->errorCode() === '00000')) {
  300. $result = true;
  301. } else {
  302. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error removing field {$class}->{$name}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__);
  303. }
  304. }
  305. } else {
  306. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  307. }
  308. return $result;
  309. }
  310. public function removeField($class, $name, array $options = array()) {
  311. $result = false;
  312. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  313. $className = $this->xpdo->loadClass($class);
  314. if ($className) {
  315. if ($defaultConstraints = $this->getDefaultConstraints($class, $name)) {
  316. foreach ($defaultConstraints as $defaultConstraint) {
  317. $this->removeConstraint($class, $defaultConstraint);
  318. }
  319. }
  320. $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} DROP COLUMN {$this->xpdo->escape($name)}";
  321. $result = $this->xpdo->exec($sql);
  322. if ($result !== false || (!$result && $this->xpdo->errorCode() === '00000')) {
  323. $result = true;
  324. } else {
  325. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error removing field {$class}->{$name}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__);
  326. }
  327. }
  328. } else {
  329. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  330. }
  331. return $result;
  332. }
  333. public function removeIndex($class, $name, array $options = array()) {
  334. $result = false;
  335. if ($this->xpdo->getConnection(array(xPDO::OPT_CONN_MUTABLE => true))) {
  336. $className = $this->xpdo->loadClass($class);
  337. if ($className) {
  338. $indexType = (isset($options['type']) && in_array($options['type'], array('PRIMARY KEY', 'UNIQUE', 'INDEX', 'FULLTEXT')) ? $options['type'] : 'INDEX');
  339. switch ($indexType) {
  340. case 'PRIMARY KEY':
  341. case 'UNIQUE':
  342. $sql = "ALTER TABLE {$this->xpdo->getTableName($className)} DROP CONSTRAINT {$this->xpdo->escape($name)}";
  343. break;
  344. default:
  345. $sql = "DROP INDEX {$this->xpdo->escape($name)} ON {$this->xpdo->getTableName($className)}";
  346. break;
  347. }
  348. $result = $this->xpdo->exec($sql);
  349. if ($result !== false || (!$result && $this->xpdo->errorCode() === '00000')) {
  350. $result = true;
  351. } else {
  352. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Error removing index {$name} from {$class}: " . print_r($this->xpdo->errorInfo(), true), '', __METHOD__, __FILE__, __LINE__);
  353. }
  354. }
  355. } else {
  356. $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, "Could not get writable connection", '', __METHOD__, __FILE__, __LINE__);
  357. }
  358. return $result;
  359. }
  360. protected function getColumnDef($class, $name, $meta, array $options = array()) {
  361. $pk= $this->xpdo->getPK($class);
  362. $pktype= $this->xpdo->getPKType($class);
  363. $dbtype= strtoupper($meta['dbtype']);
  364. $precision= (isset ($meta['precision']) && !preg_match('/ENUM/i', $dbtype) && !in_array($this->xpdo->driver->getPHPType($dbtype), array('integer', 'bit', 'date', 'datetime', 'time'))) ? '(' . $meta['precision'] . ')' : '';
  365. if (preg_match('/ENUM/i', $dbtype)) {
  366. $maxlength = 255;
  367. if (isset($meta['precision'])) {
  368. $pieces= explode(',', $meta['precision']);
  369. if (!empty($pieces)) {
  370. $length = 0;
  371. $maxlength = 0;
  372. foreach ($pieces as $piece) {
  373. $length = strlen($piece);
  374. if ($length > $maxlength) $maxlength = $length;
  375. }
  376. if ($maxlength < 1) $maxlength = 255;
  377. }
  378. }
  379. $dbtype= 'VARCHAR';
  380. $precision= "({$maxlength})";
  381. }
  382. $notNull= !isset ($meta['null']) ? false : ($meta['null'] === 'false' || empty($meta['null']));
  383. $null= $notNull ? ' NOT NULL' : ' NULL';
  384. $extra = '';
  385. if (isset ($meta['index']) && $meta['index'] == 'pk' && !is_array($pk) && $pktype == 'integer' && isset ($meta['generated']) && $meta['generated'] == 'native') {
  386. $extra= ' IDENTITY PRIMARY KEY';
  387. $null= '';
  388. }
  389. if (empty ($extra) && isset ($meta['extra'])) {
  390. $extra= ' ' . $meta['extra'];
  391. }
  392. $default= '';
  393. if (array_key_exists('default', $meta)) {
  394. $defaultVal= $meta['default'];
  395. if ($defaultVal === null || strtoupper($defaultVal) === 'NULL' || in_array($this->xpdo->driver->getPHPType($dbtype), array('integer', 'float', 'bit')) || (in_array($this->xpdo->driver->getPHPType($dbtype), array('datetime', 'date', 'timestamp', 'time')) && in_array($defaultVal, array_merge($this->xpdo->driver->_currentTimestamps, $this->xpdo->driver->_currentDates, $this->xpdo->driver->_currentTimes)))) {
  396. $default= ' DEFAULT ' . $defaultVal;
  397. } else {
  398. $default= ' DEFAULT \'' . $defaultVal . '\'';
  399. }
  400. }
  401. $attributes= (isset ($meta['attributes'])) ? ' ' . $meta['attributes'] : '';
  402. if (strpos(strtolower($attributes), 'unsigned') !== false) {
  403. $result = $this->xpdo->escape($name) . ' ' . $dbtype . $precision . $attributes . $null . $default . $extra;
  404. } else {
  405. $result = $this->xpdo->escape($name) . ' ' . $dbtype . $precision . $null . $default . $attributes . $extra;
  406. }
  407. return $result;
  408. }
  409. protected function getIndexDef($class, $name, $meta, array $options = array()) {
  410. $result = '';
  411. $index = isset($meta['columns']) ? $meta['columns'] : null;
  412. if (is_array($index)) {
  413. $indexset= array ();
  414. foreach ($index as $indexmember => $indexmemberdetails) {
  415. $indexMemberDetails = $this->xpdo->escape($indexmember);
  416. $indexset[]= $indexMemberDetails;
  417. }
  418. $result= implode(',', $indexset);
  419. }
  420. return $result;
  421. }
  422. private function getDefaultConstraints($class, $name, array $options = array()) {
  423. $constraints = array();
  424. $table = $this->xpdo->getTableName($class);
  425. $sql = "SELECT name FROM sys.default_constraints WHERE parent_object_id = object_id(?) AND type = 'D' AND parent_column_id = (SELECT column_id FROM sys.columns WHERE object_id = object_id(?) AND name = ?)";
  426. $stmt = $this->xpdo->prepare($sql);
  427. $tstart = microtime(true);
  428. if ($stmt && $stmt->execute(array($table, $table, $name))) {
  429. $this->xpdo->queryTime += microtime(true) - $tstart;
  430. $this->xpdo->executedQueries++;
  431. $constraints = $stmt->fetchAll(PDO::FETCH_COLUMN);
  432. } elseif ($stmt) {
  433. $this->xpdo->queryTime += microtime(true) - $tstart;
  434. $this->xpdo->executedQueries++;
  435. }
  436. return $constraints;
  437. }
  438. }