Skip to content

Big speed update and ADOdb from 2025 #25

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

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion classes/database/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ function getDriver(&$description) {

// Detect version and choose appropriate database driver
switch (substr($version,0,2)) {
case '14': return 'Postgres'; break;
case '13': return 'Postgres13'; break;
case '12': return 'Postgres12'; break;
case '11': return 'Postgres11'; break;
case '10': return 'Postgres10'; break;

default: return 'Postgres';
}

switch (substr($version,0,3)) {
Expand Down
80 changes: 57 additions & 23 deletions classes/database/Postgres.php
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ function getHelp($help) {
}

function getHelpPages() {
include_once('./help/PostgresDoc14.php');
include_once('./help/PostgresDocDevel.php');
return $this->help_page;
}

Expand Down Expand Up @@ -2499,19 +2499,11 @@ function insertRow($table, $fields, $values, $nulls, $format, $types) {
// Build clause
if (count($values) > 0) {
// Escape all field names
$clean_fields = array();

foreach ($fields as $field) {
array_push($clean_fields, $this->fieldClean($field));
}

$fields = $clean_fields;

$fields = array_map(array('Postgres','fieldClean'), $fields);
$f_schema = $this->_schema;
$this->fieldClean($table);
$this->fieldClean($f_schema);


$sql = '';
foreach($values as $i => $value) {
// Handle NULL values
Expand Down Expand Up @@ -6979,16 +6971,55 @@ function setPrivileges($mode, $type, $object, $public, $usernames, $groupnames,
return $this->execute($sql);
}

/**
* Helper function that computes encrypted PostgreSQL passwords
* @param $username The username
* @param $password The password
*/
function _encryptPassword($username, $password) {
return 'md5' . md5($password . $username);
}

// Tablespace functions
/**
* Helper function that computes encrypted PostgreSQL passwords
* @param $username The username
* @param $password The password
*/
function _encryptPassword($username, $password) {
return $this->_generate_postgresql_scram_sha256_verifier($password);
}

/**
* Generuje skrót hasła SCRAM-SHA-256 kompatybilny z PostgreSQL.
*
* @param string $password Hasło w postaci czystego tekstu (UTF-8).
* @param int $iterations Liczba iteracji PBKDF2 (domyślnie dla PostgreSQL >= 16 to 4096).
* @param int $saltLength Długość soli w bajtach (domyślnie 16).
* @return string Wygenerowany skrót hasła SCRAM-SHA-256.
* @throws Exception Jeśli generowanie bezpiecznych losowych bajtów zawiedzie.
*/
function _generate_postgresql_scram_sha256_verifier(string $password, int $iterations = 4096, int $saltLength = 16): string
{
$salt = random_bytes($saltLength);

// 3. Obliczenie SaltedPassword przy użyciu PBKDF2-HMAC-SHA256
// Ostatni argument `true` dla hash_pbkdf2 zwraca surowe dane binarne.
// Długość wyjściowa (trzeci od końca argument) 0 oznacza domyślną długość dla SHA256 (32 bajty).
$saltedPassword = hash_pbkdf2('sha256', $password, $salt, $iterations, 0, true);

// 4. Obliczenie ClientKey
$clientKey = hash_hmac('sha256', "Client Key", $saltedPassword, true);

$storedKey = hash('sha256', $clientKey, true);
$serverKey = hash_hmac('sha256', "Server Key", $saltedPassword, true);

$saltBase64 = base64_encode($salt);
$storedKeyBase64 = base64_encode($storedKey);
$serverKeyBase64 = base64_encode($serverKey);

// 8. Złożenie finalnego ciągu
return sprintf(
'SCRAM-SHA-256$%d:%s$%s:%s',
$iterations,
$saltBase64,
$storedKeyBase64,
$serverKeyBase64
);
}


// Tablespace functions

/**
* Retrieves information for all tablespaces
Expand Down Expand Up @@ -7792,6 +7823,9 @@ function browseQuery($type, $table, $query, $sortkey, $sortdir, $page, $page_siz
if (preg_match('/^[0-9]+$/', $sortkey) && $sortkey > 0) $orderby = array($sortkey => $sortdir, $sort_pkey ?: '1' => $sortdir);
else $orderby = array($sort_pkey ?: '1' => 'DESC');
$query = $this->getSelectSQL($table, array(), array(), array(), $orderby);

// Generate count query
$count = "SELECT COUNT(*) AS total FROM $table";
break;
case 'QUERY':
case 'SELECT':
Expand All @@ -7800,14 +7834,14 @@ function browseQuery($type, $table, $query, $sortkey, $sortdir, $page, $page_siz
// Trim off trailing semi-colon if there is one
if (substr($query, strlen($query) - 1, 1) === ';')
$query = substr($query, 0, strlen($query) - 1);

// Generate count query
$count = "SELECT COUNT(*) AS total FROM ($query) AS sub";
break;
default:
return -4;
}

// Generate count query
$count = "SELECT COUNT(*) AS total FROM ($query) AS sub";

// Open a transaction
$status = $this->beginTransaction();
if ($status != 0) return -1;
Expand Down
18 changes: 0 additions & 18 deletions classes/database/Postgres80.php
Original file line number Diff line number Diff line change
Expand Up @@ -288,24 +288,6 @@ function _alterSequence($seqrs, $name, $comment, $owner, $schema, $increment,
return 0;
}

// Role, User/group functions

/**
* Changes a user's password
* @param $username The username
* @param $password The new password
* @return 0 success
*/
function changePassword($username, $password) {
$enc = $this->_encryptPassword($username, $password);
$this->fieldClean($username);
$this->clean($enc);

$sql = "ALTER USER \"{$username}\" WITH ENCRYPTED PASSWORD '{$enc}'";

return $this->execute($sql);
}

// Aggregate functions

/**
Expand Down
9 changes: 9 additions & 0 deletions classes/database/Postgres96.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ function getSequence($sequence) {
return $this->selectSet( $sql );
}

/**
* Helper function that computes encrypted PostgreSQL passwords
* To version 10 md5 was the only option
* @param $username The username
* @param $password The password
*/
function _encryptPassword($username, $password) {
return 'md5' . md5($password . $username);
}

}
?>
4 changes: 1 addition & 3 deletions help/PostgresDoc14.php → help/PostgresDocDevel.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<?php

/**
* Help links for PostgreSQL 9.5 documentation
*
* $Id: PostgresDoc84.php,v 1.3 2008/11/18 21:35:48 ioguix Exp $
* Help links for PostgreSQL documentation
*/

include('./help/PostgresDoc13.php');
Expand Down
6 changes: 4 additions & 2 deletions intro.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@
<p><?php echo $lang['strintro'] ?></p>

<ul class="intro">
<li><a href="https://github.com/ReimuHakurei/phpPgAdmin"><?php echo $lang['strppahome'] ?></a></li>
<li><a href="http://phppgadmin.sourceforge.net/"><?php echo $lang['strppahome'] ?></a></li>
<li><a href="<?php echo $lang['strpgsqlhome_url'] ?>"><?php echo $lang['strpgsqlhome'] ?></a></li>
<li><a href="https://github.com/ReimuHakurei/phpPgAdmin/issues"><?php echo $lang['strreportbug'] ?></a></li>
<li><a href="http://sourceforge.net/tracker/?group_id=37132&amp;atid=418980"><?php echo $lang['strreportbug'] ?></a></li>
<li><a href="<?php echo $lang['strviewfaq_url'] ?>"><?php echo $lang['strviewfaq'] ?></a></li>
<li><a target="_top" href="tests/selenium/selenium-lib/core/TestRunner.html?test=..%2F..%2FTestSuite.php&resultsUrl=..%2FpostResults">Selenium tests</a></li>
</ul>

<?php
Expand Down
11 changes: 4 additions & 7 deletions libraries/adodb/adodb-active-record.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ function ADODB_SetDatabaseAdapter(&$db, $index=false)
}


#[\AllowDynamicProperties]
class ADODB_Active_Record {
static $_changeNames = true; // dynamically pluralize table names

Expand Down Expand Up @@ -1055,10 +1056,10 @@ function Update()
$valarr = array();
$neworig = array();
$pairs = array();
$i = -1;
$i = 0;
$cnt = 0;
foreach($table->flds as $name=>$fld) {
$i += 1;
$orig = $this->_original[$i++] ?? null;
$val = $this->$name;
$neworig[] = $val;

Expand All @@ -1078,11 +1079,7 @@ function Update()
}
}

if (isset($this->_original[$i]) && strcmp($val,$this->_original[$i]) == 0) {
continue;
}

if (is_null($this->_original[$i]) && is_null($val)) {
if ($val === $orig) {
continue;
}

Expand Down
7 changes: 4 additions & 3 deletions libraries/adodb/adodb-active-recordx.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ function ADODB_SetDatabaseAdapter(&$db)
}


#[\AllowDynamicProperties]
class ADODB_Active_Record {
static $_changeNames = true; // dynamically pluralize table names
static $_foreignSuffix = '_id'; //
Expand Down Expand Up @@ -1142,10 +1143,10 @@ function Update()
$valarr = array();
$neworig = array();
$pairs = array();
$i = -1;
$i = 0;
$cnt = 0;
foreach($table->flds as $name=>$fld) {
$i += 1;
$orig = $this->_original[$i++] ?? null;
$val = $this->$name;
$neworig[] = $val;

Expand All @@ -1165,7 +1166,7 @@ function Update()
}
}

if (isset($this->_original[$i]) && $val === $this->_original[$i]) {
if ($val === $orig) {
continue;
}
$valarr[] = $val;
Expand Down
41 changes: 32 additions & 9 deletions libraries/adodb/adodb-datadict.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -510,10 +510,12 @@ function addColumnSQL($tabname, $flds)
*
* As some DBMs can't do that on their own, you need to supply the complete definition of the new table,
* to allow recreating the table and copying the content over to the new table
* @param string $tabname table-name
* @param string $flds column-name and type for the changed column
* @param string $tableflds='' complete definition of the new table, eg. for postgres, default ''
*
* @param string $tabname table-name
* @param array|string $flds column-name and type for the changed column
* @param string $tableflds='' complete definition of the new table, eg. for postgres, default ''
* @param array|string $tableoptions='' options for the new table see createTableSQL, default ''
*
* @return array with SQL strings
*/
function alterColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
Expand Down Expand Up @@ -843,7 +845,7 @@ function _genFields($flds,$widespacing=false)
$fdefault = $this->connection->qstr($fdefault);
}
}
$suffix = $this->_createSuffix($fname,$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned);
$suffix = $this->_createSuffix($fname, $ftype, $fnotnull, $fdefault, $fautoinc, $fconstraint, $funsigned, $fprimary, $pkey);

// add index creation
if ($widespacing) $fname = str_pad($fname,24);
Expand Down Expand Up @@ -896,8 +898,22 @@ function _getSize($ftype, $ty, $fsize, $fprec, $options=false)
}


// return string must begin with space
function _createSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
/**
* Construct an database specific SQL string of constraints for column.
*
* @param string $fname column name
* @param string & $ftype column type
* @param bool $fnotnull NOT NULL flag
* @param string|bool $fdefault DEFAULT value
* @param bool $fautoinc AUTOINCREMENT flag
* @param string $fconstraint CONSTRAINT value
* @param bool $funsigned UNSIGNED flag
* @param string|bool $fprimary PRIMARY value
* @param array & $pkey array of primary key column names
*
* @return string Combined constraint string, must start with a space
*/
function _createSuffix($fname, &$ftype, $fnotnull, $fdefault, $fautoinc, $fconstraint, $funsigned, $fprimary, &$pkey)
{
$suffix = '';
if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
Expand Down Expand Up @@ -1027,7 +1043,6 @@ function _getSizePrec($size)
function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=false)
{
global $ADODB_FETCH_MODE;

$save = $ADODB_FETCH_MODE;
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
if ($this->connection->fetchMode !== false) $savem = $this->connection->setFetchMode(false);
Expand All @@ -1045,12 +1060,15 @@ function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=f
return $this->createTableSQL($tablename, $flds, $tableoptions);
}

$sql = [];
if (is_array($flds)) {
// Cycle through the update fields, comparing
// existing fields to fields to update.
// if the Metatype and size is exactly the
// same, ignore - by Mark Newham
$holdflds = array();
$fields_to_add = [];
$fields_to_alter = [];
foreach($flds as $k=>$v) {
if ( isset($cols[$k]) && is_object($cols[$k]) ) {
// If already not allowing nulls, then don't change
Expand All @@ -1074,15 +1092,20 @@ function changeTableSQL($tablename, $flds, $tableoptions = false, $dropOldFlds=f
if ($mt == 'X') $ml = $v['SIZE'];
if (($mt != $v['TYPE']) || ($ml != $fsize || $sc != $fprec) || (isset($v['AUTOINCREMENT']) && $v['AUTOINCREMENT'] != $obj->auto_increment)) {
$holdflds[$k] = $v;
$fields_to_alter[$k] = $v;
}
} else {
$fields_to_add[$k] = $v;
$holdflds[$k] = $v;
}
}
$flds = $holdflds;
}

$sql = $this->alterColumnSql($tablename, $flds);
$sql = array_merge(
$this->addColumnSQL($tablename, $fields_to_add),
$this->alterColumnSql($tablename, $fields_to_alter)
);
}

if ($dropOldFlds) {
foreach ($cols as $id => $v) {
Expand Down
Loading