|
3 | 3 | namespace Utopia\Database\Adapter; |
4 | 4 |
|
5 | 5 | use Exception; |
6 | | -use PDO; |
7 | 6 | use PDOException; |
8 | 7 | use Utopia\Database\Database; |
9 | 8 | use Utopia\Database\Document; |
|
14 | 13 | use Utopia\Database\Exception\Truncate as TruncateException; |
15 | 14 | use Utopia\Database\Helpers\ID; |
16 | 15 | use Utopia\Database\Query; |
17 | | -use Utopia\Database\Validator\Authorization; |
18 | 16 |
|
19 | 17 | class MariaDB extends SQL |
20 | 18 | { |
@@ -1354,346 +1352,6 @@ public function deleteDocument(string $collection, string $id): bool |
1354 | 1352 | return $deleted; |
1355 | 1353 | } |
1356 | 1354 |
|
1357 | | - /** |
1358 | | - * Find Documents |
1359 | | - * |
1360 | | - * @param Document $collection |
1361 | | - * @param array<Query> $queries |
1362 | | - * @param int|null $limit |
1363 | | - * @param int|null $offset |
1364 | | - * @param array<string> $orderAttributes |
1365 | | - * @param array<string> $orderTypes |
1366 | | - * @param array<string, mixed> $cursor |
1367 | | - * @param string $cursorDirection |
1368 | | - * @param string $forPermission |
1369 | | - * @return array<Document> |
1370 | | - * @throws DatabaseException |
1371 | | - * @throws TimeoutException |
1372 | | - * @throws Exception |
1373 | | - */ |
1374 | | - public function find(Document $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, string $forPermission = Database::PERMISSION_READ): array |
1375 | | - { |
1376 | | - $spatialAttributes = $this->getSpatialAttributes($collection); |
1377 | | - $attributes = $collection->getAttribute('attributes', []); |
1378 | | - |
1379 | | - $collection = $collection->getId(); |
1380 | | - $name = $this->filter($collection); |
1381 | | - $roles = Authorization::getRoles(); |
1382 | | - $where = []; |
1383 | | - $orders = []; |
1384 | | - $alias = Query::DEFAULT_ALIAS; |
1385 | | - $binds = []; |
1386 | | - |
1387 | | - $queries = array_map(fn ($query) => clone $query, $queries); |
1388 | | - |
1389 | | - $cursorWhere = []; |
1390 | | - |
1391 | | - foreach ($orderAttributes as $i => $originalAttribute) { |
1392 | | - $attribute = $this->getInternalKeyForAttribute($originalAttribute); |
1393 | | - $attribute = $this->filter($attribute); |
1394 | | - |
1395 | | - $orderType = $this->filter($orderTypes[$i] ?? Database::ORDER_ASC); |
1396 | | - $direction = $orderType; |
1397 | | - |
1398 | | - if ($cursorDirection === Database::CURSOR_BEFORE) { |
1399 | | - $direction = ($direction === Database::ORDER_ASC) |
1400 | | - ? Database::ORDER_DESC |
1401 | | - : Database::ORDER_ASC; |
1402 | | - } |
1403 | | - |
1404 | | - $orders[] = "{$this->quote($attribute)} {$direction}"; |
1405 | | - |
1406 | | - // Build pagination WHERE clause only if we have a cursor |
1407 | | - if (!empty($cursor)) { |
1408 | | - // Special case: No tie breaks. only 1 attribute and it's a unique primary key |
1409 | | - if (count($orderAttributes) === 1 && $i === 0 && $originalAttribute === '$sequence') { |
1410 | | - $operator = ($direction === Database::ORDER_DESC) |
1411 | | - ? Query::TYPE_LESSER |
1412 | | - : Query::TYPE_GREATER; |
1413 | | - |
1414 | | - $bindName = ":cursor_pk"; |
1415 | | - $binds[$bindName] = $cursor[$originalAttribute]; |
1416 | | - |
1417 | | - $cursorWhere[] = "{$this->quote($alias)}.{$this->quote($attribute)} {$this->getSQLOperator($operator)} {$bindName}"; |
1418 | | - break; |
1419 | | - } |
1420 | | - |
1421 | | - $conditions = []; |
1422 | | - |
1423 | | - // Add equality conditions for previous attributes |
1424 | | - for ($j = 0; $j < $i; $j++) { |
1425 | | - $prevOriginal = $orderAttributes[$j]; |
1426 | | - $prevAttr = $this->filter($this->getInternalKeyForAttribute($prevOriginal)); |
1427 | | - |
1428 | | - $bindName = ":cursor_{$j}"; |
1429 | | - $binds[$bindName] = $cursor[$prevOriginal]; |
1430 | | - |
1431 | | - $conditions[] = "{$this->quote($alias)}.{$this->quote($prevAttr)} = {$bindName}"; |
1432 | | - } |
1433 | | - |
1434 | | - // Add comparison for current attribute |
1435 | | - $operator = ($direction === Database::ORDER_DESC) |
1436 | | - ? Query::TYPE_LESSER |
1437 | | - : Query::TYPE_GREATER; |
1438 | | - |
1439 | | - $bindName = ":cursor_{$i}"; |
1440 | | - $binds[$bindName] = $cursor[$originalAttribute]; |
1441 | | - |
1442 | | - $conditions[] = "{$this->quote($alias)}.{$this->quote($attribute)} {$this->getSQLOperator($operator)} {$bindName}"; |
1443 | | - |
1444 | | - $cursorWhere[] = '(' . implode(' AND ', $conditions) . ')'; |
1445 | | - } |
1446 | | - } |
1447 | | - |
1448 | | - if (!empty($cursorWhere)) { |
1449 | | - $where[] = '(' . implode(' OR ', $cursorWhere) . ')'; |
1450 | | - } |
1451 | | - |
1452 | | - $conditions = $this->getSQLConditions($queries, $binds, attributes:$attributes); |
1453 | | - if (!empty($conditions)) { |
1454 | | - $where[] = $conditions; |
1455 | | - } |
1456 | | - |
1457 | | - if (Authorization::$status) { |
1458 | | - $where[] = $this->getSQLPermissionsCondition($name, $roles, $alias, $forPermission); |
1459 | | - } |
1460 | | - |
1461 | | - if ($this->sharedTables) { |
1462 | | - $binds[':_tenant'] = $this->tenant; |
1463 | | - $where[] = "{$this->getTenantQuery($collection, $alias, condition: '')}"; |
1464 | | - } |
1465 | | - |
1466 | | - $sqlWhere = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : ''; |
1467 | | - $sqlOrder = 'ORDER BY ' . implode(', ', $orders); |
1468 | | - |
1469 | | - $sqlLimit = ''; |
1470 | | - if (! \is_null($limit)) { |
1471 | | - $binds[':limit'] = $limit; |
1472 | | - $sqlLimit = 'LIMIT :limit'; |
1473 | | - } |
1474 | | - |
1475 | | - if (! \is_null($offset)) { |
1476 | | - $binds[':offset'] = $offset; |
1477 | | - $sqlLimit .= ' OFFSET :offset'; |
1478 | | - } |
1479 | | - |
1480 | | - $selections = $this->getAttributeSelections($queries); |
1481 | | - |
1482 | | - |
1483 | | - $sql = " |
1484 | | - SELECT {$this->getAttributeProjection($selections, $alias, $spatialAttributes)} |
1485 | | - FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} |
1486 | | - {$sqlWhere} |
1487 | | - {$sqlOrder} |
1488 | | - {$sqlLimit}; |
1489 | | - "; |
1490 | | - |
1491 | | - $sql = $this->trigger(Database::EVENT_DOCUMENT_FIND, $sql); |
1492 | | - |
1493 | | - try { |
1494 | | - $stmt = $this->getPDO()->prepare($sql); |
1495 | | - |
1496 | | - foreach ($binds as $key => $value) { |
1497 | | - if (gettype($value) === 'double') { |
1498 | | - $stmt->bindValue($key, $this->getFloatPrecision($value), PDO::PARAM_STR); |
1499 | | - } else { |
1500 | | - $stmt->bindValue($key, $value, $this->getPDOType($value)); |
1501 | | - } |
1502 | | - } |
1503 | | - |
1504 | | - $stmt->execute(); |
1505 | | - } catch (PDOException $e) { |
1506 | | - throw $this->processException($e); |
1507 | | - } |
1508 | | - |
1509 | | - $results = $stmt->fetchAll(); |
1510 | | - $stmt->closeCursor(); |
1511 | | - |
1512 | | - foreach ($results as $index => $document) { |
1513 | | - if (\array_key_exists('_uid', $document)) { |
1514 | | - $results[$index]['$id'] = $document['_uid']; |
1515 | | - unset($results[$index]['_uid']); |
1516 | | - } |
1517 | | - if (\array_key_exists('_id', $document)) { |
1518 | | - $results[$index]['$sequence'] = $document['_id']; |
1519 | | - unset($results[$index]['_id']); |
1520 | | - } |
1521 | | - if (\array_key_exists('_tenant', $document)) { |
1522 | | - $results[$index]['$tenant'] = $document['_tenant']; |
1523 | | - unset($results[$index]['_tenant']); |
1524 | | - } |
1525 | | - if (\array_key_exists('_createdAt', $document)) { |
1526 | | - $results[$index]['$createdAt'] = $document['_createdAt']; |
1527 | | - unset($results[$index]['_createdAt']); |
1528 | | - } |
1529 | | - if (\array_key_exists('_updatedAt', $document)) { |
1530 | | - $results[$index]['$updatedAt'] = $document['_updatedAt']; |
1531 | | - unset($results[$index]['_updatedAt']); |
1532 | | - } |
1533 | | - if (\array_key_exists('_permissions', $document)) { |
1534 | | - $results[$index]['$permissions'] = \json_decode($document['_permissions'] ?? '[]', true); |
1535 | | - unset($results[$index]['_permissions']); |
1536 | | - } |
1537 | | - |
1538 | | - $results[$index] = new Document($results[$index]); |
1539 | | - } |
1540 | | - |
1541 | | - if ($cursorDirection === Database::CURSOR_BEFORE) { |
1542 | | - $results = \array_reverse($results); |
1543 | | - } |
1544 | | - |
1545 | | - return $results; |
1546 | | - } |
1547 | | - |
1548 | | - /** |
1549 | | - * Count Documents |
1550 | | - * |
1551 | | - * @param Document $collection |
1552 | | - * @param array<Query> $queries |
1553 | | - * @param int|null $max |
1554 | | - * @return int |
1555 | | - * @throws Exception |
1556 | | - * @throws PDOException |
1557 | | - */ |
1558 | | - public function count(Document $collection, array $queries = [], ?int $max = null): int |
1559 | | - { |
1560 | | - $attributes = $collection->getAttribute("attributes", []); |
1561 | | - $collection = $collection->getId(); |
1562 | | - $name = $this->filter($collection); |
1563 | | - $roles = Authorization::getRoles(); |
1564 | | - $binds = []; |
1565 | | - $where = []; |
1566 | | - $alias = Query::DEFAULT_ALIAS; |
1567 | | - |
1568 | | - $limit = ''; |
1569 | | - if (! \is_null($max)) { |
1570 | | - $binds[':limit'] = $max; |
1571 | | - $limit = 'LIMIT :limit'; |
1572 | | - } |
1573 | | - |
1574 | | - $queries = array_map(fn ($query) => clone $query, $queries); |
1575 | | - |
1576 | | - $conditions = $this->getSQLConditions($queries, $binds, attributes:$attributes); |
1577 | | - if (!empty($conditions)) { |
1578 | | - $where[] = $conditions; |
1579 | | - } |
1580 | | - |
1581 | | - if (Authorization::$status) { |
1582 | | - $where[] = $this->getSQLPermissionsCondition($name, $roles, $alias); |
1583 | | - } |
1584 | | - |
1585 | | - if ($this->sharedTables) { |
1586 | | - $binds[':_tenant'] = $this->tenant; |
1587 | | - $where[] = "{$this->getTenantQuery($collection, $alias, condition: '')}"; |
1588 | | - } |
1589 | | - |
1590 | | - $sqlWhere = !empty($where) |
1591 | | - ? 'WHERE ' . \implode(' AND ', $where) |
1592 | | - : ''; |
1593 | | - |
1594 | | - $sql = " |
1595 | | - SELECT COUNT(1) as sum FROM ( |
1596 | | - SELECT 1 |
1597 | | - FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} |
1598 | | - {$sqlWhere} |
1599 | | - {$limit} |
1600 | | - ) table_count |
1601 | | - "; |
1602 | | - |
1603 | | - $sql = $this->trigger(Database::EVENT_DOCUMENT_COUNT, $sql); |
1604 | | - |
1605 | | - $stmt = $this->getPDO()->prepare($sql); |
1606 | | - |
1607 | | - foreach ($binds as $key => $value) { |
1608 | | - $stmt->bindValue($key, $value, $this->getPDOType($value)); |
1609 | | - } |
1610 | | - |
1611 | | - $stmt->execute(); |
1612 | | - |
1613 | | - $result = $stmt->fetchAll(); |
1614 | | - $stmt->closeCursor(); |
1615 | | - if (!empty($result)) { |
1616 | | - $result = $result[0]; |
1617 | | - } |
1618 | | - |
1619 | | - return $result['sum'] ?? 0; |
1620 | | - } |
1621 | | - |
1622 | | - /** |
1623 | | - * Sum an Attribute |
1624 | | - * |
1625 | | - * @param Document $collection |
1626 | | - * @param string $attribute |
1627 | | - * @param array<Query> $queries |
1628 | | - * @param int|null $max |
1629 | | - * @return int|float |
1630 | | - * @throws Exception |
1631 | | - * @throws PDOException |
1632 | | - */ |
1633 | | - public function sum(Document $collection, string $attribute, array $queries = [], ?int $max = null): int|float |
1634 | | - { |
1635 | | - $collectionAttributes = $collection->getAttribute("attributes", []); |
1636 | | - $collection = $collection->getId(); |
1637 | | - $name = $this->filter($collection); |
1638 | | - $roles = Authorization::getRoles(); |
1639 | | - $where = []; |
1640 | | - $alias = Query::DEFAULT_ALIAS; |
1641 | | - $binds = []; |
1642 | | - |
1643 | | - $limit = ''; |
1644 | | - if (! \is_null($max)) { |
1645 | | - $binds[':limit'] = $max; |
1646 | | - $limit = 'LIMIT :limit'; |
1647 | | - } |
1648 | | - |
1649 | | - $queries = array_map(fn ($query) => clone $query, $queries); |
1650 | | - |
1651 | | - $conditions = $this->getSQLConditions($queries, $binds, attributes:$collectionAttributes); |
1652 | | - if (!empty($conditions)) { |
1653 | | - $where[] = $conditions; |
1654 | | - } |
1655 | | - |
1656 | | - if (Authorization::$status) { |
1657 | | - $where[] = $this->getSQLPermissionsCondition($name, $roles, $alias); |
1658 | | - } |
1659 | | - |
1660 | | - if ($this->sharedTables) { |
1661 | | - $binds[':_tenant'] = $this->tenant; |
1662 | | - $where[] = "{$this->getTenantQuery($collection, $alias, condition: '')}"; |
1663 | | - } |
1664 | | - |
1665 | | - $sqlWhere = !empty($where) |
1666 | | - ? 'WHERE ' . \implode(' AND ', $where) |
1667 | | - : ''; |
1668 | | - |
1669 | | - $sql = " |
1670 | | - SELECT SUM({$this->quote($attribute)}) as sum FROM ( |
1671 | | - SELECT {$this->quote($attribute)} |
1672 | | - FROM {$this->getSQLTable($name)} AS {$this->quote($alias)} |
1673 | | - {$sqlWhere} |
1674 | | - {$limit} |
1675 | | - ) table_count |
1676 | | - "; |
1677 | | - |
1678 | | - $sql = $this->trigger(Database::EVENT_DOCUMENT_SUM, $sql); |
1679 | | - |
1680 | | - $stmt = $this->getPDO()->prepare($sql); |
1681 | | - |
1682 | | - foreach ($binds as $key => $value) { |
1683 | | - $stmt->bindValue($key, $value, $this->getPDOType($value)); |
1684 | | - } |
1685 | | - |
1686 | | - $stmt->execute(); |
1687 | | - |
1688 | | - $result = $stmt->fetchAll(); |
1689 | | - $stmt->closeCursor(); |
1690 | | - if (!empty($result)) { |
1691 | | - $result = $result[0]; |
1692 | | - } |
1693 | | - |
1694 | | - return $result['sum'] ?? 0; |
1695 | | - } |
1696 | | - |
1697 | 1355 | /** |
1698 | 1356 | * Handle spatial queries |
1699 | 1357 | * |
@@ -1974,9 +1632,9 @@ protected function getSQLType(string $type, int $size, bool $signed = true, bool |
1974 | 1632 | protected function getPDOType(mixed $value): int |
1975 | 1633 | { |
1976 | 1634 | return match (gettype($value)) { |
1977 | | - 'string','double' => PDO::PARAM_STR, |
1978 | | - 'integer', 'boolean' => PDO::PARAM_INT, |
1979 | | - 'NULL' => PDO::PARAM_NULL, |
| 1635 | + 'string','double' => \PDO::PARAM_STR, |
| 1636 | + 'integer', 'boolean' => \PDO::PARAM_INT, |
| 1637 | + 'NULL' => \PDO::PARAM_NULL, |
1980 | 1638 | default => throw new DatabaseException('Unknown PDO Type for ' . \gettype($value)), |
1981 | 1639 | }; |
1982 | 1640 | } |
|
0 commit comments