Ejemplo n.º 1
0
 public function buildContent()
 {
     $navigation = AdminPageNavigation::inst();
     $PARAMS['mode'] = self::MODE_TABLES_LIST;
     /*
      * Просмотр содержимого таблицы
      */
     $table = RequestArrayAdapter::inst()->str('table');
     if ($table) {
         $PARAMS['mode'] = self::MODE_TABLE_VIEW;
         $table = PsTable::inst($table);
         $PARAMS['table'] = $table;
         $PARAMS['rows'] = $table->getRows();
         $navigation->addPath(self::urlTables(), 'Настройки');
         $navigation->setCurrent('Просмотр ' . $table->getName());
     }
     /*
      * Просмотр и настройка всех таблиц
      */
     if ($PARAMS['mode'] == self::MODE_TABLES_LIST) {
         $PARAMS['errors'] = PsDbIniHelper::validateAll();
         foreach (ConfigIni::getAllowedScopes() as $scope) {
             $PARAMS['data'][$scope] = TableExporter::inst()->getTables($scope);
             $PARAMS['data']["{$scope}.ini"] = DbIni::getIniContent($scope);
         }
         $navigation->setCurrent('Настройки');
     }
     echo $this->getFoldedEntity()->fetchTpl($PARAMS);
 }
Ejemplo n.º 2
0
 private static function assertPrepeared($tableExists = null)
 {
     PsConnectionPool::assertConnectiedTo(PsConnectionParams::sdkTest());
     foreach (to_array($tableExists) as $table) {
         check_condition(PsTable::exists($table), "Таблица {$table} не существует");
     }
 }
