diff --git a/app/init.php b/app/init.php index 009bb6e5f7..e104f41b54 100644 --- a/app/init.php +++ b/app/init.php @@ -445,6 +445,21 @@ $register->set('logger', function () { return new Logger($adapter); }); +$register->set('dbMap', function () { + $dbs = App::getEnv('_APP_PROJECT_DB', ''); + $dbs = explode(',', $dbs); + + $dbMap = []; + foreach ($dbs as $db) { + $db = explode('=', $db); + $name = $db[0]; + $dsn = $db[1]; + $dbMap[$name] = $dsn; + } + + return $dbMap; +}); + $register->set('dbPool', function () { /** Parse the console databases */ $consoleDb = App::getEnv('_APP_CONSOLE_DB', ''); @@ -474,13 +489,11 @@ $register->set('dbPool', function () { $pool->setConsoleDB($name); /** Parse the project databases */ - $dbs = App::getEnv('_APP_PROJECT_DB', ''); - $dbs = explode(',', $dbs); - 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()); + global $register; + $dbs = $register->get('dbMap'); + + foreach ($dbs as $name => $dsn) { + $dsn = new DSN($dsn); $projectPool = new PDOPool( (new PDOConfig()) ->withHost($dsn->getHost()) @@ -578,13 +591,19 @@ $register->set('smtp', function () { $register->set('geodb', function () { return new Reader(__DIR__ . '/db/DBIP/dbip-country-lite-2022-03.mmdb'); }); -$register->set('db', function () { - // This is usually for our workers or CLI commands scope - $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', ''); + +$register->set('consoleDB', function () { + /** This is usually for our workers or CLI commands scope */ + $consoleDb = App::getEnv('_APP_CONSOLE_DB', ''); + $consoleDb = explode(',', $consoleDb)[0]; + $consoleDb = explode('=', $consoleDb); + $dsn = new DSN($consoleDb[1]); + + $dbHost = $dsn->getHost(); + $dbPort = $dsn->getPort(); + $dbUser = $dsn->getUser(); + $dbPass = $dsn->getPassword(); + $dbScheme = $dsn->getDatabase(); $pdo = new PDO("mysql:host={$dbHost};port={$dbPort};dbname={$dbScheme};charset=utf8mb4", $dbUser, $dbPass, array( PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4', @@ -596,6 +615,7 @@ $register->set('db', function () { return $pdo; }); + $register->set('cache', function () { // This is usually for our workers or CLI commands scope $redis = new Redis(); @@ -915,11 +935,10 @@ App::setResource('dbForProject', function ($projectDB, $cache, $project) { $database = new Database(new MariaDB($projectDB), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace("_{$project->getId()}"); - + return $database; }, ['projectDB', 'cache', 'project']); - App::setResource('deviceLocal', function () { return new Local(); }); diff --git a/app/tasks/doctor.php b/app/tasks/doctor.php index d79e8d530f..ea0a963a71 100644 --- a/app/tasks/doctor.php +++ b/app/tasks/doctor.php @@ -96,7 +96,7 @@ $cli } try { - $register->get('db'); /* @var $db PDO */ + $register->get('consoleDB'); /* @var $db PDO */ Console::success('Database............connected 👍'); } catch (\Throwable $th) { Console::error('Database.........disconnected 👎'); diff --git a/app/tasks/maintenance.php b/app/tasks/maintenance.php index 6bc06584e6..54963d4134 100644 --- a/app/tasks/maintenance.php +++ b/app/tasks/maintenance.php @@ -24,7 +24,7 @@ function getConsoleDB(): Database try { $attempts++; $cache = new Cache(new RedisCache($register->get('cache'))); - $database = new Database(new MariaDB($register->get('db')), $cache); + $database = new Database(new MariaDB($register->get('consoleDB')), $cache); $database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $database->setNamespace('_console'); // Main DB diff --git a/app/tasks/migrate.php b/app/tasks/migrate.php index ff0705eb32..760a4dea7c 100644 --- a/app/tasks/migrate.php +++ b/app/tasks/migrate.php @@ -27,15 +27,16 @@ $cli Console::success('Starting Data Migration to version ' . $version); - $db = $register->get('db', true); + $consoleDB = $register->get('consoleDB', true); $cache = $register->get('cache', true); $cache = new Cache(new RedisCache($cache)); - $projectDB = new Database(new MariaDB($db), $cache); + // TODO: Iterate through all project DBs + $projectDB = new Database(new MariaDB($consoleDB), $cache); $projectDB->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); - $consoleDB = new Database(new MariaDB($db), $cache); + $consoleDB = new Database(new MariaDB($consoleDB), $cache); $consoleDB->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $consoleDB->setNamespace('_project_console'); diff --git a/app/tasks/specs.php b/app/tasks/specs.php index 0bd94249da..f1c9f6b278 100644 --- a/app/tasks/specs.php +++ b/app/tasks/specs.php @@ -19,7 +19,7 @@ $cli ->param('version', 'latest', new Text(8), 'Spec version', true) ->param('mode', 'normal', new WhiteList(['normal', 'mocks']), 'Spec Mode', true) ->action(function ($version, $mode) use ($register) { - $db = $register->get('db'); + $consoleDB = $register->get('consoleDB'); $redis = $register->get('cache'); $appRoutes = App::getRoutes(); $response = new Response(new HttpResponse()); @@ -27,7 +27,7 @@ $cli App::setResource('request', fn () => new Request()); App::setResource('response', fn () => $response); - App::setResource('db', fn () => $db); + App::setResource('consoleDB', fn () => $consoleDB); App::setResource('cache', fn () => $redis); $platforms = [ diff --git a/app/tasks/usage.php b/app/tasks/usage.php index 2ed08af63b..c61d385985 100644 --- a/app/tasks/usage.php +++ b/app/tasks/usage.php @@ -2,6 +2,8 @@ global $cli, $register; +use Appwrite\DSN\DSN; +use Swoole\Database\PDOProxy; use Utopia\App; use Utopia\Cache\Adapter\Redis; use Utopia\Cache\Cache; @@ -236,12 +238,12 @@ $cli $max = 10; $sleep = 1; - $db = null; + $consoleDB = null; $redis = null; do { // connect to db try { $attempts++; - $db = $register->get('db'); + $consoleDB = $register->get('consoleDB'); $redis = $register->get('cache'); break; // leave the do-while if successful } catch (\Exception $e) { @@ -255,18 +257,18 @@ $cli // TODO use inject $cacheAdapter = new Cache(new Redis($redis)); - $dbForProject = new Database(new MariaDB($db), $cacheAdapter); - $dbForConsole = new Database(new MariaDB($db), $cacheAdapter); - $dbForProject->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); + $dbForConsole = new Database(new MariaDB($consoleDB), $cacheAdapter); $dbForConsole->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); $dbForConsole->setNamespace('_console'); + $dbPool = $register->get('dbPool'); + $latestTime = []; Authorization::disable(); $iterations = 0; - Console::loop(function () use ($interval, $register, $dbForProject, $dbForConsole, $globalMetrics, $periods, &$latestTime, &$iterations) { + Console::loop(function () use ($interval, $register, $dbForConsole, $dbPool, $cacheAdapter, $globalMetrics, $periods, &$latestTime, &$iterations) { $now = date('d-m-Y H:i:s', time()); Console::info("[{$now}] Aggregating usage data every {$interval} seconds"); @@ -324,6 +326,15 @@ $cli foreach ($points as $point) { $projectId = $point['projectId']; + /** Get the Dabatase name from the console DB */ + $project = Authorization::skip(fn() => $dbForConsole->getDocument('projects', $projectId)); + $dbName = $project->getAttribute('database', ''); + $projectDB = $dbPool->get($dbName); + + $dbForProject = new Database(new MariaDB($projectDB), $cacheAdapter); + $dbForProject->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite')); + + if (!empty($projectId) && $projectId !== 'console') { $dbForProject->setNamespace('_' . $projectId); $metricUpdated = $metric; @@ -364,6 +375,8 @@ $cli Console::warning($e->getTraceAsString()); } } + + $dbPool->put($projectDB, $dbName); } } catch (\Exception $e) { Console::warning("Failed to Query: {$e->getMessage()}");