Skip to content

Commit 9cdcb8a

Browse files
authored
Merge pull request #492 from utopia-php/schema-attributes
Get schema attributes
2 parents d3a8cae + 3fb18da commit 9cdcb8a

File tree

8 files changed

+183
-0
lines changed

8 files changed

+183
-0
lines changed

src/Database/Adapter.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,13 @@ abstract public function getSupportForSchemas(): bool;
781781
*/
782782
abstract public function getSupportForAttributes(): bool;
783783

784+
/**
785+
* Are schema attributes supported?
786+
*
787+
* @return bool
788+
*/
789+
abstract public function getSupportForSchemaAttributes(): bool;
790+
784791
/**
785792
* Is index supported?
786793
*
@@ -1022,4 +1029,13 @@ abstract public function getConnectionId(): string;
10221029
* @return array<string>
10231030
*/
10241031
abstract public function getInternalIndexesKeys(): array;
1032+
1033+
/**
1034+
* Get Schema Attributes
1035+
*
1036+
* @param string $collection
1037+
* @return array<Document>
1038+
* @throws DatabaseException
1039+
*/
1040+
abstract public function getSchemaAttributes(string $collection): array;
10251041
}

src/Database/Adapter/MariaDB.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,7 @@ public function updateDocuments(string $collection, Document $updates, array $do
14571457

14581458
$permissionsStmt->execute();
14591459
$permissions = $permissionsStmt->fetchAll();
1460+
$permissionsStmt->closeCursor();
14601461

14611462
$initial = [];
14621463
foreach (Database::PERMISSIONS as $type) {
@@ -2433,4 +2434,55 @@ protected function processException(PDOException $e): \Exception
24332434

24342435
return $e;
24352436
}
2437+
2438+
/**
2439+
* Get Schema Attributes
2440+
*
2441+
* @param string $collection
2442+
* @return array<Document>
2443+
* @throws DatabaseException
2444+
*/
2445+
public function getSchemaAttributes(string $collection): array
2446+
{
2447+
$schema = $this->getDatabase();
2448+
$collection = $this->getNamespace().'_'.$this->filter($collection);
2449+
2450+
try {
2451+
$stmt = $this->getPDO()->prepare('
2452+
SELECT
2453+
COLUMN_NAME as columnName,
2454+
COLUMN_DEFAULT as columnDefault,
2455+
IS_NULLABLE as isNullable,
2456+
DATA_TYPE as dataType,
2457+
CHARACTER_MAXIMUM_LENGTH as characterMaximumLength,
2458+
NUMERIC_PRECISION as numericPrecision,
2459+
NUMERIC_SCALE as numericScale,
2460+
DATETIME_PRECISION as datetimePrecision,
2461+
COLUMN_TYPE as columnType,
2462+
COLUMN_KEY as columnKey,
2463+
EXTRA as extra
2464+
FROM INFORMATION_SCHEMA.COLUMNS
2465+
WHERE TABLE_SCHEMA = :schema AND TABLE_NAME = :table
2466+
');
2467+
$stmt->bindParam(':schema', $schema);
2468+
$stmt->bindParam(':table', $collection);
2469+
$stmt->execute();
2470+
$results = $stmt->fetchAll();
2471+
$stmt->closeCursor();
2472+
2473+
foreach ($results as $index => $document) {
2474+
$results[$index] = new Document($document);
2475+
}
2476+
2477+
return $results;
2478+
2479+
} catch (PDOException $e) {
2480+
throw new DatabaseException('Failed to get schema attributes', $e->getCode(), $e);
2481+
}
2482+
}
2483+
2484+
public function getSupportForSchemaAttributes(): bool
2485+
{
2486+
return true;
2487+
}
24362488
}

src/Database/Adapter/Mongo.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,6 +1787,16 @@ public function getSupportForGetConnectionId(): bool
17871787
return false;
17881788
}
17891789

1790+
/**
1791+
* Is get schema attributes supported?
1792+
*
1793+
* @return bool
1794+
*/
1795+
public function getSupportForSchemaAttributes(): bool
1796+
{
1797+
return false;
1798+
}
1799+
17901800
/**
17911801
* Get current attribute count from collection document
17921802
*
@@ -1942,4 +1952,9 @@ public function getInternalIndexesKeys(): array
19421952
{
19431953
return [];
19441954
}
1955+
1956+
public function getSchemaAttributes(string $collection): array
1957+
{
1958+
return [];
1959+
}
19451960
}

src/Database/Adapter/Postgres.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,6 +2397,16 @@ public function getSupportForJSONOverlaps(): bool
23972397
return false;
23982398
}
23992399

2400+
/**
2401+
* Is get schema attributes supported?
2402+
*
2403+
* @return bool
2404+
*/
2405+
public function getSupportForSchemaAttributes(): bool
2406+
{
2407+
return false;
2408+
}
2409+
24002410
/**
24012411
* @return string
24022412
*/

