php-vn-lib/vn/db/conn.php

369 lines
7.9 KiB
PHP
Raw Normal View History

2015-01-23 12:38:29 +00:00
<?php
namespace Vn\Db;
2015-02-18 16:13:23 +00:00
require_once ('vn/lib/type.php');
2015-01-23 12:38:29 +00:00
require_once ('vn/db/exception.php');
class Conn
{
private $conn = NULL;
private $isOpen = FALSE;
/**
* Opens a new connection to the database.
*
* @param string $host The host name
* @param string $user The user name to authenticate
* @param string $pass The user password
* @param string $name The default schema name
*
* @return boolean %TRUE on success, %FALSE otherwise
**/
function open ($host, $user, $pass, $name, $port = NULL)
2015-01-23 12:38:29 +00:00
{
$conn = $this->conn = mysqli_init ();
$conn->options (MYSQLI_READ_DEFAULT_FILE, __DIR__.'/my.cnf');
$conn->options (MYSQLI_OPT_LOCAL_INFILE, TRUE);
@$conn->real_connect ($host, $user, $pass, $name, $port);
2015-01-23 12:38:29 +00:00
if (mysqli_connect_errno ())
{
sleep (3);
2015-01-23 12:38:29 +00:00
throw new Exception (mysqli_connect_errno (), mysqli_connect_error ());
return FALSE;
}
$this->isOpen = TRUE;
$this->query ('SET CHARACTER SET utf8');
return TRUE;
}
/**
* Closes the current connection, if it's closed does nothing.
**/
function close ()
{
if ($this->isOpen)
$this->conn->close ();
$this->isOpen = FALSE;
}
/**
* Changes the default schema for the current connection.
*
* @param string $schema The schema name
* @return boolean %TRUE if success, %FALSE otherwise
**/
function selectDb ($dbName)
{
return $this->conn->select_db ($dbName);
}
/**
* Executes the query and gets the result.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function query ($query, $params = NULL)
{
$result = $this->conn->query ($this->render ($query, $params));
if (!$result)
$this->checkError ();
else
while ($this->moreResults ())
$this->nextResult ();
return $result;
}
2015-01-23 12:38:29 +00:00
/**
* Checks whether the connection is open.
*
* @return boolean %TRUE if connection is open, %FALSE otherwise
**/
function isOpen ()
{
return $this->isOpen;
}
/**
* Gets the first row value of the first column from a result.
2015-01-23 12:38:29 +00:00
*
* @param resource $result The database result
2015-01-23 12:38:29 +00:00
*
* @return mixed[] An associative array with the first row, %NULL if error
**/
function getRowFromResult ($result)
2015-01-23 12:38:29 +00:00
{
if ($result)
{
$row = $result->fetch_assoc ();
$result->free ();
2015-01-23 12:38:29 +00:00
return $row;
}
2015-01-23 12:38:29 +00:00
return NULL;
}
2015-01-23 12:38:29 +00:00
/**
* Gets the first row value of the first column from a result.
2015-01-23 12:38:29 +00:00
*
* @param resource $result The database result
2015-01-23 12:38:29 +00:00
*
* @return mixed The value or %NULL if error
2015-01-23 12:38:29 +00:00
**/
function getValueFromResult ($result)
2015-01-23 12:38:29 +00:00
{
$value = NULL;
2015-01-23 12:38:29 +00:00
if ($result)
{
$row = $result->fetch_row ();
if ($row && count ($row) > 0)
$value = $row[0];
$result->free ();
}
2015-01-23 12:38:29 +00:00
return $value;
2015-01-23 12:38:29 +00:00
}
/**
* Executes the query and gets it's first row.
2015-01-23 12:38:29 +00:00
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed[] An associative array with the first row, %NULL if error
**/
function getRow ($query, $params = NULL)
{
$result = $this->query ($query, $params);
return $this->getRowFromResult ($result);
}
/**
* Executes the query and gets the first value of the first row.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function getValue ($query, $params = NULL)
{
$result = $this->query ($query, $params);
return $this->getValueFromResult ($result);
}
/**
* Loads a query from a file and renders it.
*
* @param string $file The file path
* @param mixed[] $params The query parameters
*
* @return mixed The query string
**/
function loadFromFile ($file, $params = NULL)
{
$query = file_get_contents ($file .'.sql');
if ($query === FALSE)
throw new Exception (NULL, 'Can not load query from file');
return $this->render ($query, $params);
}
/**
* Executes the query stored in the specified file and gets the result.
*
* @param string $file The file path
* @param mixed[] $params The query parameters
*
2015-01-23 12:38:29 +00:00
* @return mixed The value or %NULL if error
**/
function queryFromFile ($file, $params = NULL)
{
$query = $this->loadFromFile ($file, $params);
2015-01-23 12:38:29 +00:00
if ($query)
return $this->query ($query);
2015-01-23 12:38:29 +00:00
return NULL;
}
/**
* Executes the file query and gets it's first row.
2015-01-23 12:38:29 +00:00
*
* @param string $file The file path
* @param mixed[] $params The query parameters
*
* @return mixed[] An associative array with the first row, %NULL if error
**/
function getRowFromFile ($file, $params = NULL)
{
$result = $this->queryFromFile ($file, $params);
return $this->getRowFromResult ($result);
}
/**
* Executes the file query and gets the first value of the first row.
*
* @param string $file The file path
2015-01-23 12:38:29 +00:00
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function getValueFromFile ($file, $params = NULL)
2015-01-23 12:38:29 +00:00
{
$result = $this->queryFromFile ($file, $params);
return $this->getValueFromResult ($result);
2015-01-23 12:38:29 +00:00
}
/**
* Execute multiple queries separated by semicolons.
*
* @param string $query The SQL query
* @param mixed[] $params The query parameters
*
* @return mixed The value or %NULL if error
**/
function multiQuery ($query, $params = NULL)
{
2015-02-18 16:13:23 +00:00
$success = $this->conn->multi_query ($this->render ($query, $params));
2015-01-23 12:38:29 +00:00
if (!$success)
$this->checkError ();
return $success;
}
/**
* Prepare an SQL statement for execution.
*
* @param string $query The SQL query
*
* @return mixed The statement object or %FALSE if an error occurred
**/
function prepare ($query)
{
return $this->conn->prepare ($query);
}
2015-01-23 12:38:29 +00:00
function storeResult ()
{
$result = $this->conn->store_result ();
if (!$result)
$this->checkError ();
return $result;
}
function moreResults ()
{
return $this->conn->more_results ();
}
function nextResult ()
{
$hasNext = $this->conn->next_result ();
$this->checkError ();
return $hasNext;
2015-01-23 12:38:29 +00:00
}
/**
* Check if there has been an error in the last query or multiquery,
* throwing a @Db\Exception exception if any.
**/
function checkError ()
2015-01-23 12:38:29 +00:00
{
if ($this->conn->errno)
throw new Exception ($this->conn->errno, $this->conn->error);
2015-01-23 12:38:29 +00:00
}
/**
* Check if there have been warnings in the last query.
*
* @return boolean %TRUE if there have been warnings %FALSE otherwise
**/
2015-01-23 12:38:29 +00:00
function checkWarnings ()
{
return $this->conn->warning_count > 0;
2015-01-23 12:38:29 +00:00
}
2015-02-18 16:13:23 +00:00
/**
* Renders an SQL string using the given parameters.
*
* @param string $query The SQL string
* @param mixed[] $paramsMap The query parameters
*
* @return string The rendered SQL string
2015-02-18 16:13:23 +00:00
**/
function render (&$query, &$paramsMap = NULL)
{
if (isset ($paramsMap) && is_array ($paramsMap) && count ($paramsMap) > 0)
{
$i = 0;
$params = [];
foreach ($paramsMap as $key => $value)
$params[$key] = $this->renderValue ($value);
$replaceFunc = function ($matches) use (&$params, &$i)
{
$key = substr ($matches[0], 1);
if (strlen ($key) == 0)
$key = $i++;
if (isset ($params[$key]))
return $params[$key];
return '#'. $key;
};
return preg_replace_callback ('/#\w*/', $replaceFunc, $query);
}
else
return $query;
}
/**
* Gets an SQL respresentation from a PHP value.
*
* @param mixed $value The value
*
* @return string The SQL value
**/
2015-02-18 16:13:23 +00:00
function renderValue ($value)
{
if ($value !== NULL)
switch (get_type ($value))
{
case TYPE_BOOLEAN:
return ($value) ? 'TRUE' : 'FALSE';
case TYPE_STRING:
return '\'' . $this->conn->escape_string ($value) . '\'';
case TYPE_DATE:
return strftime ('\'%Y-%m-%d\'', $value->getTimestamp ());
case TYPE_TIME:
return strftime ('\'%T\'', $value->getTimestamp ());
case TYPE_DATE_TIME:
return strftime ('\'%Y-%m-%d %T\'', $value->getTimestamp ());
default:
return '\'' . $this->conn->escape_string ($value) . '\'';
2015-02-18 16:13:23 +00:00
}
else
return 'NULL';
}
2015-01-23 12:38:29 +00:00
}
?>