55
66namespace Dmstr \ApiPlatformUtils \Service ;
77
8+ use Doctrine \DBAL \Platforms \AbstractPlatform ;
9+ use Doctrine \DBAL \Platforms \PostgreSQLPlatform ;
810use Doctrine \ORM \EntityManagerInterface ;
911use Symfony \Component \Uid \Uuid ;
1012
@@ -59,17 +61,20 @@ public function findByPartialUuid(string $entityClass, string $partialId): ?obje
5961 }
6062
6163 /**
62- * Find entity with binary UUID storage using native SQL
64+ * Find entity with UUID storage using native SQL.
6365 *
64- * Uses HEX(id) to convert binary UUID to string for LIKE matching
66+ * The Symfony `uuid` type stores the value differently per platform — a
67+ * BINARY(16) on MySQL/MariaDB, a native `uuid` column on PostgreSQL — so the
68+ * partial-prefix match must be built per platform (see {@see buildPartialUuidSql}).
6569 */
6670 private function findByPartialBinaryUuid (string $ entityClass , string $ partialId ): ?object
6771 {
6872 $ metadata = $ this ->entityManager ->getClassMetadata ($ entityClass );
6973 $ tableName = $ metadata ->getTableName ();
74+ $ idColumn = $ metadata ->getColumnName ('id ' );
7075
7176 $ conn = $ this ->entityManager ->getConnection ();
72- $ sql = " SELECT BIN_TO_UUID(id) as uuid_str FROM { $ tableName} WHERE LOWER(HEX(id)) LIKE :partialId LIMIT 2 " ;
77+ $ sql = self :: buildPartialUuidSql ( $ conn -> getDatabasePlatform (), $ tableName, $ idColumn ) ;
7378 $ stmt = $ conn ->prepare ($ sql );
7479 $ stmt ->bindValue ('partialId ' , strtolower (str_replace ('- ' , '' , $ partialId )) . '% ' );
7580 $ resultSet = $ stmt ->executeQuery ();
@@ -89,6 +94,35 @@ private function findByPartialBinaryUuid(string $entityClass, string $partialId)
8994 return $ this ->entityManager ->getRepository ($ entityClass )->find ($ fullUuid );
9095 }
9196
97+ /**
98+ * Build the native partial-UUID lookup SQL for the given platform.
99+ *
100+ * Both branches select the canonical hyphenated UUID string as `uuid_str`
101+ * and match the caller's hyphen-stripped, lower-cased hex prefix:
102+ * - PostgreSQL: the column is a native `uuid`; cast to text and strip the
103+ * hyphens (`REPLACE(LOWER(id::text), '-', '')`).
104+ * - MySQL/MariaDB: the column is BINARY(16); `HEX()` yields the 32-char hex
105+ * and `BIN_TO_UUID()` reads it back as a canonical string.
106+ *
107+ * Public + static so it can be unit-tested per platform without a database.
108+ */
109+ public static function buildPartialUuidSql (AbstractPlatform $ platform , string $ tableName , string $ idColumn ): string
110+ {
111+ if ($ platform instanceof PostgreSQLPlatform) {
112+ return sprintf (
113+ "SELECT %2 \$s::text AS uuid_str FROM %1 \$s WHERE REPLACE(LOWER(%2 \$s::text), '-', '') LIKE :partialId LIMIT 2 " ,
114+ $ tableName ,
115+ $ idColumn
116+ );
117+ }
118+
119+ return sprintf (
120+ 'SELECT BIN_TO_UUID(%2$s) AS uuid_str FROM %1$s WHERE LOWER(HEX(%2$s)) LIKE :partialId LIMIT 2 ' ,
121+ $ tableName ,
122+ $ idColumn
123+ );
124+ }
125+
92126 /**
93127 * Find entity with string UUID storage using DQL
94128 *
0 commit comments