@@ -48,29 +48,68 @@ class Explorer
4848 private ?Structure $ structure = null ;
4949
5050
51- public function __construct (
51+ public static function createFromParameters (
52+ #[\SensitiveParameter]
53+ ...$ params ,
54+ ): self
55+ {
56+ $ params = count ($ params ) === 1 && is_array ($ params [0 ] ?? null ) ? $ params [0 ] : $ params ;
57+
58+ if ($ class = $ params ['driverClass ' ] ?? null ) {
59+ if (!is_subclass_of ($ class , Drivers \Driver::class)) {
60+ throw new \LogicException ("Driver class ' $ class' is not subclass of " . Drivers \Driver::class);
61+ }
62+ unset($ params ['driverClass ' ]);
63+
64+ } elseif ($ driver = $ params ['driver ' ] ?? null ) {
65+ $ class = self ::Drivers[$ driver ] ?? throw new \LogicException ("Unknown driver ' $ driver'. " );
66+ unset($ params ['driver ' ]);
67+
68+ } elseif ($ dsn = $ params ['dsn ' ] ?? null ) {
69+ $ driver = explode (': ' , $ dsn )[0 ];
70+ $ class = self ::Drivers['pdo- ' . $ driver ] ?? throw new \LogicException ("Unknown PDO driver ' $ driver'. " );
71+
72+ } else {
73+ throw new \LogicException ("Missing options 'driver', 'driverClass' or 'dsn'. " );
74+ }
75+
76+ $ args = array_diff_key ($ params , array_flip (self ::TypeConverterOptions));
77+ $ explorer = new self (new $ class (...$ args ));
78+ array_map (fn ($ opt ) => isset ($ params [$ opt ]) && ($ explorer ->typeConverter ->$ opt = (bool ) $ params [$ opt ]), self ::TypeConverterOptions);
79+ return $ explorer ;
80+ }
81+
82+
83+ public static function createFromDsn (
5284 string $ dsn ,
5385 ?string $ username = null ,
5486 #[\SensitiveParameter]
5587 ?string $ password = null ,
5688 array $ options = [],
57- ) {
58- $ driver = explode (': ' , $ dsn )[0 ];
59- $ class = empty ($ options ['driverClass ' ])
60- ? (self ::Drivers['pdo- ' . $ driver ] ?? throw new \LogicException ("Unknown PDO driver ' $ driver'. " ))
61- : $ options ['driverClass ' ];
62- $ args = compact ('dsn ' , 'username ' , 'password ' , 'options ' );
63- unset($ options ['lazy ' ], $ options ['driverClass ' ]);
89+ ): self
90+ {
91+ $ params = compact ('dsn ' , 'username ' , 'password ' , 'options ' );
6492 foreach ($ options as $ key => $ value ) {
6593 if (!is_int ($ key ) && $ value !== null ) {
66- $ args [$ key ] = $ value ;
67- unset($ args ['options ' ][$ key ]);
94+ $ params [$ key ] = $ value ;
95+ unset($ params ['options ' ][$ key ]);
6896 }
6997 }
70- $ args = array_diff_key ($ args , array_flip (self ::TypeConverterOptions));
71- $ this ->driver = new $ class (...$ args );
72- $ this ->typeConverter = new TypeConverter ;
73- array_map (fn ($ opt ) => isset ($ options [$ opt ]) && ($ this ->typeConverter ->$ opt = (bool ) $ options [$ opt ]), self ::TypeConverterOptions);
98+ unset($ params ['lazy ' ]);
99+ return self ::createFromParameters ($ params );
100+ }
101+
102+
103+ public function __construct (
104+ Drivers \Driver |string $ driver ,
105+ ) {
106+ if (is_string ($ driver )) { // back compatibility with version 3.x
107+ $ explorer = self ::createFromDsn (...func_get_args ());
108+ [$ this ->driver , $ this ->typeConverter ] = [$ explorer ->driver , $ explorer ->typeConverter ];
109+ } else {
110+ $ this ->driver = $ driver ;
111+ $ this ->typeConverter = new TypeConverter ;
112+ }
74113 }
75114
76115
0 commit comments