Skip to content

Commit

Permalink
Add an iterator method.
Browse files Browse the repository at this point in the history
  • Loading branch information
lincanbin committed Jan 25, 2019
1 parent 2679915 commit 33426fa
Showing 1 changed file with 199 additions and 46 deletions.
245 changes: 199 additions & 46 deletions src/PDO.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,66 @@
*
* A PHP MySQL PDO class similar to the the Python MySQLdb.
*/
require(dirname(__FILE__) . "/PDO.Log.class.php");
require(__DIR__ . '/PDO.Log.class.php');
require(__DIR__ . '/PDO.Iterator.class.php');
/** Class DB
* @property PDO pdo PDO object
* @property PDOStatement sQuery PDOStatement
* @property PDOLog PDOLog logObject
*/
class DB
{
private $Host;
private $DBPort;
private $DBName;
private $DBUser;
private $DBPassword;
private $DBPort;
private $pdo;
private $sQuery;
private $bConnected = false;
private $log;
private $connectionStatus = false;
private $logObject;
private $parameters;
public $rowCount = 0;
public $columnCount = 0;
public $querycount = 0;


public function __construct($Host, $DBName, $DBUser, $DBPassword, $DBPort = 3306)


private $retryAttempt = 0; // 失败重试次数
const AUTO_RECONNECT = true;
const RETRY_ATTEMPTS = 3; // 最大失败重试次数

/**
* DB constructor.
* @param $Host
* @param $DBPort
* @param $DBName
* @param $DBUser
* @param $DBPassword
*/
public function __construct($Host, $DBPort, $DBName, $DBUser, $DBPassword)
{
$this->log = new Log();
$this->logObject = new PDOLog();
$this->Host = $Host;
$this->DBPort = $DBPort;
$this->DBName = $DBName;
$this->DBUser = $DBUser;
$this->DBPassword = $DBPassword;
$this->DBPort = $DBPort;
$this->Connect();
$this->parameters = array();
$this->Connect();
}


private function Connect()
{
try {
$this->pdo = new PDO('mysql:dbname=' . $this->DBName . ';host=' . $this->Host . ';port=' . $this->DBPort . ';charset=utf8',
$dsn = 'mysql:';
$dsn .= 'host=' . $this->Host . ';';
$dsn .= 'port=' . $this->DBPort . ';';
if (!empty($this->DBName)) {
$dsn .= 'dbname=' . $this->DBName . ';';
}
$dsn .= 'charset=utf8;';
$this->pdo = new PDO($dsn,
$this->DBUser,
$this->DBPassword,
array(
Expand All @@ -68,30 +93,36 @@ private function Connect()
//$this->pdo->setAttribute(PDO::ATTR_PERSISTENT, true);//长连接
$this->pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
*/
$this->bConnected = true;
$this->connectionStatus = true;

}
catch (PDOException $e) {
echo $this->ExceptionLog($e->getMessage());
die();
$this->ExceptionLog($e, '', 'Connect');
}
}


public function CloseConnection()

private function SetFailureFlag()
{
$this->pdo = null;
$this->connectionStatus = false;
}


private function Init($query, $parameters = "")

/**
* close pdo connection
*/
public function closeConnection()
{
$this->pdo = null;
}

private function Init($query, $parameters = null, $driverOptions = array())
{
if (!$this->bConnected) {
if (!$this->connectionStatus) {
$this->Connect();
}
try {
$this->parameters = $parameters;
$this->sQuery = $this->pdo->prepare($this->BuildParams($query, $this->parameters));
$this->sQuery = $this->pdo->prepare($this->BuildParams($query, $this->parameters), $driverOptions);

if (!empty($this->parameters)) {
if (array_key_exists(0, $parameters)) {
Expand All @@ -105,19 +136,22 @@ private function Init($query, $parameters = "")
$this->sQuery->bindParam($parametersType ? intval($column) : ":" . $column, $this->parameters[$column]); //It would be query after loop end(before 'sQuery->execute()').It is wrong to use $value.
}
}

$this->succes = $this->sQuery->execute();

if (!isset($driverOptions[PDO::ATTR_CURSOR])) {
$this->sQuery->execute();
}
$this->querycount++;
}
catch (PDOException $e) {
echo $this->ExceptionLog($e->getMessage(), $this->BuildParams($query));
die();
$this->ExceptionLog($e, $this->BuildParams($query), 'Init', array('query' => $query, 'parameters' => $parameters));

}

$this->parameters = array();
}

private function BuildParams($query, $params = array()){
private function BuildParams($query, $params = null)
{
if (!empty($params)) {
$array_parameter_found = false;
foreach ($params as $parameter_key => $parameter) {
Expand All @@ -143,30 +177,116 @@ private function BuildParams($query, $params = array()){
}
return $query;
}


public function query($query, $params = null, $fetchmode = PDO::FETCH_ASSOC)

/**
* @return bool
*/
public function beginTransaction()
{
return $this->pdo->beginTransaction();
}

/**
* @return bool
*/
public function commit()
{
return $this->pdo->commit();
}

/**
* @return bool
*/
public function rollBack()
{
return $this->pdo->rollBack();
}

/**
* @return bool
*/
public function inTransaction()
{
return $this->pdo->inTransaction();
}

/**
* execute a sql query, returns an result array in the select operation, and returns the number of rows affected in other operations
* @param string $query
* @param null $params
* @param int $fetchMode
* @return array|int|null
*/
public function query($query, $params = null, $fetchMode = PDO::FETCH_ASSOC)
{
$query = trim($query);
$rawStatement = explode(" ", $query);
$this->Init($query, $params);
$statement = strtolower($rawStatement[0]);
if ($statement === 'select' || $statement === 'show') {
return $this->sQuery->fetchAll($fetchmode);
return $this->sQuery->fetchAll($fetchMode);
} elseif ($statement === 'insert' || $statement === 'update' || $statement === 'delete') {
return $this->sQuery->rowCount();
} else {
return NULL;
}
}



/**
* execute a sql query, returns an iterator in the select operation, and returns the number of rows affected in other operations
* @param string $query
* @param null $params
* @param int $fetchMode
* @return int|null|PDOIterator
*/
public function iterator($query, $params = null, $fetchMode = PDO::FETCH_ASSOC)
{
$query = trim($query);
$rawStatement = explode(" ", $query);
$this->Init($query, $params, array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$statement = strtolower($rawStatement[0]);
if ($statement === 'select' || $statement === 'show') {
return new PDOIterator($this->sQuery, $fetchMode);
} elseif ($statement === 'insert' || $statement === 'update' || $statement === 'delete') {
return $this->sQuery->rowCount();
} else {
return NULL;
}
}

/**
* @param $tableName
* @param null $params
* @return bool|string
*/
public function insert($tableName, $params = null)
{
$keys = array_keys($params);
$rowCount = $this->query(
'INSERT INTO `' . $tableName . '` (`' . implode('`,`', $keys) . '`)
VALUES (:' . implode(',:', $keys) . ')',
$params
);
if ($rowCount === 0) {
return false;
}
return $this->lastInsertId();
}

/**
* @return string
*/
public function lastInsertId()
{
return $this->pdo->lastInsertId();
}




/**
* @param $query
* @param null $params
* @return array
*/
public function column($query, $params = null)
{
$this->Init($query, $params);
Expand All @@ -177,7 +297,12 @@ public function column($query, $params = null)
return $resultColumn;
}


/**
* @param $query
* @param null $params
* @param int $fetchmode
* @return mixed
*/
public function row($query, $params = null, $fetchmode = PDO::FETCH_ASSOC)
{
$this->Init($query, $params);
Expand All @@ -187,28 +312,56 @@ public function row($query, $params = null, $fetchmode = PDO::FETCH_ASSOC)
$this->sQuery->closeCursor();
return $resultRow;
}



/**
* @param $query
* @param null $params
* @return mixed
*/
public function single($query, $params = null)
{
$this->Init($query, $params);
return $this->sQuery->fetchColumn();
}


private function ExceptionLog($message, $sql = "")

/**
* @param PDOException $e
* @param string $sql
* @param string $method
* @param array $parameters
*/
private function ExceptionLog(PDOException $e, $sql = "", $method = '', $parameters = array())
{
$message = $e->getMessage();
$exception = 'Unhandled Exception. <br />';
$exception .= $message;
$exception .= "<br /> You can find the error back in the log.";

if (!empty($sql)) {
$message .= "\r\nRaw SQL : " . $sql;
}
$this->log->write($message, $this->DBName . md5($this->DBPassword));
//Prevent search engines to crawl
header("HTTP/1.1 500 Internal Server Error");
header("Status: 500 Internal Server Error");
return $exception;
$this->logObject->write($message, $this->DBName . md5($this->DBPassword));
if (
self::AUTO_RECONNECT
&& $this->retryAttempt < self::RETRY_ATTEMPTS
&& stripos($message, 'server has gone away') !== false
&& !empty($method)
&& !$this->inTransaction()
) {
$this->SetFailureFlag();
$this->retryAttempt ++;
$this->logObject->write('Retry ' . $this->retryAttempt . ' times', $this->DBName . md5($this->DBPassword));
call_user_func_array(array($this, $method), $parameters);
} else {
if (($this->pdo === null || !$this->inTransaction()) && php_sapi_name() !== "cli") {
//Prevent search engines to crawl
header("HTTP/1.1 500 Internal Server Error");
header("Status: 500 Internal Server Error");
echo $exception;
exit();
} else {
throw $e;
}
}
}
}

0 comments on commit 33426fa

Please sign in to comment.