Ejemplo n.º 3
0
    /**
     * Список таблиц текущей схемы
     */
    public function getTables()
    {
        if (!$this->getCache()->has(self::CACHE_TABLES)) {
            $this->getCache()->set(self::CACHE_TABLES, $this->getObjects('
SELECT LOWER(TABLE_NAME) as TABLE_NAME, 
       TABLE_COMMENT 
  FROM INFORMATION_SCHEMA.TABLES 
 WHERE table_schema=DATABASE() 
   and TABLE_TYPE=?', 'BASE TABLE', PsTable::getClass(), 'TABLE_NAME'));
        }
        return $this->getCache()->get(self::CACHE_TABLES);
    }
Ejemplo n.º 4
0
 public function getModifiedTables()
 {
     if (!is_array($this->MODIFIED_TABLES)) {
         $this->MODIFIED_TABLES = array();
         /* @var $table PsTable */
         foreach (PsTable::configured() as $name => $table) {
             if ($table->hasModified()) {
                 $this->MODIFIED_TABLES[$name] = $table;
             }
         }
     }
     return $this->MODIFIED_TABLES;
 }
Ejemplo n.º 5
0
function executeProcess(array $argv)
{
    PsConnectionPool::assertDisconnectied();
    /*
     * СОЗДАЁМ SQL
     * 
     * Нам нужны настройки таблиц, которые неоткуда взять, кроме как из базы, поэтому для экспорта данных нужна БД.
     * Все данные из "редактируемых" таблиц также загружаются из этой БД.
     */
    $DB = DirManager::inst(__DIR__ . '/temp');
    $SDK = DirManager::inst(__DIR__ . '/temp/sdk');
    //Почистим файлы для удаления
    dolog('Clearing not .sql/.txt from temp dir');
    /* @var $item DirItem */
    foreach ($DB->getDirContentFull(null, DirItemFilter::FILES) as $item) {
        if (!$item->checkExtension(array(PsConst::EXT_TXT, PsConst::EXT_SQL))) {
            dolog('[-] {}', $item->remove()->getRelPath());
        }
    }
    dolog();
    /*
     * SDK
     */
    //dolog('Processing objects.sql');
    /* @var $DIR DirManager */
    foreach (array(ENTITY_SCOPE_SDK => $SDK, ENTITY_SCOPE_PROJ => $DB) as $scope => $DM) {
        dolog();
        dolog('***************************************************************');
        dolog('>>> Processing scope [{}], dir: [{}]', $scope, $DM->absDirPath());
        $SCHEMA = $DM->getDirItem(null, 'schema.sql');
        if (!$SCHEMA->isFile()) {
            dolog('schema.sql is not exists, skipping');
            continue;
            //---
        }
        $DM_SYSOBJECTS = DirManager::inst($DM->absDirPath(), 'sysobjects');
        /*
         * Очищаем папку, в которой будет содержимое для автосгенерированных файлов
         */
        $DM_AUTO = DirManager::inst($DM_SYSOBJECTS->absDirPath(), 'auto')->clearDir();
        /*
         * Создадим ссылку на файл с данными, выгруженными из таблиц
         */
        $DI_AUTO_DATA = $DM_AUTO->getDirItem(null, 'data.sql');
        /*
         * Сначала сделаем триггеры на таблицы, от которых зависит кеш и к которым привязаны фолдинги.
         */
        LOGBOX_INIT();
        LOGBOX('Making cache and folding table triggers');
        $DM_AUTO_TRIGGERS = $DM_AUTO->getDirItem('triggers')->makePath();
        $DI_AUTO_TRIGGERS_SQL = $DM_AUTO->getDirItem(null, 'triggers', 'sql')->getSqlFileBuilder();
        $triggerPattern = $SDK->getDirItem('sysobjects/patterns', 'ta_iud_pattern.sql')->getFileContents();
        //BUILDIAN AND ADDING TRIGGERS
        foreach (PsTriggersAware::getTriggeredTables($scope) as $table) {
            foreach (PsTriggersAware::getActions() as $action) {
                $actions = PsTriggersAware::getTriggerActions($table, $scope, $action);
                if (empty($actions)) {
                    continue;
                    //---
                }
                $name = 'ta' . strtolower(first_char($action)) . '_' . $table;
                $trigger = str_replace('<%NAME%>', $name, $triggerPattern);
                $trigger = str_replace('<%TABLE%>', $table, $trigger);
                $trigger = str_replace('<%ACTION%>', $action, $trigger);
                $trigger = str_replace('<%CALL%>', implode("\n", $actions), $trigger);
                dolog("+ {$name}");
                foreach ($actions as $_action) {
                    dolog($_action);
                }
                $DI_AUTO_TRIGGERS_SQL->appendFile($DM_AUTO_TRIGGERS->getDirItem(null, $name, 'sql')->putToFile($trigger));
            }
        }
        //Все автоматически сгенерированные триггеры положим в отдельный файл
        $DI_AUTO_TRIGGERS_SQL->save();
        $autoTriggers = DirManager::inst($DM_AUTO_TRIGGERS->getAbsPath())->getDirContent(null, PsConst::EXT_SQL);
        dolog('Triggers made: {}', count($autoTriggers));
        /*
         * objects.sql
         */
        $OBJECTS_SQL = $DM_AUTO->getDirItem(null, 'objects.sql')->getSqlFileBuilder();
        /*
         * Добавляем автосгенерированные триггеры
         */
        LOGBOX('Processing objects.sql');
        if (empty($autoTriggers)) {
            dolog('No auto triggers');
        } else {
            dolog('Adding {} auto triggers', count($autoTriggers));
            $OBJECTS_SQL->appendMlComment('AUTO TRIGGERS SECTION');
            /* @var $triggerDi DirItem */
            foreach ($autoTriggers as $triggerDi) {
                dolog('+ {}', $triggerDi->getName());
                $OBJECTS_SQL->appendFile($triggerDi);
            }
        }
        /*
         * Получаем строки с включениями
         */
        $ALL = $DM_SYSOBJECTS->getDirItem(null, 'all.txt')->getFileLines(false);
        if (empty($ALL)) {
            dolog('No includes');
        } else {
            dolog('Adding {} includes from all.txt', count($ALL));
            $OBJECTS_SQL->appendMlComment('INCLUDES SECTION');
            foreach ($ALL as $include) {
                dolog('+ {}', $include);
                $OBJECTS_SQL->appendFile($DM_SYSOBJECTS->getDirItem($include));
            }
        }
        $OBJECTS_SQL->save();
        /*
         * Создаём скрипты инициализации для схем
         */
        foreach (PsConnectionParams::getDefaultConnectionNames() as $connection) {
            if (PsConnectionParams::has($connection, $scope)) {
                $props = PsConnectionParams::get($connection, $scope);
                $database = $props->database();
                if (empty($database)) {
                    continue;
                    //Не задана БД - пропускаем (для root)
                }
                LOGBOX('Making schema script for {}', $props);
                $SCHEMA_SQL = $DM_AUTO->getDirItem('schemas', $database, 'sql')->makePath()->getSqlFileBuilder();
                //DROP+USE
                $SCHEMA_SQL->clean();
                $SCHEMA_SQL->appendLine("DROP DATABASE IF EXISTS {$database};");
                $SCHEMA_SQL->appendLine("CREATE DATABASE {$database} CHARACTER SET utf8 COLLATE utf8_general_ci;");
                $SCHEMA_SQL->appendLine("USE {$database};");
                if ($scope == ENTITY_SCOPE_PROJ) {
                    dolog('+ SDK PART');
                    //Добавим секцию в лог
                    $SCHEMA_SQL->appendMlComment('>>> SDK');
                    //CREATE CHEMA SCRIPT
                    $SCHEMA_SQL->appendFile($SDK->getDirItem(null, 'schema.sql'));
                    //OBJECTS SCRIPT
                    $SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/auto', 'objects.sql'));
                    //Добавим секцию в лог
                    $SCHEMA_SQL->appendMlComment('<<< SDK');
                }
                //CREATE CHEMA SCRIPT
                $SCHEMA_SQL->appendFile($SCHEMA);
                //OBJECTS SCRIPT
                $SCHEMA_SQL->appendFile($OBJECTS_SQL->getDi());
                //CREATE USER
                $grant = "grant all on {}.* to '{}'@'{}' identified by '{}';";
                $SCHEMA_SQL->appendMlComment('Grants');
                $SCHEMA_SQL->appendLine(PsStrings::replaceWithBraced($grant, $database, $props->user(), $props->host(), $props->password()));
                /*
                 * Мы должны создать тестовую схему, чтобы убедиться, что всё хорошо и сконфигурировать db.ini
                 */
                if ($connection == PsConnectionParams::CONN_TEST) {
                    dolog('Making physical schema {}', $props);
                    $rootProps = PsConnectionParams::get(PsConnectionParams::CONN_ROOT);
                    dolog('Root connection props: {}', $rootProps);
                    $rootProps->execureShell($SCHEMA_SQL->getDi());
                    dolog('Connecting to [{}]', $props);
                    PsConnectionPool::configure($props);
                    $tables = PsTable::all();
                    /*
                     * Нам нужно определить новый список таблиц SDK, чтобы по ним 
                     * провести валидацию новых db.ini.
                     * 
                     * Если мы обрабатываем проект, то SDK-шный db.ini уже готов и 
                     * можем положиться на него. Если мы подготавливаем SDK-шный db.ini,
                     * но новый список таблиц возмём из развёрнутой тестовой БД.
                     */
                    $sdkTableNames = $scope == ENTITY_SCOPE_SDK ? array_keys($tables) : DbIni::getSdkTables();
                    if ($scope == ENTITY_SCOPE_PROJ) {
                        //Уберём из всех таблиц - SDK`шные
                        array_remove_keys($tables, $sdkTableNames);
                    }
                    $scopeTableNames = array_keys($tables);
                    sort($scopeTableNames);
                    /*
                     * Составим список таблиц.
                     * Он нам особенно не нужен, но всёже будем его формировать для наглядности - какие таблицы добавились.
                     */
                    $tablesDi = $DM_AUTO->getDirItem(null, 'tables.txt')->putToFile(implode("\n", $scopeTableNames));
                    dolog('Tables: {} saved to {}', print_r($scopeTableNames, true), $tablesDi->getAbsPath());
                    /*
                     * Загружаем полный список таблиц схемы и на основе имеющихся db.ini файлов строим новые, добавляя/удаляя 
                     * таблицы, добавленные/удалённые из схемы.
                     */
                    $dbIniProps = PsDbIniHelper::makeDbIniForSchema($scope, $tables);
                    dolog('db.ini props: {}', print_r($dbIniProps, true));
                    $dbIniErrors = PsDbIniHelper::validateAndSaveDbIniTableProps($scope, $dbIniProps, $sdkTableNames);
                    if ($dbIniErrors) {
                        PsUtil::raise('db.ini errors for {}: {}', $scope, print_r($dbIniErrors, true));
                    }
                    /*
                     * Для проекта выгружаем данные, хранящиеся в файлах
                     */
                    if ($scope == ENTITY_SCOPE_PROJ) {
                        dolog('Exporting tables data from files');
                        $DM_AUTO->getDirItem('data')->makePath();
                        $AUTO_DATA_SQL = $DI_AUTO_DATA->touch()->getSqlFileBuilder();
                        //Пробегаемся по таблицам
                        foreach (DbIni::getTables() as $tableName) {
                            $table = PsTable::inst($tableName);
                            if ($table->isFilesync()) {
                                $fileData = $table->exportFileAsInsertsSql();
                                if ($fileData) {
                                    dolog(' + {}', $tableName);
                                    $AUTO_DATA_SQL->appendFile($DM_AUTO->getDirItem('data', $tableName, 'sql')->putToFile($fileData));
                                } else {
                                    dolog(' - {}', $tableName);
                                }
                            }
                        }
                        $AUTO_DATA_SQL->save();
                        /*
                         * Вставим данные в тестовую схему
                         */
                        dolog('Inserting data to test schema.');
                        $props->execureShell($DI_AUTO_DATA);
                    }
                    /*
                     * Теперь ещё создадим тестовые объекты.
                     * Мы уверены, что для SDK тестовая часть есть всегда.
                     */
                    $TEST_SCHEMA_SQL = $DM_AUTO->getDirItem('test', 'schema', 'sql')->makePath()->getSqlFileBuilder();
                    if ($scope == ENTITY_SCOPE_PROJ) {
                        dolog('+ SDK TEST PART');
                        //Добавим секцию в лог
                        $TEST_SCHEMA_SQL->appendMlComment('>>> SDK');
                        //CREATE CHEMA SCRIPT
                        $TEST_SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/auto/test', 'schema.sql'));
                        //Добавим секцию в лог
                        $TEST_SCHEMA_SQL->appendMlComment('<<< SDK');
                    }
                    $TEST_SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'schema.sql'), false);
                    $TEST_SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'data.sql'), false);
                    $TEST_SCHEMA_SQL->save();
                    /*
                     * На тестовой схеме прогоняем скрипты с тестовыми данными
                     */
                    dolog('Making test schema objects.');
                    $props->execureShell($TEST_SCHEMA_SQL->getDi());
                }
                #end conn== TEST
                /*
                 * Если были сгенерированы данные из файлов - добавляем их
                 */
                if ($DI_AUTO_DATA->isFile() && $DI_AUTO_DATA->getSize() > 0) {
                    dolog('Append data inserts to {}', $SCHEMA_SQL->getDi()->getName());
                    $SCHEMA_SQL->appendFile($DI_AUTO_DATA);
                }
                //SAVE .sql
                $SCHEMA_SQL->save();
            }
        }
    }
    dolog('Database schemas successfully exported');
}
Ejemplo n.º 6
0
/**
 * Процесс строит скрипты разворачивания БД
 * 
 * @param array $argv
 */
