Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 deletions src/Database/Barry/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -1017,12 +1017,7 @@ private function executeDataCasting(string $name): mixed
if (is_object($value)) {
return (object) $value;
}
return json_decode(
$value,
false,
512,
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_IGNORE
);
return $this->parseToJson($value);
}

if ($type === "array") {
Expand All @@ -1032,14 +1027,25 @@ private function executeDataCasting(string $name): mixed
if (is_object($value)) {
return (array) $value;
}
return json_decode(
$value,
true,
512,
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_IGNORE
);
return $this->parseToJson($value);
}

return $this->attributes[$name];
}

/**
* Parse value to json
*
* @param string $value
* @return void
*/
private function parseToJson($value)
{
return json_decode(
$value,
false,
512,
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_IGNORE
);
}
}
14 changes: 13 additions & 1 deletion src/Database/Exception/QueryBuilderException.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,17 @@

class QueryBuilderException extends ErrorException
{
// Empty
protected string $query;

public function __construct(
string $message,
string $query = '',
int $code = 0,
int $severity = E_ERROR,
?string $filename = null,
?int $line = null
) {
parent::__construct($message, $code, $severity, $filename, $line);
$this->query = $query;
}
}
142 changes: 82 additions & 60 deletions src/Database/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Bow\Support\Str;
use JsonSerializable;
use PDO;
use PDOException;
use PDOStatement;

class QueryBuilder implements JsonSerializable
Expand Down Expand Up @@ -112,6 +113,13 @@ class QueryBuilder implements JsonSerializable
*/
protected string $adapter = '';

/**
* Determine the last sql query
*
* @var string|null
*/
protected ?string $last_query = null;

/**
* QueryBuilder Constructor
*
Expand Down Expand Up @@ -170,16 +178,21 @@ public function as(string $as): QueryBuilder
* WHERE column1 $comparator $value|column
*
* @param string $where
* @param array $data
* @return QueryBuilder
*/
public function whereRaw(string $where): QueryBuilder
public function whereRaw(string $where, array $data = []): QueryBuilder
{
if ($this->where == null) {
$this->where = $where;
} else {
$this->where .= ' and ' . $where;
}

if (!empty($data)) {
$this->where_data_binding = array_merge(array_values($data), $this->where_data_binding);
}

return $this;
}

Expand All @@ -189,16 +202,21 @@ public function whereRaw(string $where): QueryBuilder
* WHERE column1 $comparator $value|column
*
* @param string $where
* @param array $data
* @return QueryBuilder
*/
public function orWhereRaw(string $where): QueryBuilder
public function orWhereRaw(string $where, array $data = []): QueryBuilder
{
if ($this->where == null) {
$this->where = $where;
} else {
$this->where .= ' or ' . $where;
}

if (!empty($data)) {
$this->where_data_binding = array_merge(array_values($data), $this->where_data_binding);
}

return $this;
}

