@@ -2960,7 +2960,10 @@ public function getDocument(string $collection, string $id, array $queries = [],
29602960 throw new NotFoundException ('Collection not found ' );
29612961 }
29622962
2963- $ queries = Query::getSelectQueries ($ queries );
2963+ $ selects = Query::getSelectQueries ($ queries );
2964+ if (count ($ selects ) !== count ($ queries )){
2965+ throw new QueryException ('Only select queries are allowed ' );
2966+ }
29642967
29652968 $ context = new QueryContext ();
29662969 $ context ->add ($ collection );
@@ -2977,45 +2980,37 @@ public function getDocument(string $collection, string $id, array $queries = [],
29772980 fn (Document $ attribute ) => $ attribute ->getAttribute ('type ' ) === self ::VAR_RELATIONSHIP
29782981 );
29792982
2980- $ selects = Query::groupByType ($ queries )['selections ' ];
29812983 $ selections = $ this ->validateSelections ($ collection , $ selects );
29822984 $ nestedSelections = [];
29832985
2984- foreach ($ queries as $ query ) {
2985- if ($ query ->getMethod () == Query::TYPE_SELECT ) {
2986- $ values = $ query ->getValues ();
2987- foreach ($ values as $ valueIndex => $ value ) {
2988- if (\str_contains ($ value , '. ' )) {
2989- // Shift the top level off the dot-path to pass the selection down the chain
2990- // 'foo.bar.baz' becomes 'bar.baz'
2991- $ nestedSelections [] = Query::select ([
2992- \implode ('. ' , \array_slice (\explode ('. ' , $ value ), 1 ))
2993- ]);
2986+ foreach ($ selects as $ i => $ q ) {
2987+ if (\str_contains ($ q ->getAttribute (), '. ' )) {
2988+ $ key = \explode ('. ' , $ q ->getAttribute ())[0 ];
29942989
2995- $ key = \explode ('. ' , $ value )[0 ];
2990+ foreach ($ relationships as $ relationship ) {
2991+ if ($ relationship ->getAttribute ('key ' ) === $ key ) {
2992+ $ nestedSelections [] = Query::select (
2993+ \implode ('. ' , \array_slice (\explode ('. ' , $ q ->getAttribute ()), 1 ))
2994+ );
29962995
2997- foreach ($ relationships as $ relationship ) {
2998- if ($ relationship ->getAttribute ('key ' ) === $ key ) {
2999- switch ($ relationship ->getAttribute ('options ' )['relationType ' ]) {
3000- case Database::RELATION_MANY_TO_MANY :
3001- case Database::RELATION_ONE_TO_MANY :
3002- unset($ values [$ valueIndex ]);
3003- break ;
2996+ switch ($ relationship ->getAttribute ('options ' )['relationType ' ]) {
2997+ case Database::RELATION_MANY_TO_MANY :
2998+ case Database::RELATION_ONE_TO_MANY :
2999+ unset($ selects [$ i ]);
3000+ break ;
30043001
3005- case Database::RELATION_MANY_TO_ONE :
3006- case Database::RELATION_ONE_TO_ONE :
3007- $ values [$ valueIndex ] = $ key ;
3008- break ;
3009- }
3010- }
3002+ case Database::RELATION_MANY_TO_ONE :
3003+ case Database::RELATION_ONE_TO_ONE :
3004+ $ q ->setAttribute ($ key );
3005+ $ selects [$ i ] = $ q ;
3006+ break ;
30113007 }
30123008 }
30133009 }
3014- $ query ->setValues (\array_values ($ values ));
30153010 }
30163011 }
30173012
3018- $ queries = \array_values ($ queries );
3013+ $ selects = \array_values ($ selects ); // Since we may unset above
30193014
30203015 $ validator = new Authorization (self ::PERMISSION_READ );
30213016 $ documentSecurity = $ collection ->getAttribute ('documentSecurity ' , false );
@@ -3057,7 +3052,7 @@ public function getDocument(string $collection, string $id, array $queries = [],
30573052 $ document = $ this ->adapter ->getDocument (
30583053 $ collection ->getId (),
30593054 $ id ,
3060- $ queries ,
3055+ $ selects ,
30613056 $ forUpdate
30623057 );
30633058
@@ -3077,7 +3072,7 @@ public function getDocument(string $collection, string $id, array $queries = [],
30773072 }
30783073
30793074 $ document = $ this ->casting ($ collection , $ document );
3080- $ document = $ this ->decode ( $ collection , $ document , $ selections );
3075+ $ document = $ this ->decodeV2 ( $ context , $ document , $ selections );
30813076 $ this ->map = [];
30823077
30833078 if ($ this ->resolveRelationships && (empty ($ selects ) || !empty ($ nestedSelections ))) {
@@ -3102,7 +3097,7 @@ public function getDocument(string $collection, string $id, array $queries = [],
31023097 // Remove internal attributes if not queried for select query
31033098 // $id, $permissions and $collection are the default selected attributes for (MariaDB, MySQL, SQLite, Postgres)
31043099 // All internal attributes are default selected attributes for (MongoDB)
3105- foreach ($ queries as $ query ) {
3100+ foreach ($ selects as $ query ) {
31063101 if ($ query ->getMethod () === Query::TYPE_SELECT ) {
31073102 $ values = $ query ->getValues ();
31083103 foreach ($ this ->getInternalAttributes () as $ internalAttribute ) {
@@ -4689,24 +4684,28 @@ public function createOrUpdateDocumentsWithIncrease(
46894684 $ documentSecurity = $ collection ->getAttribute ('documentSecurity ' , false );
46904685 $ time = DateTime::now ();
46914686
4692- $ selects = ['$internalId ' , '$permissions ' ];
4687+ $ selects = [
4688+ Query::select ('$id ' ),
4689+ Query::select ('$internalId ' ),
4690+ Query::select ('$permissions ' ),
4691+ ];
46934692
46944693 if ($ this ->getSharedTables ()) {
4695- $ selects [] = '$tenant ' ;
4694+ $ selects [] = Query:: select ( '$tenant ' ) ;
46964695 }
46974696
46984697 foreach ($ documents as $ key => $ document ) {
46994698 if ($ this ->getSharedTables () && $ this ->getTenantPerDocument ()) {
47004699 $ old = Authorization::skip (fn () => $ this ->withTenant ($ document ->getTenant (), fn () => $ this ->silent (fn () => $ this ->getDocument (
47014700 $ collection ->getId (),
47024701 $ document ->getId (),
4703- [Query:: select ( $ selects)] ,
4702+ $ selects ,
47044703 ))));
47054704 } else {
47064705 $ old = Authorization::skip (fn () => $ this ->silent (fn () => $ this ->getDocument (
47074706 $ collection ->getId (),
47084707 $ document ->getId (),
4709- [Query:: select ( $ selects)] ,
4708+ $ selects ,
47104709 )));
47114710 }
47124711
@@ -5756,20 +5755,14 @@ public function find(string $collection, array $queries = [], string $forPermiss
57565755 $ nestedSelections = [];
57575756
57585757 foreach ($ selects as $ i => $ q ) {
5759- var_dump ($ q ->getAlias ());
5760- var_dump ($ q ->getAttribute ());
57615758 if (\str_contains ($ q ->getAttribute (), '. ' )) {
5762- $ nestedSelections [] = Query::select (
5763- \implode ('. ' , \array_slice (\explode ('. ' , $ q ->getAttribute ()), 1 ))
5764- );
5765-
57665759 $ key = \explode ('. ' , $ q ->getAttribute ())[0 ];
5767-
5768- var_dump ('#################################### ' );
5769- var_dump ($ key );
5770- var_dump ('#################################### ' );
57715760 foreach ($ relationships as $ relationship ) {
57725761 if ($ relationship ->getAttribute ('key ' ) === $ key ) {
5762+ $ nestedSelections [] = Query::select (
5763+ \implode ('. ' , \array_slice (\explode ('. ' , $ q ->getAttribute ()), 1 ))
5764+ );
5765+
57735766 switch ($ relationship ->getAttribute ('options ' )['relationType ' ]) {
57745767 case Database::RELATION_MANY_TO_MANY :
57755768 case Database::RELATION_ONE_TO_MANY :
@@ -5845,7 +5838,6 @@ public function find(string $collection, array $queries = [], string $forPermiss
58455838 joins: $ joins ,
58465839 orderQueries: $ orders
58475840 );
5848-
58495841 //$skipAuth = $authorization->isValid($collection->getPermissionsByType($forPermission));
58505842
58515843 //$results = $skipAuth ? Authorization::skip($getResults) : $getResults();
@@ -6250,6 +6242,80 @@ public function decode(Document $collection, Document $document, array $selectio
62506242 return $ document ;
62516243 }
62526244
6245+ /**
6246+ * Decode Document
6247+ *
6248+ * @param QueryContext $context
6249+ * @param Document $document
6250+ * @param array<Query> $selects
6251+ * @return Document
6252+ * @throws DatabaseException
6253+ */
6254+ public function decodeV2 (QueryContext $ context , Document $ document , array $ selections = []): Document
6255+ {
6256+ $ schema = [];
6257+
6258+ foreach ($ context ->getCollections () as $ collection ) {
6259+
6260+ foreach ($ collection ->getAttribute ('attributes ' , []) as $ attribute ) {
6261+ $ key = $ attribute ->getAttribute ('key ' , $ attribute ->getAttribute ('$id ' ));
6262+ $ key = $ this ->adapter ->filter ($ key );
6263+ $ schema [$ collection ->getId ()][$ key ] = $ attribute ->getArrayCopy ();
6264+ }
6265+
6266+ foreach (Database::INTERNAL_ATTRIBUTES as $ attribute ) {
6267+ $ schema [$ collection ->getId ()][$ attribute ['$id ' ]] = new Document ($ attribute );
6268+ }
6269+ }
6270+
6271+ $ new = new Document ;
6272+
6273+ foreach ($ document as $ key => $ value ) {
6274+ $ alias = Query::DEFAULT_ALIAS ;
6275+
6276+ $ collection = $ context ->getCollectionByAlias ($ alias );
6277+ if ($ collection ->isEmpty ()) {
6278+ throw new \Exception ('Invalid query: Unknown Alias context ' );
6279+ }
6280+
6281+ $ attribute = $ schema [$ collection ->getId ()][$ key ];
6282+
6283+ $ array = $ attribute ['array ' ] ?? false ;
6284+ $ filters = $ attribute ['filters ' ] ?? [];
6285+
6286+ $ value = ($ array ) ? $ value : [$ value ];
6287+ $ value = (is_null ($ value )) ? [] : $ value ;
6288+
6289+ foreach ($ value as $ index => $ node ) {
6290+ foreach (array_reverse ($ filters ) as $ filter ) {
6291+ $ value [$ index ] = $ this ->decodeAttribute ($ filter , $ node , $ document );
6292+ }
6293+ }
6294+
6295+ if (empty ($ selections ) || \in_array ($ key , $ selections ) || \in_array ('* ' , $ selections )) {
6296+ if (
6297+ empty ($ selections )
6298+ || \in_array ($ key , $ selections )
6299+ || \in_array ('* ' , $ selections )
6300+ || \in_array ($ key , ['$createdAt ' , '$updatedAt ' ])
6301+ ) {
6302+ // Prevent null values being set for createdAt and updatedAt
6303+ if (\in_array ($ key , ['$createdAt ' , '$updatedAt ' ]) && $ value [0 ] === null ) {
6304+ //continue;
6305+ } else {
6306+ //$document->setAttribute($key, ($array) ? $value : $value[0]);
6307+ }
6308+ }
6309+ }
6310+
6311+ $ value = ($ array ) ? $ value : $ value [0 ];
6312+
6313+ $ new ->setAttribute ($ attribute ['$id ' ], $ value );
6314+ }
6315+
6316+ return $ new ;
6317+ }
6318+
62536319 /**
62546320 * Casting
62556321 *
@@ -6388,13 +6454,11 @@ private function validateSelections(Document $collection, array $queries): array
63886454
63896455 foreach ($ queries as $ query ) {
63906456 if ($ query ->getMethod () == Query::TYPE_SELECT ) {
6391- foreach ($ query ->getValues () as $ value ) {
6392- if (\str_contains ($ value , '. ' )) {
6393- $ relationshipSelections [] = $ value ;
6394- continue ;
6395- }
6396- $ selections [] = $ value ;
6457+ if (\str_contains ($ query ->getAttribute (), '. ' )) {
6458+ $ relationshipSelections [] = $ query ->getAttribute ();
6459+ continue ;
63976460 }
6461+ $ selections [] = $ query ->getAttribute ();
63986462 }
63996463 }
64006464
0 commit comments