Ejemplo n.º 1
0
 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);
         }
     }
 }