-
Notifications
You must be signed in to change notification settings - Fork 179
Initial PostgreSQL support #1933
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 17 commits
6b700c7
16ef756
22dafba
b9934e6
b070b4a
ed7396d
ad555b2
f85fd41
2707e71
c68e6d5
4729e76
4ac9bb8
d9c2312
d3b2e2b
fea65d4
cc659b2
f873aef
d7ab4a0
e827a79
3bbb957
39490e4
89fa4b7
0ec56d4
0d0f50d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| <?php | ||
|
|
||
| declare(strict_types=1); | ||
|
|
||
| namespace Bolt\Doctrine\Query; | ||
|
|
||
| use Doctrine\ORM\Query\AST\Functions\FunctionNode; | ||
| use Doctrine\ORM\Query\Lexer; | ||
| use Doctrine\ORM\Query\Parser; | ||
| use Doctrine\ORM\Query\SqlWalker; | ||
|
|
||
| class Cast extends FunctionNode | ||
| { | ||
| /** @var \Doctrine\ORM\Query\AST\PathExpression */ | ||
| protected $first; | ||
| /** @var string */ | ||
| protected $second; | ||
| /** @var string */ | ||
| protected $backend_driver; | ||
|
|
||
| public function getSql(SqlWalker $sqlWalker): string | ||
| { | ||
| $backend_driver = $sqlWalker->getConnection()->getDriver()->getName(); | ||
|
|
||
| // test if we are using MySQL | ||
| if (mb_strpos($backend_driver, 'mysql') !== false) { | ||
| // YES we are using MySQL | ||
| // how do we know what type $this->first is? For now hardcoding | ||
| // type(t.value) = JSON for MySQL. JSONB for others. | ||
| // alternatively, test if true: $this->first->dispatch($sqlWalker)==='b2_.value', | ||
| // b4_.value for /bolt/new/showcases | ||
| if ($this->first->dispatch($sqlWalker) === 'b2_.value' || | ||
| $this->first->dispatch($sqlWalker) === 'b4_.value') { | ||
| return $this->first->dispatch($sqlWalker); | ||
| } | ||
| } | ||
|
|
||
| return sprintf('CAST(%s AS %s)', | ||
| $this->first->dispatch($sqlWalker), | ||
| $this->second | ||
| ); | ||
| } | ||
|
|
||
| public function parse(Parser $parser): void | ||
| { | ||
| $parser->match(Lexer::T_IDENTIFIER); | ||
| $parser->match(Lexer::T_OPEN_PARENTHESIS); | ||
| $this->first = $parser->ArithmeticPrimary(); | ||
| $parser->match(Lexer::T_AS); | ||
| $parser->match(Lexer::T_IDENTIFIER); | ||
| $this->second = $parser->getLexer()->token['value']; | ||
| $parser->match(Lexer::T_CLOSE_PARENTHESIS); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,22 +9,27 @@ | |
| use Doctrine\DBAL\Driver\PDOConnection; | ||
| use Doctrine\DBAL\Platforms\MariaDb1027Platform; | ||
| use Doctrine\DBAL\Platforms\MySQL57Platform; | ||
| use Doctrine\DBAL\Platforms\PostgreSQL92Platform; | ||
| use Doctrine\DBAL\Platforms\SqlitePlatform; | ||
|
|
||
| class Version | ||
| { | ||
| /** | ||
| * We're g̶u̶e̶s̶s̶i̶n̶g̶ doing empirical research on which versions of SQLite | ||
| * support JSON. So far, tests indicate: | ||
| * https://www.sqlite.org/json1.html --> JSON since SQLite version 3.9.0 (2015-10-14) | ||
| * - 3.32.2 - OK (Wytse's FBSD 12.1 \w PHP 7.2) | ||
| * - 3.20.1 - Not OK (Travis PHP 7.2) | ||
| * - 3.27.2 - OK (Bob's Raspberry Pi, running PHP 7.3.11 on Raspbian) | ||
| * - 3.28.0 - OK (Travis PHP 7.3) | ||
| * - 3.28.0 - Not OK (Bob's PHP 7.2, installed with Brew) | ||
| * - 3.29.0 - OK (MacOS Mojave) | ||
| * - 3.30.1 - OK (MacOS Catalina) | ||
| */ | ||
| public const SQLITE_WITH_JSON = '3.27.0'; | ||
| public const PHP_WITH_SQLITE = '7.3.0'; | ||
| // JSON supported since SQLite version 3.9.0 | ||
| public const SQLITE_WITH_JSON = '3.9.0'; | ||
| // PHP supports SQLite since version 5.3.0 | ||
| public const PHP_WITH_SQLITE = '5.3.0'; | ||
|
||
|
|
||
| /** @var Connection */ | ||
| private $connection; | ||
|
|
@@ -87,6 +92,11 @@ public function hasJson(): bool | |
| return true; | ||
| } | ||
|
|
||
| // PostgreSQL supports JSON from v9.2 and above, later versions are implicitly included | ||
| if ($platform instanceof PostgreSQL92Platform) { | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,7 +21,7 @@ class FieldTranslation implements TranslationInterface | |
| */ | ||
| private $id; | ||
|
|
||
| /** @ORM\Column(type="json") */ | ||
| /** @ORM\Column(type="json", options={"jsonb": true}) */ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| protected $value = []; | ||
|
|
||
| public function getId(): ?int | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| <?php | ||
bobdenotter marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /** | ||
| * Copyright © Vaimo Group. All rights reserved. | ||
| * See LICENSE_VAIMO.txt for license details. | ||
| */ | ||
| namespace Vaimo\WebDriverBinaryDownloader\Analysers; | ||
|
|
||
| class PlatformAnalyser implements \Vaimo\WebDriverBinaryDownloader\Interfaces\PlatformAnalyserInterface | ||
| { | ||
| public function getPlatformCode() | ||
| { | ||
| if (stripos(PHP_OS, 'win') === 0) { | ||
| if (PHP_INT_SIZE === 8) { | ||
| return self::TYPE_WIN64; | ||
| } | ||
|
|
||
| return self::TYPE_WIN32; | ||
| } | ||
|
|
||
| if (stripos(PHP_OS, 'darwin') === 0) { | ||
| return self::TYPE_MAC64; | ||
| } | ||
|
|
||
| if (stripos(PHP_OS, 'linux') === 0) { | ||
| if (PHP_INT_SIZE === 8) { | ||
| return self::TYPE_LINUX64; | ||
| } | ||
|
|
||
| return self::TYPE_LINUX32; | ||
| } | ||
|
|
||
| if (stripos(PHP_OS, 'FreeBSD') === 0) { | ||
| if (PHP_INT_SIZE === 8) { | ||
| return self::TYPE_FREEBSD64; | ||
| } | ||
|
|
||
| return self::TYPE_FREEBSD32; | ||
| } | ||
|
|
||
|
|
||
| throw new \Exception('Platform code detection failed'); | ||
| } | ||
|
|
||
| public function getPlatformName() | ||
| { | ||
| $names = array( | ||
| self::TYPE_LINUX32 => 'Linux 32Bits', | ||
| self::TYPE_LINUX64 => 'Linux 64Bits', | ||
| self::TYPE_MAC64 => 'Mac OS X', | ||
| self::TYPE_WIN32 => 'Windows 32Bits', | ||
| self::TYPE_WIN64 => 'Windows 64Bits', | ||
| self::TYPE_FREEBSD64 => 'FreeBSD 64Bits', | ||
| self::TYPE_FREEBSD32 => 'FreeBSD 32Bits', | ||
| ); | ||
|
|
||
| return $names[$this->getPlatformCode()]; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <?php | ||
bobdenotter marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /** | ||
| * Copyright © Vaimo Group. All rights reserved. | ||
| * See LICENSE_VAIMO.txt for license details. | ||
| */ | ||
| namespace Vaimo\WebDriverBinaryDownloader\Interfaces; | ||
|
|
||
| interface PlatformAnalyserInterface | ||
| { | ||
| const TYPE_LINUX32 = 'linux32'; | ||
| const TYPE_LINUX64 = 'linux64'; | ||
| const TYPE_WIN32 = 'win32'; | ||
| const TYPE_WIN64 = 'win64'; | ||
| const TYPE_MAC64 = 'mac64'; | ||
| const TYPE_FREEBSD64 = 'unix64'; | ||
| const TYPE_FREEBSD32 = 'unix32'; | ||
|
|
||
| /** | ||
| * @return string | ||
| */ | ||
| public function getPlatformCode(); | ||
|
|
||
| /** | ||
| * @return string | ||
| */ | ||
| public function getPlatformName(); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
utf8not the default? Do we need to explicitly set it here?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is better to explicitly set here, to force users to think about the charset.
Additionally, it is hardcoded in
config/packages/doctrine.yamlascharset: utf8mb4, which is fine for MySQL but unsupported in PostgreSQL (for as far as I could find). Setting it in the DATABASE_URL ensures an override to UTF8.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, fair enough! Does Postgres still handle emoji properly, if it doesn't have
utf8mb4?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Emoji should work as they are UTF-8, I'll have to test it to know for sure.
From what I understand, MySQL utf-8 is not really full utf-8, it uses 3-bytes per character instead the regular 4byte. I do not know why it was decided, but here lies the origin: https://github.com/mysql/mysql-server/commit/43a506c0ced0e6ea101d3ab8b4b423ce3fa327d0
That's probably why for MySQL utf8mb4 is required. For postgres. utf8 is full utf8, so 4 byte.
something to keep in mind in case of problems -> https://stackoverflow.com/questions/36198847/what-type-should-i-use-to-store-emoji-in-postgresql