src/Database/Adapter/SQL.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,4 +1151,9 @@ protected function processException(PDOException $e): \Exception
11511151
{
11521152
return $e;
11531153
}
1154+
1155+
public function getSchemaAttributes(string $collection): array
1156+
{
1157+
return [];
1158+
}
11541159
}

src/Database/Adapter/SQLite.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,16 @@ public function getSupportForGetConnectionId(): bool
934934
return false;
935935
}
936936

937+
/**
938+
* Is get schema attributes supported?
939+
*
940+
* @return bool
941+
*/
942+
public function getSupportForSchemaAttributes(): bool
943+
{
944+
return false;
945+
}
946+
937947
/**
938948
* Get SQL Index Type
939949
*

src/Database/Database.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6037,4 +6037,16 @@ public function analyzeCollection(string $collection): bool
60376037
{
60386038
return $this->adapter->analyzeCollection($collection);
60396039
}
6040+
6041+
/**
6042+
* Get Schema Attributes
6043+
*
6044+
* @param string $collection
6045+
* @return array<Document>
6046+
* @throws DatabaseException
6047+
*/
6048+
public function getSchemaAttributes(string $collection): array
6049+
{
6050+
return $this->adapter->getSchemaAttributes($collection);
6051+
}
60406052
}

tests/e2e/Adapter/Base.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,69 @@ public function testPurgeCollectionCache(): void
13001300
$this->assertArrayHasKey('age', $document);
13011301
}
13021302

1303+
public function testSchemaAttribute(): void
1304+
{
1305+
if (!$this->getDatabase()->getAdapter()->getSupportForSchemaAttributes()) {
1306+
$this->expectNotToPerformAssertions();
1307+
return;
1308+
}
1309+
1310+
$collection = 'schema_attributes';
1311+
$db = static::getDatabase();
1312+
1313+
$this->assertEmpty($db->getSchemaAttributes('no_such_collection'));
1314+
1315+
$db->createCollection($collection);
1316+
1317+
$db->createAttribute($collection, 'username', Database::VAR_STRING, 128, true);
1318+
$db->createAttribute($collection, 'story', Database::VAR_STRING, 20000, true);
1319+
$db->createAttribute($collection, 'string_list', Database::VAR_STRING, 128, true, null, true, true);
1320+
$db->createAttribute($collection, 'dob', Database::VAR_DATETIME, 0, false, '2000-06-12T14:12:55.000+00:00', true, false, null, [], ['datetime']);
1321+
1322+
$attributes = [];
1323+
foreach ($db->getSchemaAttributes($collection) as $attribute) {
1324+
/**
1325+
* @var Document $attribute
1326+
*/
1327+
$attributes[$attribute->getAttribute('columnName')] = $attribute;
1328+
}
1329+
1330+
$attribute = $attributes['username'];
1331+
$this->assertEquals('username', $attribute['columnName']);
1332+
$this->assertEquals('varchar', $attribute['dataType']);
1333+
$this->assertEquals('varchar(128)', $attribute['columnType']);
1334+
$this->assertEquals('128', $attribute['characterMaximumLength']);
1335+
$this->assertEquals('YES', $attribute['isNullable']);
1336+
1337+
$attribute = $attributes['story'];
1338+
$this->assertEquals('story', $attribute['columnName']);
1339+
$this->assertEquals('text', $attribute['dataType']);
1340+
$this->assertEquals('text', $attribute['columnType']);
1341+
$this->assertEquals('65535', $attribute['characterMaximumLength']);
1342+
1343+
$attribute = $attributes['string_list'];
1344+
$this->assertEquals('string_list', $attribute['columnName']);
1345+
$this->assertTrue(in_array($attribute['dataType'], ['json', 'longtext'])); // mysql vs maria
1346+
$this->assertTrue(in_array($attribute['columnType'], ['json', 'longtext']));
1347+
$this->assertTrue(in_array($attribute['characterMaximumLength'], [null, '4294967295']));
1348+
$this->assertEquals('YES', $attribute['isNullable']);
1349+
1350+
$attribute = $attributes['dob'];
1351+
$this->assertEquals('dob', $attribute['columnName']);
1352+
$this->assertEquals('datetime', $attribute['dataType']);
1353+
$this->assertEquals('datetime(3)', $attribute['columnType']);
1354+
$this->assertEquals(null, $attribute['characterMaximumLength']);
1355+
$this->assertEquals('3', $attribute['datetimePrecision']);
1356+
1357+
if ($db->getSharedTables()) {
1358+
$attribute = $attributes['_tenant'];
1359+
$this->assertEquals('_tenant', $attribute['columnName']);
1360+
$this->assertEquals('int', $attribute['dataType']);
1361+
$this->assertEquals('10', $attribute['numericPrecision']);
1362+
$this->assertTrue(in_array($attribute['columnType'], ['int unsigned', 'int(11) unsigned']));
1363+
}
1364+
}
1365+
13031366
public function testCreateDeleteAttribute(): void
13041367
{
13051368
static::getDatabase()->createCollection('attributes');

0 commit comments

Comments
 (0)