ソースを参照

Merge pull request #3889 from cakephp/3.0-override-column-type

3.0 override column type
Mark Story 11 年 前
コミット
78598c2c19

+ 12 - 2
src/Database/Schema/Table.php

@@ -224,6 +224,11 @@ class Table {
  */
 	const ACTION_RESTRICT = 'restrict';
 
+/**
+ * Foreign key restrict default
+ *
+ * @var string
+ */
 	const ACTION_SET_DEFAULT = 'setDefault';
 
 /**
@@ -312,15 +317,20 @@ class Table {
 	}
 
 /**
- * Convenience method for getting the type of a given column.
+ * Sets the type of a column, or returns its current type
+ * if none is passed.
  *
  * @param string $name The column to get the type of.
+ * @param string $type The type to set the column to.
  * @return string|null Either the column type or null.
  */
-	public function columnType($name) {
+	public function columnType($name, $type = null) {
 		if (!isset($this->_columns[$name])) {
 			return null;
 		}
+		if ($type !== null) {
+			$this->_columns[$name]['type'] = $type;
+		}
 		return $this->_columns[$name]['type'];
 	}
 

+ 29 - 3
src/ORM/Table.php

@@ -317,9 +317,11 @@ class Table implements RepositoryInterface, EventListener {
 	public function schema($schema = null) {
 		if ($schema === null) {
 			if ($this->_schema === null) {
-				$this->_schema = $this->connection()
-					->schemaCollection()
-					->describe($this->table());
+				$this->_schema = $this->_initializeSchema(
+					$this->connection()
+						->schemaCollection()
+						->describe($this->table())
+				);
 			}
 			return $this->_schema;
 		}
@@ -343,6 +345,30 @@ class Table implements RepositoryInterface, EventListener {
 	}
 
 /**
+ * Override this function in order to alter the schema used by this table.
+ * This function is only called after fetching the schema out of the database.
+ * If you wish to provide your own schema to this table without touching the
+ * database, you can override schema() or inject the definitions though that
+ * method.
+ *
+ * ### Example:
+ *
+ * {{{
+ * protected function _initializeSchema(\Cake\Database\Schema\Table $table) {
+ *	$table->columnType('preferences', 'json');
+ *	return $table;
+ * }
+ * }}}
+ *
+ * @api
+ * @param \Cake\Database\Schema\Table $table The table definition fetched from database.
+ * @return \Cake\Database\Schema\Table the altered schema
+ */
+	protected function _initializeSchema(Schema $table) {
+		return $table;
+	}
+
+/**
  * Test to see if a Table has a specific field/column.
  *
  * Delegates to the schema object and checks for column presence

+ 17 - 0
tests/TestCase/Database/Schema/TableTest.php

@@ -79,6 +79,23 @@ class TableTest extends TestCase {
 	}
 
 /**
+ * Test columnType setter method
+ *
+ * @return void
+ */
+	public function testColumnTypeSet() {
+		$table = new Table('articles');
+		$table->addColumn('title', [
+			'type' => 'string',
+			'length' => 25,
+			'null' => false
+		]);
+		$this->assertEquals('string', $table->columnType('title'));
+		$table->columnType('title', 'json');
+		$this->assertEquals('json', $table->columnType('title'));
+	}
+
+/**
  * Attribute keys should be filtered and have defaults set.
  *
  * @return void

+ 23 - 0
tests/TestCase/ORM/TableTest.php

@@ -264,6 +264,29 @@ class TableTest extends \Cake\TestSuite\TestCase {
 	}
 
 /**
+ * Tests that _initializeSchema can be used to alter the database schema
+ *
+ * @return void
+ */
+	public function testSchemaInitialize() {
+		$schema = $this->connection->schemaCollection()->describe('users');
+		$table = $this->getMock('Cake\ORM\Table', ['_initializeSchema'], [
+			['table' => 'users', 'connection' => $this->connection]
+		]);
+		$table->expects($this->once())
+			->method('_initializeSchema')
+			->with($schema)
+			->will($this->returnCallback(function($schema) {
+				$schema->columnType('username', 'integer');
+				return $schema;
+			}));
+		$result = $table->schema();
+		$schema->columnType('username', 'integer');
+		$this->assertEquals($schema, $result);
+		$this->assertEquals($schema, $table->schema(), '_initializeSchema should be called once');
+	}
+
+/**
  * Tests that all fields for a table are added by default in a find when no
  * other fields are specified
  *