feat: inital commit for multiple db pools
This commit is contained in:
parent
f1afc45ae2
commit
039d9f0ead
2
.env
2
.env
|
@ -23,6 +23,8 @@ _APP_DB_SCHEMA=appwrite
|
|||
_APP_DB_USER=user
|
||||
_APP_DB_PASS=password
|
||||
_APP_DB_ROOT_PASS=rootsecretpassword
|
||||
_APP_PROJECT_DB=db_fra1_02=mysql://user:password@mariadb:3306/appwrite
|
||||
_APP_CONSOLE_DB=db_fra1_01=mysql://user:password@mariadb:3306/appwrite
|
||||
_APP_STORAGE_DEVICE=Local
|
||||
_APP_STORAGE_S3_ACCESS_KEY=
|
||||
_APP_STORAGE_S3_SECRET=
|
||||
|
|
|
@ -390,6 +390,17 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'database',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'logo',
|
||||
'type' => Database::VAR_STRING,
|
||||
|
|
|
@ -104,6 +104,7 @@ App::post('/v1/projects')
|
|||
'domains' => null,
|
||||
'auths' => $auths,
|
||||
'search' => implode(' ', [$projectId, $name]),
|
||||
'database'
|
||||
]));
|
||||
/** @var array $collections */
|
||||
$collections = Config::getParam('collections', []);
|
||||
|
|
|
@ -66,7 +66,7 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
|||
do {
|
||||
try {
|
||||
$attempts++;
|
||||
$db = $register->get('dbPool')->get();
|
||||
$pool = $register->get('poolForConsole')->get();
|
||||
$redis = $register->get('redisPool')->get();
|
||||
break; // leave the do-while if successful
|
||||
} catch (\Exception $e) {
|
||||
|
|
115
app/init.php
115
app/init.php
|
@ -23,6 +23,8 @@ use Ahc\Jwt\JWT;
|
|||
use Ahc\Jwt\JWTException;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Database\DatabasePool;
|
||||
use Appwrite\DSN\DSN;
|
||||
use Appwrite\Event\Audit;
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
|
@ -442,29 +444,98 @@ $register->set('logger', function () {
|
|||
$adapter = new $classname($providerConfig);
|
||||
return new Logger($adapter);
|
||||
});
|
||||
$register->set('dbPool', function () {
|
||||
|
||||
$register->set('poolForConsole', function () {
|
||||
$dbs = App::getEnv('_APP_CONSOLE_DB', '');
|
||||
$dbs = explode(',', $dbs);
|
||||
|
||||
$pools = new DatabasePool();
|
||||
foreach ($dbs as $db) {
|
||||
$db = explode('=', $db);
|
||||
$name = $db[0];
|
||||
$dsn = new DSN($db[1]);
|
||||
|
||||
// var_dump($dsn->getHost(), $dsn->getPort(), $dsn->getDatabase(), $dsn->getUser(), $dsn->getPassword());
|
||||
|
||||
$pool = new PDOPool(
|
||||
(new PDOConfig())
|
||||
->withHost($dsn->getHost())
|
||||
->withPort($dsn->getPort())
|
||||
->withDbName($dsn->getDatabase())
|
||||
->withCharset('utf8mb4')
|
||||
->withUsername($dsn->getUser())
|
||||
->withPassword($dsn->getPassword())
|
||||
->withOptions([
|
||||
PDO::ATTR_ERRMODE => App::isDevelopment() ? PDO::ERRMODE_WARNING : PDO::ERRMODE_SILENT, // If in production mode, warnings are not displayed
|
||||
]),
|
||||
64
|
||||
);
|
||||
|
||||
$pools->add($name, $pool);
|
||||
}
|
||||
|
||||
return $pools;
|
||||
});
|
||||
|
||||
$register->set('poolForProject', function () {
|
||||
// Register DB connection
|
||||
$dbHost = App::getEnv('_APP_DB_HOST', '');
|
||||
$dbPort = App::getEnv('_APP_DB_PORT', '');
|
||||
$dbUser = App::getEnv('_APP_DB_USER', '');
|
||||
$dbPass = App::getEnv('_APP_DB_PASS', '');
|
||||
$dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
|
||||
// $dbHost = App::getEnv('_APP_DB_HOST', '');
|
||||
// $dbPort = App::getEnv('_APP_DB_PORT', '');
|
||||
// $dbUser = App::getEnv('_APP_DB_USER', '');
|
||||
// $dbPass = App::getEnv('_APP_DB_PASS', '');
|
||||
// $dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
|
||||
|
||||
$pool = new PDOPool(
|
||||
(new PDOConfig())
|
||||
->withHost($dbHost)
|
||||
->withPort($dbPort)
|
||||
->withDbName($dbScheme)
|
||||
->withCharset('utf8mb4')
|
||||
->withUsername($dbUser)
|
||||
->withPassword($dbPass)
|
||||
->withOptions([
|
||||
PDO::ATTR_ERRMODE => App::isDevelopment() ? PDO::ERRMODE_WARNING : PDO::ERRMODE_SILENT, // If in production mode, warnings are not displayed
|
||||
]),
|
||||
64
|
||||
);
|
||||
// var_dump($dbHost, $dbPort, $dbScheme, $dbUser, $dbPass);
|
||||
// $pool = new PDOPool(
|
||||
// (new PDOConfig())
|
||||
// ->withHost($dbHost)
|
||||
// ->withPort($dbPort)
|
||||
// ->withDbName($dbScheme)
|
||||
// ->withCharset('utf8mb4')
|
||||
// ->withUsername($dbUser)
|
||||
// ->withPassword($dbPass)
|
||||
// ->withOptions([
|
||||
// PDO::ATTR_ERRMODE => App::isDevelopment() ? PDO::ERRMODE_WARNING : PDO::ERRMODE_SILENT, // If in production mode, warnings are not displayed
|
||||
// ]),
|
||||
// 64
|
||||
// );
|
||||
|
||||
return $pool;
|
||||
// return $pool;
|
||||
|
||||
// $dbForConsole = App::getEnv('_APP_CONSOLE_DB', '');
|
||||
// $dbForConsole = explode('=', $dbForConsole);
|
||||
// $name = $dbForConsole[0];
|
||||
// $dsn = new DSN($dbForConsole[1]);
|
||||
|
||||
$dbs = App::getEnv('_APP_PROJECT_DB', '');
|
||||
$dbs = explode(',', $dbs);
|
||||
|
||||
$pools = new DatabasePool();
|
||||
foreach ($dbs as $db) {
|
||||
$db = explode('=', $db);
|
||||
$name = $db[0];
|
||||
$dsn = new DSN($db[1]);
|
||||
|
||||
// var_dump($dsn->getHost(), $dsn->getPort(), $dsn->getDatabase(), $dsn->getUser(), $dsn->getPassword());
|
||||
|
||||
$pool = new PDOPool(
|
||||
(new PDOConfig())
|
||||
->withHost($dsn->getHost())
|
||||
->withPort($dsn->getPort())
|
||||
->withDbName($dsn->getDatabase())
|
||||
->withCharset('utf8mb4')
|
||||
->withUsername($dsn->getUser())
|
||||
->withPassword($dsn->getPassword())
|
||||
->withOptions([
|
||||
PDO::ATTR_ERRMODE => App::isDevelopment() ? PDO::ERRMODE_WARNING : PDO::ERRMODE_SILENT, // If in production mode, warnings are not displayed
|
||||
]),
|
||||
64
|
||||
);
|
||||
|
||||
$pools->add($name, $pool);
|
||||
}
|
||||
|
||||
return $pools;
|
||||
});
|
||||
$register->set('redisPool', function () {
|
||||
$redisHost = App::getEnv('_APP_REDIS_HOST', '');
|
||||
|
@ -867,6 +938,10 @@ App::setResource('console', function () {
|
|||
App::setResource('dbForProject', function ($db, $cache, $project) {
|
||||
$cache = new Cache(new RedisCache($cache));
|
||||
|
||||
// Get name of database from the projects collection in the console DB
|
||||
|
||||
// $dbName = $project->getAttribute('database','');
|
||||
|
||||
$database = new Database(new MariaDB($db), $cache);
|
||||
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
|
||||
$database->setNamespace("_{$project->getId()}");
|
||||
|
|
192
composer.lock
generated
192
composer.lock
generated
|
@ -689,16 +689,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
"version": "2.2.1",
|
||||
"version": "2.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/psr7.git",
|
||||
"reference": "c94a94f120803a18554c1805ef2e539f8285f9a2"
|
||||
"reference": "a119247127ff95789a2d95c347cd74721fbedaa4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2",
|
||||
"reference": "c94a94f120803a18554c1805ef2e539f8285f9a2",
|
||||
"url": "https://api.github.com/repos/guzzle/psr7/zipball/a119247127ff95789a2d95c347cd74721fbedaa4",
|
||||
"reference": "a119247127ff95789a2d95c347cd74721fbedaa4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -784,7 +784,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/psr7/issues",
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.2.1"
|
||||
"source": "https://github.com/guzzle/psr7/tree/2.2.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -800,7 +800,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-20T21:55:58+00:00"
|
||||
"time": "2022-06-08T19:55:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "influxdb/influxdb-php",
|
||||
|
@ -1704,88 +1704,6 @@
|
|||
],
|
||||
"time": "2022-02-25T11:15:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.26.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
|
||||
"reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.26-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-24T11:49:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.26.0",
|
||||
|
@ -2905,21 +2823,21 @@
|
|||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.10.0",
|
||||
"version": "1.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozarts/assert.git",
|
||||
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
|
||||
"reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
|
||||
"url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
"ext-ctype": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"phpstan/phpstan": "<0.12.20",
|
||||
|
@ -2957,9 +2875,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozarts/assert/issues",
|
||||
"source": "https://github.com/webmozarts/assert/tree/1.10.0"
|
||||
"source": "https://github.com/webmozarts/assert/tree/1.11.0"
|
||||
},
|
||||
"time": "2021-03-09T10:59:23+00:00"
|
||||
"time": "2022-06-03T18:03:27+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
@ -5086,6 +5004,88 @@
|
|||
],
|
||||
"time": "2022-04-18T20:38:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.26.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
|
||||
"reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.26-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-24T11:49:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.26.0",
|
||||
|
|
|
@ -143,6 +143,8 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_PROJECT_DB
|
||||
- _APP_CONSOLE_DB
|
||||
- _APP_SMTP_HOST
|
||||
- _APP_SMTP_PORT
|
||||
- _APP_SMTP_SECURE
|
||||
|
@ -221,6 +223,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- _APP_USAGE_STATS
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
@ -251,6 +254,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
|
@ -311,6 +315,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- *x-env-storage
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
@ -344,6 +349,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
|
@ -375,6 +381,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
|
@ -409,6 +416,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
|
||||
|
@ -439,6 +447,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- _APP_FUNCTIONS_TIMEOUT
|
||||
- _APP_EXECUTOR_SECRET
|
||||
- _APP_EXECUTOR_HOST
|
||||
|
@ -551,6 +560,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DB
|
||||
- _APP_MAINTENANCE_INTERVAL
|
||||
- _APP_MAINTENANCE_RETENTION_EXECUTION
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
|
@ -576,11 +586,8 @@ services:
|
|||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DB_HOST
|
||||
- _APP_DB_PORT
|
||||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
|
||||
- _APP_DB
|
||||
- _APP_INFLUXDB_HOST
|
||||
- _APP_INFLUXDB_PORT
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
|
|
134
src/Appwrite/DSN/DSN.php
Normal file
134
src/Appwrite/DSN/DSN.php
Normal file
|
@ -0,0 +1,134 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\DSN;
|
||||
|
||||
class DSN {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $scheme;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
protected ?string $user;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
protected ?string $password;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $host;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
protected ?string $port;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
protected ?string $database;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
protected ?string $query;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* Construct a new DSN object
|
||||
*
|
||||
* @param string $dsn
|
||||
*/
|
||||
public function __construct(string $dsn)
|
||||
{
|
||||
$parts = parse_url($dsn);
|
||||
|
||||
if (!$parts) {
|
||||
throw new \InvalidArgumentException("Unable to parse DSN: $dsn");
|
||||
}
|
||||
|
||||
$this->scheme = $parts['scheme'] ?? null;
|
||||
$this->user = $parts['user'] ?? null;
|
||||
$this->password = $parts['pass'] ?? null;
|
||||
$this->host = $parts['host'] ?? null;
|
||||
$this->port = $parts['port'] ?? null;
|
||||
$this->database = $parts['path'] ?? null;
|
||||
$this->query = $parts['query'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scheme.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme(): string
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the user.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getUser(): ?string
|
||||
{
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the password.
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getPassword(): ?string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the host
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHost(): string
|
||||
{
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the port
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getPort(): ?string
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the database
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getDatabase(): ?string
|
||||
{
|
||||
return ltrim($this->database, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query string
|
||||
*
|
||||
* @return ?string
|
||||
*/
|
||||
public function getQuery(): ?string
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
}
|
37
src/Appwrite/Database/DatabasePool.php
Normal file
37
src/Appwrite/Database/DatabasePool.php
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Database;
|
||||
|
||||
use PDO;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Swoole\Database\PDOPool;
|
||||
use Swoole\Database\PDOProxy;
|
||||
|
||||
class DatabasePool {
|
||||
|
||||
protected array $pools = [];
|
||||
|
||||
public function add(string $name, PDOPool $dbPool): void
|
||||
{
|
||||
$this->pools[$name] = $dbPool;
|
||||
}
|
||||
|
||||
public function get(string $name = 'console'): ?PDOProxy
|
||||
{
|
||||
$pool = $this->pools[$name] ?? null;
|
||||
if ($pool === null) {
|
||||
throw new Exception("Database Pool with name : $name not found. Please check the value of _APP_PROJECT_DB in .env", 500);
|
||||
}
|
||||
return $pool->get();
|
||||
}
|
||||
|
||||
public function put(PDOProxy $db, string $name = 'console'): void
|
||||
{
|
||||
$pool = $this->pools[$name] ?? null;
|
||||
if ($pool === null) {
|
||||
throw new Exception("Database Pool with name : $name not found. Cannot put", 500);
|
||||
}
|
||||
$pool->put($db);
|
||||
}
|
||||
|
||||
}
|
90
tests/unit/DSN/DSNTest.php
Normal file
90
tests/unit/DSN/DSNTest.php
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Appwrite\DSN\DSN;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class DSNTest extends TestCase
|
||||
{
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function tearDown(): void
|
||||
{
|
||||
}
|
||||
|
||||
public function testSuccess(): void
|
||||
{
|
||||
$dsn = new DSN("mariadb://user:password@localhost:3306/database?charset=utf8&timezone=UTC");
|
||||
$this->assertEquals("mariadb", $dsn->getScheme());
|
||||
$this->assertEquals("user", $dsn->getUser());
|
||||
$this->assertEquals("password", $dsn->getPassword());
|
||||
$this->assertEquals("localhost", $dsn->getHost());
|
||||
$this->assertEquals("3306", $dsn->getPort());
|
||||
$this->assertEquals("database", $dsn->getDatabase());
|
||||
$this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery());
|
||||
|
||||
$dsn = new DSN("mariadb://user@localhost:3306/database?charset=utf8&timezone=UTC");
|
||||
$this->assertEquals("mariadb", $dsn->getScheme());
|
||||
$this->assertEquals("user", $dsn->getUser());
|
||||
$this->assertNull($dsn->getPassword());
|
||||
$this->assertEquals("localhost", $dsn->getHost());
|
||||
$this->assertEquals("3306", $dsn->getPort());
|
||||
$this->assertEquals("database", $dsn->getDatabase());
|
||||
$this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery());
|
||||
|
||||
$dsn = new DSN("mariadb://user@localhost/database?charset=utf8&timezone=UTC");
|
||||
$this->assertEquals("mariadb", $dsn->getScheme());
|
||||
$this->assertEquals("user", $dsn->getUser());
|
||||
$this->assertNull($dsn->getPassword());
|
||||
$this->assertEquals("localhost", $dsn->getHost());
|
||||
$this->assertNull($dsn->getPort());
|
||||
$this->assertEquals("database", $dsn->getDatabase());
|
||||
$this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery());
|
||||
|
||||
$dsn = new DSN("mariadb://user@localhost?charset=utf8&timezone=UTC");
|
||||
$this->assertEquals("mariadb", $dsn->getScheme());
|
||||
$this->assertEquals("user", $dsn->getUser());
|
||||
$this->assertNull($dsn->getPassword());
|
||||
$this->assertEquals("localhost", $dsn->getHost());
|
||||
$this->assertNull($dsn->getPort());
|
||||
$this->assertEmpty($dsn->getDatabase());
|
||||
$this->assertEquals("charset=utf8&timezone=UTC", $dsn->getQuery());
|
||||
|
||||
$dsn = new DSN("mariadb://user@localhost");
|
||||
$this->assertEquals("mariadb", $dsn->getScheme());
|
||||
$this->assertEquals("user", $dsn->getUser());
|
||||
$this->assertNull($dsn->getPassword());
|
||||
$this->assertEquals("localhost", $dsn->getHost());
|
||||
$this->assertNull($dsn->getPort());
|
||||
$this->assertEmpty($dsn->getDatabase());
|
||||
$this->assertNull($dsn->getQuery());
|
||||
|
||||
$dsn = new DSN("mariadb://user:@localhost");
|
||||
$this->assertEquals("mariadb", $dsn->getScheme());
|
||||
$this->assertEquals("user", $dsn->getUser());
|
||||
$this->assertEmpty($dsn->getPassword());
|
||||
$this->assertEquals("localhost", $dsn->getHost());
|
||||
$this->assertNull($dsn->getPort());
|
||||
$this->assertEmpty($dsn->getDatabase());
|
||||
$this->assertNull($dsn->getQuery());
|
||||
|
||||
$dsn = new DSN("mariadb://localhost");
|
||||
$this->assertEquals("mariadb", $dsn->getScheme());
|
||||
$this->assertNull($dsn->getUser());
|
||||
$this->assertNull($dsn->getPassword());
|
||||
$this->assertEquals("localhost", $dsn->getHost());
|
||||
$this->assertNull($dsn->getPort());
|
||||
$this->assertEmpty($dsn->getDatabase());
|
||||
$this->assertNull($dsn->getQuery());
|
||||
}
|
||||
|
||||
public function testFail(): void
|
||||
{
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$dsn = new DSN("mariadb://");
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue