From 8b387117723e6efde8050e08600d4cd5610c8543 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Wed, 3 Apr 2024 06:53:23 +0200 Subject: [PATCH 1/2] expose transport configuration options in transport factory --- CHANGELOG.md | 6 +++ README.md | 37 ++++++++++++------- .../RepositoryFactoryDoctrineDBAL.php | 8 ++++ 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 121e5d6d..2a6ee795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ Changelog 1.x === +1.12.0 +------ + +* Added: Factory now accepts an optional parameter `jackalope.case_sensitive_encoding` to set `Client::setCaseSensitiveEncoding`. +* Bugfix: Factory now actually accepts the optional parameter `jackalope.uuid_generator` + 1.11.2 ------ diff --git a/README.md b/README.md index a5ebd5f0..0110ff58 100644 --- a/README.md +++ b/README.md @@ -46,32 +46,41 @@ $ composer require jackalope/jackalope-doctrine-dbal ## Create a repository -Set up a new database supported by Doctrine DBAL. You can use your favorite GUI frontend or just do something like this: +Set up a new database supported by Doctrine DBAL. You can use your favorite GUI +frontend or use the following commands: ### MySQL -Note that you need at least version 5.1.5 of MySQL, otherwise you will get ``SQLSTATE[42000]: Syntax error or access violation: 1305 FUNCTION cmf-app.EXTRACTVALUE does not exist`` +Note that you need at least version 5.1.5 of MySQL, otherwise you will get +``SQLSTATE[42000]: Syntax error or access violation: 1305 FUNCTION cmf-app.EXTRACTVALUE does not exist`` ```sh -$ mysqladmin -u root -p create database jackalope -$ echo "grant all privileges on jackalope.* to 'jackalope'@'localhost' identified by '1234test'; flush privileges;" | mysql -u root -p +mysqladmin -u root -p create database jackalope +echo "grant all privileges on jackalope.* to 'jackalope'@'localhost' identified by '1234test'; flush privileges;" | mysql -u root -p ``` + +If you run into issues with the encoding, e.g. `SQLSTATE[42000]: Syntax error or access violation: 1253 COLLATION 'utf8_bin' is not valid for CHARACTER SET 'utf8mb4'`, +configure the `charset` when creating the Doctrine DBAL connection, or set the +`jackalope.case_sensitive_encoding` parameter in the call to +`RepositoryFactoryDoctrineDBAL::getRepository`. + ### PostgreSQL ```sh -$ psql -c "CREATE ROLE jackalope WITH ENCRYPTED PASSWORD '1234test' NOINHERIT LOGIN;" -U postgres -$ psql -c "CREATE DATABASE jackalope WITH OWNER = jackalope;" -U postgres +psql -c "CREATE ROLE jackalope WITH ENCRYPTED PASSWORD '1234test' NOINHERIT LOGIN;" -U postgres +psql -c "CREATE DATABASE jackalope WITH OWNER = jackalope;" -U postgres ``` ### SQLite -Database is created automatically if you specify driver and path ("pdo_sqlite", "jackalope.db"). Database name is not needed. +Database is created automatically if you specify driver and path ("pdo_sqlite", +"jackalope.db"). Database name is not needed. For further details, please see the [Doctrine configuration page](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connection-details). ### Oracle -Disclaimer: There is no continous integration with Oracle. Jackalope 1.8.0 was +Disclaimer: There is no continuous integration with Oracle. Jackalope 1.8.0 was successfully tested by one of our users against `Oracle 19c Enterprise Edition`. If you plan to use Jackalope with an Oracle Database, we recommend that you set up the Jackalope test suite to ensure your version of Jackalope and Oracle work @@ -91,7 +100,7 @@ the connection parameters. Then you can run the commands from the jackalope directory with ``./bin/jackalope`` NOTE: If you are using PHPCR inside of **Symfony**, the DoctrinePHPCRBundle -provides the commands inside the normal Symfony console and you don't need to +provides the commands inside the normal Symfony console, and you don't need to prepare anything special. There is the Jackalope specific command ``jackalope:init:dbal`` which you need @@ -145,6 +154,7 @@ $user = 'jackalope'; $pass = ''; $database = 'jackalope'; // $path = 'jackalope.db'; // for SQLite $workspace = 'default'; +$charset = 'utf8mb4'; // for mysql, you need to specify which charset to use // Bootstrap Doctrine $connection = DriverManager::getConnection([ @@ -154,6 +164,7 @@ $connection = DriverManager::getConnection([ 'password' => $pass, 'dbname' => $database, // 'path' => $path, // for SQLite + 'charset' => $charset, // only for MySQL ]); $factory = new RepositoryFactoryDoctrineDBAL(); @@ -232,12 +243,12 @@ use Jackalope\Transport\Logging\DebugStack; $factory = new RepositoryFactoryDoctrineDBAL(); $logger = new DebugStack(); -$options = [ +$parameters = [ 'jackalope.doctrine_dbal_connection' => $connection, 'jackalope.logger' => $logger, ]; -$repository = $factory->getRepository($options); +$repository = $factory->getRepository($parameters); //... @@ -255,8 +266,8 @@ debug toolbar. ## Custom UUID generator By default, Jackalope uses the UUIDHelper class from phpcr-utils. If you want -to use something else, you can provide a closure that returns UUIDs as option -`jackalope.uuid_generator` to `$factory->getRepository($options)` +to use something else, you can provide a closure that returns UUIDs as parameter +`jackalope.uuid_generator` to `$factory->getRepository($parameters)` # Implementation notes diff --git a/src/Jackalope/RepositoryFactoryDoctrineDBAL.php b/src/Jackalope/RepositoryFactoryDoctrineDBAL.php index b2c3442c..b9dd01dc 100644 --- a/src/Jackalope/RepositoryFactoryDoctrineDBAL.php +++ b/src/Jackalope/RepositoryFactoryDoctrineDBAL.php @@ -37,6 +37,7 @@ class RepositoryFactoryDoctrineDBAL implements RepositoryFactoryInterface public const JACKALOPE_DATA_CACHES = 'jackalope.data_caches'; public const JACKALOPE_CHECK_LOGIN_ON_SERVER = 'jackalope.check_login_on_server'; public const JACKALOPE_UUID_GENERATOR = 'jackalope.uuid_generator'; + public const JACKALOPE_CASE_SENSITIVE_ENCODING = 'jackalope.case_sensitive_encoding'; public const JACKALOPE_LOGGER = 'jackalope.logger'; public const JACKALOPE_DISABLE_TRANSACTIONS = 'jackalope.disable_transactions'; public const JACKALOPE_DISABLE_STREAM_WRAPPER = 'jackalope.disable_stream_wrapper'; @@ -59,6 +60,8 @@ class RepositoryFactoryDoctrineDBAL implements RepositoryFactoryInterface private static $optional = [ self::JACKALOPE_FACTORY => 'string or object: Use a custom factory class for Jackalope objects', self::JACKALOPE_CHECK_LOGIN_ON_SERVER => 'boolean: if set to empty or false, skip initial check whether repository exists. Enabled by default, disable to gain a few milliseconds off each repository instantiation.', + self::JACKALOPE_UUID_GENERATOR => 'Closure: A callable that provides universally unique ids to overwrite the default generator.', + self::JACKALOPE_CASE_SENSITIVE_ENCODING => 'string: Define the collation for MySQL. Override if automatic determination fails.', self::JACKALOPE_DISABLE_TRANSACTIONS => 'boolean: if set and not empty, transactions are disabled, otherwise transactions are enabled. If transactions are enabled but not actively used, every save operation is wrapped into a transaction.', self::JACKALOPE_DISABLE_STREAM_WRAPPER => 'boolean: if set and not empty, stream wrapper is disabled, otherwise the stream wrapper is enabled and streams are only fetched when reading from for the first time. If your code always uses all binary properties it reads, you can disable this for a small performance gain.', self::JACKALOPE_DATA_CACHES => 'array: an array of PSR-16 SimpleCache or Doctrine Cache instances. keys can be "meta" and "nodes", should be separate namespaces for best performance.', @@ -110,6 +113,7 @@ public function getRepository(array $parameters = null) || class_exists(ArrayCache::class) ) ; + /** @var CachedClient|Client $transport */ $transport = $canUseCache ? $factory->get(CachedClient::class, [$dbConn, $parameters[self::JACKALOPE_DATA_CACHES]]) : $factory->get(Client::class, [$dbConn]); @@ -122,6 +126,10 @@ public function getRepository(array $parameters = null) $transport->setUuidGenerator($parameters[self::JACKALOPE_UUID_GENERATOR]); } + if (array_key_exists(self::JACKALOPE_CASE_SENSITIVE_ENCODING, $parameters)) { + $transport->setCaseSensitiveEncoding($parameters[self::JACKALOPE_CASE_SENSITIVE_ENCODING]); + } + if (array_key_exists(self::JACKALOPE_LOGGER, $parameters)) { $transport = $factory->get(LoggingClient::class, [$transport, $parameters[self::JACKALOPE_LOGGER]]); } From 453bdeeab22ad93ecfde2ed4247a325a1167b4a3 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Wed, 3 Apr 2024 07:01:43 +0200 Subject: [PATCH 2/2] cs fix --- src/Jackalope/Transport/DoctrineDBAL/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Jackalope/Transport/DoctrineDBAL/Client.php b/src/Jackalope/Transport/DoctrineDBAL/Client.php index cd3c55a6..9bdebaa9 100644 --- a/src/Jackalope/Transport/DoctrineDBAL/Client.php +++ b/src/Jackalope/Transport/DoctrineDBAL/Client.php @@ -1696,7 +1696,7 @@ private function moveNode(string $srcAbsPath, string $destAbsPath): void 'path_prefix' => $srcAbsPath.'/%', 'path' => $srcAbsPath, 'workspace' => $this->workspaceName, - ]); + ]); /* * TODO: https://github.com/jackalope/jackalope-doctrine-dbal/pull/26/files#L0R1057