3636
3737class Database
3838{
39- public const VAR_STRING = 'string ' ;
4039 // Simple Types
40+ public const VAR_STRING = 'string ' ;
4141 public const VAR_INTEGER = 'integer ' ;
4242 public const VAR_FLOAT = 'double ' ;
4343 public const VAR_BOOLEAN = 'boolean ' ;
4444 public const VAR_DATETIME = 'datetime ' ;
45- public const VAR_ID = 'id ' ;
46- public const VAR_OBJECT_ID = 'objectId ' ;
47- public const VAR_VECTOR = 'vector ' ;
4845
49- public const INT_MAX = 2147483647 ;
50- public const BIG_INT_MAX = PHP_INT_MAX ;
51- public const DOUBLE_MAX = PHP_FLOAT_MAX ;
52- public const VECTOR_MAX_SIZE = 16000 ; // pgvector limit
46+ // ID types
47+ public const VAR_ID = 'id ' ;
48+ public const VAR_UUID = 'uuid ' ;
5349
54- // Global SRID for geographic coordinates (WGS84)
55- public const SRID = 4326 ;
50+ // Vector types
51+ public const VAR_VECTOR = ' vector ' ;
5652
5753 // Relationship Types
5854 public const VAR_RELATIONSHIP = 'relationship ' ;
@@ -62,7 +58,12 @@ class Database
6258 public const VAR_LINESTRING = 'linestring ' ;
6359 public const VAR_POLYGON = 'polygon ' ;
6460
65- public const SPATIAL_TYPES = [self ::VAR_POINT ,self ::VAR_LINESTRING , self ::VAR_POLYGON ];
61+ // All spatial types
62+ public const SPATIAL_TYPES = [
63+ self ::VAR_POINT ,
64+ self ::VAR_LINESTRING ,
65+ self ::VAR_POLYGON
66+ ];
6667
6768 // Index Types
6869 public const INDEX_KEY = 'key ' ;
@@ -72,8 +73,17 @@ class Database
7273 public const INDEX_HNSW_EUCLIDEAN = 'hnsw_euclidean ' ;
7374 public const INDEX_HNSW_COSINE = 'hnsw_cosine ' ;
7475 public const INDEX_HNSW_DOT = 'hnsw_dot ' ;
76+
77+ // Max limits
78+ public const INT_MAX = 2147483647 ;
79+ public const BIG_INT_MAX = PHP_INT_MAX ;
80+ public const DOUBLE_MAX = PHP_FLOAT_MAX ;
81+ public const VECTOR_MAX_DIMENSIONS = 16000 ;
7582 public const ARRAY_INDEX_LENGTH = 255 ;
7683
84+ // Global SRID for geographic coordinates (WGS84)
85+ public const SRID = 4326 ;
86+
7787 // Relation Types
7888 public const RELATION_ONE_TO_ONE = 'oneToOne ' ;
7989 public const RELATION_ONE_TO_MANY = 'oneToMany ' ;
@@ -409,7 +419,8 @@ public function __construct(
409419 Adapter $ adapter ,
410420 Cache $ cache ,
411421 array $ filters = []
412- ) {
422+ )
423+ {
413424 $ this ->adapter = $ adapter ;
414425 $ this ->cache = $ cache ;
415426 $ this ->instanceFilters = $ filters ;
@@ -1786,7 +1797,8 @@ private function validateAttribute(
17861797 ?string $ format ,
17871798 array $ formatOptions ,
17881799 array $ filters
1789- ): Document {
1800+ ): Document
1801+ {
17901802 // Attribute IDs are case-insensitive
17911803 $ attributes = $ collection ->getAttribute ('attributes ' , []);
17921804
@@ -1877,8 +1889,8 @@ private function validateAttribute(
18771889 if ($ size <= 0 ) {
18781890 throw new DatabaseException ('Vector dimensions must be a positive integer ' );
18791891 }
1880- if ($ size > self ::VECTOR_MAX_SIZE ) {
1881- throw new DatabaseException ('Vector dimensions cannot exceed ' . self ::VECTOR_MAX_SIZE );
1892+ if ($ size > self ::VECTOR_MAX_DIMENSIONS ) {
1893+ throw new DatabaseException ('Vector dimensions cannot exceed ' . self ::VECTOR_MAX_DIMENSIONS );
18821894 }
18831895 break ;
18841896 default :
@@ -2254,8 +2266,8 @@ public function updateAttribute(string $collection, string $id, ?string $type =
22542266 if ($ size <= 0 ) {
22552267 throw new DatabaseException ('Vector size must be a positive integer ' );
22562268 }
2257- if ($ size > self ::VECTOR_MAX_SIZE ) {
2258- throw new DatabaseException ('Vector size cannot exceed ' . self ::VECTOR_MAX_SIZE );
2269+ if ($ size > self ::VECTOR_MAX_DIMENSIONS ) {
2270+ throw new DatabaseException ('Vector size cannot exceed ' . self ::VECTOR_MAX_DIMENSIONS );
22592271 }
22602272 break ;
22612273 default :
@@ -2627,7 +2639,8 @@ public function createRelationship(
26272639 ?string $ id = null ,
26282640 ?string $ twoWayKey = null ,
26292641 string $ onDelete = Database::RELATION_MUTATE_RESTRICT
2630- ): bool {
2642+ ): bool
2643+ {
26312644 $ collection = $ this ->silent (fn () => $ this ->getCollection ($ collection ));
26322645
26332646 if ($ collection ->isEmpty ()) {
@@ -2818,7 +2831,8 @@ public function updateRelationship(
28182831 ?string $ newTwoWayKey = null ,
28192832 ?bool $ twoWay = null ,
28202833 ?string $ onDelete = null
2821- ): bool {
2834+ ): bool
2835+ {
28222836 if (
28232837 \is_null ($ newKey )
28242838 && \is_null ($ newTwoWayKey )
@@ -3254,8 +3268,10 @@ public function createIndex(string $collection, string $id, string $type, array
32543268 case Database::INDEX_HNSW_EUCLIDEAN :
32553269 case Database::INDEX_HNSW_COSINE :
32563270 case Database::INDEX_HNSW_DOT :
3257- // Vector indexes - validate that we have a single vector attribute
3258- if (count ($ attributes ) !== 1 ) {
3271+ if (!$ this ->adapter ->getSupportForVectors ()) {
3272+ throw new DatabaseException ('Vector indexes are not supported ' );
3273+ }
3274+ if (\count ($ attributes ) !== 1 ) {
32593275 throw new DatabaseException ('Vector indexes require exactly one attribute ' );
32603276 }
32613277 break ;
@@ -3920,7 +3936,8 @@ public function createDocuments(
39203936 array $ documents ,
39213937 int $ batchSize = self ::INSERT_BATCH_SIZE ,
39223938 ?callable $ onNext = null ,
3923- ): int {
3939+ ): int
3940+ {
39243941 if (!$ this ->adapter ->getSharedTables () && $ this ->adapter ->getTenantPerDocument ()) {
39253942 throw new DatabaseException ('Shared tables must be enabled if tenant per document is enabled. ' );
39263943 }
@@ -4205,7 +4222,8 @@ private function relateDocuments(
42054222 bool $ twoWay ,
42064223 string $ twoWayKey ,
42074224 string $ side ,
4208- ): string {
4225+ ): string
4226+ {
42094227 switch ($ relationType ) {
42104228 case Database::RELATION_ONE_TO_ONE :
42114229 if ($ twoWay ) {
@@ -4286,7 +4304,8 @@ private function relateDocumentsById(
42864304 bool $ twoWay ,
42874305 string $ twoWayKey ,
42884306 string $ side ,
4289- ): void {
4307+ ): void
4308+ {
42904309 // Get the related document, will be empty on permissions failure
42914310 $ related = $ this ->skipRelationships (fn () => $ this ->getDocument ($ relatedCollection ->getId (), $ relationId ));
42924311
@@ -4362,7 +4381,7 @@ public function updateDocument(string $collection, string $id, Document $documen
43624381
43634382 if ($ document ->offsetExists ('$permissions ' )) {
43644383 $ originalPermissions = $ old ->getPermissions ();
4365- $ currentPermissions = $ document ->getPermissions ();
4384+ $ currentPermissions = $ document ->getPermissions ();
43664385
43674386 sort ($ originalPermissions );
43684387 sort ($ currentPermissions );
@@ -4571,7 +4590,8 @@ public function updateDocuments(
45714590 int $ batchSize = self ::INSERT_BATCH_SIZE ,
45724591 ?callable $ onNext = null ,
45734592 ?callable $ onError = null ,
4574- ): int {
4593+ ): int
4594+ {
45754595 if ($ updates ->isEmpty ()) {
45764596 return 0 ;
45774597 }
@@ -4676,7 +4696,7 @@ public function updateDocuments(
46764696 break ;
46774697 }
46784698
4679- $ currentPermissions = $ updates ->getPermissions ();
4699+ $ currentPermissions = $ updates ->getPermissions ();
46804700 sort ($ currentPermissions );
46814701
46824702 $ this ->withTransaction (function () use ($ collection , $ updates , &$ batch , $ currentPermissions ) {
@@ -4909,7 +4929,7 @@ private function updateDocumentRelationships(Document $collection, Document $old
49094929 $ document ->setAttribute ($ key , $ related ->getId ());
49104930 break ;
49114931 }
4912- // no break
4932+ // no break
49134933 case 'NULL ' :
49144934 if (!\is_null ($ oldValue ?->getId())) {
49154935 $ oldRelated = $ this ->skipRelationships (
@@ -5164,7 +5184,8 @@ public function createOrUpdateDocuments(
51645184 array $ documents ,
51655185 int $ batchSize = self ::INSERT_BATCH_SIZE ,
51665186 ?callable $ onNext = null ,
5167- ): int {
5187+ ): int
5188+ {
51685189 return $ this ->createOrUpdateDocumentsWithIncrease (
51695190 $ collection ,
51705191 '' ,
@@ -5193,7 +5214,8 @@ public function createOrUpdateDocumentsWithIncrease(
51935214 array $ documents ,
51945215 ?callable $ onNext = null ,
51955216 int $ batchSize = self ::INSERT_BATCH_SIZE
5196- ): int {
5217+ ): int
5218+ {
51975219 if (empty ($ documents )) {
51985220 return 0 ;
51995221 }
@@ -5223,7 +5245,7 @@ public function createOrUpdateDocumentsWithIncrease(
52235245
52245246 if ($ document ->offsetExists ('$permissions ' )) {
52255247 $ originalPermissions = $ old ->getPermissions ();
5226- $ currentPermissions = $ document ->getPermissions ();
5248+ $ currentPermissions = $ document ->getPermissions ();
52275249
52285250 sort ($ originalPermissions );
52295251 sort ($ currentPermissions );
@@ -5419,7 +5441,8 @@ public function increaseDocumentAttribute(
54195441 string $ attribute ,
54205442 int |float $ value = 1 ,
54215443 int |float |null $ max = null
5422- ): Document {
5444+ ): Document
5445+ {
54235446 if ($ value <= 0 ) { // Can be a float
54245447 throw new \InvalidArgumentException ('Value must be numeric and greater than 0 ' );
54255448 }
@@ -5516,7 +5539,8 @@ public function decreaseDocumentAttribute(
55165539 string $ attribute ,
55175540 int |float $ value = 1 ,
55185541 int |float |null $ min = null
5519- ): Document {
5542+ ): Document
5543+ {
55205544 if ($ value <= 0 ) { // Can be a float
55215545 throw new \InvalidArgumentException ('Value must be numeric and greater than 0 ' );
55225546 }
@@ -5773,7 +5797,8 @@ private function deleteRestrict(
57735797 bool $ twoWay ,
57745798 string $ twoWayKey ,
57755799 string $ side
5776- ): void {
5800+ ): void
5801+ {
57775802 if ($ value instanceof Document && $ value ->isEmpty ()) {
57785803 $ value = null ;
57795804 }
@@ -6063,7 +6088,8 @@ public function deleteDocuments(
60636088 int $ batchSize = self ::DELETE_BATCH_SIZE ,
60646089 ?callable $ onNext = null ,
60656090 ?callable $ onError = null ,
6066- ): int {
6091+ ): int
6092+ {
60676093 if ($ this ->adapter ->getSharedTables () && empty ($ this ->adapter ->getTenant ())) {
60686094 throw new DatabaseException ('Missing tenant. Tenant must be set when table sharing is enabled. ' );
60696095 }
@@ -6597,7 +6623,7 @@ public static function addFilter(string $name, callable $encode, callable $decod
65976623 public function encode (Document $ collection , Document $ document ): Document
65986624 {
65996625 $ attributes = $ collection ->getAttribute ('attributes ' , []);
6600- $ internalDateAttributes = ['$createdAt ' ,'$updatedAt ' ];
6626+ $ internalDateAttributes = ['$createdAt ' , '$updatedAt ' ];
66016627 foreach ($ this ->getInternalAttributes () as $ attribute ) {
66026628 $ attributes [] = $ attribute ;
66036629 }
@@ -7021,7 +7047,7 @@ public static function convertQuery(Document $collection, Query $query): Query
70217047 }
70227048 }
70237049
7024- if (! $ attribute ->isEmpty ()) {
7050+ if (!$ attribute ->isEmpty ()) {
70257051 $ query ->setOnArray ($ attribute ->getAttribute ('array ' , false ));
70267052
70277053 if ($ attribute ->getAttribute ('type ' ) == Database::VAR_DATETIME ) {
@@ -7138,7 +7164,8 @@ private function checkQueriesType(array $queries): void
71387164 private function processRelationshipQueries (
71397165 array $ relationships ,
71407166 array $ queries ,
7141- ): array {
7167+ ): array
7168+ {
71427169 $ nestedSelections = [];
71437170
71447171 foreach ($ queries as $ query ) {
@@ -7279,7 +7306,7 @@ public function decodeSpatialData(string $wkt): array
72797306 // POINT(x y)
72807307 if (str_starts_with ($ upper , 'POINT( ' )) {
72817308 $ start = strpos ($ wkt , '( ' ) + 1 ;
7282- $ end = strrpos ($ wkt , ') ' );
7309+ $ end = strrpos ($ wkt , ') ' );
72837310 $ inside = substr ($ wkt , $ start , $ end - $ start );
72847311
72857312 $ coords = explode (' ' , trim ($ inside ));
@@ -7289,7 +7316,7 @@ public function decodeSpatialData(string $wkt): array
72897316 // LINESTRING(x1 y1, x2 y2, ...)
72907317 if (str_starts_with ($ upper , 'LINESTRING( ' )) {
72917318 $ start = strpos ($ wkt , '( ' ) + 1 ;
7292- $ end = strrpos ($ wkt , ') ' );
7319+ $ end = strrpos ($ wkt , ') ' );
72937320 $ inside = substr ($ wkt , $ start , $ end - $ start );
72947321
72957322 $ points = explode (', ' , $ inside );
@@ -7302,7 +7329,7 @@ public function decodeSpatialData(string $wkt): array
73027329 // POLYGON((x1,y1),(x2,y2))
73037330 if (str_starts_with ($ upper , 'POLYGON(( ' )) {
73047331 $ start = strpos ($ wkt , '(( ' ) + 2 ;
7305- $ end = strrpos ($ wkt , ')) ' );
7332+ $ end = strrpos ($ wkt , ')) ' );
73067333 $ inside = substr ($ wkt , $ start , $ end - $ start );
73077334
73087335 $ rings = explode ('),( ' , $ inside );
0 commit comments