Skip to content

Commit

Permalink
Create a mysql driver
Browse files Browse the repository at this point in the history
  • Loading branch information
duncan3dc committed Aug 12, 2017
1 parent e2587e6 commit ff01d38
Show file tree
Hide file tree
Showing 9 changed files with 645 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,13 @@ environment:
- PHP_VERSION: 7.0
- PHP_VERSION: 7.1

services:
- mysql

init:
- SET DUNCAN3DC_CACHE=c:\duncan3dc
- SET MYSQL_PWD=Password12!
- SET PATH=C:\Program Files\MySQL\MySQL Server 5.7\bin\;%PATH%;

cache:
- '%DUNCAN3DC_CACHE%'
Expand Down
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ script:
after_success:
- vendor/bin/coveralls

services:
- mysql

git:
depth: 5

Expand Down
44 changes: 44 additions & 0 deletions src/Driver/Mysql/Result.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace duncan3dc\Sql\Driver\Mysql;

use duncan3dc\Sql\Driver\ResultInterface;

class Result implements ResultInterface
{

/**
* Create a new instance.
*
* @param mixed $result Something returned by \Mysqli::query()
*/
public function __construct($result)
{
$this->result = $result;
}


/**
* Fetch the next row from the result set.
*
* @return array|null
*/
public function getNextRow()
{
return $this->result->fetch_assoc();
}


/**
* Free the memory used by the result resource.
*
* @return void
*/
public function free()
{
if ($this->result instanceof \mysqli_result) {
$this->result->free();
$this->result = null;
}
}
}
238 changes: 238 additions & 0 deletions src/Driver/Mysql/Server.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
<?php

namespace duncan3dc\Sql\Driver\Mysql;

use duncan3dc\Sql\Driver\ServerInterface;
use duncan3dc\Sql\Exceptions\QueryException;

class Server implements ServerInterface
{
/**
* @var \Mysqli $mysqli The connection to the database server.
*/
private $mysqli;

/**
* @var string $hostname The host or ip address of the database server.
*/
private $hostname;

/**
* @var string $username The user to authenticate with.
*/
private $username;

/**
* @var string $password The password to authenticate with.
*/
private $password;

/**
* @var string $database The database to use.
*/
private $database;

/**
* @var string $charset The character set to use.
*/
private $charset;

/**
* @var string $timezone The timezone to use.
*/
private $timezone;


/**
* Create a new instance.
*
* @param string $hostname The host or ip address of the database server
* @param string $username The user to authenticate with
* @param string $password The password to authenticate with
*/
public function __construct($hostname, $username, $password)
{
$this->hostname = $hostname;
$this->username = $username;
$this->password = $password;
}


/**
* Set the current active database.
*
* @param string $database The database to use
*
* @return $this
*/
public function setDatabase($database)
{
$this->database = $database;

if ($this->mysqli) {
if (!$this->mysqli->select_db($this->database)) {
throw new QueryException("Failed to switch to database {$database}");
}
}

return $this;
}


/**
* Set the character set to use/
*
* @param string $charset The character set to use
*
* @return $this
*/
public function setCharset($charset)
{
$this->charset = $charset;

if ($this->mysqli) {
$this->mysqli->set_charset($this->charset);
}

return $this;
}


/**
* Set the timezone to use.
*
* @param string $time The timezone set to use
*
* @return $this
*/
public function setTimezone(string $timezone = "")
{
if ($timezone === "") {
$timezone = ini_get("date.timezone");
}

$this->timezone = $timezone;

if ($this->mysqli) {
$statement = $this->mysqli->prepare("SET time_zone = ?");
$statement->bind_param("s", $this->timezone);
if (!$statement->execute()) {
throw new QueryException($this->getErrorMessage(), $this->getErrorCode());
}
$statement->close();
}

return $this;
}


/**
* Connect to the database using the previously supplied credentials.
*
* @return bool
*/
public function connect(): bool
{
$this->mysqli = new \Mysqli($this->hostname, $this->username, $this->password);
if ($this->mysqli->connect_error) {
return false;
}

$this->mysqli->options(\MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);

if ($this->charset !== null) {
$this->setCharset($this->charset);
}

if ($this->timezone !== null) {
$this->setTimezone($this->timezone);
}

if ($this->database !== null) {
$this->setDatabase($this->database);
}

return true;
}


/**
* Run a query.
*
* @param string $query The query to run
* @param array $params The parameters to substitute in the query string
* @param string $preparedQuery A simulated prepared query (if the server doesn't support prepared statements)
*
* @return ResultInterface|null Successful statements should return a Result instance
*/
public function query(string $query, array $params, string $preparedQuery)
{
$result = $this->mysqli->query($preparedQuery);

if ($result) {
return new Result($result);
}
}


/**
* Quote the supplied string with the relevant characters used by the database driver.
*
* @param string $value The string to quote
*
* @return string The quoted string
*/
public function quoteValue(string $value): string
{
return "'" . $this->mysqli->real_escape_string($value) . "'";
}


/**
* Get the error code of the last error.
*
* @return mixed
*/
public function getErrorCode()
{
if ($this->mysqli->connect_errno) {
return $this->mysqli->connect_errno;
}

return $this->mysqli->errno;
}


/**
* Get the error message text of the last error.
*
* @return string
*/
public function getErrorMessage(): string
{
if ($this->mysqli->connect_error) {
return $this->mysqli->connect_error;
}

return $this->mysqli->error;
}


/**
* Close the sql connection.
*
* @return bool
*/
public function disconnect(): bool
{
if (!$this->mysqli || $this->mysqli->connect_error) {
return true;
}

$result = $this->mysqli->close();

$this->mysqli = null;

return $result;
}
}
22 changes: 22 additions & 0 deletions src/Driver/ResultInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace duncan3dc\Sql\Driver;

interface ResultInterface
{

/**
* Internal method to fetch the next row from the result set.
*
* @return array|null
*/
public function getNextRow();


/**
* Free the memory used by the result resource.
*
* @return void
*/
public function free();
}
60 changes: 60 additions & 0 deletions src/Driver/ServerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace duncan3dc\Sql\Driver;

interface ServerInterface
{

/**
* Connect to the database using the previously supplied credentials.
*
* @return bool
*/
public function connect(): bool;


/**
* Run a query.
*
* @param string $query The query to run
* @param array $params The parameters to substitute in the query string
* @param string $preparedQuery A simulated prepared query (if the server doesn't support prepared statements)
*
* @return ResultInterface|null Successful statements should return a Result instance
*/
public function query(string $query, array $params, string $preparedQuery);


/**
* Quote the supplied string with the relevant characters used by the database driver.
*
* @param string $table The string to quote
*
* @return string The quoted string
*/
public function quoteValue(string $string): string;


/**
* Get the error code of the last error.
*
* @return mixed
*/
public function getErrorCode();


/**
* Get the error message text of the last error.
*
* @return string
*/
public function getErrorMessage(): string;


/**
* Close the sql connection.
*
* @return bool
*/
public function disconnect(): bool;
}

0 comments on commit ff01d38

Please sign in to comment.