- <?php
- /**
- * Zend Framework (http://framework.zend.com/)
- *
- * @link http://github.com/zendframework/zf2 for the canonical source repository
- * @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
-
- namespace Zend\Db\Metadata\Source;
-
- use Zend\Db\Adapter\Adapter;
- use Zend\Db\Metadata\MetadataInterface;
- use Zend\Db\Metadata\Object;
-
- abstract class AbstractSource implements MetadataInterface
- {
- const DEFAULT_SCHEMA = '__DEFAULT_SCHEMA__';
-
- /**
- *
- * @var Adapter
- */
- protected $adapter = null;
-
- /**
- *
- * @var string
- */
- protected $defaultSchema = null;
-
- /**
- *
- * @var array
- */
- protected $data = array();
-
- /**
- * Constructor
- *
- * @param Adapter $adapter
- */
- public function __construct(Adapter $adapter)
- {
- $this->adapter = $adapter;
- $this->defaultSchema = ($adapter->getCurrentSchema()) ?: self::DEFAULT_SCHEMA;
- }
-
- /**
- * Get schemas
- *
- */
- public function getSchemas()
- {
- $this->loadSchemaData();
-
- return $this->data['schemas'];
- }
-
- /**
- * Get table names
- *
- * @param string $schema
- * @param bool $includeViews
- * @return string[]
- */
- public function getTableNames($schema = null, $includeViews = false)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadTableNameData($schema);
-
- if ($includeViews) {
- return array_keys($this->data['table_names'][$schema]);
- }
-
- $tableNames = array();
- foreach ($this->data['table_names'][$schema] as $tableName => $data) {
- if ('BASE TABLE' == $data['table_type']) {
- $tableNames[] = $tableName;
- }
- }
- return $tableNames;
-
- }
-
- /**
- * Get tables
- *
- * @param string $schema
- * @param bool $includeViews
- * @return Object\TableObject[]
- */
- public function getTables($schema = null, $includeViews = false)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $tables = array();
- foreach ($this->getTableNames($schema, $includeViews) as $tableName) {
- $tables[] = $this->getTable($tableName, $schema);
- }
- return $tables;
- }
-
- /**
- * Get table
- *
- * @param string $tableName
- * @param string $schema
- * @return Object\TableObject
- */
- public function getTable($tableName, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadTableNameData($schema);
-
- if (!isset($this->data['table_names'][$schema][$tableName])) {
- throw new \Exception('Table "' . $tableName . '" does not exist');
- }
-
- $data = $this->data['table_names'][$schema][$tableName];
- switch ($data['table_type']) {
- case 'BASE TABLE':
- $table = new Object\TableObject($tableName);
- break;
- case 'VIEW':
- $table = new Object\ViewObject($tableName);
- $table->setViewDefinition($data['view_definition']);
- $table->setCheckOption($data['check_option']);
- $table->setIsUpdatable($data['is_updatable']);
- break;
- default:
- throw new \Exception('Table "' . $tableName . '" is of an unsupported type "' . $data['table_type'] . '"');
- }
- $table->setColumns($this->getColumns($tableName, $schema));
- $table->setConstraints($this->getConstraints($tableName, $schema));
- return $table;
- }
-
- /**
- * Get view names
- *
- * @param string $schema
- * @return array
- */
- public function getViewNames($schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadTableNameData($schema);
-
- $viewNames = array();
- foreach ($this->data['table_names'][$schema] as $tableName => $data) {
- if ('VIEW' == $data['table_type']) {
- $viewNames[] = $tableName;
- }
- }
- return $viewNames;
- }
-
- /**
- * Get views
- *
- * @param string $schema
- * @return array
- */
- public function getViews($schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $views = array();
- foreach ($this->getViewNames($schema) as $tableName) {
- $views[] = $this->getTable($tableName, $schema);
- }
- return $views;
- }
-
- /**
- * Get view
- *
- * @param string $viewName
- * @param string $schema
- * @return \Zend\Db\Metadata\Object\TableObject
- */
- public function getView($viewName, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadTableNameData($schema);
-
- $tableNames = $this->data['table_names'][$schema];
- if (isset($tableNames[$viewName]) && 'VIEW' == $tableNames[$viewName]['table_type']) {
- return $this->getTable($viewName, $schema);
- }
- throw new \Exception('View "' . $viewName . '" does not exist');
- }
-
- /**
- * Gt column names
- *
- * @param string $table
- * @param string $schema
- * @return array
- */
- public function getColumnNames($table, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadColumnData($table, $schema);
-
- if (!isset($this->data['columns'][$schema][$table])) {
- throw new \Exception('"' . $table . '" does not exist');
- }
-
- return array_keys($this->data['columns'][$schema][$table]);
- }
-
- /**
- * Get columns
- *
- * @param string $table
- * @param string $schema
- * @return array
- */
- public function getColumns($table, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadColumnData($table, $schema);
-
- $columns = array();
- foreach ($this->getColumnNames($table, $schema) as $columnName) {
- $columns[] = $this->getColumn($columnName, $table, $schema);
- }
- return $columns;
- }
-
- /**
- * Get column
- *
- * @param string $columnName
- * @param string $table
- * @param string $schema
- * @return Object\ColumnObject
- */
- public function getColumn($columnName, $table, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadColumnData($table, $schema);
-
- if (!isset($this->data['columns'][$schema][$table][$columnName])) {
- throw new \Exception('A column by that name was not found.');
- }
-
- $info = $this->data['columns'][$schema][$table][$columnName];
-
- $column = new Object\ColumnObject($columnName, $table, $schema);
- $props = array(
- 'ordinal_position', 'column_default', 'is_nullable',
- 'data_type', 'character_maximum_length', 'character_octet_length',
- 'numeric_precision', 'numeric_scale', 'numeric_unsigned',
- 'erratas'
- );
- foreach ($props as $prop) {
- if (isset($info[$prop])) {
- $column->{'set' . str_replace('_', '', $prop)}($info[$prop]);
- }
- }
-
- $column->setOrdinalPosition($info['ordinal_position']);
- $column->setColumnDefault($info['column_default']);
- $column->setIsNullable($info['is_nullable']);
- $column->setDataType($info['data_type']);
- $column->setCharacterMaximumLength($info['character_maximum_length']);
- $column->setCharacterOctetLength($info['character_octet_length']);
- $column->setNumericPrecision($info['numeric_precision']);
- $column->setNumericScale($info['numeric_scale']);
- $column->setNumericUnsigned($info['numeric_unsigned']);
- $column->setErratas($info['erratas']);
-
- return $column;
- }
-
- /**
- * Get constraints
- *
- * @param string $table
- * @param string $schema
- * @return array
- */
- public function getConstraints($table, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadConstraintData($table, $schema);
-
- $constraints = array();
- foreach (array_keys($this->data['constraints'][$schema][$table]) as $constraintName) {
- $constraints[] = $this->getConstraint($constraintName, $table, $schema);
- }
-
- return $constraints;
- }
-
- /**
- * Get constraint
- *
- * @param string $constraintName
- * @param string $table
- * @param string $schema
- * @return Object\ConstraintObject
- */
- public function getConstraint($constraintName, $table, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadConstraintData($table, $schema);
-
- if (!isset($this->data['constraints'][$schema][$table][$constraintName])) {
- throw new \Exception('Cannot find a constraint by that name in this table');
- }
-
- $info = $this->data['constraints'][$schema][$table][$constraintName];
- $constraint = new Object\ConstraintObject($constraintName, $table, $schema);
-
- foreach (array(
- 'constraint_type' => 'setType',
- 'match_option' => 'setMatchOption',
- 'update_rule' => 'setUpdateRule',
- 'delete_rule' => 'setDeleteRule',
- 'columns' => 'setColumns',
- 'referenced_table_schema' => 'setReferencedTableSchema',
- 'referenced_table_name' => 'setReferencedTableName',
- 'referenced_columns' => 'setReferencedColumns',
- 'check_clause' => 'setCheckClause',
- ) as $key => $setMethod) {
- if (isset($info[$key])) {
- $constraint->{$setMethod}($info[$key]);
- }
- }
-
- return $constraint;
- }
-
- /**
- * Get constraint keys
- *
- * @param string $constraint
- * @param string $table
- * @param string $schema
- * @return array
- */
- public function getConstraintKeys($constraint, $table, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadConstraintReferences($table, $schema);
-
- // organize references first
- $references = array();
- foreach ($this->data['constraint_references'][$schema] as $refKeyInfo) {
- if ($refKeyInfo['constraint_name'] == $constraint) {
- $references[$refKeyInfo['constraint_name']] = $refKeyInfo;
- }
- }
-
- $this->loadConstraintDataKeys($schema);
-
- $keys = array();
- foreach ($this->data['constraint_keys'][$schema] as $constraintKeyInfo) {
- if ($constraintKeyInfo['table_name'] == $table && $constraintKeyInfo['constraint_name'] === $constraint) {
- $keys[] = $key = new Object\ConstraintKeyObject($constraintKeyInfo['column_name']);
- $key->setOrdinalPosition($constraintKeyInfo['ordinal_position']);
- if (isset($references[$constraint])) {
- //$key->setReferencedTableSchema($constraintKeyInfo['referenced_table_schema']);
- $key->setForeignKeyUpdateRule($references[$constraint]['update_rule']);
- $key->setForeignKeyDeleteRule($references[$constraint]['delete_rule']);
- //$key->setReferencedTableSchema($references[$constraint]['referenced_table_schema']);
- $key->setReferencedTableName($references[$constraint]['referenced_table_name']);
- $key->setReferencedColumnName($references[$constraint]['referenced_column_name']);
- }
- }
- }
-
- return $keys;
- }
-
- /**
- * Get trigger names
- *
- * @param string $schema
- * @return array
- */
- public function getTriggerNames($schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadTriggerData($schema);
-
- return array_keys($this->data['triggers'][$schema]);
- }
-
- /**
- * Get triggers
- *
- * @param string $schema
- * @return array
- */
- public function getTriggers($schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $triggers = array();
- foreach ($this->getTriggerNames($schema) as $triggerName) {
- $triggers[] = $this->getTrigger($triggerName, $schema);
- }
- return $triggers;
- }
-
- /**
- * Get trigger
- *
- * @param string $triggerName
- * @param string $schema
- * @return Object\TriggerObject
- */
- public function getTrigger($triggerName, $schema = null)
- {
- if ($schema === null) {
- $schema = $this->defaultSchema;
- }
-
- $this->loadTriggerData($schema);
-
- if (!isset($this->data['triggers'][$schema][$triggerName])) {
- throw new \Exception('Trigger "' . $triggerName . '" does not exist');
- }
-
- $info = $this->data['triggers'][$schema][$triggerName];
-
- $trigger = new Object\TriggerObject();
-
- $trigger->setName($triggerName);
- $trigger->setEventManipulation($info['event_manipulation']);
- $trigger->setEventObjectCatalog($info['event_object_catalog']);
- $trigger->setEventObjectSchema($info['event_object_schema']);
- $trigger->setEventObjectTable($info['event_object_table']);
- $trigger->setActionOrder($info['action_order']);
- $trigger->setActionCondition($info['action_condition']);
- $trigger->setActionStatement($info['action_statement']);
- $trigger->setActionOrientation($info['action_orientation']);
- $trigger->setActionTiming($info['action_timing']);
- $trigger->setActionReferenceOldTable($info['action_reference_old_table']);
- $trigger->setActionReferenceNewTable($info['action_reference_new_table']);
- $trigger->setActionReferenceOldRow($info['action_reference_old_row']);
- $trigger->setActionReferenceNewRow($info['action_reference_new_row']);
- $trigger->setCreated($info['created']);
-
- return $trigger;
- }
-
- /**
- * Prepare data hierarchy
- *
- * @param string $type
- * @param string $key ...
- */
- protected function prepareDataHierarchy($type)
- {
- $data = &$this->data;
- foreach (func_get_args() as $key) {
- if (!isset($data[$key])) {
- $data[$key] = array();
- }
- $data = &$data[$key];
- }
- }
-
- /**
- * Load schema data
- */
- protected function loadSchemaData()
- {
- }
-
- /**
- * Load table name data
- *
- * @param string $schema
- */
- protected function loadTableNameData($schema)
- {
- if (isset($this->data['table_names'][$schema])) {
- return;
- }
-
- $this->prepareDataHierarchy('table_names', $schema);
- }
-
- /**
- * Load column data
- *
- * @param string $table
- * @param string $schema
- */
- protected function loadColumnData($table, $schema)
- {
- if (isset($this->data['columns'][$schema][$table])) {
- return;
- }
-
- $this->prepareDataHierarchy('columns', $schema, $table);
- }
-
- /**
- * Load constraint data
- *
- * @param string $table
- * @param string $schema
- */
- protected function loadConstraintData($table, $schema)
- {
- if (isset($this->data['constraints'][$schema])) {
- return;
- }
-
- $this->prepareDataHierarchy('constraints', $schema);
- }
-
- /**
- * Load constraint data keys
- *
- * @param string $schema
- */
- protected function loadConstraintDataKeys($schema)
- {
- if (isset($this->data['constraint_keys'][$schema])) {
- return;
- }
-
- $this->prepareDataHierarchy('constraint_keys', $schema);
- }
-
- /**
- * Load constraint references
- *
- * @param string $table
- * @param string $schema
- */
- protected function loadConstraintReferences($table, $schema)
- {
- if (isset($this->data['constraint_references'][$schema])) {
- return;
- }
-
- $this->prepareDataHierarchy('constraint_references', $schema);
- }
-
- /**
- * Load trigger data
- *
- * @param string $schema
- */
- protected function loadTriggerData($schema)
- {
- if (isset($this->data['triggers'][$schema])) {
- return;
- }
-
- $this->prepareDataHierarchy('triggers', $schema);
- }
- }