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); } } }