Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM composer:2.0 AS composer
FROM composer:2.8 AS composer

WORKDIR /usr/local/src/

Expand All @@ -11,13 +11,12 @@ RUN composer install \
--no-plugins \
--no-scripts \
--prefer-dist
FROM php:8.3.10-cli-alpine3.20 AS compile

FROM php:8.3.19-cli-alpine3.21 AS compile

ENV PHP_REDIS_VERSION="6.0.2" \
PHP_SWOOLE_VERSION="v5.1.3" \
PHP_MONGO_VERSION="1.16.1" \
PHP_XDEBUG_VERSION="3.3.2"
PHP_SWOOLE_VERSION="v5.1.7" \
PHP_XDEBUG_VERSION="3.4.2"

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

Expand Down Expand Up @@ -58,20 +57,10 @@ RUN \
&& ./configure --enable-http2 \
&& make && make install

## MongoDB Extension
FROM compile AS mongodb
RUN \
git clone --depth 1 --branch $PHP_MONGO_VERSION https://github.com/mongodb/mongo-php-driver.git \
&& cd mongo-php-driver \
&& git submodule update --init \
&& phpize \
&& ./configure \
&& make && make install

## PCOV Extension
FROM compile AS pcov
RUN \
git clone https://github.com/krakjoe/pcov.git \
git clone --depth 1 https://github.com/krakjoe/pcov.git \
&& cd pcov \
&& phpize \
&& ./configure --enable-pcov \
Expand All @@ -97,7 +86,6 @@ WORKDIR /usr/src/code

RUN echo extension=redis.so >> /usr/local/etc/php/conf.d/redis.ini
RUN echo extension=swoole.so >> /usr/local/etc/php/conf.d/swoole.ini
RUN echo extension=mongodb.so >> /usr/local/etc/php/conf.d/mongodb.ini
RUN echo extension=pcov.so >> /usr/local/etc/php/conf.d/pcov.ini
RUN echo extension=xdebug.so >> /usr/local/etc/php/conf.d/xdebug.ini

Expand All @@ -110,7 +98,6 @@ RUN echo "memory_limit=1024M" >> $PHP_INI_DIR/php.ini
COPY --from=composer /usr/local/src/vendor /usr/src/code/vendor
COPY --from=swoole /usr/local/lib/php/extensions/no-debug-non-zts-20230831/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/
COPY --from=redis /usr/local/lib/php/extensions/no-debug-non-zts-20230831/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/
COPY --from=mongodb /usr/local/lib/php/extensions/no-debug-non-zts-20230831/mongodb.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/
COPY --from=pcov /usr/local/lib/php/extensions/no-debug-non-zts-20230831/pcov.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/
COPY --from=xdebug /usr/local/lib/php/extensions/no-debug-non-zts-20230831/xdebug.so /usr/local/lib/php/extensions/no-debug-non-zts-20230831/

Expand Down
11 changes: 0 additions & 11 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,6 @@ services:
- "8704:3306"
environment:
- MYSQL_ROOT_PASSWORD=password

mongo:
image: mongo:5.0
container_name: utopia-mongo
networks:
- database
ports:
- "8705:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example

mysql:
image: mysql:8.0.33
Expand Down
36 changes: 33 additions & 3 deletions src/Database/Adapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ abstract class Adapter

protected ?int $tenant = null;

protected bool $tenantPerDocument = false;

protected int $inTransaction = 0;

/**
Expand Down Expand Up @@ -190,6 +192,34 @@ public function getTenant(): ?int
return $this->tenant;
}

/**
* Set Tenant Per Document.
*
* Set whether to use a different tenant for each document
*
* @param bool $tenantPerDocument
*
* @return bool
*/
public function setTenantPerDocument(bool $tenantPerDocument): bool
{
$this->tenantPerDocument = $tenantPerDocument;

return true;
}

/**
* Get Tenant Per Document.
*
* Get whether to use a different tenant for each document
*
* @return bool
*/
public function getTenantPerDocument(): bool
{
return $this->tenantPerDocument;
}

