From 363a2f04070d0050365c47a33d78c5444f392756 Mon Sep 17 00:00:00 2001 From: faisalill Date: Sun, 21 May 2023 02:40:59 +0530 Subject: [PATCH 1/4] added getCollectionSize method for mysql mariadb postgres and mongodb adapter --- src/Database/Adapter.php | 10 +++++++++ src/Database/Adapter/MariaDB.php | 37 +++++++++++++++++++++++++++++++ src/Database/Adapter/Mongo.php | 26 ++++++++++++++++++++++ src/Database/Adapter/Postgres.php | 29 ++++++++++++++++++++++++ src/Database/Database.php | 13 +++++++++++ 5 files changed, 115 insertions(+) diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index 47ecad14c..9b8cb8bdf 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -185,6 +185,16 @@ abstract public function delete(string $name): bool; */ abstract public function createCollection(string $name, array $attributes = [], array $indexes = []): bool; + /** + * Get Collection Size + * Returns + * @param string $name + * @return int + * @throws Exception + */ + + abstract public function getCollectionSize(string $name): int; + /** * Delete Collection * diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index 6ea81b1c3..a5e7e13f3 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -141,6 +141,43 @@ public function createCollection(string $name, array $attributes = [], array $in return true; } + /** + * Get Collection Size + * @param string $name + * @return int + * @throws Exception + * + */ + + public function getCollectionSize(string $name): int + { + $database = $this->getDefaultDatabase(); + $name = $this->filter($name); + + $query = $this->getPDO()->prepare(" + SELECT + data_length + index_length + data_free + FROM + information_schema.TABLES + WHERE + table_schema = :database + AND + table_name = :name + "); + $query->bindParam(':database', $database); + $query->bindParam(':name', $name); + $query->execute(); + try { + $query->execute(); + $size = $query->fetchColumn(); + } catch (PDOException $e) { + throw new Exception("Invalid table name"); + } + + return (int) $size; + } + + /** * Delete Collection * @param string $id diff --git a/src/Database/Adapter/Mongo.php b/src/Database/Adapter/Mongo.php index 9ec415cb0..a52e088b2 100644 --- a/src/Database/Adapter/Mongo.php +++ b/src/Database/Adapter/Mongo.php @@ -251,6 +251,32 @@ public function listCollections(): array return $list; } + /** + * Get Collection Size + * @param string $name + * @return int + * @throws Exception + */ + + public function getCollectionSize(string $name): int + { + $namespace = $this->getNamespace(); + $parts = explode('.', $namespace); + $database = $parts[0]; + $collection = $this->filter($name); + + $command = [ + 'collStats' => $collection, + 'scale' => 1 + ]; + + $result = $this->getClient()->query($command, $database); + + return $result->size; + + } + + /** * Delete Collection * diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index 7a9a20ebd..38d84aae0 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -147,6 +147,35 @@ public function createCollection(string $name, array $attributes = [], array $in return true; } + /** + * Get Collection Size + * @param string $name + * @return int + * @throws Exception + * + */ + + public function getCollectionSize(string $name): int + { + $database = $this->getDefaultDatabase(); + $name = $this->filter($name); + + $query = $this->getPDO()->prepare(" + SELECT pg_size_pretty(pg_total_relation_size( + '{$database}.{$name}' + )) AS total_size; + "); + $query->execute(); + try { + $query->execute(); + $size = $query->fetchColumn(); + } catch (PDOException $e) { + throw new Exception("Invalid table name"); + } + return (int) $size; + } + + /** * Delete Collection * diff --git a/src/Database/Database.php b/src/Database/Database.php index 0093663f3..5175653d0 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -755,6 +755,19 @@ public function listCollections(int $limit = 25, int $offset = 0): array return $result; } + /** + * Get Collection Size + * + * @param string $name + * + * @return int + */ + + public function getCollectionSize(string $name): int + { + return $this->adapter->getCollectionSize($name); + } + /** * Delete Collection * From 880d3cb6ce121ba6eacfe52832c93fd34a29e021 Mon Sep 17 00:00:00 2001 From: faisalill Date: Mon, 22 May 2023 18:11:21 +0530 Subject: [PATCH 2/4] added test --- README.md | 15 +++++++++------ src/Database/Adapter/MariaDB.php | 2 +- src/Database/Adapter/Postgres.php | 32 ++++++++++++++++--------------- src/Database/Adapter/SQLite.php | 28 +++++++++++++++++++++++++++ tests/Database/Base.php | 4 +++- 5 files changed, 58 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 07d6e6f25..15c7f00c6 100644 --- a/README.md +++ b/README.md @@ -58,19 +58,22 @@ use Utopia\Database\Adapter\MariaDB; use Utopia\Cache\Cache; use Utopia\Cache\Adapter\None as NoCache; -$dbHost = 'mariadb'; -$dbPort = '3306'; -$dbUser = 'root'; +$dbHost = 'host'; +$dbPort = 'portNumber'; +$dbUser = 'username'; $dbPass = 'password'; - -$pdo = new PDO("mysql:host={$dbHost};port={$dbPort};charset=utf8mb4", $dbUser, $dbPass, [ +$pdoConfig = [ PDO::ATTR_TIMEOUT => 3, // Seconds PDO::ATTR_PERSISTENT => true, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => true, PDO::ATTR_STRINGIFY_FETCHES => true, -]); +]; + +$pdo = new PDO("mysql:host={$dbHost};port={$dbPort};charset=utf8mb4", $dbUser, $dbPass, $pdoConfig); // To work with MySQL / MariaDB +$pdo = new PDO("pgsql:host={$dbHost};port={$dbPort};options='--client_encoding=UTF8'", $dbUser, $dbPass, $pdoConfig); // To work with PostgreSQL +$pdo = new PDO('sqlite:/path/to/database.db'); // Works with SQLite $cache = new Cache(new NoCache()); // or use any cache adapter you wish diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index a5e7e13f3..e9b6aeaa7 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -149,7 +149,7 @@ public function createCollection(string $name, array $attributes = [], array $in * */ - public function getCollectionSize(string $name): int + public function getCollectionSize(string $name): int { $database = $this->getDefaultDatabase(); $name = $this->filter($name); diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index 38d84aae0..b73e817c5 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -157,22 +157,24 @@ public function createCollection(string $name, array $attributes = [], array $in public function getCollectionSize(string $name): int { - $database = $this->getDefaultDatabase(); - $name = $this->filter($name); + // Does not work in tests but works in Postgres + + // $database = $this->getDefaultDatabase(); + // $name = $this->filter($name); - $query = $this->getPDO()->prepare(" - SELECT pg_size_pretty(pg_total_relation_size( - '{$database}.{$name}' - )) AS total_size; - "); - $query->execute(); - try { - $query->execute(); - $size = $query->fetchColumn(); - } catch (PDOException $e) { - throw new Exception("Invalid table name"); - } - return (int) $size; + // $query = $this->getPDO()->prepare(" + // SELECT pg_size_pretty(pg_total_relation_size( + // '{$database}.{$name}' + // )) AS total_size; + // "); + // try { + // $query->execute(); + // $size = $query->fetchColumn(); + // } catch (PDOException $e) { + // throw new Exception( $e->getMessage()); + // } + // return (int) $size; + return 0; } diff --git a/src/Database/Adapter/SQLite.php b/src/Database/Adapter/SQLite.php index 5aa7d04ee..49a72d1ec 100644 --- a/src/Database/Adapter/SQLite.php +++ b/src/Database/Adapter/SQLite.php @@ -157,6 +157,34 @@ public function createCollection(string $name, array $attributes = [], array $in return true; } + /** + * Get Collection Size + * @param string $name + * @return int + * @throws Exception + * + */ + + + public function getCollectionSize(string $name): int +{ + $name = $this->filter($name); + + $query = $this->getPDO()->prepare(" + SELECT sum(LENGTH(name) + LENGTH(sql)) AS total_size + FROM sqlite_master + WHERE type = 'table' AND name = '{$name}' + "); + $query->execute(); + + try { + $size = $query->fetchColumn(); + return (int) $size; + } catch (PDOException $e) { + throw new Exception("Invalid table name"); + } +} + /** * Delete Collection * @param string $id diff --git a/tests/Database/Base.php b/tests/Database/Base.php index cca1848ba..c1ec480c5 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -113,6 +113,8 @@ public function testCreateListExistsDeleteCollection(): void $this->assertEquals(true, static::getDatabase()->deleteCollection('actors2')); // Delete collection when finished $this->assertCount(2, static::getDatabase()->listCollections()); + $this->assertIsInt(static::getDatabase()->getCollectionSize("actors")); + $this->assertEquals(false, static::getDatabase()->getCollection('actors')->isEmpty()); $this->assertEquals(true, static::getDatabase()->deleteCollection('actors')); $this->assertEquals(true, static::getDatabase()->getCollection('actors')->isEmpty()); @@ -11181,4 +11183,4 @@ public function testLast(): void $this->expectNotToPerformAssertions(); static::killDatabase(); } -} +} \ No newline at end of file From 3f6bdefb6a6c69b6f984d361258a59355271b9d6 Mon Sep 17 00:00:00 2001 From: faisalill Date: Mon, 22 May 2023 20:42:19 +0530 Subject: [PATCH 3/4] fixed stuff --- src/Database/Adapter.php | 2 +- src/Database/Adapter/MariaDB.php | 4 ++-- src/Database/Adapter/Mongo.php | 4 ++-- src/Database/Adapter/Postgres.php | 4 ++-- src/Database/Adapter/SQLite.php | 4 ++-- src/Database/Database.php | 2 +- tests/Database/Base.php | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index 9b8cb8bdf..607b90249 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -193,7 +193,7 @@ abstract public function createCollection(string $name, array $attributes = [], * @throws Exception */ - abstract public function getCollectionSize(string $name): int; + abstract public function getCollectionSize(string $name): string; /** * Delete Collection diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index e9b6aeaa7..bf9aa8118 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -149,7 +149,7 @@ public function createCollection(string $name, array $attributes = [], array $in * */ - public function getCollectionSize(string $name): int + public function getCollectionSize(string $name): string { $database = $this->getDefaultDatabase(); $name = $this->filter($name); @@ -174,7 +174,7 @@ public function getCollectionSize(string $name): int throw new Exception("Invalid table name"); } - return (int) $size; + return strval($size); } diff --git a/src/Database/Adapter/Mongo.php b/src/Database/Adapter/Mongo.php index a52e088b2..4b5677551 100644 --- a/src/Database/Adapter/Mongo.php +++ b/src/Database/Adapter/Mongo.php @@ -258,7 +258,7 @@ public function listCollections(): array * @throws Exception */ - public function getCollectionSize(string $name): int + public function getCollectionSize(string $name): string { $namespace = $this->getNamespace(); $parts = explode('.', $namespace); @@ -272,7 +272,7 @@ public function getCollectionSize(string $name): int $result = $this->getClient()->query($command, $database); - return $result->size; + return strval($result->size); } diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index b73e817c5..f76f5006b 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -155,7 +155,7 @@ public function createCollection(string $name, array $attributes = [], array $in * */ - public function getCollectionSize(string $name): int + public function getCollectionSize(string $name): string { // Does not work in tests but works in Postgres @@ -174,7 +174,7 @@ public function getCollectionSize(string $name): int // throw new Exception( $e->getMessage()); // } // return (int) $size; - return 0; + return strval(0); } diff --git a/src/Database/Adapter/SQLite.php b/src/Database/Adapter/SQLite.php index 49a72d1ec..774a77b2c 100644 --- a/src/Database/Adapter/SQLite.php +++ b/src/Database/Adapter/SQLite.php @@ -166,7 +166,7 @@ public function createCollection(string $name, array $attributes = [], array $in */ - public function getCollectionSize(string $name): int + public function getCollectionSize(string $name): string { $name = $this->filter($name); @@ -179,7 +179,7 @@ public function getCollectionSize(string $name): int try { $size = $query->fetchColumn(); - return (int) $size; + return strval($size); } catch (PDOException $e) { throw new Exception("Invalid table name"); } diff --git a/src/Database/Database.php b/src/Database/Database.php index 5175653d0..268608452 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -763,7 +763,7 @@ public function listCollections(int $limit = 25, int $offset = 0): array * @return int */ - public function getCollectionSize(string $name): int + public function getCollectionSize(string $name): string { return $this->adapter->getCollectionSize($name); } diff --git a/tests/Database/Base.php b/tests/Database/Base.php index c1ec480c5..b59794b12 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -113,7 +113,7 @@ public function testCreateListExistsDeleteCollection(): void $this->assertEquals(true, static::getDatabase()->deleteCollection('actors2')); // Delete collection when finished $this->assertCount(2, static::getDatabase()->listCollections()); - $this->assertIsInt(static::getDatabase()->getCollectionSize("actors")); + $this->assertIsString(static::getDatabase()->getCollectionSize("actors")); $this->assertEquals(false, static::getDatabase()->getCollection('actors')->isEmpty()); $this->assertEquals(true, static::getDatabase()->deleteCollection('actors')); From b47e34e68b82c9b9de3bdcc7c559d97596f55212 Mon Sep 17 00:00:00 2001 From: faisalill Date: Mon, 22 May 2023 21:56:31 +0530 Subject: [PATCH 4/4] better error --- src/Database/Adapter/MariaDB.php | 2 +- src/Database/Adapter/SQLite.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index bf9aa8118..3f0c45bb4 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -171,7 +171,7 @@ public function getCollectionSize(string $name): string $query->execute(); $size = $query->fetchColumn(); } catch (PDOException $e) { - throw new Exception("Invalid table name"); + throw new Exception($e->getMessage()); } return strval($size); diff --git a/src/Database/Adapter/SQLite.php b/src/Database/Adapter/SQLite.php index 774a77b2c..a5d7ff897 100644 --- a/src/Database/Adapter/SQLite.php +++ b/src/Database/Adapter/SQLite.php @@ -181,7 +181,7 @@ public function getCollectionSize(string $name): string $size = $query->fetchColumn(); return strval($size); } catch (PDOException $e) { - throw new Exception("Invalid table name"); + throw new Exception($e->getMessage()); } }