mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Resolve #866
This commit is contained in:
parent
ba543c95d7
commit
b9ef8ae2c9
3 changed files with 62 additions and 135 deletions
|
|
@ -63,80 +63,51 @@ abstract class PdoAbstract
|
||||||
*/
|
*/
|
||||||
protected function getPDO() : \PDO
|
protected function getPDO() : \PDO
|
||||||
{
|
{
|
||||||
if ($this->oPDO)
|
if ($this->oPDO) {
|
||||||
{
|
|
||||||
return $this->oPDO;
|
return $this->oPDO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!\class_exists('PDO'))
|
if (!\class_exists('PDO')) {
|
||||||
{
|
|
||||||
throw new \Exception('Class PDO does not exist');
|
throw new \Exception('Class PDO does not exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sType = $sDsn = $sDbLogin = $sDbPassword = '';
|
$sType = $sDsn = $sDbLogin = $sDbPassword = '';
|
||||||
list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData();
|
list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData();
|
||||||
|
|
||||||
if (!\in_array($sType, static::getAvailableDrivers()))
|
if (!\in_array($sType, static::getAvailableDrivers())) {
|
||||||
{
|
|
||||||
throw new \Exception('Unknown PDO SQL connection type');
|
throw new \Exception('Unknown PDO SQL connection type');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($sDsn))
|
if (empty($sDsn)) {
|
||||||
{
|
|
||||||
throw new \Exception('Empty PDO DSN configuration');
|
throw new \Exception('Empty PDO DSN configuration');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->sDbType = $sType;
|
$this->sDbType = $sType;
|
||||||
|
|
||||||
$oPdo = false;
|
$oPdo = new \PDO($sDsn, $sDbLogin, $sDbPassword);
|
||||||
try
|
$sPdoType = $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||||
{
|
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
// $bCaseFunc = false;
|
|
||||||
$oPdo = new \PDO($sDsn, $sDbLogin, $sDbPassword);
|
|
||||||
if ($oPdo)
|
|
||||||
{
|
|
||||||
$sPdoType = $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
|
||||||
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
|
||||||
|
|
||||||
if ('mysql' === $sType && 'mysql' === $sPdoType)
|
// $bCaseFunc = false;
|
||||||
{
|
if ('mysql' === $sType && 'mysql' === $sPdoType) {
|
||||||
$oPdo->exec('SET NAMES utf8mb4 COLLATE utf8mb4_general_ci');
|
$oPdo->exec('SET NAMES utf8mb4 COLLATE utf8mb4_general_ci');
|
||||||
}
|
|
||||||
// else if ('sqlite' === $sType && 'sqlite' === $sPdoType && $this->bSqliteCollate)
|
|
||||||
// {
|
|
||||||
// if (\method_exists($oPdo, 'sqliteCreateCollation'))
|
|
||||||
// {
|
|
||||||
// $oPdo->sqliteCreateCollation('SQLITE_NOCASE_UTF8', array($this, 'sqliteNoCaseCollationHelper'));
|
|
||||||
// $bCaseFunc = true;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// $this->oLogger->Write('PDO:'.$sPdoType.($bCaseFunc ? '/SQLITE_NOCASE_UTF8' : ''));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (\Throwable $oException)
|
|
||||||
{
|
|
||||||
throw $oException;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($oPdo)
|
|
||||||
{
|
|
||||||
$this->oPDO = $oPdo;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new \Exception('PDO = false');
|
|
||||||
}
|
}
|
||||||
|
// else if ('sqlite' === $sType && 'sqlite' === $sPdoType && $this->bSqliteCollate) {
|
||||||
|
// if (\method_exists($oPdo, 'sqliteCreateCollation')) {
|
||||||
|
// $oPdo->sqliteCreateCollation('SQLITE_NOCASE_UTF8', array($this, 'sqliteNoCaseCollationHelper'));
|
||||||
|
// $bCaseFunc = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// $this->oLogger->Write('PDO:'.$sPdoType.($bCaseFunc ? '/SQLITE_NOCASE_UTF8' : ''));
|
||||||
|
|
||||||
|
$this->oPDO = $oPdo;
|
||||||
return $oPdo;
|
return $oPdo;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function lastInsertId(?string $sTabelName = null, ?string $sColumnName = null) : string
|
protected function lastInsertId(?string $sTabelName = null, ?string $sColumnName = null) : string
|
||||||
{
|
{
|
||||||
$mName = null;
|
$mName = null;
|
||||||
if ('pgsql' === $this->sDbType &&
|
if ('pgsql' === $this->sDbType && null !== $sTabelName && $sColumnName !== null) {
|
||||||
null !== $sTabelName && $sColumnName !== null)
|
|
||||||
{
|
|
||||||
$mName = \strtolower($sTabelName.'_'.$sColumnName.'_seq');
|
$mName = \strtolower($sTabelName.'_'.$sColumnName.'_seq');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,8 +131,7 @@ abstract class PdoAbstract
|
||||||
|
|
||||||
protected function prepareAndExecute(string $sSql, array $aParams = array(), bool $bMultiplyParams = false, bool $bLogParams = false) : ?\PDOStatement
|
protected function prepareAndExecute(string $sSql, array $aParams = array(), bool $bMultiplyParams = false, bool $bLogParams = false) : ?\PDOStatement
|
||||||
{
|
{
|
||||||
if ($this->bExplain && !$bMultiplyParams)
|
if ($this->bExplain && !$bMultiplyParams) {
|
||||||
{
|
|
||||||
$this->prepareAndExplain($sSql, $aParams);
|
$this->prepareAndExplain($sSql, $aParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,27 +139,19 @@ abstract class PdoAbstract
|
||||||
|
|
||||||
$this->writeLog($sSql);
|
$this->writeLog($sSql);
|
||||||
$oStmt = $this->getPDO()->prepare($sSql);
|
$oStmt = $this->getPDO()->prepare($sSql);
|
||||||
if ($oStmt)
|
if ($oStmt) {
|
||||||
{
|
|
||||||
$aLogs = array();
|
$aLogs = array();
|
||||||
$aRootParams = $bMultiplyParams ? $aParams : array($aParams);
|
$aRootParams = $bMultiplyParams ? $aParams : array($aParams);
|
||||||
foreach ($aRootParams as $aSubParams)
|
foreach ($aRootParams as $aSubParams) {
|
||||||
{
|
foreach ($aSubParams as $sName => $aValue) {
|
||||||
foreach ($aSubParams as $sName => $aValue)
|
if ($bLogParams) {
|
||||||
{
|
|
||||||
if ($bLogParams)
|
|
||||||
{
|
|
||||||
$aLogs[$sName] = $aValue[0];
|
$aLogs[$sName] = $aValue[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$mResult = $oStmt->execute() && !$bMultiplyParams ? $oStmt : null;
|
$mResult = $oStmt->execute() && !$bMultiplyParams ? $oStmt : null;
|
||||||
}
|
}
|
||||||
|
if ($bLogParams && $aLogs) {
|
||||||
if ($bLogParams && $aLogs)
|
|
||||||
{
|
|
||||||
$this->writeLog('Params: '.\json_encode($aLogs, JSON_UNESCAPED_UNICODE));
|
$this->writeLog('Params: '.\json_encode($aLogs, JSON_UNESCAPED_UNICODE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -200,15 +162,12 @@ abstract class PdoAbstract
|
||||||
protected function prepareAndExplain(string $sSql, array $aParams = array())
|
protected function prepareAndExplain(string $sSql, array $aParams = array())
|
||||||
{
|
{
|
||||||
$mResult = null;
|
$mResult = null;
|
||||||
if (0 === strpos($sSql, 'SELECT '))
|
if (0 === \strpos($sSql, 'SELECT ')) {
|
||||||
{
|
|
||||||
$sSql = 'EXPLAIN '.$sSql;
|
$sSql = 'EXPLAIN '.$sSql;
|
||||||
$this->writeLog($sSql);
|
$this->writeLog($sSql);
|
||||||
$oStmt = $this->getPDO()->prepare($sSql);
|
$oStmt = $this->getPDO()->prepare($sSql);
|
||||||
if ($oStmt)
|
if ($oStmt) {
|
||||||
{
|
foreach ($aParams as $sName => $aValue) {
|
||||||
foreach ($aParams as $sName => $aValue)
|
|
||||||
{
|
|
||||||
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,8 +175,7 @@ abstract class PdoAbstract
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($mResult)
|
if ($mResult) {
|
||||||
{
|
|
||||||
$aFetch = $mResult->fetchAll(\PDO::FETCH_ASSOC);
|
$aFetch = $mResult->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
$this->oLogger->WriteDump($aFetch);
|
$this->oLogger->WriteDump($aFetch);
|
||||||
|
|
||||||
|
|
@ -231,18 +189,12 @@ abstract class PdoAbstract
|
||||||
*/
|
*/
|
||||||
protected function writeLog($mData)
|
protected function writeLog($mData)
|
||||||
{
|
{
|
||||||
if ($this->oLogger)
|
if ($this->oLogger) {
|
||||||
{
|
if ($mData instanceof \Throwable) {
|
||||||
if ($mData instanceof \Throwable)
|
|
||||||
{
|
|
||||||
$this->oLogger->WriteException($mData, \LOG_ERR, 'SQL');
|
$this->oLogger->WriteException($mData, \LOG_ERR, 'SQL');
|
||||||
}
|
} else if (\is_scalar($mData)) {
|
||||||
else if (\is_scalar($mData))
|
|
||||||
{
|
|
||||||
$this->oLogger->Write((string) $mData, \LOG_INFO, 'SQL');
|
$this->oLogger->Write((string) $mData, \LOG_INFO, 'SQL');
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->oLogger->WriteDump($mData, \LOG_INFO, 'SQL');
|
$this->oLogger->WriteDump($mData, \LOG_INFO, 'SQL');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -257,18 +209,15 @@ abstract class PdoAbstract
|
||||||
protected function getVersion(string $sName) : ?int
|
protected function getVersion(string $sName) : ?int
|
||||||
{
|
{
|
||||||
$oPdo = $this->getPDO();
|
$oPdo = $this->getPDO();
|
||||||
if ($oPdo)
|
if ($oPdo) {
|
||||||
{
|
|
||||||
$sQuery = 'SELECT MAX(value_int) FROM rainloop_system WHERE sys_name = ?';
|
$sQuery = 'SELECT MAX(value_int) FROM rainloop_system WHERE sys_name = ?';
|
||||||
|
|
||||||
$this->writeLog($sQuery);
|
$this->writeLog($sQuery);
|
||||||
|
|
||||||
$oStmt = $oPdo->prepare($sQuery);
|
$oStmt = $oPdo->prepare($sQuery);
|
||||||
if ($oStmt->execute(array($sName.'_version')))
|
if ($oStmt->execute(array($sName.'_version'))) {
|
||||||
{
|
|
||||||
$mRow = $oStmt->fetch(\PDO::FETCH_NUM);
|
$mRow = $oStmt->fetch(\PDO::FETCH_NUM);
|
||||||
if ($mRow && isset($mRow[0]))
|
if ($mRow && isset($mRow[0])) {
|
||||||
{
|
|
||||||
return (int) $mRow[0];
|
return (int) $mRow[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,21 +232,18 @@ abstract class PdoAbstract
|
||||||
{
|
{
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
$oPdo = $this->getPDO();
|
$oPdo = $this->getPDO();
|
||||||
if ($oPdo)
|
if ($oPdo) {
|
||||||
{
|
|
||||||
$sQuery = 'DELETE FROM rainloop_system WHERE sys_name = ? AND value_int <= ?;';
|
$sQuery = 'DELETE FROM rainloop_system WHERE sys_name = ? AND value_int <= ?;';
|
||||||
$this->writeLog($sQuery);
|
$this->writeLog($sQuery);
|
||||||
|
|
||||||
$oStmt = $oPdo->prepare($sQuery);
|
$oStmt = $oPdo->prepare($sQuery);
|
||||||
$bResult = !!$oStmt->execute(array($sName.'_version', $iVersion));
|
$bResult = !!$oStmt->execute(array($sName.'_version', $iVersion));
|
||||||
if ($bResult)
|
if ($bResult) {
|
||||||
{
|
|
||||||
$sQuery = 'INSERT INTO rainloop_system (sys_name, value_int) VALUES (?, ?);';
|
$sQuery = 'INSERT INTO rainloop_system (sys_name, value_int) VALUES (?, ?);';
|
||||||
$this->writeLog($sQuery);
|
$this->writeLog($sQuery);
|
||||||
|
|
||||||
$oStmt = $oPdo->prepare($sQuery);
|
$oStmt = $oPdo->prepare($sQuery);
|
||||||
if ($oStmt)
|
if ($oStmt) {
|
||||||
{
|
|
||||||
$bResult = !!$oStmt->execute(array($sName.'_version', $iVersion));
|
$bResult = !!$oStmt->execute(array($sName.'_version', $iVersion));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -314,8 +260,7 @@ abstract class PdoAbstract
|
||||||
$bResult = true;
|
$bResult = true;
|
||||||
|
|
||||||
$oPdo = $this->getPDO();
|
$oPdo = $this->getPDO();
|
||||||
if ($oPdo)
|
if ($oPdo) {
|
||||||
{
|
|
||||||
$aQ = array();
|
$aQ = array();
|
||||||
switch ($this->sDbType)
|
switch ($this->sDbType)
|
||||||
{
|
{
|
||||||
|
|
@ -361,24 +306,17 @@ rl_email text NOT NULL DEFAULT \'\'
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (\count($aQ))
|
if (\count($aQ)) {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach ($aQ as $sQuery)
|
foreach ($aQ as $sQuery) {
|
||||||
{
|
$this->writeLog($sQuery);
|
||||||
if ($bResult)
|
$bResult = false !== $oPdo->exec($sQuery);
|
||||||
{
|
if (!$bResult) {
|
||||||
$this->writeLog($sQuery);
|
$this->writeLog('Result=false');
|
||||||
$bResult = false !== $oPdo->exec($sQuery);
|
break;
|
||||||
if (!$bResult)
|
} else {
|
||||||
{
|
$this->writeLog('Result=true');
|
||||||
$this->writeLog('Result=false');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->writeLog('Result=true');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -402,12 +340,10 @@ rl_email text NOT NULL DEFAULT \'\'
|
||||||
}
|
}
|
||||||
catch (\PDOException $oException)
|
catch (\PDOException $oException)
|
||||||
{
|
{
|
||||||
$this->writeLog($oException);
|
// $this->writeLog($oException);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->initSystemTables();
|
$this->initSystemTables();
|
||||||
|
|
||||||
$iFromVersion = $this->getVersion($sName);
|
$iFromVersion = $this->getVersion($sName);
|
||||||
}
|
}
|
||||||
catch (\PDOException $oSubException)
|
catch (\PDOException $oSubException)
|
||||||
|
|
@ -418,33 +354,26 @@ rl_email text NOT NULL DEFAULT \'\'
|
||||||
}
|
}
|
||||||
|
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
if (\is_int($iFromVersion) && 0 <= $iFromVersion)
|
if (\is_int($iFromVersion) && 0 <= $iFromVersion) {
|
||||||
{
|
|
||||||
$oPdo = false;
|
$oPdo = false;
|
||||||
|
|
||||||
foreach ($aData as $iVersion => $aQuery)
|
foreach ($aData as $iVersion => $aQuery) {
|
||||||
{
|
if (0 === \count($aQuery)) {
|
||||||
if (0 === \count($aQuery))
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$oPdo)
|
if (!$oPdo) {
|
||||||
{
|
|
||||||
$oPdo = $this->getPDO();
|
$oPdo = $this->getPDO();
|
||||||
$bResult = true;
|
$bResult = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($iFromVersion < $iVersion && $oPdo)
|
if ($iFromVersion < $iVersion && $oPdo) {
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach ($aQuery as $sQuery)
|
foreach ($aQuery as $sQuery) {
|
||||||
{
|
|
||||||
$this->writeLog($sQuery);
|
$this->writeLog($sQuery);
|
||||||
$bExec = $oPdo->exec($sQuery);
|
$bExec = $oPdo->exec($sQuery);
|
||||||
if (false === $bExec)
|
if (false === $bExec) {
|
||||||
{
|
|
||||||
$this->writeLog('Result: false');
|
$this->writeLog('Result: false');
|
||||||
|
|
||||||
$bResult = false;
|
$bResult = false;
|
||||||
|
|
@ -458,8 +387,7 @@ rl_email text NOT NULL DEFAULT \'\'
|
||||||
throw $oException;
|
throw $oException;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$bResult)
|
if (!$bResult) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,9 @@ class Legacy
|
||||||
if (\strlen($sValue)) {
|
if (\strlen($sValue)) {
|
||||||
$oTypes = $oProp['TYPE'];
|
$oTypes = $oProp['TYPE'];
|
||||||
$aTypes = $oTypes ? $oTypes->getParts() : array();
|
$aTypes = $oTypes ? $oTypes->getParts() : array();
|
||||||
$pref = 100;
|
$pref = empty($oProp['PREF']) ? 100 : \min(100, \max(1, $oProp['PREF']->getValue()));
|
||||||
if (0 < $oProp['PREF']) {
|
$pref = \str_pad($pref, 3, '0', \STR_PAD_LEFT);
|
||||||
$pref = (int) $oProp['PREF'];
|
$aTmp[$pref . $sValue] = new Property($iType, $sValue, \implode(',', $aTypes));
|
||||||
}
|
|
||||||
$aTmp[\substr(1000+$pref,-3) . $sValue] = new Property($iType, $sValue, \implode(',', $aTypes));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\ksort($aTmp);
|
\ksort($aTmp);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ abstract class Stream
|
||||||
\ob_implicit_flush();
|
\ob_implicit_flush();
|
||||||
\ini_set('implicit_flush',1);
|
\ini_set('implicit_flush',1);
|
||||||
\ini_set('output_buffering', 0);
|
\ini_set('output_buffering', 0);
|
||||||
|
\ini_set('display_errors', 0);
|
||||||
if ($i = \ob_get_level()) {
|
if ($i = \ob_get_level()) {
|
||||||
# Clear buffers:
|
# Clear buffers:
|
||||||
while ($i-- && \ob_end_clean());
|
while ($i-- && \ob_end_clean());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue