/** * Build the fixtures table schema from the fields property. * * @return void */ protected function _schemaFromFields() { $this->_schema = new Table($this->table); foreach ($this->fields as $field => $data) { if ($field === '_constraints' || $field === '_indexes' || $field === '_options') { continue; } // Trigger errors on deprecated usage. if (is_array($data) && isset($data['key'])) { $msg = 'Usage of the `key` options in columns is not supported. Try using the upgrade shell to migrate your fixtures.'; $msg .= ' You can download the upgrade shell from https://github.com/cakephp/upgrade.'; trigger_error($msg, E_USER_NOTICE); } $this->_schema->addColumn($field, $data); } if (!empty($this->fields['_constraints'])) { foreach ($this->fields['_constraints'] as $name => $data) { $this->_schema->addConstraint($name, $data); } } if (!empty($this->fields['_indexes'])) { // Trigger errors on deprecated usage. if (empty($data['type'])) { $msg = 'Indexes must define a type. Try using the upgrade shell to migrate your fixtures.'; $msg .= ' You can download the upgrade shell from https://github.com/cakephp/upgrade.'; trigger_error($msg, E_USER_NOTICE); } foreach ($this->fields['_indexes'] as $name => $data) { $this->_schema->addIndex($name, $data); } } if (!empty($this->fields['_options'])) { $this->_schema->options($this->fields['_options']); } }
/** * {@inheritDoc} */ public function createConstraints(ConnectionInterface $db) { if (empty($this->_constraints)) { return true; } foreach ($this->_constraints as $name => $data) { $this->_schema->addConstraint($name, $data); } $sql = $this->_schema->addConstraintSql($db); if (empty($sql)) { return true; } foreach ($sql as $stmt) { $db->execute($stmt)->closeCursor(); } return true; }
protected function _ensureTable($archiveTable) { try { $archiveTable->schema(); } catch (Exception $e) { $djSchema = TableRegistry::get('DelayedJobs.DelayedJobs')->schema(); $djColumns = $djSchema->columns(); $columns = []; foreach ($djColumns as $djColumn) { $columns[$djColumn] = $djSchema->column($djColumn); } $columns['payload']['type'] = 'binary'; $columns['options']['type'] = 'binary'; $archiveTableSchema = new Table($archiveTable->table(), $columns); $archiveTableSchema->addConstraint('primary', $djSchema->constraint('primary')); $createSql = $archiveTableSchema->createSql($archiveTable->connection()); foreach ($createSql as $createSqlQuery) { $archiveTable->connection()->query($createSqlQuery); } } }
/** * Build the fixtures table schema from the fields property. * * @return void */ protected function _schemaFromFields() { $this->_schema = new Table($this->table); foreach ($this->fields as $field => $data) { if ($field === '_constraints' || $field === '_indexes' || $field === '_options') { continue; } $this->_schema->addColumn($field, $data); } if (!empty($this->fields['_constraints'])) { foreach ($this->fields['_constraints'] as $name => $data) { $this->_schema->addConstraint($name, $data); } } if (!empty($this->fields['_indexes'])) { foreach ($this->fields['_indexes'] as $name => $data) { $this->_schema->addIndex($name, $data); } } if (!empty($this->fields['_options'])) { $this->_schema->options($this->fields['_options']); } }
/** * {@inheritDoc} */ public function convertForeignKeyDescription(Table $table, $row) { $data = ['type' => Table::CONSTRAINT_FOREIGN, 'columns' => [$row['COLUMN_NAME']], 'references' => [$row['REFERENCED_TABLE_NAME'], $row['REFERENCED_COLUMN_NAME']], 'update' => $this->_convertOnClause($row['UPDATE_RULE']), 'delete' => $this->_convertOnClause($row['DELETE_RULE'])]; $name = $row['CONSTRAINT_NAME']; $table->addConstraint($name, $data); }
/** * Returns the schema table object describing this table's properties. * * If an \Cake\Database\Schema\Table is passed, it will be used for this table * instead of the default one. * * If an array is passed, a new \Cake\Database\Schema\Table will be constructed * out of it and used as the schema for this table. * * @param array|\Cake\Database\Schema\Table|null $schema New schema to be used for this table * @return \Cake\Database\Schema\Table */ public function schema($schema = null) { if ($schema === null) { if ($this->_schema === null) { $this->_schema = $this->_initializeSchema($this->connection()->schemaCollection()->describe($this->table())); } return $this->_schema; } if (is_array($schema)) { $constraints = []; if (isset($schema['_constraints'])) { $constraints = $schema['_constraints']; unset($schema['_constraints']); } $schema = new Schema($this->table(), $schema); foreach ($constraints as $name => $value) { $schema->addConstraint($name, $value); } } return $this->_schema = $schema; }
/** * {@inheritDoc} */ public function convertForeignKeyDescription(Table $table, $row) { preg_match('/REFERENCES ([^\\)]+)\\(([^\\)]+)\\)/', $row['definition'], $matches); $tableName = $matches[1]; $column = $matches[2]; preg_match('/FOREIGN KEY \\(([^\\)]+)\\) REFERENCES/', $row['definition'], $matches); $columns = $this->_convertColumnList($matches[1]); $data = ['type' => Table::CONSTRAINT_FOREIGN, 'columns' => $columns, 'references' => [$tableName, $column], 'update' => $this->_convertOnClause($row['update_type']), 'delete' => $this->_convertOnClause($row['delete_type'])]; $name = $row['name']; $table->addConstraint($name, $data); }
/** * Add/update a constraint into the schema object. * * @param \Cake\Database\Schema\Table $table The table to update. * @param string $name The index name. * @param string $type The index type. * @param array $row The metadata record to update with. * @return void */ protected function _convertConstraint($table, $name, $type, $row) { $constraint = $table->constraint($name); if (!$constraint) { $constraint = ['type' => $type, 'columns' => []]; } $constraint['columns'][] = $row['attname']; $table->addConstraint($name, $constraint); }
/** * Test that an exception is raised when constraints * are added for fields that do not exist. * * @dataProvider addConstaintErrorProvider * @expectedException \Cake\Database\Exception * @return void */ public function testAddConstraintError($props) { $table = new Table('articles'); $table->addColumn('author_id', 'integer'); $table->addConstraint('author_idx', $props); }
/** * Test that if a table already exists in the test database, it will dropped * before being recreated * * @return void */ public function testResetDbIfTableExists() { $db = ConnectionManager::get('test'); $restore = $db->logQueries(); $db->logQueries(true); $this->manager->setDebug(true); $buffer = new ConsoleOutput(); Log::config('testQueryLogger', ['className' => 'Console', 'stream' => $buffer]); $table = new Table('articles', ['id' => ['type' => 'integer', 'unsigned' => true], 'title' => ['type' => 'string', 'length' => 255]]); $table->addConstraint('primary', ['type' => 'primary', 'columns' => ['id']]); $sql = $table->createSql($db); foreach ($sql as $stmt) { $db->execute($stmt); } $test = $this->getMockBuilder('Cake\\TestSuite\\TestCase')->getMock(); $test->fixtures = ['core.articles']; $this->manager->fixturize($test); $this->manager->load($test); $db->logQueries($restore); $this->assertContains('DROP TABLE', implode('', $buffer->messages())); }
/** * test schema reflection without $import or $fields will reflect the schema * * @return void */ public function testInitNoImportNoFields() { $db = ConnectionManager::get('test'); $collection = $db->schemaCollection(); if (!in_array('letters', $collection->listTables())) { $table = new Table('letters', ['id' => ['type' => 'integer'], 'letter' => ['type' => 'string', 'length' => 1]]); $table->addConstraint('primary', ['type' => 'primary', 'columns' => ['id']]); $sql = $table->createSql($db); foreach ($sql as $stmt) { $db->execute($stmt); } } $fixture = new LettersFixture(); $fixture->init(); $this->assertEquals(['id', 'letter'], $fixture->schema()->columns()); $db = $this->getMockBuilder('Cake\\Database\\Connection')->setMethods(['prepare', 'execute'])->disableOriginalConstructor()->getMock(); $db->expects($this->never())->method('prepare'); $db->expects($this->never())->method('execute'); $this->assertTrue($fixture->create($db)); $this->assertTrue($fixture->drop($db)); }
<?php /** * Queued Tasks schema file * * @author David Yell <*****@*****.**> * @author MGriesbach@gmail.com */ use Cake\Database\Schema\Table; $t = new Table('queued_tasks'); $t->addColumn('id', ['type' => 'integer', 'length' => 10, 'null' => false, 'default' => null]); $t->addColumn('job_type', ['type' => 'string', 'null' => false, 'length' => 45]); $t->addColumn('data', ['type' => 'text', 'null' => true, 'default' => null]); $t->addColumn('job_group', ['type' => 'string', 'length' => 255, 'null' => true, 'default' => null]); $t->addColumn('reference', ['type' => 'string', 'length' => 255, 'null' => true, 'default' => null]); $t->addColumn('created', ['type' => 'datetime', 'null' => true, 'default' => null]); $t->addColumn('notbefore', ['type' => 'datetime', 'null' => true, 'default' => null]); $t->addColumn('fetched', ['type' => 'datetime', 'null' => true, 'default' => null]); $t->addColumn('progress', ['type' => 'float', 'length' => '3,2', 'null' => true, 'default' => null]); $t->addColumn('status', ['type' => 'string', 'length' => 255, 'null' => true, 'default' => null]); $t->addColumn('completed', ['type' => 'datetime', 'null' => true, 'default' => null]); $t->addColumn('failed', ['type' => 'integer', 'null' => false, 'default' => '0', 'length' => 3]); $t->addColumn('failure_message', ['type' => 'text', 'null' => true, 'default' => null]); $t->addColumn('workerkey', ['type' => 'string', 'null' => true, 'length' => 45]); $t->addConstraint('primary', ['type' => 'primary', 'columns' => ['id']]); $t->options(['collate' => 'utf8_unicode_ci']);
/** * {@inheritDoc} */ public function convertForeignKeyDescription(Table $table, $row) { $row = array_change_key_case($row); $data = ['type' => Table::CONSTRAINT_FOREIGN, 'columns' => strtoupper($row['column_name']), 'references' => [$row['referenced_owner'] . '.' . $row['referenced_table_name'], strtoupper($row['referenced_column_name'])], 'update' => Table::ACTION_SET_NULL, 'delete' => $this->_convertOnClause($row['delete_rule'])]; $table->addConstraint($row['constraint_name'], $data); }
/** * Prepare primary constraint * * @param DOMElement $table * @param DOMXPath $xpath * @param Table $schemaTable */ protected function preparePrimaryConstraint(DOMElement $table, DOMXPath $xpath, Table $schemaTable) { $primaryTags = $xpath->query(sprintf('/database/table[@name="%s"]/primary', $table->getAttribute('name'))); /** @var DOMElement $primaryTag */ foreach ($primaryTags as $primaryTag) { $primaryColumns = $primaryTag->getElementsByTagName('primary-column'); $constraintName = $primaryTag->getAttribute('name'); $tmpPrimaryColumn = []; /** @var DOMElement $primaryColumn */ foreach ($primaryColumns as $primaryColumn) { $tmpPrimaryColumn[] = $primaryColumn->getAttribute('name'); } if (empty(trim($constraintName))) { $constraintName = sprintf('%s_%s_%s', $table->getAttribute('name'), implode('_', $tmpPrimaryColumn), 'primary'); } $schemaTable->addConstraint($constraintName, ['type' => 'primary', 'columns' => $tmpPrimaryColumn]); } }
/** * Gets an schema instance for the given fixture class. * * @param string $fixtureClassName The fixture to be "converted" * @return \Cake\Database\Schema\Table Schema instance */ protected function _prepareSchema($fixtureClassName) { $fixture = new $fixtureClassName(); if (!empty($fixture->table)) { $tableName = $fixture->table; } else { $tableName = (string) Inflector::underscore(str_replace_last('Fixture', '', $fixtureClassName)); } list($fields, $constraints, $indexes, $options) = $this->_prepareSchemaProperties($fixture); $schema = new TableSchema($tableName, $fields); foreach ($constraints as $name => $attrs) { $schema->addConstraint($name, $attrs); } foreach ($indexes as $name => $attrs) { $schema->addIndex($name, $attrs); } if (!empty($options)) { $schema->options($options); } return $schema; }
/** * {@inheritDoc} */ public function convertForeignKeyDescription(Table $table, $row) { $data = ['type' => Table::CONSTRAINT_FOREIGN, 'columns' => [$row['from']], 'references' => [$row['table'], $row['to']], 'update' => $this->_convertOnClause($row['on_update']), 'delete' => $this->_convertOnClause($row['on_delete'])]; $name = $row['from'] . '_fk'; $table->addConstraint($name, $data); }
/** * {@inheritDoc} */ public function convertForeignKeyDescription(Table $table, $row) { $name = $row['from'] . '_fk'; $update = isset($row['on_update']) ? $row['on_update'] : ''; $delete = isset($row['on_delete']) ? $row['on_delete'] : ''; $data = ['type' => Table::CONSTRAINT_FOREIGN, 'columns' => [$row['from']], 'references' => [$row['table'], $row['to']], 'update' => $this->_convertOnClause($update), 'delete' => $this->_convertOnClause($delete)]; if (isset($this->_constraintsIdMap[$table->name()][$row['id']])) { $name = $this->_constraintsIdMap[$table->name()][$row['id']]; } else { $this->_constraintsIdMap[$table->name()][$row['id']] = $name; } $table->addConstraint($name, $data); }
public function convertForeignKeyDescription(Table $table, $row) { $data = ['type' => Table::CONSTRAINT_FOREIGN, 'columns' => [strtolower($row['COLUMN_NAME'])], 'references' => ["{$row['REFERENCED_OWNER']}.{$row['REFERENCED_TABLE_NAME']}", strtolower($row['REFERENCED_COLUMN_NAME'])], 'update' => Table::ACTION_SET_NULL, 'delete' => $this->_convertOnClause($row['DELETE_RULE'])]; $name = $row['CONSTRAINT_NAME']; $table->addConstraint($name, $data); }
/** * {@inheritDoc} */ public function convertForeignKeyDescription(Table $table, $row) { $data = $table->constraint($row['name']); if (empty($data)) { $data = ['type' => Table::CONSTRAINT_FOREIGN, 'columns' => [], 'references' => [$row['references_table'], $row['references_field']], 'update' => $this->_convertOnClause($row['on_update']), 'delete' => $this->_convertOnClause($row['on_delete'])]; } $data['columns'][] = $row['column_name']; $table->addConstraint($row['name'], $data); }