@@ -1400,218 +1400,9 @@ public function updateDocument(string $collection, string $id, Document $documen
14001400 * @param string $attribute
14011401 * @param array<Change> $changes
14021402 * @return array<Document>
1403- * @throws DatabaseException
14041403 */
1405- public function createOrUpdateDocuments (
1406- string $ collection ,
1407- string $ attribute ,
1408- array $ changes
1409- ): array {
1410- if (empty ($ changes )) {
1411- return $ changes ;
1412- }
1413-
1414- try {
1415- $ name = $ this ->filter ($ collection );
1416- $ attribute = $ this ->filter ($ attribute );
1417-
1418- $ attributes = [];
1419- $ bindIndex = 0 ;
1420- $ batchKeys = [];
1421- $ bindValues = [];
1422- $ documentIds = [];
1423- $ documentTenants = [];
1424-
1425- foreach ($ changes as $ change ) {
1426- $ document = $ change ->getNew ();
1427- $ attributes = $ document ->getAttributes ();
1428- $ attributes ['_uid ' ] = $ document ->getId ();
1429- $ attributes ['_createdAt ' ] = $ document ->getCreatedAt ();
1430- $ attributes ['_updatedAt ' ] = $ document ->getUpdatedAt ();
1431- $ attributes ['_permissions ' ] = \json_encode ($ document ->getPermissions ());
1432-
1433- if (!empty ($ document ->getInternalId ())) {
1434- $ attributes ['_id ' ] = $ document ->getInternalId ();
1435- } else {
1436- $ documentIds [] = $ document ->getId ();
1437- }
1438-
1439- if ($ this ->sharedTables ) {
1440- $ attributes ['_tenant ' ]
1441- = $ documentTenants []
1442- = $ document ->getTenant ();
1443- }
1444-
1445- // Enforce deterministic order
1446- \ksort ($ attributes );
1447-
1448- $ columns = [];
1449- foreach (\array_keys ($ attributes ) as $ key => $ attr ) {
1450- $ columns [$ key ] = $ this ->quote ($ this ->filter ($ attr ));
1451- }
1452- $ columns = '( ' . \implode (', ' , $ columns ) . ') ' ;
1453-
1454- /** Value list for this row */
1455- $ bindKeys = [];
1456- foreach ($ attributes as $ attrValue ) {
1457- if (\is_array ($ attrValue )) {
1458- $ attrValue = \json_encode ($ attrValue );
1459- }
1460- $ attrValue = (\is_bool ($ attrValue )) ? (int )$ attrValue : $ attrValue ;
1461- $ bindKey = 'key_ ' . $ bindIndex ;
1462- $ bindKeys [] = ': ' . $ bindKey ;
1463- $ bindValues [$ bindKey ] = $ attrValue ;
1464- $ bindIndex ++;
1465- }
1466-
1467- $ batchKeys [] = '( ' . \implode (', ' , $ bindKeys ) . ') ' ;
1468- }
1469-
1470- $ getUpdateClause = function (string $ attribute , bool $ increment = false ): string {
1471- $ attribute = $ this ->quote ($ this ->filter ($ attribute ));
1472-
1473- $ newValue = $ increment
1474- ? "{$ attribute } + EXCLUDED. {$ attribute }"
1475- : "EXCLUDED. {$ attribute }" ;
1476-
1477- // tenant-aware overwrite guard
1478- if ($ this ->sharedTables ) {
1479- return "{$ attribute } = CASE
1480- WHEN _tenant = EXCLUDED._tenant
1481- THEN {$ newValue }
1482- ELSE {$ attribute }
1483- END " ;
1484- }
1485-
1486- return "{$ attribute } = {$ newValue }" ;
1487- };
1488-
1489- if (!empty ($ attribute )) {
1490- $ updateColumns = [
1491- $ getUpdateClause ($ attribute , increment: true ),
1492- $ getUpdateClause ('_updatedAt ' ),
1493- ];
1494- } else {
1495- $ updateColumns = [];
1496- foreach (\array_keys ($ attributes ) as $ attr ) {
1497- $ updateColumns [] = $ getUpdateClause ($ this ->filter ($ attr ));
1498- }
1499- }
1500-
1501- // Conflict target: _uid, plus _tenant if shared tables
1502- $ conflictTarget = $ this ->sharedTables
1503- ? '(_uid, _tenant) '
1504- : '(_uid) ' ;
1505-
1506- $ sql = "
1507- INSERT INTO {$ this ->getSQLTable ($ name )} {$ columns }
1508- VALUES " . \implode (', ' , $ batchKeys ) . "
1509- ON CONFLICT {$ conflictTarget } DO UPDATE SET
1510- " . \implode (', ' , $ updateColumns );
1511-
1512- $ stmt = $ this ->getPDO ()->prepare ($ sql );
1513-
1514- foreach ($ bindValues as $ key => $ binding ) {
1515- $ stmt ->bindValue ($ key , $ binding , $ this ->getPDOType ($ binding ));
1516- }
1517-
1518- $ stmt ->execute ();
1519- $ stmt ->closeCursor ();
1520-
1521- $ removeQueries = [];
1522- $ removeBindValues = [];
1523- $ addQueries = [];
1524- $ addBindValues = [];
1525-
1526- foreach ($ changes as $ index => $ change ) {
1527- $ old = $ change ->getOld ();
1528- $ document = $ change ->getNew ();
1529-
1530- $ current = [];
1531- foreach (Database::PERMISSIONS as $ type ) {
1532- $ current [$ type ] = $ old ->getPermissionsByType ($ type );
1533- }
1534-
1535- // Calculate removals
1536- foreach (Database::PERMISSIONS as $ type ) {
1537- $ toRemove = \array_diff ($ current [$ type ], $ document ->getPermissionsByType ($ type ));
1538- if (!empty ($ toRemove )) {
1539- $ removeQueries [] = "(
1540- _document = :_uid_ {$ index }
1541- {$ this ->getTenantQuery ($ collection , tenantCount: \count ($ toRemove ))}
1542- AND _type = ' {$ type }'
1543- AND _permission IN ( " . \implode (', ' , \array_map (fn ($ i ) => ":remove_ {$ type }_ {$ index }_ {$ i }" , \array_keys ($ toRemove ))) . ")
1544- ) " ;
1545- $ removeBindValues [":_uid_ {$ index }" ] = $ document ->getId ();
1546- $ removeBindValues [":_tenant_ {$ index }" ] = $ document ->getTenant ();
1547- foreach ($ toRemove as $ i => $ perm ) {
1548- $ removeBindValues [":remove_ {$ type }_ {$ index }_ {$ i }" ] = $ perm ;
1549- }
1550- }
1551- }
1552-
1553- // Calculate additions
1554- foreach (Database::PERMISSIONS as $ type ) {
1555- $ toAdd = \array_diff ($ document ->getPermissionsByType ($ type ), $ current [$ type ]);
1556-
1557- foreach ($ toAdd as $ i => $ permission ) {
1558- $ addQuery = "(:_uid_ {$ index }, ' {$ type }', :add_ {$ type }_ {$ index }_ {$ i }" ;
1559-
1560- if ($ this ->sharedTables ) {
1561- $ addQuery .= ", :_tenant_ {$ index }" ;
1562- }
1563-
1564- $ addQuery .= ") " ;
1565- $ addQueries [] = $ addQuery ;
1566- $ addBindValues [":_uid_ {$ index }" ] = $ document ->getId ();
1567- $ addBindValues [":add_ {$ type }_ {$ index }_ {$ i }" ] = $ permission ;
1568-
1569- if ($ this ->sharedTables ) {
1570- $ addBindValues [":_tenant_ {$ index }" ] = $ document ->getTenant ();
1571- }
1572- }
1573- }
1574- }
1575-
1576- // Execute permission removals
1577- if (!empty ($ removeQueries )) {
1578- $ removeQuery = \implode (' OR ' , $ removeQueries );
1579- $ stmtRemovePermissions = $ this ->getPDO ()->prepare ("DELETE FROM {$ this ->getSQLTable ($ name . '_perms ' )} WHERE {$ removeQuery }" );
1580- foreach ($ removeBindValues as $ key => $ value ) {
1581- $ stmtRemovePermissions ->bindValue ($ key , $ value , $ this ->getPDOType ($ value ));
1582- }
1583- $ stmtRemovePermissions ->execute ();
1584- }
1585-
1586- // Execute permission additions
1587- if (!empty ($ addQueries )) {
1588- $ sqlAddPermissions = "INSERT INTO {$ this ->getSQLTable ($ name . '_perms ' )} (_document, _type, _permission " ;
1589- if ($ this ->sharedTables ) {
1590- $ sqlAddPermissions .= ", _tenant " ;
1591- }
1592- $ sqlAddPermissions .= ") VALUES " . \implode (', ' , $ addQueries );
1593- $ stmtAddPermissions = $ this ->getPDO ()->prepare ($ sqlAddPermissions );
1594- foreach ($ addBindValues as $ key => $ value ) {
1595- $ stmtAddPermissions ->bindValue ($ key , $ value , $ this ->getPDOType ($ value ));
1596- }
1597- $ stmtAddPermissions ->execute ();
1598- }
1599-
1600- $ internalIds = $ this ->getInternalIds (
1601- $ collection ,
1602- $ documentIds ,
1603- $ documentTenants
1604- );
1605-
1606- foreach ($ changes as $ change ) {
1607- if (isset ($ internalIds [$ change ->getNew ()->getId ()])) {
1608- $ change ->getNew ()->setAttribute ('$internalId ' , $ internalIds [$ change ->getNew ()->getId ()]);
1609- }
1610- }
1611- } catch (\PDOException $ e ) {
1612- throw $ this ->processException ($ e );
1613- }
1614-
1404+ public function createOrUpdateDocuments (string $ collection , string $ attribute , array $ changes ): array
1405+ {
16151406 return \array_map (fn ($ change ) => $ change ->getNew (), $ changes );
16161407 }
16171408
@@ -2334,7 +2125,7 @@ public function getSupportForSchemaAttributes(): bool
23342125
23352126 public function getSupportForUpserts (): bool
23362127 {
2337- return true ;
2128+ return false ;
23382129 }
23392130
23402131 /**
0 commit comments