Skip to content

Commit

Permalink
DatabaseConnection interface introduced
Browse files Browse the repository at this point in the history
  • Loading branch information
ilijastuden committed Sep 24, 2015
1 parent d094ed6 commit 1bc578b
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 63 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ if ($database_link->connect_error) {

$connection = new Connection($database_link);

foreach ($this->connection->advancedExecute('SELECT * FROM `writers` ORDER BY `id`', null, Connection::LOAD_ALL_ROWS, Connection::RETURN_OBJECT_BY_CLASS, '\ActiveCollab\DatabaseConnection\Test\Fixture\Writer') as $writer) {
foreach ($this->connection->advancedExecute('SELECT * FROM `writers` ORDER BY `id`', null, ConnectionInterface::LOAD_ALL_ROWS, ConnectionInterface::RETURN_OBJECT_BY_CLASS, '\ActiveCollab\DatabaseConnection\Test\Fixture\Writer') as $writer) {
print '#' . $writer->getId() . ' ' . $writer->getName() . ' (' . $writer->getBirthday()->format('Y-m-d') . ')';
}
```
Expand All @@ -136,7 +136,7 @@ if ($database_link->connect_error) {

$connection = new Connection($database_link);

foreach ($this->connection->advancedExecute('SELECT * FROM `writers` ORDER BY `id`', null, Connection::LOAD_ALL_ROWS, Connection::RETURN_OBJECT_BY_FIELD, 'type') as $writer) {
foreach ($this->connection->advancedExecute('SELECT * FROM `writers` ORDER BY `id`', null, ConnectionInterface::LOAD_ALL_ROWS, ConnectionInterface::RETURN_OBJECT_BY_FIELD, 'type') as $writer) {
print '#' . $writer->getId() . ' ' . $writer->getName() . ' (' . $writer->getBirthday()->format('Y-m-d') . ')';
}
```
Expand Down
57 changes: 13 additions & 44 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,8 @@
/**
* @package ActiveCollab\DatabaseConnection
*/
class Connection
class Connection implements ConnectionInterface
{
/**
* Load mode
*
* LOAD_ALL_ROWS - Load all rows
* LOAD_FIRST_ROW - Limit result set to first row and load it
* LOAD_FIRST_COLUMN - Return content of first column
* LOAD_FIRST_CELL - Load only first cell of first row
*/
const LOAD_ALL_ROWS = 0;
const LOAD_FIRST_ROW = 1;
const LOAD_FIRST_COLUMN = 2;
const LOAD_FIRST_CELL = 3;

/**
* Return method for DB results
*
* RETURN_ARRAY - Return fields as associative array
* RETURN_OBJECT_BY_CLASS - Create new object instance and hydrate it
* RETURN_OBJECT_BY_FIELD - Read class from record field, create instance
* and hydrate it
*/
const RETURN_ARRAY = 0;
const RETURN_OBJECT_BY_CLASS = 1;
const RETURN_OBJECT_BY_FIELD = 2;

/**
* Insert mode, used by insert() method
*/
const INSERT = 'INSERT';
const REPLACE = 'REPLACE';

/**
* @var mysqli
*/
Expand All @@ -69,7 +38,7 @@ public function __construct(mysqli $link)
*/
public function execute()
{
return $this->executeBasedOnFunctionArguments(func_get_args(), self::LOAD_ALL_ROWS);
return $this->executeBasedOnFunctionArguments(func_get_args(), ConnectionInterface::LOAD_ALL_ROWS);
}

/**
Expand All @@ -79,7 +48,7 @@ public function execute()
*/
public function executeFirstRow()
{
return $this->executeBasedOnFunctionArguments(func_get_args(), self::LOAD_FIRST_ROW);
return $this->executeBasedOnFunctionArguments(func_get_args(), ConnectionInterface::LOAD_FIRST_ROW);
}

/**
Expand All @@ -89,7 +58,7 @@ public function executeFirstRow()
*/
public function executeFirstColumn()
{
return $this->executeBasedOnFunctionArguments(func_get_args(), self::LOAD_FIRST_COLUMN);
return $this->executeBasedOnFunctionArguments(func_get_args(), ConnectionInterface::LOAD_FIRST_COLUMN);
}

/**
Expand All @@ -99,7 +68,7 @@ public function executeFirstColumn()
*/
public function executeFirstCell()
{
return $this->executeBasedOnFunctionArguments(func_get_args(), self::LOAD_FIRST_CELL);
return $this->executeBasedOnFunctionArguments(func_get_args(), ConnectionInterface::LOAD_FIRST_CELL);
}

/**
Expand Down Expand Up @@ -131,11 +100,11 @@ private function executeBasedOnFunctionArguments($arguments, $load_mode)
* @return mixed
* @throws Query
*/
public function advancedExecute($sql, $arguments = null, $load_mode = self::LOAD_ALL_ROWS, $return_mode = self::RETURN_ARRAY, $return_class_or_field = null, array $constructor_arguments = null)
public function advancedExecute($sql, $arguments = null, $load_mode = ConnectionInterface::LOAD_ALL_ROWS, $return_mode = ConnectionInterface::RETURN_ARRAY, $return_class_or_field = null, array $constructor_arguments = null)
{
if ($return_mode == self::RETURN_OBJECT_BY_CLASS && empty($return_class_or_field)) {
if ($return_mode == ConnectionInterface::RETURN_OBJECT_BY_CLASS && empty($return_class_or_field)) {
throw new InvalidArgumentException('Class is required');
} elseif ($return_mode == self::RETURN_OBJECT_BY_FIELD && empty($return_class_or_field)) {
} elseif ($return_mode == ConnectionInterface::RETURN_OBJECT_BY_FIELD && empty($return_class_or_field)) {
throw new InvalidArgumentException('Field name is required');
}

Expand All @@ -148,13 +117,13 @@ public function advancedExecute($sql, $arguments = null, $load_mode = self::LOAD
if ($query_result instanceof mysqli_result) {
if ($query_result->num_rows > 0) {
switch ($load_mode) {
case self::LOAD_FIRST_ROW:
case ConnectionInterface::LOAD_FIRST_ROW:
$result = $query_result->fetch_assoc();
$this->getDefaultCaster()->castRowValues($result);

break;

case self::LOAD_FIRST_COLUMN:
case ConnectionInterface::LOAD_FIRST_COLUMN:
$result = [];

while ($row = $query_result->fetch_assoc()) {
Expand All @@ -166,7 +135,7 @@ public function advancedExecute($sql, $arguments = null, $load_mode = self::LOAD

break;

case self::LOAD_FIRST_CELL:
case ConnectionInterface::LOAD_FIRST_CELL:
$result = null;

foreach ($query_result->fetch_assoc() as $k => $v) {
Expand Down Expand Up @@ -201,15 +170,15 @@ public function advancedExecute($sql, $arguments = null, $load_mode = self::LOAD
* @return int
* @throws InvalidArgumentException
*/
public function insert($table, array $field_value_map, $mode = self::INSERT)
public function insert($table, array $field_value_map, $mode = ConnectionInterface::INSERT)
{
if (empty($field_value_map)) {
throw new InvalidArgumentException("Values array can't be empty");
}

$mode = strtoupper($mode);

if ($mode != self::INSERT && $mode != self::REPLACE) {
if ($mode != ConnectionInterface::INSERT && $mode != ConnectionInterface::REPLACE) {
throw new InvalidArgumentException("Mode '$mode' is not a valid insert mode");
}

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

namespace ActiveCollab\DatabaseConnection;

use ActiveCollab\DatabaseConnection\Exception\Query;
use ActiveCollab\DatabaseConnection\Result\Result;
use InvalidArgumentException;
use Closure;
use Exception;

/**
* @package ActiveCollab\DatabaseConnection
*/
interface ConnectionInterface
{
/**
* Load mode
*
* LOAD_ALL_ROWS - Load all rows
* LOAD_FIRST_ROW - Limit result set to first row and load it
* LOAD_FIRST_COLUMN - Return content of first column
* LOAD_FIRST_CELL - Load only first cell of first row
*/
const LOAD_ALL_ROWS = 0;
const LOAD_FIRST_ROW = 1;
const LOAD_FIRST_COLUMN = 2;
const LOAD_FIRST_CELL = 3;

/**
* Return method for DB results
*
* RETURN_ARRAY - Return fields as associative array
* RETURN_OBJECT_BY_CLASS - Create new object instance and hydrate it
* RETURN_OBJECT_BY_FIELD - Read class from record field, create instance
* and hydrate it
*/
const RETURN_ARRAY = 0;
const RETURN_OBJECT_BY_CLASS = 1;
const RETURN_OBJECT_BY_FIELD = 2;

/**
* Insert mode, used by insert() method
*/
const INSERT = 'INSERT';
const REPLACE = 'REPLACE';

/**
* Execute a query and return a result
*
* @return Result|true|null
*/
public function execute();

/**
* Return first row that provided SQL query returns
*
* @return array
*/
public function executeFirstRow();

/**
* Return value from the first cell of each column that provided SQL query returns
*
* @return array
*/
public function executeFirstColumn();

/**
* Return value from the first cell of the first row that provided SQL query returns
*
* @return mixed
*/
public function executeFirstCell();

/**
* Prepare and execute query, while letting the developer change the load and return modes
*
* @param string $sql
* @param mixed $arguments
* @param int $load_mode
* @param int $return_mode
* @param string $return_class_or_field
* @param array|null $constructor_arguments
* @return mixed
* @throws Query
*/
public function advancedExecute($sql, $arguments = null, $load_mode = self::LOAD_ALL_ROWS, $return_mode = self::RETURN_ARRAY, $return_class_or_field = null, array $constructor_arguments = null);

/**
* Insert into $table a row that is reperesented with $values (key is field name, and value is value that we need to set)
*
* @param string $table
* @param array $field_value_map
* @param string $mode
* @return int
* @throws InvalidArgumentException
*/
public function insert($table, array $field_value_map, $mode = self::INSERT);

/**
* Return last insert ID
*
* @return integer
*/
public function lastInsertId();

/**
* Update one or more rows with the given list of values for fields
*
* $conditions can be a string, or an array where first element is a patter and other elements are arguments
*
* @param string $table_name
* @param array $field_value_map
* @param string|array|null $conditions
* @return int
* @throws InvalidArgumentException
*/
public function update($table_name, array $field_value_map, $conditions = null);

/**
* Delete one or more records from the table
*
* $conditions can be a string, or an array where first element is a patter and other elements are arguments
*
* @param string $table_name
* @param string|array|null $conditions
* @return int
* @throws InvalidArgumentException
*/
public function delete($table_name, $conditions = null);

/**
* Return number of affected rows
*
* @return integer
*/
public function affectedRows();

/**
* Run body commands within a transation
*
* @param Closure $body
* @param Closure|null $on_success
* @param CLosure|null $on_error
* @throws Exception
*/
public function transact(Closure $body, $on_success = null, $on_error = null);

/**
* Begin transaction
*/
public function beginWork();

/**
* Commit transaction
*/
public function commit();

/**
* Rollback transaction
*/
public function rollback();

/**
* Return true if system is in transaction
*
* @return boolean
*/
public function inTransaction();

/**
* Return true if table named $table_name exists in the selected database
*
* @param string $table_name
* @return bool
*/
public function tableExists($table_name);

/**
* Return array of table names
*
* @return array
*/
public function getTableNames();

/**
* Drop a table named $table_name from selected database
*
* @param string $table_name
*/
public function dropTable($table_name);

/**
* Prepare SQL (replace ? with data from $arguments array)
*
* @return string
*/
public function prepare();

/**
* Prepare conditions and return them as string
*
* @param array|string|null $conditions
* @return string
*/
public function prepareConditions($conditions);

/**
* Escape string before we use it in query...
*
* @param mixed $unescaped
* @return string
* @throws InvalidArgumentException
*/
public function escapeValue($unescaped);

/**
* Escape table field name
*
* @param string $unescaped
* @return string
*/
public function escapeFieldName($unescaped);

/**
* Escape table name
*
* @param string $unescaped
* @return string
*/
public function escapeTableName($unescaped);

// ---------------------------------------------------
// Events
// ---------------------------------------------------

/**
* Set a callback that will receive every query after we run it
*
* Callback should accept two parameters: first for SQL that was ran, and second for time that it took to run
*
* @param callable|null $callback
*/
public function onLogQuery(callable $callback = null);
}
Loading

0 comments on commit 1bc578b

Please sign in to comment.