Exemple #1
0
function executeProcess(array $argv)
{
    $CLASS_PATTERN = file_get_contents(file_path(__DIR__, 'class.txt'));
    $METHOD_PATTERN = file_get_contents(file_path(__DIR__, 'method.txt'));
    /*
     * Название тестового файла.
     * Для проверки мы сначала удалим класс для него, если он был, потом проверим, что за класс был сгенерирован.
     */
    $TEST_MESSAGES_FILE = 'ExampleSdkProcessMessages';
    //Убедимся, что тестовый .msgs существует и удалим тестовый .php файл
    $TEST_PHP_DI = DirItem::inst(__DIR__ . '/classes', $TEST_MESSAGES_FILE, PsConst::EXT_PHP)->remove();
    $TEST_MSGS_DI = DirItem::inst(__DIR__ . '/classes', $TEST_MESSAGES_FILE, PsConst::EXT_MSGS);
    check_condition($TEST_MSGS_DI->isFile(), "File {$TEST_MSGS_DI->getAbsPath()} must exists");
    dolog('Loading all files, ended with Messages.msgs');
    //TODO - после нужно получать эту информацию из какого-нибудь места
    $exceptDirs[] = DirManager::autogen()->relDirPath();
    $exceptDirs[] = DirManager::resources()->relDirPath();
    $exceptDirs[] = DirManager::stuff()->relDirPath();
    //$exceptDirs = array();
    $items = DirManager::inst()->getDirContentFull(null, function (DirItem $di) {
        dolog($di->getAbsPath());
        return $di->isFile() && ends_with($di->getName(), 'Messages.msgs');
    }, $exceptDirs);
    dolog('Message files for processing: {}', count($items));
    //Проверим, что был выбран тестовый файл
    check_condition(in_array($TEST_MSGS_DI, $items, true), "Test file [{$TEST_MESSAGES_FILE}] is not included");
    //Удалим его из массива...
    array_remove_value($items, $TEST_MSGS_DI, true);
    //И поместим наверх, чтобы он был обработан первым
    array_unshift($items, $TEST_MSGS_DI);
    /* @var $msgsDi DirItem */
    foreach ($items as $msgsDi) {
        LOGBOX('PROCESSING [{}]', $msgsDi->getAbsPath());
        //Сбросим методы
        $METHODS = array();
        //Извлечём название класса
        $CLASS = $msgsDi->getNameNoExt();
        //DirItem файла с сообщениями php
        $classDi = DirItem::inst($msgsDi->getDirname(), $CLASS, PsConst::EXT_PHP);
        //Получаем сообщения из файла .msgs
        $messages = $msgsDi->getFileAsProps();
        foreach ($messages as $MSG_KEY => $MGG_VALUE) {
            dolog(' >> {}={}', $MSG_KEY, $MGG_VALUE);
            //Получим список всех параметров из макросов ({0}, {1}, {2} и т.д.)
            preg_match_all("/\\{(.+?)\\}/", $MGG_VALUE, $args);
            $args = array_values(array_unique($args[1]));
            sort($args, SORT_NUMERIC);
            $ARGS = array();
            for ($index = 0; $index < count($args); $index++) {
                $arg = $args[$index];
                $lineDescr = PsStrings::replaceWithBraced('[{}] in line [{}={}]', $msgsDi->getRelPath(), $MSG_KEY, $MGG_VALUE);
                check_condition(is_inumeric($arg), "Invalid argument [{$arg}] for {$lineDescr}");
                check_condition($index == $args[$index], "Missing index [{$index}] for {$lineDescr}");
                $ARGS[] = '$p' . $index;
            }
            $ARGS = join(', ', $ARGS);
            //Добавляем метод
            dolog(" A: {}::{} ({})", $CLASS, $MSG_KEY, $ARGS);
            $PARAMS['SUPPORT_CLASS'] = PsMsgs::getClass();
            $PARAMS['MESSAGE'] = $MGG_VALUE;
            $PARAMS['FUNCTION'] = $MSG_KEY;
            $PARAMS['ARGS'] = $ARGS;
            $METHODS[] = PsStrings::replaceMapBracedKeys($METHOD_PATTERN, $PARAMS);
        }
        dolog('Made methods: ({})', count($METHODS));
        if ($METHODS) {
            $PARAMS['FILE'] = $msgsDi->getAbsPath();
            $PARAMS['CLASS'] = $CLASS;
            $PARAMS['DATE'] = date(DF_PS);
            $PARAMS['METHODS'] = "\n" . join("\n\n", $METHODS) . "\n";
            $CLASS_PHP = PsStrings::replaceMapBracedKeys($CLASS_PATTERN, $PARAMS);
            $classDi->putToFile($CLASS_PHP);
        }
        /*
         * Если обрабатываем тестовый файл - проверим его
         */
        //TEST CLASS VALIDATION START >>>
        if ($msgsDi->equals($TEST_MSGS_DI)) {
            dolog('');
            dolog('Validating test class {}', $TEST_MESSAGES_FILE);
            //Проверим, что .php был сгенерирован
            check_condition($TEST_PHP_DI->isFile(), "File {$TEST_PHP_DI->getAbsPath()} was not created!");
            //Проверим, что для каждого сообщения был создан метод
            $methods = PsUtil::newReflectionClass($TEST_MESSAGES_FILE)->getMethods();
            $messages = $TEST_MSGS_DI->getFileAsProps();
            check_condition(count($methods) == count($messages), 'Methods count missmatch, check ' . $TEST_PHP_DI->getAbsPath());
            /* @var $method ReflectionMethod */
            foreach ($methods as $method) {
                check_condition(array_key_exists($method->getName(), $messages), "No method {$TEST_MESSAGES_FILE}::" . $method->getName());
            }
            //Проверим, что возвращают методы тестового сгенерированного класса
            function doTest($className, $methodName, array $params, $expected)
            {
                $method = "{$className}::{$methodName}";
                $actual = call_user_func_array($method, $params);
                dolog("{}({})='{}', Expected='{}'", $method, join(', ', $params), $actual, $expected);
                check_condition($actual == $expected, "{$actual} != {$expected}");
            }
            doTest($TEST_MESSAGES_FILE, 'message1', array(), 'Message 1');
            doTest($TEST_MESSAGES_FILE, 'message2', array('a', 'b', 'c'), 'Parametred a,c,b');
            dolog('Test class is valid!');
        }
        //TEST CLASS VALIDATION END <<<
    }
    //# DirItems validation end
}
Exemple #2
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');
}
Exemple #3
0
 */
