14
14
use Doctrine \DBAL \Driver \PgSQL \Driver as PgSQLDriver ;
15
15
use Doctrine \DBAL \Driver \SQLite3 \Driver as SQLite3Driver ;
16
16
use 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 ;
25
19
26
20
class DriverDetector
27
21
{
@@ -38,139 +32,114 @@ class DriverDetector
38
32
public const SQLITE3 = 'sqlite3 ' ;
39
33
public const SQLSRV = 'sqlsrv ' ;
40
34
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
45
39
{
46
- $ this ->failOnInvalidConnection = $ failOnInvalidConnection ;
40
+ $ driver = $ connection ->getDriver ();
41
+
42
+ return $ this ->deduceFromDriverClass (get_class ($ driver )) ?? $ this ->deduceFromParams ($ connection );
47
43
}
48
44
49
- public function failsOnInvalidConnection (): bool
45
+ /**
46
+ * @return array<mixed>
47
+ */
48
+ public function detectDriverOptions (Connection $ connection ): array
50
49
{
51
- return $ this -> failOnInvalidConnection ;
50
+ return $ connection -> getParams ()[ ' driverOptions ' ] ?? [] ;
52
51
}
53
52
54
53
/**
55
54
* @return self::*|null
56
55
*/
57
- public function detect ( Connection $ connection ): ?string
56
+ private function deduceFromDriverClass ( string $ driverClass ): ?string
58
57
{
59
- $ driver = $ connection ->getDriver ();
60
-
61
- if ($ driver instanceof MysqliDriver) {
58
+ if (is_a ($ driverClass , MysqliDriver::class, true )) {
62
59
return self ::MYSQLI ;
63
60
}
64
61
65
- if ($ driver instanceof PdoMysqlDriver) {
62
+ if (is_a ( $ driverClass , PdoMysqlDriver::class, true ) ) {
66
63
return self ::PDO_MYSQL ;
67
64
}
68
65
69
- if ($ driver instanceof PdoSQLiteDriver) {
66
+ if (is_a ( $ driverClass , PdoSQLiteDriver::class, true ) ) {
70
67
return self ::PDO_SQLITE ;
71
68
}
72
69
73
- if ($ driver instanceof PdoSqlSrvDriver) {
70
+ if (is_a ( $ driverClass , PdoSqlSrvDriver::class, true ) ) {
74
71
return self ::PDO_SQLSRV ;
75
72
}
76
73
77
- if ($ driver instanceof PdoOciDriver) {
74
+ if (is_a ( $ driverClass , PdoOciDriver::class, true ) ) {
78
75
return self ::PDO_OCI ;
79
76
}
80
77
81
- if ($ driver instanceof PdoPgSQLDriver) {
78
+ if (is_a ( $ driverClass , PdoPgSQLDriver::class, true ) ) {
82
79
return self ::PDO_PGSQL ;
83
80
}
84
81
85
- if ($ driver instanceof SQLite3Driver) {
82
+ if (is_a ( $ driverClass , SQLite3Driver::class, true ) ) {
86
83
return self ::SQLITE3 ;
87
84
}
88
85
89
- if ($ driver instanceof PgSQLDriver) {
86
+ if (is_a ( $ driverClass , PgSQLDriver::class, true ) ) {
90
87
return self ::PGSQL ;
91
88
}
92
89
93
- if ($ driver instanceof SqlSrvDriver) {
90
+ if (is_a ( $ driverClass , SqlSrvDriver::class, true ) ) {
94
91
return self ::SQLSRV ;
95
92
}
96
93
97
- if ($ driver instanceof Oci8Driver) {
94
+ if (is_a ( $ driverClass , Oci8Driver::class, true ) ) {
98
95
return self ::OCI8 ;
99
96
}
100
97
101
- if ($ driver instanceof IbmDb2Driver) {
98
+ if (is_a ( $ driverClass , IbmDb2Driver::class, true ) ) {
102
99
return self ::IBM_DB2 ;
103
100
}
104
101
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
+ }
150
104
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 ;
153
138
}
154
139
}
155
140
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 ' ]);
174
143
}
175
144
176
145
return null ;
0 commit comments