Skip to content

Commit

Permalink
Merge pull request #509 from utopia-php/feat-improve-queries
Browse files Browse the repository at this point in the history
Only query tenant is null against metadata
  • Loading branch information
abnegate authored Jan 20, 2025
2 parents 77121e8 + 8d76bab commit 240478a
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 98 deletions.
11 changes: 10 additions & 1 deletion src/Database/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ abstract public function createCollection(string $name, array $attributes = [],
abstract public function deleteCollection(string $id): bool;

/**
* Analyze a collection updating it's metadata on the database engine
* Analyze a collection updating its metadata on the database engine
*
* @param string $collection
* @return bool
Expand Down Expand Up @@ -1045,4 +1045,13 @@ abstract public function getInternalIndexesKeys(): array;
* @throws DatabaseException
*/
abstract public function getSchemaAttributes(string $collection): array;

/**
* Get the query to check for tenant when in shared tables mode
*
* @param string $collection The collection being queried
* @param string $parentAlias The alias of the parent collection if in a subquery
* @return string
*/
abstract public function getTenantQuery(string $collection, string $parentAlias = ''): string;
}
65 changes: 29 additions & 36 deletions src/Database/Adapter/MariaDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -1123,12 +1123,9 @@ public function updateDocument(string $collection, string $id, Document $documen
SELECT _type, _permission
FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);

