a SQL implementation:
abstract class SQL
{
abstract public function connect();
abstract public function query($sql);
abstract public function queryAndReturn($sql);
abstract public function startTransaction();
abstract public function commit();
abstract public function rollback();
}
class MySQL extends SQL
{
public function connect()
{
mysql_connect (....)
}
public function query($sql)
{
return mysql_query($sql);
}
public function queryAndReturn()
{
$result = $this->query($sql);
$results = [];
whilte ($item = mysql_fetch_assoc($result))
{
$results[] = $item;
}
return $results;
}
public function startTransaction()
{
return $this->query('START TRANSACTION');
}
public function commit()
{
return $this->query('COMMIT');
}
public function rollback()
{
return $this->query('ROLLBACK');
}
public function runAtomicFunction (\Closure $function)
{
try
{
$this->query('SET autocommit=0');
$this->startTransaction();
$function();
$this->commit();
}
catch (Exception $e)
{
$this->rollback();
}
}
}
the last 4 methods is something like "transaction" so lets move them to another class:
class MySQL extends SQL
{
public function connect()
{
mysql_connect (....)
}
public function query($sql)
{
return mysql_query($sql);
}
public function queryAndReturn()
{
$result = $this->query($sql);
$results = [];
whilte ($item = mysql_fetch_assoc($result))
{
$results[] = $item;
}
return $results;
}
public function getNewTransaction()
{
return new Transaction($this);
}
}
class Transaction
{
private $db;
public function __construct(Sql $db)
{
$this->db = $db;
}
public function startTransaction()
{
return $this->db->query('START TRANSACTION');
}
public function commit()
{
return $this->db->query('COMMIT');
}
public function rollback()
{
return $this->db->query('ROLLBACK');
}
public function runAtomicFunction (\Closure $function)
{
try
{
$this->db->query('SET autocommit=0');
$this->db->startTransaction();
$function();
$this->db->commit();
}
catch (Exception $e)
{
$this->db->rollback();
}
}
}
$sql = new MySQL();
$t = $sql->getNewTransaction();
$t->runAtomicFunction(...);
this is all good, but this is when circular references enter. Sql
depends on Transaction
and vice versa. Is this a sign that I must not separate the transaction?