1414use Doctrine \DBAL \Driver \PgSQL \Driver as PgSQLDriver ;
1515use Doctrine \DBAL \Driver \SQLite3 \Driver as SQLite3Driver ;
1616use Doctrine \DBAL \Driver \SQLSrv \Driver as SqlSrvDriver ;
17- use mysqli ;
18- use PDO ;
19- use SQLite3 ;
20- use Throwable ;
21- use function get_resource_type ;
22- use function is_resource ;
23- use function method_exists ;
24- use function strpos ;
17+ use function get_class ;
18+ use function is_a ;
2519
2620class DriverDetector
2721{
@@ -38,139 +32,114 @@ class DriverDetector
3832 public const SQLITE3 = 'sqlite3 ' ;
3933 public const SQLSRV = 'sqlsrv ' ;
4034
41- /** @var bool */
42- private $ failOnInvalidConnection ;
43-
44- public function __construct ( bool $ failOnInvalidConnection )
35+ /**
36+ * @return self::*|null
37+ */
38+ public function detect ( Connection $ connection ): ? string
4539 {
46- $ this ->failOnInvalidConnection = $ failOnInvalidConnection ;
40+ $ driver = $ connection ->getDriver ();
41+
42+ return $ this ->deduceFromDriverClass (get_class ($ driver )) ?? $ this ->deduceFromParams ($ connection );
4743 }
4844
49- public function failsOnInvalidConnection (): bool
45+ /**
46+ * @return array<mixed>
47+ */
48+ public function detectDriverOptions (Connection $ connection ): array
5049 {
51- return $ this -> failOnInvalidConnection ;
50+ return $ connection -> getParams ()[ ' driverOptions ' ] ?? [] ;
5251 }
5352
5453 /**
5554 * @return self::*|null
5655 */
57- public function detect ( Connection $ connection ): ?string
56+ private function deduceFromDriverClass ( string $ driverClass ): ?string
5857 {
59- $ driver = $ connection ->getDriver ();
60-
61- if ($ driver instanceof MysqliDriver) {
58+ if (is_a ($ driverClass , MysqliDriver::class, true )) {
6259 return self ::MYSQLI ;
6360 }
6461
65- if ($ driver instanceof PdoMysqlDriver) {
62+ if (is_a ( $ driverClass , PdoMysqlDriver::class, true ) ) {
6663 return self ::PDO_MYSQL ;
6764 }
6865
69- if ($ driver instanceof PdoSQLiteDriver) {
66+ if (is_a ( $ driverClass , PdoSQLiteDriver::class, true ) ) {
7067 return self ::PDO_SQLITE ;
7168 }
7269
73- if ($ driver instanceof PdoSqlSrvDriver) {
70+ if (is_a ( $ driverClass , PdoSqlSrvDriver::class, true ) ) {
7471 return self ::PDO_SQLSRV ;
7572 }
7673
77- if ($ driver instanceof PdoOciDriver) {
74+ if (is_a ( $ driverClass , PdoOciDriver::class, true ) ) {
7875 return self ::PDO_OCI ;
7976 }
8077
81- if ($ driver instanceof PdoPgSQLDriver) {
78+ if (is_a ( $ driverClass , PdoPgSQLDriver::class, true ) ) {
8279 return self ::PDO_PGSQL ;
8380 }
8481
85- if ($ driver instanceof SQLite3Driver) {
82+ if (is_a ( $ driverClass , SQLite3Driver::class, true ) ) {
8683 return self ::SQLITE3 ;
8784 }
8885
89- if ($ driver instanceof PgSQLDriver) {
86+ if (is_a ( $ driverClass , PgSQLDriver::class, true ) ) {
9087 return self ::PGSQL ;
9188 }
9289
93- if ($ driver instanceof SqlSrvDriver) {
90+ if (is_a ( $ driverClass , SqlSrvDriver::class, true ) ) {
9491 return self ::SQLSRV ;
9592 }
9693
97- if ($ driver instanceof Oci8Driver) {
94+ if (is_a ( $ driverClass , Oci8Driver::class, true ) ) {
9895 return self ::OCI8 ;
9996 }
10097
101- if ($ driver instanceof IbmDb2Driver) {
98+ if (is_a ( $ driverClass , IbmDb2Driver::class, true ) ) {
10299 return self ::IBM_DB2 ;
103100 }
104101
105- // fallback to connection-based detection when driver is wrapped by middleware
106-
107- if (!method_exists ($ connection , 'getNativeConnection ' )) {
108- return null ; // dbal < 3.3 (released in 2022-01)
109- }
110-
111- try {
112- $ nativeConnection = $ connection ->getNativeConnection ();
113- } catch (Throwable $ e ) {
114- if ($ this ->failOnInvalidConnection ) {
115- throw $ e ;
116- }
117- return null ; // connection cannot be established
118- }
119-
120- if ($ nativeConnection instanceof mysqli) {
121- return self ::MYSQLI ;
122- }
123-
124- if ($ nativeConnection instanceof SQLite3) {
125- return self ::SQLITE3 ;
126- }
127-
128- if ($ nativeConnection instanceof \PgSql \Connection) {
129- return self ::PGSQL ;
130- }
131-
132- if ($ nativeConnection instanceof PDO ) {
133- $ driverName = $ nativeConnection ->getAttribute (PDO ::ATTR_DRIVER_NAME );
134-
135- if ($ driverName === 'mysql ' ) {
136- return self ::PDO_MYSQL ;
137- }
138-
139- if ($ driverName === 'sqlite ' ) {
140- return self ::PDO_SQLITE ;
141- }
142-
143- if ($ driverName === 'pgsql ' ) {
144- return self ::PDO_PGSQL ;
145- }
146-
147- if ($ driverName === 'oci ' ) { // semi-verified (https://stackoverflow.com/questions/10090709/get-current-pdo-driver-from-existing-connection/10090754#comment12923198_10090754)
148- return self ::PDO_OCI ;
149- }
102+ return null ;
103+ }
150104
151- if ($ driverName === 'sqlsrv ' ) {
152- return self ::PDO_SQLSRV ;
105+ /**
106+ * @return self::*|null
107+ */
108+ private function deduceFromParams (Connection $ connection ): ?string
109+ {
110+ $ params = $ connection ->getParams ();
111+
112+ if (isset ($ params ['driver ' ])) {
113+ switch ($ params ['driver ' ]) {
114+ case 'pdo_mysql ' :
115+ return self ::PDO_MYSQL ;
116+ case 'pdo_sqlite ' :
117+ return self ::PDO_SQLITE ;
118+ case 'pdo_pgsql ' :
119+ return self ::PDO_PGSQL ;
120+ case 'pdo_oci ' :
121+ return self ::PDO_OCI ;
122+ case 'oci8 ' :
123+ return self ::OCI8 ;
124+ case 'ibm_db2 ' :
125+ return self ::IBM_DB2 ;
126+ case 'pdo_sqlsrv ' :
127+ return self ::PDO_SQLSRV ;
128+ case 'mysqli ' :
129+ return self ::MYSQLI ;
130+ case 'pgsql ' : // @phpstan-ignore-line never matches on PHP 7.3- with old dbal
131+ return self ::PGSQL ;
132+ case 'sqlsrv ' :
133+ return self ::SQLSRV ;
134+ case 'sqlite3 ' : // @phpstan-ignore-line never matches on PHP 7.3- with old dbal
135+ return self ::SQLITE3 ;
136+ default :
137+ return null ;
153138 }
154139 }
155140
156- if (is_resource ($ nativeConnection )) {
157- $ resourceType = get_resource_type ($ nativeConnection );
158-
159- if (strpos ($ resourceType , 'oci ' ) !== false ) { // not verified
160- return self ::OCI8 ;
161- }
162-
163- if (strpos ($ resourceType , 'db2 ' ) !== false ) { // not verified
164- return self ::IBM_DB2 ;
165- }
166-
167- if (strpos ($ resourceType , 'SQL Server Connection ' ) !== false ) {
168- return self ::SQLSRV ;
169- }
170-
171- if (strpos ($ resourceType , 'pgsql link ' ) !== false ) {
172- return self ::PGSQL ;
173- }
141+ if (isset ($ params ['driverClass ' ])) {
142+ return $ this ->deduceFromDriverClass ($ params ['driverClass ' ]);
174143 }
175144
176145 return null ;
0 commit comments