/**
Expand Down Expand Up @@ -1200,12 +1197,9 @@ public function updateDocument(string $collection, string $id, Document $documen
DELETE
FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$removeQuery = $sql . $removeQuery;

$removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery);
Expand Down Expand Up @@ -1287,12 +1281,9 @@ public function updateDocument(string $collection, string $id, Document $documen
UPDATE {$this->getSQLTable($name)}
SET {$columns} _uid = :_newUid
WHERE _uid = :_existingUid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_DOCUMENT_UPDATE, $sql);

$stmt = $this->getPDO()->prepare($sql);
Expand Down Expand Up @@ -1436,12 +1427,9 @@ public function updateDocuments(string $collection, Document $updates, array $do
SELECT _type, _permission
FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);

$permissionsStmt = $this->getPDO()->prepare($sql);
Expand Down Expand Up @@ -1481,14 +1469,9 @@ public function updateDocuments(string $collection, Document $updates, array $do
$removeBindKeys[] = ':uid_' . $index;
$removeBindValues[$bindKey] = $document->getId();

$tenantQuery = '';
if ($this->sharedTables) {
$tenantQuery = ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$removeQueries[] = "(
_document = :uid_{$index}
{$tenantQuery}
{$this->getTenantQuery($collection)}
AND _type = '{$type}'
AND _permission IN (" . \implode(', ', \array_map(function (string $i) use ($permissionsToRemove, $index, $type, &$removeBindKeys, &$removeBindValues) {
$bindKey = 'remove_' . $type . '_' . $index . '_' . $i;
Expand Down Expand Up @@ -1616,11 +1599,9 @@ public function increaseDocumentAttribute(string $collection, string $id, string
`{$attribute}` = `{$attribute}` + :val,
`_updatedAt` = :updatedAt
WHERE _uid = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql .= $sqlMax . $sqlMin;

Expand Down Expand Up @@ -1656,12 +1637,9 @@ public function deleteDocument(string $collection, string $id): bool
$sql = "
DELETE FROM {$this->getSQLTable($name)}
WHERE _uid = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_DOCUMENT_DELETE, $sql);

$stmt = $this->getPDO()->prepare($sql);
Expand All @@ -1675,12 +1653,9 @@ public function deleteDocument(string $collection, string $id): bool
$sql = "
DELETE FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);

$stmtPermissions = $this->getPDO()->prepare($sql);
Expand Down Expand Up @@ -1886,7 +1861,13 @@ public function find(string $collection, array $queries = [], ?int $limit = 25,
}

if ($this->sharedTables) {
$where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)";
$orIsNull = '';

if ($collection === Database::METADATA) {
$orIsNull = " OR table_main._tenant IS NULL";
}

$where[] = "(table_main._tenant = :_tenant {$orIsNull})";
}

$sqlWhere = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
Expand Down Expand Up @@ -2014,7 +1995,13 @@ public function count(string $collection, array $queries = [], ?int $max = null)
}

if ($this->sharedTables) {
$where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)";
$orIsNull = '';

if ($collection === Database::METADATA) {
$orIsNull = " OR table_main._tenant IS NULL";
}

$where[] = "(table_main._tenant = :_tenant {$orIsNull})";
}

$sqlWhere = !empty($where)
Expand Down Expand Up @@ -2086,7 +2073,13 @@ public function sum(string $collection, string $attribute, array $queries = [],
}

if ($this->sharedTables) {
$where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)";
$orIsNull = '';

if ($collection === Database::METADATA) {
$orIsNull = " OR table_main._tenant IS NULL";
}

$where[] = "(table_main._tenant = :_tenant {$orIsNull})";
}

$sqlWhere = !empty($where)
Expand Down
5 changes: 5 additions & 0 deletions src/Database/Adapter/Mongo.php
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ private function insertDocument(string $name, array $document): array

$filters = [];
$filters['_uid'] = $document['_uid'];

if ($this->sharedTables) {
$filters['_tenant'] = (string)$this->getTenant();
}
Expand Down Expand Up @@ -1963,4 +1964,8 @@ public function getSchemaAttributes(string $collection): array
return [];
}

public function getTenantQuery(string $collection, string $parentAlias = ''): string
{
return (string)$this->getTenant();
}
}
71 changes: 36 additions & 35 deletions src/Database/Adapter/Postgres.php
Original file line number Diff line number Diff line change
Expand Up @@ -1161,12 +1161,9 @@ public function updateDocument(string $collection, string $id, Document $documen
SELECT _type, _permission
FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_PERMISSIONS_READ, $sql);

/**
Expand Down Expand Up @@ -1239,12 +1236,9 @@ public function updateDocument(string $collection, string $id, Document $documen
DELETE
FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$removeQuery = $sql . $removeQuery;

$removeQuery = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $removeQuery);
Expand Down Expand Up @@ -1311,12 +1305,9 @@ public function updateDocument(string $collection, string $id, Document $documen
UPDATE {$this->getSQLTable($name)}
SET {$columns} _uid = :_newUid
WHERE _uid = :_existingUid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_DOCUMENT_UPDATE, $sql);

$stmt = $this->getPDO()->prepare($sql);
Expand Down Expand Up @@ -1395,7 +1386,13 @@ public function updateDocuments(string $collection, Document $updates, array $do
$where[] = "_uid IN (" . \implode(', ', \array_map(fn ($index) => ":_id_{$index}", \array_keys($ids))) . ")";

if ($this->sharedTables) {
$where[] = "(_tenant = :_tenant OR _tenant IS NULL)";
$whereTenant = "(_tenant = :_tenant";

if ($collection === Database::METADATA) {
$whereTenant .= " OR _tenant IS NULL";
}

$where[] = $whereTenant . ')';
}

$sqlWhere = 'WHERE ' . implode(' AND ', $where);
Expand Down Expand Up @@ -1504,14 +1501,9 @@ public function updateDocuments(string $collection, Document $updates, array $do
$removeBindKeys[] = ':uid_' . $index;
$removeBindValues[$bindKey] = $document->getId();

$tenantQuery = '';
if ($this->sharedTables) {
$tenantQuery = ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$removeQueries[] = "(
_document = :uid_{$index}
{$tenantQuery}
{$this->getTenantQuery($collection)}
AND _type = '{$type}'
AND _permission IN (" . \implode(', ', \array_map(function (string $i) use ($permissionsToRemove, $index, $type, &$removeBindKeys, &$removeBindValues) {
$bindKey = 'remove_' . $type . '_' . $index . '_' . $i;
Expand Down Expand Up @@ -1638,13 +1630,10 @@ public function increaseDocumentAttribute(string $collection, string $id, string
SET
\"{$attribute}\" = \"{$attribute}\" + :val,
\"_updatedAt\" = :updatedAt
WHERE _uid = :_uid
WHERE _uid = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql .= $sqlMax . $sqlMin;

$sql = $this->trigger(Database::EVENT_DOCUMENT_UPDATE, $sql);
Expand Down Expand Up @@ -1677,12 +1666,9 @@ public function deleteDocument(string $collection, string $id): bool
$sql = "
DELETE FROM {$this->getSQLTable($name)}
WHERE _uid = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_DOCUMENT_DELETE, $sql);
$stmt = $this->getPDO()->prepare($sql);
$stmt->bindValue(':_uid', $id, PDO::PARAM_STR);
Expand All @@ -1694,12 +1680,9 @@ public function deleteDocument(string $collection, string $id): bool
$sql = "
DELETE FROM {$this->getSQLTable($name . '_perms')}
WHERE _document = :_uid
{$this->getTenantQuery($collection)}
";

if ($this->sharedTables) {
$sql .= ' AND (_tenant = :_tenant OR _tenant IS NULL)';
}

$sql = $this->trigger(Database::EVENT_PERMISSIONS_DELETE, $sql);

$stmtPermissions = $this->getPDO()->prepare($sql);
Expand Down Expand Up @@ -1903,7 +1886,13 @@ public function find(string $collection, array $queries = [], ?int $limit = 25,
}

if ($this->sharedTables) {
$where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)";
$orIsNull = '';

if ($collection === Database::METADATA) {
$orIsNull = " OR table_main._tenant IS NULL";
}

$where[] = "(table_main._tenant = :_tenant {$orIsNull})";
}

if (Authorization::$status) {
Expand Down Expand Up @@ -2031,7 +2020,13 @@ public function count(string $collection, array $queries = [], ?int $max = null)
}

if ($this->sharedTables) {
$where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)";
$orIsNull = '';

if ($collection === Database::METADATA) {
$orIsNull = " OR table_main._tenant IS NULL";
}

$where[] = "(table_main._tenant = :_tenant {$orIsNull})";
}

if (Authorization::$status) {
Expand Down Expand Up @@ -2096,7 +2091,13 @@ public function sum(string $collection, string $attribute, array $queries = [],
}

if ($this->sharedTables) {
$where[] = "(table_main._tenant = :_tenant OR table_main._tenant IS NULL)";
$orIsNull = '';

if ($collection === Database::METADATA) {
$orIsNull = " OR table_main._tenant IS NULL";
}

$where[] = "(table_main._tenant = :_tenant {$orIsNull})";
}

if (Authorization::$status) {
Expand Down
Loading

0 comments on commit 240478a

Please sign in to comment.