function executeProcess(array $argv)
{
    /*
     * СОЗДАЁМ SQL
     * 
     * Нам нужны настройки таблиц, которые неоткуда взять, кроме как из базы, поэтому для экспорта данных нужна БД.
     */
    $DB = DirManager::inst(__DIR__ . '/temp');
    $SDK = DirManager::inst(__DIR__ . '/temp/ps-sdk');
    //Почистим файлы, которые нам не интересны
    $cleanExt = array(PsConst::EXT_TXT, PsConst::EXT_SQL);
    dolog('Clearing not {} files from temp dir', array_to_string($cleanExt));
    /* @var $item DirItem */
    foreach ($DB->getDirContentFull(null, DirItemFilter::FILES) as $item) {
        if (!$item->checkExtension($cleanExt)) {
            dolog('[-] {}', $item->remove()->getRelPath());
        }
    }
    //Пробежимся по скоупам и выполним обработку
    /* @var $DIR DirManager */
    foreach (array(ENTITY_SCOPE_SDK => $SDK, ENTITY_SCOPE_PROJ => $DB) as $scope => $DM) {
        dolog();
        dolog('***************************** SCOPE [{}] *****************************', $scope);
        dolog('Working directory: [{}]', $DM->absDirPath());
        $SCHEMA = $DM->getDirItem(null, 'schema', PsConst::EXT_SQL);
        if (!$SCHEMA->isFile()) {
            dolog('schema.sql is not exists, skipping');
            continue;
            //---
        }
        //Директория с системными объектами
        $DM_SYSOBJECTS = DirManager::inst($DM->absDirPath(), 'sysobjects');
        //Директория, в которой будет содержимое для автосгенерированных файлов
        $DM_BUILD = DirManager::inst($DM->absDirPath(), 'build')->clearDir();
        //Создадим ссылку на файл с объектами
        $DM_BUILD_ALL_SQL = $DM_BUILD->getDirItem(null, 'all', PsConst::EXT_SQL)->getSqlFileBuilder();
        //Строим objects.sql
        dolog('Processing all.sql');
        /*
         * Получаем строки с включениями в objects.sql
         */
        $ALL_LINES = $DM_SYSOBJECTS->getDirItem(null, 'all', PsConst::EXT_TXT)->getFileLines(false);
        if (empty($ALL_LINES)) {
            dolog('No includes');
        } else {
            dolog('Adding {} includes from all.txt', count($ALL_LINES));
            foreach ($ALL_LINES as $include) {
                dolog('+ {}', $include);
                $DM_BUILD_ALL_SQL->appendFile($DM_SYSOBJECTS->getDirItem($include));
            }
        }
        // << Сохраняем objects.sql
        $DM_BUILD_ALL_SQL->save();
        /*
         * Создаём скрипты инициализации для схем
         */
        dolog('Processing default connection names: {}', array_to_string(array_values(PsConnectionParams::getDefaultConnectionNames())));
        foreach (PsConnectionParams::getDefaultConnectionNames() as $connection) {
            //На момент обработки скоупа мы не должны быть подключены никуда
            PsConnectionPool::assertDisconnectied();
            //Для данного скоупа не задан коннект? Пропускаем...
            if (PsConnectionParams::CONN_ROOT == $connection) {
                dolog('Skip {}', $connection);
                continue;
                //---
            }
            if (!PsConnectionParams::has($connection, $scope)) {
                dolog('No connection properties for {}', $connection);
                continue;
                //---
            }
            //Поработаем с настройками
            $props = PsConnectionParams::get($connection, $scope);
            $database = $props->database();
            if (empty($database)) {
                continue;
                //Не задана БД - пропускаем (для root)
            }
            dolog('Making schema script for {}', $props);
            $SCHEMA_DI = $DM_BUILD->getDirItem('schemas', $database, PsConst::EXT_SQL)->makePath();
            check_condition(!$SCHEMA_DI->isFile(), 'Schema file for database "{}" is already exists. Dublicate database names?', $database);
            $SCHEMA_SQL = $SCHEMA_DI->getSqlFileBuilder();
            //DROP+USE
            $SCHEMA_SQL->clean();
            $SCHEMA_SQL->appendLine("DROP DATABASE IF EXISTS {$database};");
            $SCHEMA_SQL->appendLine("CREATE DATABASE {$database} CHARACTER SET utf8 COLLATE utf8_general_ci;");
            $SCHEMA_SQL->appendLine("USE {$database};");
            //CREATE USER
            $grant = "grant all on {}.* to '{}'@'{}' identified by '{}';";
            $SCHEMA_SQL->appendMlComment('Create user with grants');
            $SCHEMA_SQL->appendLine(PsStrings::replaceWithBraced($grant, $database, $props->user(), $props->host(), $props->password()));
            if ($scope == ENTITY_SCOPE_PROJ) {
                dolog('+ SDK PART');
                //Добавим секцию в лог
                $SCHEMA_SQL->appendMlComment('>>> SDK');
                //CREATE CHEMA SCRIPT
                $SCHEMA_SQL->appendFile($SDK->getDirItem(null, 'schema', PsConst::EXT_SQL));
                //OBJECTS SCRIPT
                $SCHEMA_SQL->appendFile($SDK->getDirItem('build', 'all', PsConst::EXT_SQL));
                //Добавим секцию в лог
                $SCHEMA_SQL->appendMlComment('<<< SDK');
            }
            //CREATE CHEMA SCRIPT
            $SCHEMA_SQL->appendFile($SCHEMA);
            //OBJECTS SCRIPT
            $SCHEMA_SQL->appendFile($DM_BUILD_ALL_SQL->getDi());
            /*
             * Мы должны создать тестовую схему, чтобы убедиться, что всё хорошо и сконфигурировать db.ini
             */
            if ($connection != PsConnectionParams::CONN_TEST) {
                //Всё, сохраняем скрипт, работа закончена
                $SCHEMA_SQL->save();
                continue;
                //---
            }
            /*
             * На тестовой схеме прогоняем скрипт
             */
            dolog('Making physical schema {}', $props);
            $rootProps = PsConnectionParams::get(PsConnectionParams::CONN_ROOT);
            dolog('Root connection props: {}', $rootProps);
            $rootProps->execureShell($SCHEMA_SQL->getDi());
            dolog('Connecting to [{}]', $props);
            PsConnectionPool::configure($props);
            $tables = PsTable::all();
            /*
             * Нам нужно определить новый список таблиц SDK, чтобы по ним 
             * провести валидацию новых db.ini.
             * 
             * Если мы обрабатываем проект, то SDK-шный db.ini уже готов и 
             * можем положиться на него. Если мы подготавливаем SDK-шный db.ini,
             * но новый список таблиц возмём из развёрнутой тестовой БД.
             */
            $sdkTableNames = $scope == ENTITY_SCOPE_SDK ? array_keys($tables) : $SDK->getDirItem('build', 'tables', PsConst::EXT_TXT)->getFileLines();
            if ($scope == ENTITY_SCOPE_PROJ) {
                //Уберём из всех таблиц - SDK`шные
                array_remove_keys($tables, $sdkTableNames);
            }
            $scopeTableNames = array_keys($tables);
            sort($scopeTableNames);
            /*
             * Составим список таблиц.
             * Он нам особенно не нужен, но всёже будем его формировать для наглядности - какие таблицы добавились.
             */
            $TABLES_DI = $DM_BUILD->getDirItem(null, 'tables', PsConst::EXT_TXT)->touch()->putToFile(implode("\n", $scopeTableNames));
            dolog('Tables saved to {}: {}', $TABLES_DI->getRelPath(), print_r($scopeTableNames, true));
            /*
             * Выгрузим данные из таблиц в файл, чтобы убедиться, что всё корректно вставилось.
             */
            if ($scopeTableNames) {
                dolog("Exporting '{}' schema tables data to file", $database);
                $DATA_DI_SQL = $DM_BUILD->getDirItem(null, 'data', PsConst::EXT_SQL)->getSqlFileBuilder();
                $DATA_DI_SQL->clean();
                //Пробегаемся по таблицам
                foreach ($scopeTableNames as $tableName) {
                    $fileData = PsTable::inst($tableName)->exportAsSqlString();
                    if ($fileData) {
                        dolog(' + {} [not empty]', $tableName);
                        $DATA_DI_SQL->appendMlComment('+ table ' . $tableName);
                        $DATA_DI_SQL->appendLine($fileData);
                    } else {
                        dolog(' - {} [empty]', $tableName);
                    }
                }
                $DATA_DI_SQL->save();
            }
            /*
             * Теперь ещё создадим тестовые объекты.
             * Для каждого скоупа свои тестовые данные, так что таблицы можно называть одинаково.
             */
            dolog('Add test part');
            $SCHEMA_SQL->appendMlComment('Test part');
            /*
             if ($scope == ENTITY_SCOPE_PROJ) {
             dolog('+ SDK TEST PART');
            
             //Добавим секцию в лог
             $SCHEMA_SQL->appendMlComment('>>> SDK TEST PART');
            
             //CREATE CHEMA SCRIPT
             $SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/test', 'schema', PsConst::EXT_SQL));
            
             //ADD TEST DATA
             $SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/test', 'data', PsConst::EXT_SQL));
            
             //Добавим секцию в лог
             $SCHEMA_SQL->appendMlComment('<<< SDK TEST PART');
             }
            */
            $SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'schema', PsConst::EXT_SQL), false);
            $SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'data', PsConst::EXT_SQL), false);
            $SCHEMA_SQL->save();
            #end conn== TEST
            /*
             * Всё, сохраняем финальный скрипт
             */
            //SAVE .sql
            $SCHEMA_SQL->save();
            //Переразвернём тестовую схему с тестовыми таблицами
            dolog("Rebuilding checma '{}'", $database);
            $rootProps->execureShell($SCHEMA_SQL->getDi());
            //Отключимся от схемы
            PsConnectionPool::disconnect();
        }
    }
    dolog('Database schemas successfully exported');
}
Ejemplo n.º 7
0
 /**
  * Метод валидирует настройки таблицы, переданные извне
  */
 public static function validateTablePropertiesCustom(PsTable $table, array $tableProperties = null)
 {
     $errors = array();
     if ($tableProperties === null) {
         return $errors;
         // Нет настроет - нет проблем:)
     }
     $tableName = $table->getName();
     //Пробегаемся по настройкам, заданным для таблицы и валидируем её
     foreach ($tableProperties as $propName => $propValue) {
         if (!in_array($propName, self::names())) {
             $errors[] = "Настройка {$propName} для таблицы {$tableName} не существует.";
             continue;
             //---
         }
         $prop = self::valueOf($propName);
         /*
          * Таблица
          */
         if ($prop->isTableProperty()) {
             if (!$prop->isAllowedForTable($table)) {
                 $errors[] = "Настройка {$propName} не допустима для таблицы {$tableName}.";
             }
             continue;
             //---
         }
         /*
          * Столец
          */
         if ($prop->isColumnProperty()) {
             if (!$prop->isAllowedForTableColumns($table)) {
                 $errors[] = "Настройка {$propName} не допустима для столбцов таблицы {$tableName}.";
                 continue;
                 //---
             }
             if (!is_array($propValue)) {
                 $errors[] = "Настройка {$propName} для таблицы {$tableName} должна быть задана в виде массива, передано: " . PsUtil::toString($propValue);
                 continue;
                 //---
             }
             foreach ($propValue as $colName) {
                 if (!$table->hasColumn($colName)) {
                     $errors[] = "Настройка {$propName} для столбца {$tableName}.{$colName} некорректна - столбец не существует.";
                 }
             }
             continue;
             //---
         }
         raise_error("Invalid table col property [{$propName}]");
     }
     /*
      * Если мы обнаружили ошибку или таблица не сконфигурирована - возвращаем.
      * Мы не запрещаем, чтобы в db.ini были настройки для несконфигурированной таблицы,
      * но они должны быть корректно описаны.
      */
     if ($errors || !self::TABLE_CONFIGURED()->isTableHasPropertyCustom($tableName, $tableProperties)) {
         return $errors;
         //---
     }
     //Если нет первичного ключа или он является автоинкремент полем - нужен столбец, замещающий ПК
     if (!self::COL_PK()->getColumnsWithPropertyCustom($tableName, $tableProperties)) {
         //Нет альтернативы ПК
         if (!$table->hasPk()) {
             $errors[] = "Таблица {$tableName} не имеет первичного ключа и его альтернативы";
         } else {
             if ($table->isPkAi()) {
                 $errors[] = "Первичный ключ {$tableName}.{$table->getPk()->getName()} является autoincrement полем, и при этом не имеет альтернативы";
             }
         }
     }
     return $errors;
 }
