PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Db/Metadata/Source/MysqlMetadata.php

http://github.com/zendframework/zf2
PHP | 493 lines | 398 code | 86 blank | 9 comment | 40 complexity | ef5a47f4083a7d6f09e81ebd5b437f58 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Db\Metadata\Source;
  10. use Zend\Db\Adapter\Adapter;
  11. class MysqlMetadata extends AbstractSource
  12. {
  13. protected function loadSchemaData()
  14. {
  15. if (isset($this->data['schemas'])) {
  16. return;
  17. }
  18. $this->prepareDataHierarchy('schemas');
  19. $p = $this->adapter->getPlatform();
  20. $sql = 'SELECT ' . $p->quoteIdentifier('SCHEMA_NAME')
  21. . ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'SCHEMATA'))
  22. . ' WHERE ' . $p->quoteIdentifier('SCHEMA_NAME')
  23. . ' != \'INFORMATION_SCHEMA\'';
  24. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  25. $schemas = array();
  26. foreach ($results->toArray() as $row) {
  27. $schemas[] = $row['SCHEMA_NAME'];
  28. }
  29. $this->data['schemas'] = $schemas;
  30. }
  31. protected function loadTableNameData($schema)
  32. {
  33. if (isset($this->data['table_names'][$schema])) {
  34. return;
  35. }
  36. $this->prepareDataHierarchy('table_names', $schema);
  37. $p = $this->adapter->getPlatform();
  38. $isColumns = array(
  39. array('T', 'TABLE_NAME'),
  40. array('T', 'TABLE_TYPE'),
  41. array('V', 'VIEW_DEFINITION'),
  42. array('V', 'CHECK_OPTION'),
  43. array('V', 'IS_UPDATABLE'),
  44. );
  45. array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); });
  46. $sql = 'SELECT ' . implode(', ', $isColumns)
  47. . ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
  48. . ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'VIEWS')) . ' V'
  49. . ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  50. . ' = ' . $p->quoteIdentifierChain(array('V', 'TABLE_SCHEMA'))
  51. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  52. . ' = ' . $p->quoteIdentifierChain(array('V', 'TABLE_NAME'))
  53. . ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
  54. . ' IN (\'BASE TABLE\', \'VIEW\')';
  55. if ($schema != self::DEFAULT_SCHEMA) {
  56. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  57. . ' = ' . $p->quoteTrustedValue($schema);
  58. } else {
  59. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  60. . ' != \'INFORMATION_SCHEMA\'';
  61. }
  62. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  63. $tables = array();
  64. foreach ($results->toArray() as $row) {
  65. $tables[$row['TABLE_NAME']] = array(
  66. 'table_type' => $row['TABLE_TYPE'],
  67. 'view_definition' => $row['VIEW_DEFINITION'],
  68. 'check_option' => $row['CHECK_OPTION'],
  69. 'is_updatable' => ('YES' == $row['IS_UPDATABLE']),
  70. );
  71. }
  72. $this->data['table_names'][$schema] = $tables;
  73. }
  74. protected function loadColumnData($table, $schema)
  75. {
  76. if (isset($this->data['columns'][$schema][$table])) {
  77. return;
  78. }
  79. $this->prepareDataHierarchy('columns', $schema, $table);
  80. $p = $this->adapter->getPlatform();
  81. $isColumns = array(
  82. array('C', 'ORDINAL_POSITION'),
  83. array('C', 'COLUMN_DEFAULT'),
  84. array('C', 'IS_NULLABLE'),
  85. array('C', 'DATA_TYPE'),
  86. array('C', 'CHARACTER_MAXIMUM_LENGTH'),
  87. array('C', 'CHARACTER_OCTET_LENGTH'),
  88. array('C', 'NUMERIC_PRECISION'),
  89. array('C', 'NUMERIC_SCALE'),
  90. array('C', 'COLUMN_NAME'),
  91. array('C', 'COLUMN_TYPE'),
  92. );
  93. array_walk($isColumns, function (&$c) use ($p) { $c = $p->quoteIdentifierChain($c); });
  94. $sql = 'SELECT ' . implode(', ', $isColumns)
  95. . ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
  96. . ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'COLUMNS')) . 'C'
  97. . ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  98. . ' = ' . $p->quoteIdentifierChain(array('C', 'TABLE_SCHEMA'))
  99. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  100. . ' = ' . $p->quoteIdentifierChain(array('C', 'TABLE_NAME'))
  101. . ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
  102. . ' IN (\'BASE TABLE\', \'VIEW\')'
  103. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  104. . ' = ' . $p->quoteTrustedValue($table);
  105. if ($schema != self::DEFAULT_SCHEMA) {
  106. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  107. . ' = ' . $p->quoteTrustedValue($schema);
  108. } else {
  109. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  110. . ' != \'INFORMATION_SCHEMA\'';
  111. }
  112. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  113. $columns = array();
  114. foreach ($results->toArray() as $row) {
  115. $erratas = array();
  116. $matches = array();
  117. if (preg_match('/^(?:enum|set)\((.+)\)$/i', $row['COLUMN_TYPE'], $matches)) {
  118. $permittedValues = $matches[1];
  119. if (preg_match_all("/\\s*'((?:[^']++|'')*+)'\\s*(?:,|\$)/", $permittedValues, $matches, PREG_PATTERN_ORDER)) {
  120. $permittedValues = str_replace("''", "'", $matches[1]);
  121. } else {
  122. $permittedValues = array($permittedValues);
  123. }
  124. $erratas['permitted_values'] = $permittedValues;
  125. }
  126. $columns[$row['COLUMN_NAME']] = array(
  127. 'ordinal_position' => $row['ORDINAL_POSITION'],
  128. 'column_default' => $row['COLUMN_DEFAULT'],
  129. 'is_nullable' => ('YES' == $row['IS_NULLABLE']),
  130. 'data_type' => $row['DATA_TYPE'],
  131. 'character_maximum_length' => $row['CHARACTER_MAXIMUM_LENGTH'],
  132. 'character_octet_length' => $row['CHARACTER_OCTET_LENGTH'],
  133. 'numeric_precision' => $row['NUMERIC_PRECISION'],
  134. 'numeric_scale' => $row['NUMERIC_SCALE'],
  135. 'numeric_unsigned' => (false !== strpos($row['COLUMN_TYPE'], 'unsigned')),
  136. 'erratas' => $erratas,
  137. );
  138. }
  139. $this->data['columns'][$schema][$table] = $columns;
  140. }
  141. protected function loadConstraintData($table, $schema)
  142. {
  143. if (isset($this->data['constraints'][$schema][$table])) {
  144. return;
  145. }
  146. $this->prepareDataHierarchy('constraints', $schema, $table);
  147. $isColumns = array(
  148. array('T', 'TABLE_NAME'),
  149. array('TC', 'CONSTRAINT_NAME'),
  150. array('TC', 'CONSTRAINT_TYPE'),
  151. array('KCU', 'COLUMN_NAME'),
  152. array('RC', 'MATCH_OPTION'),
  153. array('RC', 'UPDATE_RULE'),
  154. array('RC', 'DELETE_RULE'),
  155. array('KCU', 'REFERENCED_TABLE_SCHEMA'),
  156. array('KCU', 'REFERENCED_TABLE_NAME'),
  157. array('KCU', 'REFERENCED_COLUMN_NAME'),
  158. );
  159. $p = $this->adapter->getPlatform();
  160. array_walk($isColumns, function (&$c) use ($p) {
  161. $c = $p->quoteIdentifierChain($c);
  162. });
  163. $sql = 'SELECT ' . implode(', ', $isColumns)
  164. . ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . ' T'
  165. . ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS')) . ' TC'
  166. . ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  167. . ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
  168. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  169. . ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
  170. . ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . ' KCU'
  171. . ' ON ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
  172. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_SCHEMA'))
  173. . ' AND ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
  174. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_NAME'))
  175. . ' AND ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
  176. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'CONSTRAINT_NAME'))
  177. . ' LEFT JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS')) . ' RC'
  178. . ' ON ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_SCHEMA'))
  179. . ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_SCHEMA'))
  180. . ' AND ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
  181. . ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_NAME'))
  182. . ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  183. . ' = ' . $p->quoteTrustedValue($table)
  184. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
  185. . ' IN (\'BASE TABLE\', \'VIEW\')';
  186. if ($schema != self::DEFAULT_SCHEMA) {
  187. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  188. . ' = ' . $p->quoteTrustedValue($schema);
  189. } else {
  190. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  191. . ' != \'INFORMATION_SCHEMA\'';
  192. }
  193. $sql .= ' ORDER BY CASE ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_TYPE'))
  194. . " WHEN 'PRIMARY KEY' THEN 1"
  195. . " WHEN 'UNIQUE' THEN 2"
  196. . " WHEN 'FOREIGN KEY' THEN 3"
  197. . " ELSE 4 END"
  198. . ', ' . $p->quoteIdentifierChain(array('TC', 'CONSTRAINT_NAME'))
  199. . ', ' . $p->quoteIdentifierChain(array('KCU', 'ORDINAL_POSITION'));
  200. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  201. $realName = null;
  202. $constraints = array();
  203. foreach ($results->toArray() as $row) {
  204. if ($row['CONSTRAINT_NAME'] !== $realName) {
  205. $realName = $row['CONSTRAINT_NAME'];
  206. $isFK = ('FOREIGN KEY' == $row['CONSTRAINT_TYPE']);
  207. if ($isFK) {
  208. $name = $realName;
  209. } else {
  210. $name = '_zf_' . $row['TABLE_NAME'] . '_' . $realName;
  211. }
  212. $constraints[$name] = array(
  213. 'constraint_name' => $name,
  214. 'constraint_type' => $row['CONSTRAINT_TYPE'],
  215. 'table_name' => $row['TABLE_NAME'],
  216. 'columns' => array(),
  217. );
  218. if ($isFK) {
  219. $constraints[$name]['referenced_table_schema'] = $row['REFERENCED_TABLE_SCHEMA'];
  220. $constraints[$name]['referenced_table_name'] = $row['REFERENCED_TABLE_NAME'];
  221. $constraints[$name]['referenced_columns'] = array();
  222. $constraints[$name]['match_option'] = $row['MATCH_OPTION'];
  223. $constraints[$name]['update_rule'] = $row['UPDATE_RULE'];
  224. $constraints[$name]['delete_rule'] = $row['DELETE_RULE'];
  225. }
  226. }
  227. $constraints[$name]['columns'][] = $row['COLUMN_NAME'];
  228. if ($isFK) {
  229. $constraints[$name]['referenced_columns'][] = $row['REFERENCED_COLUMN_NAME'];
  230. }
  231. }
  232. $this->data['constraints'][$schema][$table] = $constraints;
  233. }
  234. protected function loadConstraintDataNames($schema)
  235. {
  236. if (isset($this->data['constraint_names'][$schema])) {
  237. return;
  238. }
  239. $this->prepareDataHierarchy('constraint_names', $schema);
  240. $p = $this->adapter->getPlatform();
  241. $isColumns = array(
  242. array('TC', 'TABLE_NAME'),
  243. array('TC', 'CONSTRAINT_NAME'),
  244. array('TC', 'CONSTRAINT_TYPE'),
  245. );
  246. array_walk($isColumns, function (&$c) use ($p) {
  247. $c = $p->quoteIdentifierChain($c);
  248. });
  249. $sql = 'SELECT ' . implode(', ', $isColumns)
  250. . ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
  251. . ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLE_CONSTRAINTS')) . 'TC'
  252. . ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  253. . ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_SCHEMA'))
  254. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  255. . ' = ' . $p->quoteIdentifierChain(array('TC', 'TABLE_NAME'))
  256. . ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
  257. . ' IN (\'BASE TABLE\', \'VIEW\')';
  258. if ($schema != self::DEFAULT_SCHEMA) {
  259. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  260. . ' = ' . $p->quoteTrustedValue($schema);
  261. } else {
  262. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  263. . ' != \'INFORMATION_SCHEMA\'';
  264. }
  265. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  266. $data = array();
  267. foreach ($results->toArray() as $row) {
  268. $data[] = array_change_key_case($row, CASE_LOWER);
  269. }
  270. $this->data['constraint_names'][$schema] = $data;
  271. }
  272. protected function loadConstraintDataKeys($schema)
  273. {
  274. if (isset($this->data['constraint_keys'][$schema])) {
  275. return;
  276. }
  277. $this->prepareDataHierarchy('constraint_keys', $schema);
  278. $p = $this->adapter->getPlatform();
  279. $isColumns = array(
  280. array('T', 'TABLE_NAME'),
  281. array('KCU', 'CONSTRAINT_NAME'),
  282. array('KCU', 'COLUMN_NAME'),
  283. array('KCU', 'ORDINAL_POSITION'),
  284. );
  285. array_walk($isColumns, function (&$c) use ($p) {
  286. $c = $p->quoteIdentifierChain($c);
  287. });
  288. $sql = 'SELECT ' . implode(', ', $isColumns)
  289. . ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
  290. . ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . 'KCU'
  291. . ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  292. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_SCHEMA'))
  293. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  294. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_NAME'))
  295. . ' WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
  296. . ' IN (\'BASE TABLE\', \'VIEW\')';
  297. if ($schema != self::DEFAULT_SCHEMA) {
  298. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  299. . ' = ' . $p->quoteTrustedValue($schema);
  300. } else {
  301. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  302. . ' != \'INFORMATION_SCHEMA\'';
  303. }
  304. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  305. $data = array();
  306. foreach ($results->toArray() as $row) {
  307. $data[] = array_change_key_case($row, CASE_LOWER);
  308. }
  309. $this->data['constraint_keys'][$schema] = $data;
  310. }
  311. protected function loadConstraintReferences($table, $schema)
  312. {
  313. parent::loadConstraintReferences($table, $schema);
  314. $p = $this->adapter->getPlatform();
  315. $isColumns = array(
  316. array('RC', 'TABLE_NAME'),
  317. array('RC', 'CONSTRAINT_NAME'),
  318. array('RC', 'UPDATE_RULE'),
  319. array('RC', 'DELETE_RULE'),
  320. array('KCU', 'REFERENCED_TABLE_SCHEMA'),
  321. array('KCU', 'REFERENCED_TABLE_NAME'),
  322. array('KCU', 'REFERENCED_COLUMN_NAME'),
  323. );
  324. array_walk($isColumns, function (&$c) use ($p) {
  325. $c = $p->quoteIdentifierChain($c);
  326. });
  327. $sql = 'SELECT ' . implode(', ', $isColumns)
  328. . 'FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TABLES')) . 'T'
  329. . ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'REFERENTIAL_CONSTRAINTS')) . 'RC'
  330. . ' ON ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  331. . ' = ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_SCHEMA'))
  332. . ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_NAME'))
  333. . ' = ' . $p->quoteIdentifierChain(array('RC', 'TABLE_NAME'))
  334. . ' INNER JOIN ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'KEY_COLUMN_USAGE')) . 'KCU'
  335. . ' ON ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_SCHEMA'))
  336. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_SCHEMA'))
  337. . ' AND ' . $p->quoteIdentifierChain(array('RC', 'TABLE_NAME'))
  338. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'TABLE_NAME'))
  339. . ' AND ' . $p->quoteIdentifierChain(array('RC', 'CONSTRAINT_NAME'))
  340. . ' = ' . $p->quoteIdentifierChain(array('KCU', 'CONSTRAINT_NAME'))
  341. . 'WHERE ' . $p->quoteIdentifierChain(array('T', 'TABLE_TYPE'))
  342. . ' IN (\'BASE TABLE\', \'VIEW\')';
  343. if ($schema != self::DEFAULT_SCHEMA) {
  344. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  345. . ' = ' . $p->quoteTrustedValue($schema);
  346. } else {
  347. $sql .= ' AND ' . $p->quoteIdentifierChain(array('T', 'TABLE_SCHEMA'))
  348. . ' != \'INFORMATION_SCHEMA\'';
  349. }
  350. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  351. $data = array();
  352. foreach ($results->toArray() as $row) {
  353. $data[] = array_change_key_case($row, CASE_LOWER);
  354. }
  355. $this->data['constraint_references'][$schema] = $data;
  356. }
  357. protected function loadTriggerData($schema)
  358. {
  359. if (isset($this->data['triggers'][$schema])) {
  360. return;
  361. }
  362. $this->prepareDataHierarchy('triggers', $schema);
  363. $p = $this->adapter->getPlatform();
  364. $isColumns = array(
  365. // 'TRIGGER_CATALOG',
  366. // 'TRIGGER_SCHEMA',
  367. 'TRIGGER_NAME',
  368. 'EVENT_MANIPULATION',
  369. 'EVENT_OBJECT_CATALOG',
  370. 'EVENT_OBJECT_SCHEMA',
  371. 'EVENT_OBJECT_TABLE',
  372. 'ACTION_ORDER',
  373. 'ACTION_CONDITION',
  374. 'ACTION_STATEMENT',
  375. 'ACTION_ORIENTATION',
  376. 'ACTION_TIMING',
  377. 'ACTION_REFERENCE_OLD_TABLE',
  378. 'ACTION_REFERENCE_NEW_TABLE',
  379. 'ACTION_REFERENCE_OLD_ROW',
  380. 'ACTION_REFERENCE_NEW_ROW',
  381. 'CREATED',
  382. );
  383. array_walk($isColumns, function (&$c) use ($p) {
  384. $c = $p->quoteIdentifier($c);
  385. });
  386. $sql = 'SELECT ' . implode(', ', $isColumns)
  387. . ' FROM ' . $p->quoteIdentifierChain(array('INFORMATION_SCHEMA', 'TRIGGERS'))
  388. . ' WHERE ';
  389. if ($schema != self::DEFAULT_SCHEMA) {
  390. $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
  391. . ' = ' . $p->quoteTrustedValue($schema);
  392. } else {
  393. $sql .= $p->quoteIdentifier('TRIGGER_SCHEMA')
  394. . ' != \'INFORMATION_SCHEMA\'';
  395. }
  396. $results = $this->adapter->query($sql, Adapter::QUERY_MODE_EXECUTE);
  397. $data = array();
  398. foreach ($results->toArray() as $row) {
  399. $row = array_change_key_case($row, CASE_LOWER);
  400. if (null !== $row['created']) {
  401. $row['created'] = new \DateTime($row['created']);
  402. }
  403. $data[$row['trigger_name']] = $row;
  404. }
  405. $this->data['triggers'][$schema] = $data;
  406. }
  407. }