From 51d93393ddced649da6066db233bc8e285a6588c Mon Sep 17 00:00:00 2001 From: Barry O'Donovan Date: Sat, 14 Jul 2018 09:34:24 +0100 Subject: [PATCH] Add MySQL IS_IPV4_MAPPED/COMPAT functions --- README.md | 2 +- config/mysql.yml | 2 ++ src/Query/Mysql/IsIpv4Compat.php | 44 ++++++++++++++++++++++++++ src/Query/Mysql/IsIpv4Mapped.php | 44 ++++++++++++++++++++++++++ tests/Query/Mysql/IsIpv4CompatTest.php | 16 ++++++++++ tests/Query/Mysql/IsIpv4MappedTest.php | 16 ++++++++++ 6 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/Query/Mysql/IsIpv4Compat.php create mode 100644 src/Query/Mysql/IsIpv4Mapped.php create mode 100644 tests/Query/Mysql/IsIpv4CompatTest.php create mode 100644 tests/Query/Mysql/IsIpv4MappedTest.php diff --git a/README.md b/README.md index 31343ce0..76051ee0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ MySQL, Oracle, PostgreSQL and SQLite. | DB | Functions | |:--:|:---------:| -| MySQL | `ACOS, AES_DECRYPT, AES_ENCRYPT, ANY_VALUE, ASCII, ASIN, ATAN, ATAN2, BINARY, BIT_COUNT, BIT_XOR, CAST, CEIL, CHAR_LENGTH, COLLATE, CONCAT_WS, CONVERT_TZ, COS, COT, COUNTIF, CRC32, DATE, DATE_FORMAT, DATEADD, DATEDIFF, DATESUB, DAY, DAYNAME, DAYOFWEEK, DAYOFYEAR, DEGREES, DIV, EXP, EXTRACT, FIELD, FIND_IN_SET, FLOOR, FROM_UNIXTIME, GREATEST, GROUP_CONCAT, HEX, HOUR, IFELSE, IFNULL, INET_ATON, INET_NTOA, INET6_ATON, INET6_NTOA, INSTR, IS_IPV4, IS_IPV6, LAST_DAY, LEAST, LOG, LOG10, LOG2, LPAD, MATCH, MD5, MINUTE, MONTH, MONTHNAME, NOW, NULLIF, PERIOD_DIFF, PI, POWER, QUARTER, RADIANS, RAND, REGEXP, REPLACE, ROUND, RPAD, SECOND, SECTOTIME, SHA1, SHA2, SIN, SOUNDEX, STD, STDDEV, STRTODATE, STR_TO_DATE, SUBSTRING_INDEX, TAN, TIME, TIMEDIFF, TIMESTAMPADD, TIMESTAMPDIFF, TIMETOSEC, UNHEX, UNIX_TIMESTAMP, UTC_TIMESTAMP, UUID_SHORT, VARIANCE, WEEK, WEEKDAY, YEAR, YEARMONTH, YEARWEEK` | +| MySQL | `ACOS, AES_DECRYPT, AES_ENCRYPT, ANY_VALUE, ASCII, ASIN, ATAN, ATAN2, BINARY, BIT_COUNT, BIT_XOR, CAST, CEIL, CHAR_LENGTH, COLLATE, CONCAT_WS, CONVERT_TZ, COS, COT, COUNTIF, CRC32, DATE, DATE_FORMAT, DATEADD, DATEDIFF, DATESUB, DAY, DAYNAME, DAYOFWEEK, DAYOFYEAR, DEGREES, DIV, EXP, EXTRACT, FIELD, FIND_IN_SET, FLOOR, FROM_UNIXTIME, GREATEST, GROUP_CONCAT, HEX, HOUR, IFELSE, IFNULL, INET_ATON, INET_NTOA, INET6_ATON, INET6_NTOA, INSTR, IS_IPV4, IS_IPV4_COMPAT, IS_IPV4_MAPPED, IS_IPV6, LAST_DAY, LEAST, LOG, LOG10, LOG2, LPAD, MATCH, MD5, MINUTE, MONTH, MONTHNAME, NOW, NULLIF, PERIOD_DIFF, PI, POWER, QUARTER, RADIANS, RAND, REGEXP, REPLACE, ROUND, RPAD, SECOND, SECTOTIME, SHA1, SHA2, SIN, SOUNDEX, STD, STDDEV, STRTODATE, STR_TO_DATE, SUBSTRING_INDEX, TAN, TIME, TIMEDIFF, TIMESTAMPADD, TIMESTAMPDIFF, TIMETOSEC, UNHEX, UNIX_TIMESTAMP, UTC_TIMESTAMP, UUID_SHORT, VARIANCE, WEEK, WEEKDAY, YEAR, YEARMONTH, YEARWEEK` | | Oracle | `DAY, LISTAGG, MONTH, NVL, TO_CHAR, TO_DATE, TRUNC, YEAR` | | Sqlite | `DATE, MINUTE, HOUR, DAY, WEEK, WEEKDAY, MONTH, YEAR, STRFTIME, DATE_FORMAT*, CASE WHEN THEN ELSE END, IFNULL, REPLACE, ROUND` | | PostgreSQL | `TO_DATE, TO_CHAR, AT_TIME_ZONE, COUNT_FILTER, STRING_AGG` | diff --git a/config/mysql.yml b/config/mysql.yml index 3bb925a2..83c99b16 100644 --- a/config/mysql.yml +++ b/config/mysql.yml @@ -92,6 +92,8 @@ doctrine: inet6_ntoa: DoctrineExtensions\Query\Mysql\Inet6Ntoa instr: DoctrineExtensions\Query\Mysql\Instr is_ipv4: DoctrineExtensions\Query\Mysql\IsIpv4 + is_ipv4_compat: DoctrineExtensions\Query\Mysql\IsIpv4Compat + is_ipv4_mapped: DoctrineExtensions\Query\Mysql\IsIpv4Mapped is_ipv6: DoctrineExtensions\Query\Mysql\IsIpv6 least: DoctrineExtensions\Query\Mysql\Least lpad: DoctrineExtensions\Query\Mysql\Lpad diff --git a/src/Query/Mysql/IsIpv4Compat.php b/src/Query/Mysql/IsIpv4Compat.php new file mode 100644 index 00000000..8324a255 --- /dev/null +++ b/src/Query/Mysql/IsIpv4Compat.php @@ -0,0 +1,44 @@ +match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + $this->valueExpression = $parser->StringPrimary(); + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } + + /** + * @param SqlWalker $sqlWalker + * + * @return string + */ + public function getSql(SqlWalker $sqlWalker) + { + return 'IS_IPV4_COMPAT(' + . ( + $this->valueExpression instanceof Node + ? $this->valueExpression->dispatch($sqlWalker) + : "'" . $this->valueExpression . "'" + ) + .')'; + } +} diff --git a/src/Query/Mysql/IsIpv4Mapped.php b/src/Query/Mysql/IsIpv4Mapped.php new file mode 100644 index 00000000..56171377 --- /dev/null +++ b/src/Query/Mysql/IsIpv4Mapped.php @@ -0,0 +1,44 @@ +match(Lexer::T_IDENTIFIER); + $parser->match(Lexer::T_OPEN_PARENTHESIS); + $this->valueExpression = $parser->StringPrimary(); + $parser->match(Lexer::T_CLOSE_PARENTHESIS); + } + + /** + * @param SqlWalker $sqlWalker + * + * @return string + */ + public function getSql(SqlWalker $sqlWalker) + { + return 'IS_IPV4_MAPPED(' + . ( + $this->valueExpression instanceof Node + ? $this->valueExpression->dispatch($sqlWalker) + : "'" . $this->valueExpression . "'" + ) + .')'; + } +} diff --git a/tests/Query/Mysql/IsIpv4CompatTest.php b/tests/Query/Mysql/IsIpv4CompatTest.php new file mode 100644 index 00000000..d5cb76c2 --- /dev/null +++ b/tests/Query/Mysql/IsIpv4CompatTest.php @@ -0,0 +1,16 @@ +assertDqlProducesSql( + "SELECT IS_IPV4_COMPAT(INET6_ATON('::192.0.2.1')) FROM DoctrineExtensions\Tests\Entities\Blank b", + "SELECT IS_IPV4_COMPAT(INET6_ATON('::192.0.2.1')) AS sclr_0 FROM Blank b0_" + ); + } +} diff --git a/tests/Query/Mysql/IsIpv4MappedTest.php b/tests/Query/Mysql/IsIpv4MappedTest.php new file mode 100644 index 00000000..f878e6dd --- /dev/null +++ b/tests/Query/Mysql/IsIpv4MappedTest.php @@ -0,0 +1,16 @@ +assertDqlProducesSql( + "SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:192.0.2.1')) FROM DoctrineExtensions\Tests\Entities\Blank b", + "SELECT IS_IPV4_MAPPED(INET6_ATON('::ffff:192.0.2.1')) AS sclr_0 FROM Blank b0_" + ); + } +}