Ejemplo n.º 8
0
 public function buildContent()
 {
     PsDefines::setReplaceFormulesWithImages(false);
     $navigation = AdminPageNavigation::inst();
     /*
      * Инициализируем необходимые менеджеры
      */
     $TE = TableExporter::inst();
     $RQ = GetArrayAdapter::inst();
     $FORM = FORM_RecEditForm::getInstance();
     $TABLES = PsTable::configured();
     /*
      * Инициализируем параметры, которые нужно будет передать smarty
      */
     $PARAMS['mode'] = null;
     $PARAMS['table'] = null;
     $PARAMS['error'] = null;
     $PARAMS['errors'] = PsDbIniHelper::validateAll();
     /*
      * Обработаем форму
      */
     try {
         if ($FORM->isValid4Process()) {
             $this->processForm($FORM->getData());
         } else {
             if ($FORM->isErrorOccurred()) {
                 $PARAMS['error'] = PsHtml::divErr($FORM->getError());
             }
         }
     } catch (Exception $e) {
         $PARAMS['error'] = ExceptionHandler::getHtml($e);
     }
     /*
      * Обработаем параметры и определим режим работы
      */
     $MODE = $RQ->str('mode', self::MODE_TABLES_LIST);
     /** @var PsTable */
     $TABLE = null;
     // Таблица
     $ROW = null;
     // Редактируемая строка
     switch ($MODE) {
         case self::MODE_ROW_ADD:
             //Если передан фолдинг, то подставим в форму создания его параметры
             $folding = Handlers::getInstance()->getFolding($RQ->str('ftype'), $RQ->str('fsubtype'), false);
             $fident = $RQ->str('fident');
             if ($folding && $folding->getTableName() && $fident) {
                 $TABLE = $TE->getTable($folding);
                 $ROW = $folding->getDbRec4Entity($fident);
                 break;
             }
             $TABLE = PsTable::inst($RQ->str('table'));
             /*
              * Нам не удалось определить внешний вид создаваемой строки, 
              * но если у данной таблицы один фолдинг - возмём вид строки у него.
              */
             $folding = $TABLE->getSingleFolding();
             $ROW = $folding ? $folding->getDbRec4Entity($folding->getNextEntityIdent()) : null;
             break;
         case self::MODE_TABLE_ROWS:
         case self::MODE_TABLE_SQL:
         case self::MODE_TABLE_ARR:
         case self::MODE_ROW_EDIT:
         case self::MODE_ROW_DELETE:
             $TABLE = PsTable::inst($RQ->str('table'));
             switch ($MODE) {
                 case self::MODE_ROW_EDIT:
                 case self::MODE_ROW_DELETE:
                     $ROW = $TABLE->getRow($RQ->int($TABLE->getPk()->getName()));
                     break;
             }
             break;
         case self::MODE_INSERTS:
             //Nothing to do
             break;
         default:
             //Защитимся от некорректного значения параметра 'mode'
             $MODE = self::MODE_TABLES_LIST;
             break;
     }
     $PARAMS['mode'] = $MODE;
     $PARAMS['table'] = $TABLE;
     /*
      * ВЫПОЛНЯЕМ ОБРАБОТКУ
      */
     switch ($MODE) {
         case self::MODE_TABLES_LIST:
             $PARAMS['tables'] = $TABLES;
             $navigation->setCurrent('Список таблиц');
             break;
         case self::MODE_INSERTS:
             $PARAMS['tables'] = $TABLES;
             $navigation->addPath(self::urlTables(), 'Список таблиц');
             $navigation->setCurrent('Вставка данных');
             break;
         case self::MODE_TABLE_ROWS:
             $PARAMS['rows'] = $TABLE->getRows();
             $PARAMS['addurl'] = self::urlRecAdd($TABLE);
             $PARAMS['modified'] = $TABLE->getModifiedRows();
         case self::MODE_TABLE_SQL:
         case self::MODE_TABLE_ARR:
             $navigation->addPath(self::urlTables(), 'Список таблиц');
             $navigation->setCurrent($TABLE->getName());
             break;
         default:
             switch ($MODE) {
                 /*
                  * Помимо действий над записью, мы ещё раздиляем действия над фолдингами 
                  * (если они есть для таблицы). Поэтому мы установм: 
                  * FormAction - для типа редактирования записи
                  * FormButton - для типа работы с фолдингом
                  */
                 case self::MODE_ROW_ADD:
                     $FORM->setFormAction(PS_ACTION_CREATE);
                     $FORM->setButtons(FORM_RecEditForm::BUTTON_CREATE);
                     if ($TABLE->hasFoldings()) {
                         $FORM->addButton(FORM_RecEditForm::BUTTON_CREATEF);
                     }
                     $navigation->setCurrent('Создание записи');
                     break;
                 case self::MODE_ROW_EDIT:
                     $FORM->setFormAction(PS_ACTION_EDIT);
                     $FORM->setButtons(FORM_RecEditForm::BUTTON_EDIT);
                     if ($TABLE->hasFoldings() && !$TABLE->hasFoldingEntity4DbRec($ROW, true)) {
                         $FORM->addButton(FORM_RecEditForm::BUTTON_EDITF);
                     }
                     $navigation->setCurrent('Редактирование записи');
                     break;
                 case self::MODE_ROW_DELETE:
                     $FORM->setFormAction(PS_ACTION_DELETE);
                     $FORM->setButtons(FORM_RecEditForm::BUTTON_DELETE);
                     if ($TABLE->hasFoldingEntity4DbRec($ROW, true)) {
                         $FORM->addButton(FORM_RecEditForm::BUTTON_DELETEF);
                     }
                     $navigation->setCurrent('Удаление записи');
                     break;
                 default:
                     raise_error("Неизвестный режим: [{$MODE}]");
             }
             $FORM->setHidden('table', $TABLE->getName());
             $FORM->setSmartyParam('table', $TABLE);
             $FORM->setSmartyParam('rec', $ROW);
             $navigation->addPath(self::urlTables(), 'Список таблиц');
             $navigation->addPath(self::urlTableRows($TABLE), $TABLE->getName());
             break;
     }
     echo $this->getFoldedEntity()->fetchTpl($PARAMS);
 }
Ejemplo n.º 9
0
 /**
  * Метод расширяет настройки для SDK таблиц - недостающими.
  */
 private static function extendSdkDbIniSettings($scope, array $tableSettings, array $sdkTableNames)
 {
     if ($scope == ENTITY_SCOPE_SDK) {
         $notSelectedTables = array_diff($sdkTableNames, array_keys($tableSettings));
         foreach ($notSelectedTables as $tableName) {
             $tableSettings[$tableName] = array();
             /* @var $property PsTableColumnProps */
             foreach (PsTableColumnProps::getAllowedTableProperties(PsTable::inst($tableName)) as $propName => $property) {
                 $tableSettings[$tableName][$propName] = false;
             }
         }
     }
     return $tableSettings;
 }