Skip to content

Commit 1346015

Browse files
committed
DecodeV2
1 parent 311555c commit 1346015

File tree

3 files changed

+139
-70
lines changed

3 files changed

+139
-70
lines changed

src/Database/Adapter/MariaDB.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,7 +1838,7 @@ public function find(
18381838
//$selections = $this->getAttributeSelections($selects);
18391839

18401840
$sql = "
1841-
SELECT {$this->getAttributeProjectionV2($selects, $alias)}
1841+
SELECT {$this->getAttributeProjectionV2($selects)}
18421842
FROM {$this->getSQLTable($mainCollection)} AS {$this->quote($alias)}
18431843
{$sqlJoin}
18441844
{$sqlWhere}
@@ -2066,8 +2066,6 @@ protected function getSQLCondition(Query $query, array &$binds): string
20662066
$alias = $query->getAlias();
20672067
$alias = $this->filter($alias);
20682068
$alias = $this->quote($alias);
2069-
2070-
//$placeholder = $this->getSQLPlaceholder($query);
20712069
$placeholder = ID::unique();
20722070

20732071
switch ($query->getMethod()) {

src/Database/Adapter/SQL.php

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -214,28 +214,29 @@ public function list(): array
214214
public function getDocument(string $collection, string $id, array $queries = [], bool $forUpdate = false): Document
215215
{
216216
$name = $this->filter($collection);
217-
$selections = $this->getAttributeSelections($queries);
217+
$alias = Query::DEFAULT_ALIAS;
218+
//$selections = $this->getAttributeSelections($queries);
218219

219220
$forUpdate = $forUpdate ? 'FOR UPDATE' : '';
220221

221222
$sql = "
222-
SELECT {$this->getAttributeProjection($selections)}
223-
FROM {$this->getSQLTable($name)}
224-
WHERE _uid = :_uid
225-
{$this->getTenantQuery($collection)}
223+
SELECT {$this->getAttributeProjectionV2($queries)}
224+
FROM {$this->getSQLTable($name)} AS {$this->quote($alias)}
225+
WHERE {$this->quote($alias)}._uid = :_uid
226+
{$this->getTenantQuery($collection, $alias)}
226227
";
227228

228229
if ($this->getSupportForUpdateLock()) {
229230
$sql .= " {$forUpdate}";
230231
}
231232

232233
$stmt = $this->getPDO()->prepare($sql);
233-
234234
$stmt->bindValue(':_uid', $id);
235235

236236
if ($this->sharedTables) {
237237
$stmt->bindValue(':_tenant', $this->getTenant());
238238
}
239+
echo $stmt->queryString;
239240

240241
$stmt->execute();
241242
$document = $stmt->fetchAll();
@@ -1540,22 +1541,28 @@ protected function getAttributeProjectionV2(array $selects): string
15401541

15411542
$string = '';
15421543
foreach ($selects as $select) {
1543-
var_dump($select->getAttribute());
1544-
var_dump($select->getAlias());
1545-
if(!empty($string)){
1546-
$string .= ', ';
1547-
}
1548-
1549-
$alias = $this->filter($select->getAlias());
1550-
1544+
$alias = $select->getAlias();
1545+
$alias = $this->filter($alias);
15511546
$attribute = $select->getAttribute();
1552-
$attribute = $this->getInternalKeyForAttribute($attribute);
1547+
$attribute = match ($attribute) {
1548+
'$id' => '_uid',
1549+
'$internalId' => '_id',
1550+
'$tenant' => '_tenant',
1551+
'$createdAt' => '_createdAt',
1552+
'$updatedAt' => '_updatedAt',
1553+
'$permissions' => '_permissions',
1554+
default => $attribute
1555+
};
15531556

15541557
if ($attribute !== '*'){
15551558
$attribute = $this->filter($attribute);
15561559
$attribute = $this->quote($attribute);
15571560
}
15581561

1562+
if (!empty($string)){
1563+
$string .= ', ';
1564+
}
1565+
15591566
$string .= "{$this->quote($alias)}.{$attribute}";
15601567
}
15611568

src/Database/Database.php

Lines changed: 116 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)