Expand All @@ -217,8 +235,7 @@ public function orWhere(string $column, mixed $comparator = '=', mixed $value =
{
if (is_null($this->where)) {
throw new QueryBuilderException(
'This function can not be used without a where before.',
E_ERROR
'This function can not be used without a where before.'
);
}

Expand Down Expand Up @@ -252,13 +269,12 @@ public function where(
}

if ($value === null) {
throw new QueryBuilderException('Unresolved comparison value', E_ERROR);
throw new QueryBuilderException('Unresolved comparison value');
}

if (!in_array(Str::lower($boolean), ['and', 'or'])) {
throw new QueryBuilderException(
'The bool ' . $boolean . ' not accepted',
E_ERROR
'The bool ' . $boolean . ' not accepted'
);
}

Expand Down Expand Up @@ -719,8 +735,7 @@ public function andOn(string $first, $comparator = '=', $second = null): QueryBu
{
if (is_null($this->join)) {
throw new QueryBuilderException(
'The inner join clause is already initialized.',
E_ERROR
'The inner join clause is already initialized.'
);
}

Expand Down Expand Up @@ -750,7 +765,6 @@ public function orOn(string $first, $comparator = '=', $second = null): QueryBui
if (is_null($this->join)) {
throw new QueryBuilderException(
'The inner join clause is already initialized.',
E_ERROR
);
}

Expand Down Expand Up @@ -889,13 +903,8 @@ private function aggregate($aggregate, $column): mixed
}
}

$statement = $this->connection->prepare($sql);

$this->bind($statement, $this->where_data_binding);
$statement = $this->execute($sql, $this->where_data_binding);

$statement->execute();

$this->triggerQueryEvent($sql, $this->where_data_binding);
$this->where_data_binding = [];

if ($statement->rowCount() > 1) {
Expand Down Expand Up @@ -926,7 +935,9 @@ private function bind(PDOStatement $pdo_statement, array $bindings = []): void
// Named placeholders
foreach ($bindings as $key => $value) {
$param = PDO::PARAM_STR;
if (is_null($value) || strtolower((string) $value) === 'null') {
if (is_array($value) || is_object($value)) {
$value = json_encode($value);
} elseif (is_null($value) || strtolower((string) $value) === 'null') {
$param = PDO::PARAM_NULL;
} elseif (is_int($value)) {
$param = PDO::PARAM_INT;
Expand All @@ -945,7 +956,9 @@ private function bind(PDOStatement $pdo_statement, array $bindings = []): void
$i = 1;
foreach ($bindings as $value) {
$param = PDO::PARAM_STR;
if (is_null($value) || strtolower((string) $value) === 'null') {
if (is_array($value) || is_object($value)) {
$value = json_encode($value);
} elseif (is_null($value) || strtolower((string) $value) === 'null') {
$param = PDO::PARAM_NULL;
} elseif (is_int($value)) {
$param = PDO::PARAM_INT;
Expand Down Expand Up @@ -1110,17 +1123,12 @@ public function get(array $columns = []): array|object|null
// Execution of request.
$sql = $this->toSql();

$statement = $this->connection->prepare($sql);

$this->bind($statement, $this->where_data_binding);

$statement->execute();
$statement = $this->execute($sql, $this->where_data_binding);

$data = $statement->fetchAll();

$statement->closeCursor();

$this->triggerQueryEvent($sql, $this->where_data_binding);
$this->where_data_binding = [];

if (!$this->first) {
Expand Down Expand Up @@ -1215,20 +1223,14 @@ public function update(array $data = []): int
$sql .= ' where ' . $this->where;

$this->where = null;

$this->where_data_binding = array_merge(array_values($data), $this->where_data_binding);
}

$statement = $this->connection->prepare($sql);
$this->where_data_binding = array_merge(array_values($data), $this->where_data_binding);

$this->bind($statement, $this->where_data_binding);

// Execution of the request
$statement->execute();
$statement = $this->execute($sql, $this->where_data_binding);

$result = $statement->rowCount();

$this->triggerQueryEvent($sql, $this->where_data_binding);
$this->where_data_binding = [];

return (int) $result;
Expand Down Expand Up @@ -1265,15 +1267,10 @@ public function delete(): int
$this->where = null;
}

$statement = $this->connection->prepare($sql);

$this->bind($statement, $this->where_data_binding);

$statement->execute();
$statement = $this->execute($sql, $this->where_data_binding);

$result = $statement->rowCount();

$this->triggerQueryEvent($sql, $this->where_data_binding);
$this->where_data_binding = [];

return (int) $result;
Expand All @@ -1292,6 +1289,18 @@ public function increment(string $column, int $step = 1): int
return $this->incrementAction($column, $step);
}

/**
* Decrement column
*
* @param string $column
* @param int $step
* @return int
*/
public function decrement(string $column, int $step = 1): int
{
return $this->incrementAction($column, $step, '-');
}

/**
* Method to customize the increment and decrement methods
*
Expand All @@ -1310,27 +1319,11 @@ private function incrementAction(string $column, int $step = 1, string $directio
$this->where = null;
}

$statement = $this->connection->prepare($sql);

$this->bind($statement, $this->where_data_binding);

$statement->execute();
$statement = $this->execute($sql, $this->where_data_binding);

return (int)$statement->rowCount();
}

/**
* Decrement column
*
* @param string $column
* @param int $step
* @return int
*/
public function decrement(string $column, int $step = 1): int
{
return $this->incrementAction($column, $step, '-');
}

/**
* Allows a query with the DISTINCT clause
*
Expand Down Expand Up @@ -1371,10 +1364,14 @@ public function truncate(): bool
$sql = 'truncate table ' . $this->table . ';';
}

$this->last_query = $sql;

$result = (bool) $this->connection->exec($sql);

$this->triggerQueryEvent($sql, []);

$this->last_query = $sql;

return $result;
}

Expand Down Expand Up @@ -1422,7 +1419,6 @@ public function insert(array $values): int
if ($single_item_structure_detected && $mixture_item_structure_detected) {
throw new QueryBuilderException(
'Mixed structure detected in insert data. Cannot mix single and multiple row inserts.',
E_ERROR
);
}

Expand Down Expand Up @@ -1455,15 +1451,39 @@ private function insertOne(array $values): int

$sql .= '(' . implode(', ', $this->add2points($fields, true)) . ');';

$statement = $this->execute($sql, $values);

return (int) $statement->rowCount();
}

/**
* Execute statement
*
* @param string $sql
* @param array $bindings
* @return PDOStatement
*/
private function execute(string $sql, array $bindings = []): PDOStatement
{
$this->last_query = $sql;

$statement = $this->connection->prepare($sql);

$this->bind($statement, $values);
$this->bind($statement, $bindings);

$statement->execute();
try {
$statement->execute();

$this->triggerQueryEvent($sql, $values);
$this->triggerQueryEvent($sql, $bindings);
} catch (\Exception $e) {
throw new QueryBuilderException(
'Error executing query: ' . $e->getMessage(),
$this->last_query,
E_ERROR,
);
}

return (int) $statement->rowCount();
return $statement;
}

/**
Expand All @@ -1475,6 +1495,8 @@ public function drop(): bool
{
$sql = 'drop table ' . $this->table;

$this->last_query = $sql;

$result = (bool) $this->connection->exec($sql);

$this->triggerQueryEvent($sql, []);
Expand Down
Loading
Loading