/**
* Set metadata for query comments
*
Expand Down Expand Up @@ -261,7 +291,7 @@ abstract public function setTimeout(int $milliseconds, string $event = Database:
public function clearTimeout(string $event): void
{
// Clear existing callback
$this->before($event, 'timeout', null);
$this->before($event, 'timeout');
}

/**
Expand Down Expand Up @@ -301,7 +331,6 @@ abstract public function rollbackTransaction(): bool;
* Check if a transaction is active.
*
* @return bool
* @throws DatabaseException
*/
public function inTransaction(): bool
{
Expand Down Expand Up @@ -482,7 +511,7 @@ abstract public function createAttribute(string $collection, string $id, string
* @param int $size
* @param bool $signed
* @param bool $array
* @param string $newKey
* @param string|null $newKey
*
* @return bool
*/
Expand Down Expand Up @@ -620,6 +649,7 @@ abstract public function createDocuments(string $collection, array $documents):
* Update Document
*
* @param string $collection
* @param string $id
* @param Document $document
*
* @return Document
Expand Down
92 changes: 35 additions & 57 deletions src/Database/Adapter/MariaDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,9 @@ public function createAttribute(string $collection, string $id, string $type, in
* @param int $size
* @param bool $signed
* @param bool $array
* @param string $newKey
* @param string|null $newKey
* @return bool
* @throws Exception
* @throws PDOException
* @throws DatabaseException
*/
public function updateAttribute(string $collection, string $id, string $type, int $size, bool $signed = true, bool $array = false, ?string $newKey = null): bool
{
Expand Down Expand Up @@ -853,7 +852,7 @@ public function createDocument(string $collection, Document $document): Document
$attributes['_permissions'] = \json_encode($document->getPermissions());

if ($this->sharedTables) {
$attributes['_tenant'] = $this->tenant;
$attributes['_tenant'] = $document->getTenant();
}

$name = $this->filter($collection);
Expand Down Expand Up @@ -896,58 +895,46 @@ public function createDocument(string $collection, Document $document): Document

$attributeIndex = 0;
foreach ($attributes as $value) {
if (is_array($value)) {
$value = json_encode($value);
if (\is_array($value)) {
$value = \json_encode($value);
}

$bindKey = 'key_' . $attributeIndex;
$attribute = $this->filter($attribute);
$value = (is_bool($value)) ? (int)$value : $value;
$value = (\is_bool($value)) ? (int)$value : $value;
$stmt->bindValue(':' . $bindKey, $value, $this->getPDOType($value));
$attributeIndex++;
}

$permissions = [];
foreach (Database::PERMISSIONS as $type) {
foreach ($document->getPermissionsByType($type) as $permission) {
$tenantBind = $this->sharedTables ? ", :_tenant" : '';
$permission = \str_replace('"', '', $permission);
$permission = "('{$type}', '{$permission}', '{$document->getId()}'";

if ($this->sharedTables) {
$permission .= ", :_tenant)";
} else {
$permission .= ")";
}

$permission = "('{$type}', '{$permission}', :_uid {$tenantBind})";
$permissions[] = $permission;
}
}

if (!empty($permissions)) {
$tenantColumn = $this->sharedTables ? ', _tenant' : '';
$permissions = \implode(', ', $permissions);

$sqlPermissions = "
INSERT INTO {$this->getSQLTable($name . '_perms')} (_type, _permission, _document
";

if ($this->sharedTables) {
$sqlPermissions .= ', _tenant)';
} else {
$sqlPermissions .= ")";
}
INSERT INTO {$this->getSQLTable($name . '_perms')} (_type, _permission, _document {$tenantColumn})
VALUES {$permissions};
";

$sqlPermissions .= " VALUES {$permissions}";
$sqlPermissions = $this->trigger(Database::EVENT_PERMISSIONS_CREATE, $sqlPermissions);
$stmtPermissions = $this->getPDO()->prepare($sqlPermissions);

$stmtPermissions->bindValue(':_uid', $document->getId());
if ($this->sharedTables) {
$stmtPermissions->bindValue(':_tenant', $this->tenant);
$stmtPermissions->bindValue(':_tenant', $document->getTenant());
}
}

$stmt->execute();

$document['$internalId'] = $this->getDocument($collection, $document->getId(), [Query::select(['$internalId'])])->getInternalId();
$document['$internalId'] = $this->pdo->lastInsertId();

if (empty($document['$internalId'])) {
throw new DatabaseException('Error creating document empty "$internalId"');
Expand Down Expand Up @@ -1014,10 +1001,7 @@ public function createDocuments(string $collection, array $documents): array
$permissions = [];
$documentIds = [];

foreach ($documents as $document) {
/**
* @var Document $document
*/
foreach ($documents as $index => $document) {
$attributes = $document->getAttributes();
$attributes['_uid'] = $document->getId();
$attributes['_createdAt'] = $document->getCreatedAt();
Expand All @@ -1032,7 +1016,7 @@ public function createDocuments(string $collection, array $documents): array
}

if ($this->sharedTables) {
$attributes['_tenant'] = $this->tenant;
$attributes['_tenant'] = $document->getTenant();
}

$bindKeys = [];
Expand All @@ -1052,25 +1036,20 @@ public function createDocuments(string $collection, array $documents): array
$batchKeys[] = '(' . \implode(', ', $bindKeys) . ')';
foreach (Database::PERMISSIONS as $type) {
foreach ($document->getPermissionsByType($type) as $permission) {
$tenantBind = $this->sharedTables ? ", :_tenant_{$index}" : '';
$permission = \str_replace('"', '', $permission);
$permission = "('{$type}', '{$permission}', '{$document->getId()}'";

if ($this->sharedTables) {
$permission .= ", :_tenant)";
} else {
$permission .= ")";
}

$permission = "('{$type}', '{$permission}', :_uid_{$index} {$tenantBind})";
$permissions[] = $permission;
}
}
}

$stmt = $this->getPDO()->prepare(
"
$batchKeys = \implode(', ', $batchKeys);

$stmt = $this->getPDO()->prepare("
INSERT INTO {$this->getSQLTable($name)} {$columns}
VALUES " . \implode(', ', $batchKeys)
);
VALUES {$batchKeys}
");

foreach ($bindValues as $key => $value) {
$stmt->bindValue($key, $value, $this->getPDOType($value));
Expand All @@ -1079,22 +1058,21 @@ public function createDocuments(string $collection, array $documents): array
$stmt->execute();

if (!empty($permissions)) {
$tenantColumn = $this->sharedTables ? ', _tenant' : '';
$permissions = \implode(', ', $permissions);

$sqlPermissions = "
INSERT INTO {$this->getSQLTable($name . '_perms')} (_type, _permission, _document
INSERT INTO {$this->getSQLTable($name . '_perms')} (_type, _permission, _document {$tenantColumn})
VALUES {$permissions};
";

if ($this->sharedTables) {
$sqlPermissions .= ', _tenant)';
} else {
$sqlPermissions .= ")";
}

$sqlPermissions .= " VALUES " . \implode(', ', $permissions);

$stmtPermissions = $this->getPDO()->prepare($sqlPermissions);

if ($this->sharedTables) {
$stmtPermissions->bindValue(':_tenant', $this->tenant);
foreach ($documents as $index => $document) {
$stmtPermissions->bindValue(":_uid_{$index}", $document->getId());
if ($this->sharedTables) {
$stmtPermissions->bindValue(":_tenant_{$index}", $document->getTenant());
}
}

$stmtPermissions?->execute();
Expand Down Expand Up @@ -2228,7 +2206,7 @@ public function find(string $collection, array $queries = [], ?int $limit = 25,
unset($results[$index]['_id']);
}
if (\array_key_exists('_tenant', $document)) {
$results[$index]['$tenant'] = $document['_tenant'];
$document['$tenant'] = $document['_tenant'] === null ? null : (int)$document['_tenant'];
unset($results[$index]['_tenant']);
}
if (\array_key_exists('_createdAt', $document)) {
Expand Down
Loading