private function sqlChange(ObjectParameter $instance, $mode = null) { $idObject = $instance->id_object; if ($idObject == null) { return false; } $isDelete = $mode == 'delete'; $isInsert = $mode == 'insert'; $objectCurrent = DaObject::getById($idObject); $table = $objectCurrent->table_name; $type = $instance->getDataType(); $fieldName = $instance->getFieldName(); if ($objectCurrent->object_type != DaObject::OBJECT_TYPE_TABLE) { return false; } if ($table == null) { if (Yii::app()->isBackend) { Yii::app()->addMessage('Свойство не было ' . ($isDelete ? 'удалено' : ($isInsert ? 'создано' : 'изменено')) . ' в базе данных, т.к. у объекта не указано имя таблицы', BackendApplication::MESSAGE_TYPE_ERROR, true); } return false; } $tableNotExists = Yii::app()->db->createCommand('SHOW TABLES LIKE :t')->queryScalar(array(':t' => $objectCurrent->table_name)) == null; $sqls = array(); $allowQuery = true; $abstractCurrent = DataType::getSqlType($type) == null; $instanceOld = null; if ($isDelete) { $instanceOld = $instance; } else { if (!$isInsert) { $instanceOld = ObjectParameter::model()->findByIdInstance($instance->getIdInstance()); if ($instanceOld == null) { // такой вариант может быть только в случае, если у параметра поменяли ИД. Тогда мы не можем найти старый параметр и не можем понять какие были данные. Поэтому ничего не делаем. return; } } } // Если поле меняется, загружаем старые данные и проверяем, поменялось ли что-то if (!$isInsert && !$isDelete) { $isTypeChange = DataType::getSqlType($instanceOld->getDataType()) != DataType::getSqlType($type); $allowQuery = $instanceOld->getFieldName() != $fieldName || $isTypeChange || $instanceOld->getDefaultValue() != $instance->getDefaultValue() || $instanceOld->isRequired() != $instance->isRequired(); if ($isTypeChange) { // если тип поля меняется с SQL на абстрактный - удаляем поле if ($abstractCurrent && DataType::getSqlType($instanceOld->getDataType()) != null) { $sqls[] = 'ALTER TABLE `' . $table . '` DROP `' . $instanceOld->getFieldName() . '`'; // наоборот, если тип поля меняется с абстрактного на SQL - добавляем поле } else { if (!$abstractCurrent && DataType::getSqlType($instanceOld->getDataType()) == null) { $isInsert = true; } } } } $msg = ''; // Составляем запросы if ($allowQuery && !$abstractCurrent) { $fieldExists = false; $countFields = 0; if (!$tableNotExists) { $columns = Yii::app()->db->createCommand('SHOW COLUMNS FROM ' . $table)->queryAll(); if ($instanceOld != null) { $fieldName = $instanceOld->getFieldName(); } foreach ($columns as $column) { if ($column['Field'] == $fieldName) { $fieldExists = true; } $countFields++; } } if ((!$isInsert || $isDelete) && !$fieldExists) { $allowQuery = false; $msg = 'В таблице ' . $table . ' не существует поля "' . $instanceOld->getFieldName() . '"'; } if ($isInsert && $fieldExists) { $allowQuery = false; $msg = 'В таблице ' . $table . ' уже существует поле "' . $instance->getFieldName() . '"'; } // TODO проверки еще [Field] => person_type [Type] => int(8) [Null] => YES [Key] => [Default] => [Extra] => if ($allowQuery) { if ($isDelete) { if ($countFields == 1) { $sqls[] = 'DROP TABLE `' . $table . '`'; } else { $sqls[] = 'ALTER TABLE `' . $table . '` DROP `' . $instance->getFieldName() . '`'; } } else { $definition = '`' . $instance->getFieldName() . '` ' . DataType::getSqlType($type); if ($instance->isRequired()) { $definition .= ' NOT NULL'; } if ($instance->getDefaultValue() != null && !in_array($type, array(DataType::TEXTAREA, DataType::EDITOR))) { $definition .= ' default \'' . $instance->getDefaultValue() . '\''; } if ($type == DataType::PRIMARY_KEY) { $definition .= ' AUTO_INCREMENT'; } $definition .= ' COMMENT ' . $this->dbConnection->quoteValue($instance->getCaption()); // Создаем таблицу с полем if ($tableNotExists) { $sqls[] = $objectCurrent->getCreateTableSql(); // Таблица уже существует } else { $sql = 'ALTER TABLE `' . $table . '`'; if ($isInsert) { $sql .= ' ADD ' . $definition . ' '; } else { $sql .= ' CHANGE `' . $instanceOld->getFieldName() . '` ' . $definition . ' '; } $sqls[] = $sql; if ($isInsert) { if ($type == DataType::PRIMARY_KEY) { $sqls[] = 'ALTER TABLE `' . $table . '` ADD PRIMARY KEY (`' . $fieldName . '`)'; } if ($instance->isUnique()) { $sqls[] = 'ALTER TABLE `' . $table . '` ADD UNIQUE (`' . $fieldName . '`)'; } } } } } } foreach ($sqls as $sql) { Yii::app()->db->createCommand($sql)->execute(); $msg .= 'Выполнено: ' . $sql . '<br>'; } if ($msg != '') { if (Yii::app()->isBackend) { Yii::app()->addMessage($msg); } } }
public function getCreateTableSql($html = false) { $sql = ""; if ($this->id_object != null && $this->table_name != null && $this->object_type != self::OBJECT_TYPE_CONTROLLER) { // Сооружаем sql-запрос $props = $this->parameters; $primary = ''; $text_sql = array(); foreach ($props as $prop) { $type = $prop->getType(); $name = $prop->getFieldName(); $type_var = DataType::getSqlType($type); if ($type_var == null) { continue; } $null = $prop->isRequired() ? "NOT NULL" : "NULL"; $default = ""; if ($prop->getDefaultValue() != null) { $default = "default '" . $prop->getDefaultValue() . "'"; } if ($type == DataType::PRIMARY_KEY) { $primary = "PRIMARY KEY(`" . $name . "`)"; $default .= ' AUTO_INCREMENT'; } $text_sql[] = trim("`" . $name . "` " . $type_var . " " . $null . " " . $default); } if (count($text_sql)) { $table = $this->table_name; if (is_numeric($table)) { $obParent = DaObject::getById($table); $table = $obParent->table_name; } $htmlStr = "\n"; if ($html) { $htmlStr = "<br/>"; } $sql = "CREATE TABLE IF NOT EXISTS `" . $table . "` (" . $htmlStr . "\n " . implode(", " . $htmlStr, $text_sql) . ($primary != '' ? " ," . $htmlStr . "\n {$primary}" : '') . $htmlStr . "\n ) ENGINE = InnoDB COMMENT=" . $this->dbConnection->quoteValue($this->name) . ";"; } } return $sql; }
private function getInsertTable() { $sql = ""; $primaryKeyText = ""; $uniqueText = ""; $tableColumns = array(); foreach ($this->checkAttributes as $i => $checkValue) { if (!($parameterName = $this->newObjectParameters[$i])) { continue; } $objectParameter = ObjectParameter::model()->find(array('condition' => 'id_object = :obj AND id_parameter = :param', 'params' => array(':obj' => $this->objectId, ':param' => $this->objectParameters[$i]))); $tableColumns[$objectParameter->id_parameter] = "`{$parameterName}`" . " " . DataType::getSqlType($objectParameter->getDataType()); if ($objectParameter->default_value) { $tableColumns[$objectParameter->id_parameter] .= " DEFAULT '{$objectParameter->default_value}'"; } if ($objectParameter->isRequired()) { $tableColumns[$objectParameter->id_parameter] .= " NOT NULL "; } if ($objectParameter->isUnique()) { $uniqueText = ", UNIQUE (`{$objectParameter->field_name}`)"; //$tableColumns[$objectParameter->id_parameter] .= " UNIQUE "; } if ($objectParameter->getDataType() == DataType::PRIMARY_KEY) { $primaryKeyText = ", PRIMARY KEY (`{$objectParameter->field_name}`)"; $tableColumns[$objectParameter->id_parameter] .= " AUTO_INCREMENT "; } } $sql .= "CREATE TABLE IF NOT EXISTS `" . $this->tableName . "`(" . implode(',', $tableColumns); $sql .= $primaryKeyText; $sql .= $uniqueText; $sql .= ");"; return $sql; }