LOGBOX('Set consts');
$props = DirItem::inst(__DIR__, 'consts.txt')->getFileAsProps();
dolog(print_r($props, true));
PsGlobals::inst()->updateProps($props);
/*
 * УДАЛИМ ТЕСТОВЫЕ ДИРЕКТОРИИ
 */
LOGBOX('Remove test dirs');
$dirs = DirManager::inst()->getDirContentFull(null, DirItemFilter::DIRS);
$testDirNames = array('temp', 'orig', '4use', 'tests', 'testcase');
$testDirStartsWith = array('!');
/* @var $dir DirItem */
foreach ($dirs as $dir) {
    if (in_array($dir->getName(), $testDirNames) || starts_with($dir->getName(), $testDirStartsWith)) {
        $path = $dir->getAbsPath();
        dolog('Removing: ' . $path);
        DirManager::inst($path)->clearDir(null, true);
    }
}
/*
 * УДАЛИМ АРХИВЫ
 */
LOGBOX('Remove archivs');
$archivs = DirManager::inst()->getDirContentFull(null, DirItemFilter::ARCHIVES);
/* @var $dir DirItem */
foreach ($archivs as $arc) {
    dolog('Removing: ' . $arc->getAbsPath());
    $arc->remove();
}
dolog("\nFile actions successfully finished\n");