Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PDO drivers refactoring with preload, new drivers for firebird and DB2 #826

Open
wants to merge 59 commits into
base: master
Choose a base branch
from

Conversation

dregad
Copy link
Member

@dregad dregad commented Apr 2, 2022

This PR's purpose is to facilitate review of @mnewnham's recent work on PDO drivers.

Includes updated mysql, sqlite, pgsql, sqlsrv and oci drivers, plus new drivers for firebird and ibm db2.

The only change required for legacy code is to update the 'ADONewConnection() call, as follows:

before

$db = ADONewConnection('PDO');
$db->connect('mysql:<parameters>');

after

$db = ADONewConnection('PDO\mysql');

All of the driver files are loaded as necessary by ADOLoadCode(). This allows the class to load properly i.e. 'ADORecordset_pdo_mysql -> ADORecordset_pdo -> ADORecordset', rather than the current method, where 'ADORecordset' loads 'ADORecordset_pdo_mysql'

Removes methods that provide existence checks in the wrong direction, i.e. from parent to child.
The oci driver is the only pdo driver that does not use the core method for time()
Init method duplicates core ADOd b method
Copied in meta functions from native driver
This supports the most recent versions of informix (12.14)
Removes methods that provide existence checks in the wrong direction, i.e. from parent to child.
@dregad dregad added enhancement feature Enhancement requests pdo The PHP PDO Driver (Tier 2) labels Apr 2, 2022
@dregad dregad added this to the v5.23.0 milestone Apr 2, 2022
@mnewnham
Copy link
Contributor

mnewnham commented Apr 2, 2022

See more about this new driver At the new documentation page

adodb.inc.php Outdated
* need to remove the driver portion of the file
*/
$pdoExtension = '';
$pdoSplit = explode('\\',$db);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be on the safe side, just in case there's another \ somewhere in the DSN, I would suggest

explode('\\', $db, 2);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that as it stands, provision of the DSN on the newADOcommand line is no longer supported. Not to say that the processing of the parameter should be super robust. I did note it in the Quick upgrade notes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provision of the DSN on the newADOcommand line is no longer supported
I did note it in the Quick upgrade notes.

I missed that bit.
Is there a particular reason for dropping this functionality ? It could be fairly easily maintained by adapting the PDO-specific logic to use the $pdoExtension variable:

diff --git a/adodb.inc.php b/adodb.inc.php
index c5e30f09..6ff88c0b 100644
--- a/adodb.inc.php
+++ b/adodb.inc.php
@@ -5547,17 +5547,11 @@ class ADORecordSet implements IteratorAggregate {
                $dsna['host'] = '';
            }
 
-           if (strncmp($origdsn,'pdo',3) == 0) {
-               $sch = explode('_',$dsna['scheme']);
-               if (sizeof($sch)>1) {
-                   $dsna['host'] = isset($dsna['host']) ? rawurldecode($dsna['host']) : '';
-                   if ($sch[1] == 'sqlite') {
-                       $dsna['host'] = rawurlencode($sch[1].':'.rawurldecode($dsna['host']));
-                   } else {
-                       $dsna['host'] = rawurlencode($sch[1].':host='.rawurldecode($dsna['host']));
-                   }
-                   $dsna['scheme'] = 'pdo';
-               }
+           if ($pdoExtension) {
+               $host = $pdoExtension
+                   . ($pdoExtension == 'sqlite' ? ':' : ':host=')
+                   . rawurldecode($dsna['host'] ?? '');
+               $dsna['host'] = rawurlencode($host);
            }
 
            $db = @$dsna['scheme'];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things on future issues,

  1. The ''_'' character can't be used if using off-the-shelf PSR style autoloaders, we'll probably need a project in the future to remove them from classnames. Might as well start somewhere.
  2. To be honest, I don't particularly like fact that you can assign a DSN through here (and not any other type of parameter). It feels very unstructured, and I'd certainly not do it if I did the original design.

$pdoExtension = '';
$pdoSplit = explode('\\',$db);

if (count($pdoSplit) > 1)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this logic, we accept that whenever there is a \ in $db, we will connect to PDO regardless of what string is before it, i.e. xyz\mysql will successfully connect just like pdo\mysql.

Shouldn't we test the actual value ? Or maybe set $db = $pdoSplit[0] and let ADOLoadCode() deal with it ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be better if I split the entirety of the statement

$split = preg_split('/^(pdo\\)/',$driver);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would work better indeed.

I would suggest adjusting the regex: /^pdo[_\\]/

adodb.inc.php Outdated Show resolved Hide resolved
else
{
$cls = 'ADODB_'.$db;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since $db == 'pdo' if $pdoExtension is not empty, this can be simplified

			$cls = 'ADODB_' . $db;
			if ($pdoExtension) {
				$cls .= '_' . $pdoExtension
			}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what about performing early detection of legacy ADONewConnection('pdo') calls (i.e. when $db == 'pdo' && $pdoExtension == ''), either here or maybe even better when we split and process the pdo driver string above, and throw an error instead of delaying this until ADODB_pdo::_connect()

adodb.inc.php Outdated Show resolved Hide resolved
drivers/adodb-pdo_mysql.inc.php Outdated Show resolved Hide resolved
drivers/adodb-pdo_oci.inc.php Outdated Show resolved Hide resolved
drivers/adodb-pdo_pgsql.inc.php Outdated Show resolved Hide resolved
drivers/adodb-pdo_sqlite.inc.php Outdated Show resolved Hide resolved
drivers/adodb-pdo_sqlsrv.inc.php Outdated Show resolved Hide resolved
@mnewnham mnewnham marked this pull request as ready for review November 19, 2023 03:50
@mnewnham
Copy link
Contributor

@dregad I have brought this repo up to date, could you take a look again please

dregad pushed a commit to dregad/ADOdb that referenced this pull request Nov 20, 2023
Includes updated mysql, sqlite, pgsql, sqlsrv and oci drivers.

All of the driver files are loaded as necessary by ADOLoadCode(). This
allows the class to load properly i.e. 'ADORecordset_pdo_mysql ->
ADORecordset_pdo -> ADORecordset', rather than the current method, where
'ADORecordset' loads 'ADORecordset_pdo_mysql'

Change required for legacy code to connect:
- before
    $db = ADONewConnection('PDO');
    $db->connect('mysql:<parameters>');
- after
    $db = ADONewConnection('PDO\mysql');

Co-authored-by: Damien Regad <dregad@mantisbt.org>

This a squashed merge of @mnewwnham's original feature branch (see ADOdb#826)
with the latest master with all conflicts resolved, excluding the new
Firebird and DB2 drivers which will be committed separately.

Conflicts:
	adodb.inc.php
	drivers/adodb-pdo.inc.php
	drivers/adodb-pdo_sqlsrv.inc.php
dregad added a commit to dregad/ADOdb that referenced this pull request Nov 20, 2023
This is the remainder of squash-merged original commits from ADOdb#826.

Co-authored-by: Damien Regad <dregad@mantisbt.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature Enhancement requests pdo The PHP PDO Driver (Tier 2)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants