when trying to build robust database code (table locking, transactions, etc) i am always annoyed by the mass of code that needs to be done.
For example a transaction out of two prepared statements where i want to delete a user and update something about him in an "actions" table:
This is how i do it (maybe im doing it wrong?). And if i do it that way its a lot of work and annoying. So i thought automateing that stuff.
What i want is something like this:
$DB->startTransaction();
$DB->query($query);
$DB->query($query2);
$DB->query($query3);
$DB->endTransaction();
And internally the database abstraction layer ontop of mysqli will take care of table locking, prepared statements and transactions itself. Shouldn't we be able to automate this?
This is one of my attempts:
public function query($query, $table, $params = null) {
if($params == null) {
$this->connection->query("LOCK TABLES $table WRITE");
$query = str_replace("!", $table, $query);
$result = $this->connection->query($query);
$this->connection->query("UNLOCK TABLES");
return $result;
}
else {
if (!$this->checkParams($query, $params)) {
return false;
}
$this->connection->query("LOCK TABLES $table WRITE");
$query = str_replace("!", $table, $query);
$stmt = $this->connection->prepare($query);
if ($stmt != false) {
$typesString = "";
foreach ($params as $param) {
if (is_numeric($param)) {
$typesString .= "i";
} else if (is_double($param)) {
$typesString .= "d";
} else {
$typesString .= "s";
}
}
$finalParamArray = array($typesString);
$finalParamArray = array_merge($finalParamArray, $params);
call_user_func_array(array($stmt, "bind_param"), $this->ref($finalParamArray));
$this->checkStatement($stmt);
$stmt->execute();
$this->checkStatement($stmt);
$result = $stmt->get_result();
$stmt->close();
$this->connection->query("UNLOCK TABLES");
return $result;
}
$this->query("UNLOCK TABLES");
return false;
}
}
This would be callable like this:
$DB->query("DELETE FROM ! WHERE userID =?", "Users", array($userID));
I am however not feeling confident about this. I googled a bit and didn't find something like i want. So my question now is: Is something like i want actually possible (well it should be)? Am i doing it wrong?
EDIT: I also have 2 other attempts of doing this, which look MUCH MORE complicated (300+ lines of code). I can post them as well, if you want. I am still however not satisfied with them and not confident if this is actually correct!