Start to implement pdo updater

This commit is contained in:
RainLoop Team 2013-12-02 20:08:41 +04:00
parent c29be81a65
commit f1f7a84a3e

View file

@ -9,6 +9,11 @@ abstract class PdoAbstract
*/ */
protected $oLogger; protected $oLogger;
/**
* @var string
*/
protected $sDbType;
/** /**
* @return bool * @return bool
*/ */
@ -26,32 +31,51 @@ abstract class PdoAbstract
} }
/** /**
* @param \RainLoop\Account $oAccount
* *
* @return array * @return array
*/ */
protected function getPdoAccessData(\RainLoop\Account $oAccount) protected function getPdoAccessData()
{ {
$aResult = array('mysql', '', '', ''); $aResult = array('mysql', '', '', '');
return $aResult; return $aResult;
} }
/** /**
* @param \RainLoop\Account $oAccount * @return array
* @staticvar array $aPdoCache */
* protected function getPdoSystemTables()
{
$aResult = array();
if ('mysql' === $this->sDbType)
{
$aResult[] = 'CREATE TABLE IF NOT EXISTS `rainloop_system` (
`sys_name` varchar(50) NOT NULL,
`value_int` int(11) UNSIGNED NOT NULL DEFAULT \'0\',
`value_str` varchar(255) NOT NULL DEFAULT \'\'
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;';
$aResult[] = 'CREATE TABLE IF NOT EXISTS `rainloop_users` (
`id_user` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`rl_email` varchar(255) /*!40101 CHARACTER SET ascii COLLATE ascii_general_ci */ NOT NULL,
UNIQUE `email_unique` (`rl_email`),
PRIMARY KEY(`id_user`)
) /*!40000 ENGINE=INNODB */;';
}
return $aResult;
}
/**
* @return \PDO * @return \PDO
* *
* @throws \Exception * @throws \Exception
*/ */
protected function getPDO(\RainLoop\Account $oAccount) protected function getPDO($oAccount = null)
{ {
static $aPdoCache = array(); static $aPdoCache = null;
if ($aPdoCache)
$sEmail = $oAccount->ParentEmailHelper();
if (isset($aPdoCache[$sEmail]))
{ {
return $aPdoCache[$sEmail]; return $aPdoCache;
} }
if (!\class_exists('PDO')) if (!\class_exists('PDO'))
@ -61,7 +85,8 @@ abstract class PdoAbstract
// TODO // TODO
$sType = $sDsn = $sDbLogin = $sDbPassword = ''; $sType = $sDsn = $sDbLogin = $sDbPassword = '';
list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData($oAccount); list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData();
$this->sType = $sType;
$oPdo = false; $oPdo = false;
try try
@ -70,7 +95,7 @@ abstract class PdoAbstract
if ($oPdo) if ($oPdo)
{ {
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
if ('mysql' === $sType) if ('mysql' === $this->sType)
{ {
} }
@ -83,7 +108,7 @@ abstract class PdoAbstract
if ($oPdo) if ($oPdo)
{ {
$aPdoCache[$sEmail] = $oPdo; $aPdoCache = $oPdo;
} }
else else
{ {
@ -100,7 +125,7 @@ abstract class PdoAbstract
* *
* @return \PDOStatement|null * @return \PDOStatement|null
*/ */
protected function prepareAndExecute(\RainLoop\Account $oAccount, $sSql, $aParams = array()) protected function prepareAndExecute($sSql, $aParams = array())
{ {
if ($this->oLogger) if ($this->oLogger)
{ {
@ -108,7 +133,7 @@ abstract class PdoAbstract
} }
$mResult = null; $mResult = null;
$oStmt = $this->getPDO($oAccount)->prepare($sSql); $oStmt = $this->getPDO()->prepare($sSql);
if ($oStmt) if ($oStmt)
{ {
foreach ($aParams as $sName => $aValue) foreach ($aParams as $sName => $aValue)
@ -123,20 +148,21 @@ abstract class PdoAbstract
} }
/** /**
* @param \RainLoop\Account $oAccount * @param string $sEmail
* @param bool $bSkipInsert = false * @param bool $bSkipInsert = false
* *
* @return int * @return int
*/ */
protected function getUserId(\RainLoop\Account $oAccount, $bSkipInsert = false) protected function getUserId($sEmail, $bSkipInsert = false)
{ {
$sEmail = \strtolower($oAccount->ParentEmailHelper()); $sEmail = \strtolower(\trim($sEmail));
if (empty($sEmail))
{
throw new \InvalidArgumentException('Empty Email argument');
}
$oStmt = $this->prepareAndExecute($oAccount, $oStmt = $this->prepareAndExecute('SELECT id_user FROM rainloop_users WHERE rl_email = :rl_email',
'SELECT `id_user` FROM `rainloop_users` WHERE `email` = :email LIMIT 1', array(':rl_email' => array($sEmail, \PDO::PARAM_STR)));
array(
':email' => array($sEmail, \PDO::PARAM_STR)
));
$mRow = $oStmt->fetch(\PDO::FETCH_ASSOC); $mRow = $oStmt->fetch(\PDO::FETCH_ASSOC);
if ($mRow && isset($mRow['id_user']) && \is_numeric($mRow['id_user'])) if ($mRow && isset($mRow['id_user']) && \is_numeric($mRow['id_user']))
@ -148,13 +174,10 @@ abstract class PdoAbstract
{ {
$oStmt->closeCursor(); $oStmt->closeCursor();
$oStmt = $this->prepareAndExecute($oAccount, $oStmt = $this->prepareAndExecute('INSERT INTO rainloop_users (rl_email) VALUES (:rl_email)',
'INSERT INTO rainloop_users (`email`) VALUES (:email)', array(':rl_email' => array($sEmail, \PDO::PARAM_STR)));
array(
':email' => array($sEmail, \PDO::PARAM_STR)
));
return $this->getUserId($oAccount, true); return $this->getUserId($sEmail, true);
} }
throw new \Exception('id_user = 0'); throw new \Exception('id_user = 0');
@ -179,4 +202,129 @@ abstract class PdoAbstract
{ {
return '\''.$sValue.'\''; return '\''.$sValue.'\'';
} }
/**
* @param string $sType
* @param bool $bReturnIntValue = true
*
* @return int|string|bool
*/
protected function getSystemValue($sName, $bReturnIntValue = true)
{
$oPdo = $this->getPDO();
if ($oPdo)
{
$oStmt = $oPdo->prepare('SELECT * FROM rainloop_system WHERE sys_name = ?');
$oStmt->execute(array($sName));
$mRow = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
if ($mRow && isset($mRow[0]['sys_name'], $mRow[0]['value_int'], $mRow[0]['value_str']))
{
return $bReturnIntValue ? (int) $mRow[0]['value_int'] : (string) $mRow[0]['value_str'];
}
}
return false;
}
/**
* @param string $sType
* @param int $iVersion
*
* @return bool
*/
protected function setVersion($sName, $iVersion)
{
$bResult = false;
$oPdo = $this->getPDO();
if ($oPdo)
{
$oPdo->beginTransaction();
$oStmt = $oPdo->prepare('DELETE FROM rainloop_system WHERE sys_name = ? AND value_int <= ?');
$bResult = !!$oStmt->execute(array($sName, $iVersion));
if ($bResult)
{
$oStmt = $oPdo->prepare('INSERT INTO `rainloop_system (sys_name, value_int) VALUES (?, ?)');
if ($oStmt)
{
$bResult = !!$oStmt->execute(array($sName, $iVersion));
}
}
if ($bResult)
{
$oPdo->commit();
}
else
{
$oPdo->rollBack();
}
}
return $bResult;
}
/**
* @throws \Exception
*/
protected function initSystemTables()
{
$aQ = $this->getPdoSystemTables();
$oPdo = $this->getPDO();
if ($oPdo && 0 < count($aQ))
{
$oPdo->beginTransaction();
try
{
foreach ($aQ as $sQuery)
{
$oPdo->exec($sQuery);
}
}
catch (\Exception $oException)
{
$oPdo->rollBack();
throw $oException;
}
$oPdo->commit();
}
}
/**
* @param string $sFromName
* @param int $iFromVersion
* @param array $aData = array()
*
* @return bool
*/
protected function smartDataBaseUpgrade($sFromName, $iFromVersion, $aData = array())
{
$bResult = false;
$oPdo = $this->getPDO();
if ($oPdo)
{
$bResult = true;
if (0 === $iFromVersion)
{
$this->initSystemTables();
}
foreach ($aData as $iVersion => $aQuery)
{
if ($iFromVersion < $iVersion)
{
foreach ($aQuery as $sQuery)
{
$oPdo->exec($sQuery);
}
$this->setVersion($sFromName, $iVersion);
}
}
}
return $bResult;
}
} }