devimteam/doctrine-extensions

适用于MySQL和PostgreSQL的Doctrine扩展。支持bigint的分支

1.2.0 2017-07-17 10:33 UTC

README

Build Status

目录

DQL函数

此库提供了一组跨数据库的Doctrine DQL函数。支持的数据库是MySQL和PostgreSQL。可用函数

  • DATE(expr) - 提取日期或日期时间表达式的日期部分
  • TIME(expr) - 提取传递的表达式的时分秒部分
  • TIMESTAMP(expr) - 将表达式转换为TIMESTAMP
  • TIMESTAMPDIFF(unit, datetime_expr1, datetime_expr2) - 返回 datetime_expr2datetime_expr1,其中 datetime_expr1datetime_expr2 是日期或日期时间表达式。单位应该是以下值之一:MICROSECOND(微秒)、SECONDMINUTEHOURDAYWEEKMONTHQUARTERYEAR
  • CONVERT_TZ(expr, from_tz, to_tz) - 将日期时间值expr从from_tz指定的时间区域转换为to_tz指定的时间区域,并返回结果日期时间值
  • DAY(expr) - 返回月份中的天数(0-31)
  • DAYOFWEEK(expr) - 返回日期的星期索引(1 = 星期日,2 = 星期一,…,7 = 星期六)。这些索引值对应于ODBC标准。
  • DAYOFMONTH(expr) - 返回日期的月份,范围1到31,或对于'0000-00-00'或'2008-00-00'之类的日期(具有零天部分)为0
  • DAYOFYEAR(expr) - 返回年份中的天数(1-366)
  • HOUR(expr) - 返回日期中的小时
  • MD5(expr) - 计算MD5校验和
  • MINUTE(expr) - 返回日期中的分钟
  • MONTH(expr) - 返回日期中的月份
  • QUARTER(expr) - 返回日期中的季度
  • SECOND(expr) - 返回日期中的秒
  • WEEK(expr) - 一年中年中该天的星期数。根据定义(ISO 8601),星期从星期一开始,一年中的第一周包含该年的1月4日。换句话说,该年的第一个星期四在该年的第一周。
  • YEAR(expr) - 返回日期中的年份
  • POW(expr, power) - 返回指定幂的参数
  • ROUND(value, precision) - 返回具有指定精度的值
  • SIGN(expr) - 返回参数的符号
  • CAST(expr as type) - 接受任何类型的表达式并生成指定类型的值。支持的类型是:"char, string, text, date, datetime, time, int, integer, decimal, boolean"
  • CONCAT_WS - 连接所有除第一个参数之外的所有参数,第一个参数用作分隔符字符串。
  • GROUP_CONCAT - 返回一个连接的字符串
  • REPLACE(subject,from,to) - 在字符串"subject"中替换所有出现的"from"为"to"
  • DATE_FORMAT(date,format) - 根据格式字符串格式化日期值。格式字符串中可以使用以下指定符。在格式指定符字符之前需要使用%字符。

GROUP_CONCAT完整语法

GROUP_CONCAT([DISTINCT] expr [,expr ...]
            [ORDER BY {unsigned_integer | col_name | expr}
                [ASC | DESC] [,col_name ...]]
            [SEPARATOR str_val])

安装

将以下依赖项添加到您的composer.json中

{
    "require": {
        "oro/doctrine-extensions": "dev-master"
    }
}

函数注册

Doctrine2

Doctrine2 文档:"DQL 用户自定义函数"

<?php
$config = new \Doctrine\ORM\Configuration();
$config->addCustomStringFunction('group_concat', 'Oro\ORM\Query\AST\Functions\String\GroupConcat');
$config->addCustomNumericFunction('hour', 'Oro\ORM\Query\AST\Functions\SimpleFunction');
$config->addCustomDatetimeFunction('date', 'Oro\ORM\Query\AST\Functions\SimpleFunction');

$em = EntityManager::create($dbParams, $config);

Symfony2

在Symfony2中,您可以在config.yml中注册函数

doctrine:
    orm:
        dql:
            datetime_functions:
                date:           Oro\ORM\Query\AST\Functions\SimpleFunction
                time:           Oro\ORM\Query\AST\Functions\SimpleFunction
                timestamp:      Oro\ORM\Query\AST\Functions\SimpleFunction
                convert_tz:     Oro\ORM\Query\AST\Functions\DateTime\ConvertTz
            numeric_functions:
                timestampdiff:  Oro\ORM\Query\AST\Functions\Numeric\TimestampDiff
                dayofyear:      Oro\ORM\Query\AST\Functions\SimpleFunction
                dayofmonth:     Oro\ORM\Query\AST\Functions\SimpleFunction
                dayofweek:      Oro\ORM\Query\AST\Functions\SimpleFunction
                week:           Oro\ORM\Query\AST\Functions\SimpleFunction
                day:            Oro\ORM\Query\AST\Functions\SimpleFunction
                hour:           Oro\ORM\Query\AST\Functions\SimpleFunction
                minute:         Oro\ORM\Query\AST\Functions\SimpleFunction
                month:          Oro\ORM\Query\AST\Functions\SimpleFunction
                quarter:        Oro\ORM\Query\AST\Functions\SimpleFunction
                second:         Oro\ORM\Query\AST\Functions\SimpleFunction
                year:           Oro\ORM\Query\AST\Functions\SimpleFunction
                sign:           Oro\ORM\Query\AST\Functions\Numeric\Sign
                pow:            Oro\ORM\Query\AST\Functions\Numeric\Pow
                round:          Oro\ORM\Query\AST\Functions\Numeric\Round
            string_functions:
                md5:            Oro\ORM\Query\AST\Functions\SimpleFunction
                group_concat:   Oro\ORM\Query\AST\Functions\String\GroupConcat
                concat_ws:      Oro\ORM\Query\AST\Functions\String\ConcatWs
                cast:           Oro\ORM\Query\AST\Functions\Cast
                replace:        Oro\ORM\Query\AST\Functions\String\Replace
                date_format:    Oro\ORM\Query\AST\Functions\String\DateFormat

Silex

如果您正在使用ORM服务提供商,请确保您已将自定义函数添加到配置中

对于palmasev/DoctrineORMServiceProvider

    $config = $app['doctrine_orm.configuration'];

    $config->addCustomDateTimeFunction( 'year', 'Oro\ORM\Query\AST\Functions\SimpleFunction' );
    $config->addCustomDateTimeFunction( 'month', 'Oro\ORM\Query\AST\Functions\SimpleFunction' );

对于dflydev/dflydev-doctrine-orm-service-provider

    $app->register( new Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider, [
        ...
        'orm.custom.functions.string' => [
            'md5'           => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'cast'          => 'Oro\ORM\Query\AST\Functions\Cast',
            'group_concat'  => 'Oro\ORM\Query\AST\Functions\String\GroupConcat',
            'concat_ws'     => 'Oro\ORM\Query\AST\Functions\String\ConcatWs',
            'replace'       => 'Oro\ORM\Query\AST\Functions\String\Replace',
            'date_format'   => 'Oro\ORM\Query\AST\Functions\String\DateFormat'
        ],
        'orm.custom.functions.datetime' => [
            'date'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'time'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'timestamp'     => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'convert_tz'    => 'Oro\ORM\Query\AST\Functions\DateTime\ConvertTz'
        ],
        'orm.custom.functions.numeric' => [
            'timestampdiff' => 'Oro\ORM\Query\AST\Functions\Numeric\TimestampDiff',
            'dayofyear'     => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'dayofweek'     => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'week'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'day'           => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'hour'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'minute'        => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'month'         => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'quarter'       => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'second'        => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'year'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
            'sign'          => 'Oro\ORM\Query\AST\Functions\Numeric\Sign',
            'pow'           => 'Oro\ORM\Query\AST\Functions\Numeric\Pow',
            'round'         => 'Oro\ORM\Query\AST\Functions\Numeric\Round',
        ]
    ]);

Zend Framework 2

在Zend Framework 2中,您可以在config/autoload/doctrine.global.php中注册函数

return [
        'doctrine' => [
        'configuration' => [
            'orm_default' => [
                'datetime_functions' => [
                    'date'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'time'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'timestamp'     => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'convert_tz'    => 'Oro\ORM\Query\AST\Functions\DateTime\ConvertTz',
                ],
                'numeric_functions' => [
                    'timestampdiff' => 'Oro\ORM\Query\AST\Functions\Numeric\TimestampDiff',
                    'dayofyear'     => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'dayofmonth'    => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'dayofweek'     => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'week'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'day'           => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'hour'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'minute'        => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'month'         => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'quarter'       => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'second'        => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'year'          => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'sign'          => 'Oro\ORM\Query\AST\Functions\Numeric\Sign',
                    'pow'           => 'Oro\ORM\Query\AST\Functions\Numeric\Pow',
                    'round'         => 'Oro\ORM\Query\AST\Functions\Numeric\Round',
                ],
                'string_functions'  => [
                    'md5'           => 'Oro\ORM\Query\AST\Functions\SimpleFunction',
                    'group_concat'  => 'Oro\ORM\Query\AST\Functions\String\GroupConcat',
                    'cast'          => 'Oro\ORM\Query\AST\Functions\Cast',
                    'concat_ws'     => 'Oro\ORM\Query\AST\Functions\String\ConcatWs',
                    'replace'       => 'Oro\ORM\Query\AST\Functions\String\Replace',
                    'date_format'   => 'Oro\ORM\Query\AST\Functions\String\DateFormat'
                ]
            ]
        ]
    ]
];

可扩展性和数据库支持

架构

大多数仅需要一个算术一级参数的函数可以使用Oro\ORM\Query\AST\Functions\SimpleFunction进行解析。该类负责解析函数定义并将解析后的数据保存到参数中。它从Oro\ORM\Query\AST\Functions\AbstractPlatformAwareFunctionNode扩展而来。这一层处理DQL函数解析。SQL生成是特定平台的函数的责任,这些函数扩展了PlatformFunctionNodeAbstractPlatformAwareFunctionNode根据当前连接数据库平台实例名称和DQL函数名称创建适当平台函数的实例。

平台函数类的命名规则是

Oro\ORM\Query\AST\Platform\Functions\$platformName\$functionName

添加新平台

要添加对新平台的支持,您只需创建新的文件夹Oro\ORM\Query\AST\Platform\Functions\$platformName,并根据命名规则在其中的实现所需函数。

添加新函数

如果您的函数是只有一个算术一级参数的函数,您可能不需要创建DQL函数解析器,而可以使用Oro\ORM\Query\AST\Functions\SimpleFunction。在这种情况下,只需平台特定的函数的SQL实现。

如果您的函数更复杂,例如GROUP_CONCAT,则需要DQL解析器和SQL实现。

如果您想向此库添加新函数,请随时进行分支并创建带有您实现情况的pull request。请记住更新文档以包含您的新函数。所有新函数都必须为所有平台实现。

字段类型

此库还包括额外的字段类型

  • MoneyType
  • PercentType
  • ObjectType
  • ArrayType

ObjectTypeArrayType使用base64编码的字符串来在Db中存储值,而不是存储序列化字符串。为了向后兼容,已存储在Db中的值将在不进行base64编码的情况下反序列化。新值将在存储到Db之前进行base64编码,并在反序列化之前进行base64解码。