Phalcon использует взгляды Oracle - PullRequest
0 голосов
/ 06 июня 2018

В проекте Phalcon у меня есть несколько баз данных в Oracle и mySQL с количеством таблиц и представлений.Созданы модели для соответствующих таблиц и представлений.Но не может получить доступ к просмотрам.Я инициализирую в модели ниже:

public function initialize()
    {
        $this->setConnectionService('dbBznes');
        $this->setSchema('POLICY');
        $this->setSource("BUSINESS_ALL");
    }

1 Ответ

0 голосов
/ 06 июня 2018

Согласно комментариям, это очевидно проблема метаданных, и стратегия метаданных по умолчанию является самоанализом и пытается проверить, существует ли таблица.Вы можете настроить свою собственную стратегию метаданных следующим образом:

$di['modelsMetadata'] = function()
{
    $metadata = new \Phalcon\Mvc\Model\MetaData\Memory();
    $metadata->setStrategy(
        new MyIntrospectionStrategy()
    );

    return $metadata;
};

«Память» в этом случае означает, что вы не должны использовать кэширование метаданных любого рода.Это переходит в другую касательную, поскольку вы можете кэшировать разными способами для большей скорости производства и т. Д.

Что касается класса MyIntrospectionStrategy, описанного выше, он представляет ваш собственный класс на основе стратегии самоанализа Phalcon, которая пытается анализироватьбаза данных для определения полей и их типов, связанных с таблицей.

Я считаю, что я правильно преобразовал Phalcon \ Mvc \ Model \ MetaData \ Strategy \ Introspection из Zephir в PHP следующим образом:

class MyIntrospectionStrategy implements \Phalcon\Mvc\Model\MetaData\StrategyInterface
{

    public final function getMetaData(\Phalcon\Mvc\ModelInterface $model, \Phalcon\DiInterface $dependencyInjector)
    {
        $schema = $model->getSchema();
        $table = $model->getSource();

        $readConnection = $model->getReadConnection();



        if( !$readConnection->tableExists($table, $schema) )
        {
            if($schema)
            {
                $completeTable = $schema . "'.'" . $table;
            } else {
                $completeTable = $table;
            }

            throw new \Phalcon\Mvc\Model\Exception(
                "Table '" . $completeTable . "' doesn't exist in database when dumping meta-data for " . get_class($model)
            );
        }



        $columns = $readConnection->describeColumns($table, $schema);

        if( !count($columns) )
        {

            if($schema)
            {
                $completeTable = $schema . "'.'" . $table;
            } else {
                $completeTable = $table;
            }

            /**
             * The table not exists
             */
            throw new \Phalcon\Mvc\Model\Exception(
                "Cannot obtain table columns for the mapped source '" . completeTable . "' used in model " . get_class(model)
            );
        }



        $attributes = [];
        $primaryKeys = [];
        $nonPrimaryKeys = [];
        $numericTyped = [];
        $notNull = [];
        $fieldTypes = [];
        $fieldBindTypes = [];
        $automaticDefault = [];
        $identityField = false;
        $defaultValues = [];
        $emptyStringValues = [];

        foreach($columns as $column)
        {

            $fieldName = $column->getName();
            $attributes[] = $fieldName;

            if ($column->isPrimary() === true)
            {
                $primaryKeys[] = $fieldName;
            } else {
                $nonPrimaryKeys[] = $fieldName;
            }

            if ($column->isNumeric() === true)
            {
                $numericTyped[$fieldName] = true;
            }

            if ($column->isNotNull() === true)
            {
                $notNull[] = $fieldName;
            }

            if ($column->isAutoIncrement() === true)
            {
                $identityField = $fieldName;
            }

            $fieldTypes[$fieldName] = $column->getType();

            $fieldBindTypes[$fieldName] = $column->getBindType();

            $defaultValue = $column->getDefault();
            if ($defaultValue !== null || $column->isNotNull() === false)
            {
                if ( !$column->isAutoIncrement() )
                {
                    $defaultValues[$fieldName] = $defaultValue;
                }
            }
        }

        return [
            \Phalcon\Mvc\Model\MetaData::MODELS_ATTRIBUTES               => $attributes,
            \Phalcon\Mvc\Model\MetaData::MODELS_PRIMARY_KEY              => $primaryKeys,
            \Phalcon\Mvc\Model\MetaData::MODELS_NON_PRIMARY_KEY          => $nonPrimaryKeys,
            \Phalcon\Mvc\Model\MetaData::MODELS_NOT_NULL                 => $notNull,
            \Phalcon\Mvc\Model\MetaData::MODELS_DATA_TYPES               => $fieldTypes,
            \Phalcon\Mvc\Model\MetaData::MODELS_DATA_TYPES_NUMERIC       => $numericTyped,
            \Phalcon\Mvc\Model\MetaData::MODELS_IDENTITY_COLUMN          => $identityField,
            \Phalcon\Mvc\Model\MetaData::MODELS_DATA_TYPES_BIND          => $fieldBindTypes,
            \Phalcon\Mvc\Model\MetaData::MODELS_AUTOMATIC_DEFAULT_INSERT => $automaticDefault,
            \Phalcon\Mvc\Model\MetaData::MODELS_AUTOMATIC_DEFAULT_UPDATE => $automaticDefault,
            \Phalcon\Mvc\Model\MetaData::MODELS_DEFAULT_VALUES           => $defaultValues,
            \Phalcon\Mvc\Model\MetaData::MODELS_EMPTY_STRING_VALUES      => $emptyStringValues
        ];

    }


    public final function getColumnMaps(\Phalcon\Mvc\ModelInterface $model, \Phalcon\DiInterface $dependencyInjector)
    {
        $orderedColumnMap = null;
        $reversedColumnMap = null;

        if (method_exists($model, 'columnMap'))
        {

            $userColumnMap = $model->columnMap();
            if ( gettype($userColumnMap) != 'array')
            {
                // Bad grammer directly in cphalcon :sadface:
                throw new \Phalcon\Mvc\Model\Exception('columnMap() not returned an array');
            }

            $reversedColumnMap = [];
            $orderedColumnMap = $userColumnMap;
            foreach($userColumnMap as $name => $userName)
            {
                $reversedColumnMap[$userName] = $name;
            }
        }

        return [$orderedColumnMap, $reversedColumnMap];
    }


}

Я не проверял это.

Если добавить поддержку представлений, которые будут обрабатываться как таблицы, изменение может быть простым:

До:

if( !$readConnection->tableExists($table, $schema) )

После:

if( !$readConnection->tableExists($table, $schema) && !$readConnection->viewExists($table, $schema) )

Если это не сработает из-за удушья логики с descriptionColumns, вам может потребоваться написать что-то конкретное для работы с представлениями в Oracle для этого диалекта.

Что касается других решений, вы можете предоставить собственный метод метаданных непосредственно в модели, указав свой собственный метод metaData непосредственно в нем.

Anotее решение состоит в том, чтобы использовать метаданные вместо интроспекции.Затем вы поместите свои метаданные в виде комментариев в код для анализа Phalcon.

Если вы продолжаете сталкиваться с проблемами с представлениями базы данных, просто запустите их как необработанный SQL, а не пытайтесь использовать ORM для этого,Вы можете просто определить новый метод в вашей модели для запуска необработанного SQL.

...