From 5a1b526ae868f6e8276c0966f588b4da3ddccf40 Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 12 Nov 2013 13:35:40 +0200 Subject: [PATCH] "yii\sphinx\ColumnSchema' extracted. --- extensions/sphinx/ColumnSchema.php | 81 +++++++++++++++++++++++ extensions/sphinx/QueryBuilder.php | 48 ++++++++++++++ extensions/sphinx/Schema.php | 20 ++---- tests/unit/data/sphinx/sphinx.conf | 1 + tests/unit/extensions/sphinx/ColumnSchemaTest.php | 55 +++++++++++++++ tests/unit/extensions/sphinx/CommandTest.php | 1 + 6 files changed, 193 insertions(+), 13 deletions(-) create mode 100644 extensions/sphinx/ColumnSchema.php create mode 100644 tests/unit/extensions/sphinx/ColumnSchemaTest.php diff --git a/extensions/sphinx/ColumnSchema.php b/extensions/sphinx/ColumnSchema.php new file mode 100644 index 0000000..47eca5f --- /dev/null +++ b/extensions/sphinx/ColumnSchema.php @@ -0,0 +1,81 @@ + + * @since 2.0 + */ +class ColumnSchema extends Object +{ + /** + * @var string name of this column (without quotes). + */ + public $name; + /** + * @var string abstract type of this column. Possible abstract types include: + * string, text, boolean, smallint, integer, bigint, float, decimal, datetime, + * timestamp, time, date, binary, and money. + */ + public $type; + /** + * @var string the PHP type of this column. Possible PHP types include: + * string, boolean, integer, double. + */ + public $phpType; + /** + * @var string the DB type of this column. Possible DB types vary according to the type of DBMS. + */ + public $dbType; + /** + * @var boolean whether this column is a primary key + */ + public $isPrimaryKey; + /** + * @var boolean whether this column is an attribute + */ + public $isAttribute; + /** + * @var boolean whether this column is a indexed field + */ + public $isField; + /** + * @var boolean whether this column is a multi value attribute (MVA) + */ + public $isMva; + + /** + * Converts the input value according to [[phpType]]. + * If the value is null or an [[Expression]], it will not be converted. + * @param mixed $value input value + * @return mixed converted value + */ + public function typecast($value) + { + if ($value === null || gettype($value) === $this->phpType || $value instanceof Expression) { + return $value; + } + if ($value === '' && $this->type !== Schema::TYPE_TEXT && $this->type !== Schema::TYPE_STRING) { + return null; + } + switch ($this->phpType) { + case 'string': + return (string)$value; + case 'integer': + return (integer)$value; + case 'boolean': + return (boolean)$value; + } + return $value; + } +} \ No newline at end of file diff --git a/extensions/sphinx/QueryBuilder.php b/extensions/sphinx/QueryBuilder.php index e3f52de..b0502e6 100644 --- a/extensions/sphinx/QueryBuilder.php +++ b/extensions/sphinx/QueryBuilder.php @@ -6,6 +6,7 @@ */ namespace yii\sphinx; +use yii\db\Expression; /** * Class QueryBuilder @@ -72,4 +73,51 @@ class QueryBuilder extends \yii\db\mysql\QueryBuilder } return 'OPTION ' . implode(', ', $optionLines); } + + /** + * Creates an INSERT SQL statement. + * For example, + * + * ~~~ + * $sql = $queryBuilder->insert('tbl_user', [ + * 'name' => 'Sam', + * 'age' => 30, + * ], $params); + * ~~~ + * + * The method will properly escape the table and column names. + * + * @param string $table the table that new rows will be inserted into. + * @param array $columns the column data (name => value) to be inserted into the table. + * @param array $params the binding parameters that will be generated by this method. + * They should be bound to the DB command later. + * @return string the INSERT SQL + */ + public function insert($table, $columns, &$params) + { + if (($tableSchema = $this->db->getTableSchema($table)) !== null) { + $columnSchemas = $tableSchema->columns; + } else { + $columnSchemas = []; + } + $names = []; + $placeholders = []; + foreach ($columns as $name => $value) { + $names[] = $this->db->quoteColumnName($name); + if ($value instanceof Expression) { + $placeholders[] = $value->expression; + foreach ($value->params as $n => $v) { + $params[$n] = $v; + } + } else { + $phName = self::PARAM_PREFIX . count($params); + $placeholders[] = $phName; + $params[$phName] = !is_array($value) && isset($columnSchemas[$name]) ? $columnSchemas[$name]->typecast($value) : $value; + } + } + + return 'INSERT INTO ' . $this->db->quoteTableName($table) + . ' (' . implode(', ', $names) . ') VALUES (' + . implode(', ', $placeholders) . ')'; + } } \ No newline at end of file diff --git a/extensions/sphinx/Schema.php b/extensions/sphinx/Schema.php index 557becd..b9a34be 100644 --- a/extensions/sphinx/Schema.php +++ b/extensions/sphinx/Schema.php @@ -7,7 +7,6 @@ namespace yii\sphinx; -use yii\db\ColumnSchema; use yii\db\TableSchema; /** @@ -101,15 +100,9 @@ class Schema extends \yii\db\mysql\Schema $column = new ColumnSchema; $column->name = $info['Field']; - $column->isPrimaryKey = ($column->name == 'id'); - // Not supported : - //$column->allowNull = $info['Null'] === 'YES'; - //$column->autoIncrement = stripos($info['Extra'], 'auto_increment') !== false; - //$column->comment = $info['Comment']; - - $column->dbType = $info['Type']; - //$column->unsigned = strpos($column->dbType, 'unsigned') !== false; + + $column->isPrimaryKey = ($column->name == 'id'); $type = $info['Type']; if (isset($this->typeMap[$type])) { @@ -118,11 +111,12 @@ class Schema extends \yii\db\mysql\Schema $column->type = self::TYPE_STRING; } - $column->phpType = $this->getColumnPhpType($column); + $column->isField = ($type == 'field'); + $column->isAttribute = !$column->isField; - /*if ($column->type !== 'timestamp' || $info['Default'] !== 'CURRENT_TIMESTAMP') { - $column->defaultValue = $column->typecast($info['Default']); - }*/ + $column->isMva = ($type == 'mva'); + + $column->phpType = $this->getColumnPhpType($column); return $column; } diff --git a/tests/unit/data/sphinx/sphinx.conf b/tests/unit/data/sphinx/sphinx.conf index e58166c..6ab6625 100644 --- a/tests/unit/data/sphinx/sphinx.conf +++ b/tests/unit/data/sphinx/sphinx.conf @@ -80,6 +80,7 @@ index yii2_test_rt_index rt_field = title rt_field = content rt_attr_uint = type_id + rt_attr_multi = category } diff --git a/tests/unit/extensions/sphinx/ColumnSchemaTest.php b/tests/unit/extensions/sphinx/ColumnSchemaTest.php new file mode 100644 index 0000000..7d62c1d --- /dev/null +++ b/tests/unit/extensions/sphinx/ColumnSchemaTest.php @@ -0,0 +1,55 @@ +type = $type; + $columnSchema->phpType = $phpType; + $this->assertEquals($expectedResult, $columnSchema->typecast($value)); + } +} \ No newline at end of file diff --git a/tests/unit/extensions/sphinx/CommandTest.php b/tests/unit/extensions/sphinx/CommandTest.php index 639dea2..0a15bf8 100644 --- a/tests/unit/extensions/sphinx/CommandTest.php +++ b/tests/unit/extensions/sphinx/CommandTest.php @@ -103,6 +103,7 @@ class CommandTest extends SphinxTestCase 'title' => 'Test title', 'content' => 'Test content', 'type_id' => 2, + 'category' => [41, 42], 'id' => 1, ]); $this->assertEquals(1, $command->execute(), 'Unable to execute insert!');