3 Commits
1.0.4 ... 1.0.7

Author SHA1 Message Date
Gregory Letellier
293eb9e555 cast extended models when loading from database 2025-01-09 12:00:25 +01:00
Gregory Letellier
d961d2a80f ajout model de type readonly pour une requête de select uniquement 2024-06-18 13:02:18 +02:00
Gregory Letellier
0db845a116 add orWhere 2023-11-15 11:50:15 +01:00
3 changed files with 98 additions and 35 deletions

View File

@@ -12,20 +12,27 @@ class Model implements JsonSerializable
protected string $connection = "";
protected string $pk;
private bool $new;
private bool $ro;
public function __construct()
public function __construct($ro = false)
{
$this->new = true;
$this->values = array();
$this->updated = array();
$this->pk = "id";
$this->ro = $ro;
$this->initTable();
}
private function initTable(): void
{
if ($this->table == "") {
$this->table = $this->getDefaultTableName();
if (!$this->ro) {
if ($this->table == "") {
$this->table = $this->getDefaultTableName();
}
} else {
$this->table = "ReadOnlyModel";
$this->pk = "__idpk";
}
}
@@ -77,7 +84,7 @@ class Model implements JsonSerializable
public function find(mixed $key): mixed
{
$qb = $this->newQueryBuilder();
$qb = $this->newQueryBuilder(get_class($this));
$find = $qb->find($key);
if ($find !== null) {
$this->fillData($find->getValues());
@@ -89,27 +96,29 @@ class Model implements JsonSerializable
public function save(): bool
{
$ret = false;
$qb = $this->newQueryBuilder();
if ($this->new) {
$query = $qb->getPreparedQuery($this->values);
$id = Connection::getInstance($this->connection)->insertQuery($query);
if ($id !== false) {
$this->values[$this->pk] = $id;
$this->new = false;
$ret = true;
}
} else {
if (isset($this->values[$this->pk])) {
if (count($this->updated) > 0) {
$data = [];
$data[$this->pk] = $this->values[$this->pk];
foreach ($this->updated as $updatecol) {
$data[$updatecol] = $this->values[$updatecol];
}
$query = $qb->getPreparedQuery($data, false);
$ret = Connection::getInstance($this->connection)->updateQuery($query);
if ($ret) {
$this->updated = [];
if (!$this->ro) {
$qb = $this->newQueryBuilder("");
if ($this->new) {
$query = $qb->getPreparedQuery($this->values);
$id = Connection::getInstance($this->connection)->insertQuery($query);
if ($id !== false) {
$this->values[$this->pk] = $id;
$this->new = false;
$ret = true;
}
} else {
if (isset($this->values[$this->pk])) {
if (count($this->updated) > 0) {
$data = [];
$data[$this->pk] = $this->values[$this->pk];
foreach ($this->updated as $updatecol) {
$data[$updatecol] = $this->values[$updatecol];
}
$query = $qb->getPreparedQuery($data, false);
$ret = Connection::getInstance($this->connection)->updateQuery($query);
if ($ret) {
$this->updated = [];
}
}
}
}
@@ -117,9 +126,9 @@ class Model implements JsonSerializable
return $ret;
}
public function newQueryBuilder(): QueryBuilder
public function newQueryBuilder($className): QueryBuilder
{
return new QueryBuilder($this->table, $this->pk, $this->connection);
return new QueryBuilder($this->table, $this->pk, $this->connection, $className);
}
public function __set($name, $value): void
@@ -139,10 +148,16 @@ class Model implements JsonSerializable
}
}
public static function getClassName()
{
return static::class;
}
public static function q(): QueryBuilder
{
$cls = self::getClassName();
$ist = new static();
return $ist->newQueryBuilder();
return $ist->newQueryBuilder($cls);
}
public function __get($name): mixed

View File

@@ -6,9 +6,11 @@ class QueryBuilder
{
protected array $columns;
protected array $wheres;
protected array $orwheres;
protected array $orders;
protected array $groupby;
protected string $table;
protected string $classname;
protected string $connection;
protected string $pk;
protected ?int $take;
@@ -16,8 +18,12 @@ class QueryBuilder
protected string $raw_query;
protected bool $distinct;
public function __construct($table, $pk = "id", $connection = "")
public const MODE_AND = 0;
public const MODE_OR = 1;
public function __construct($table, $pk = "id", $connection = "", $classname = "")
{
$this->classname = $classname;
$this->table = $table;
$this->pk = $pk;
$this->connection = $connection;
@@ -28,6 +34,7 @@ class QueryBuilder
{
$this->columns = [];
$this->wheres = [];
$this->orwheres = [];
$this->orders = [];
$this->groupby = [];
$this->offset = null;
@@ -128,12 +135,28 @@ class QueryBuilder
return $this;
}
public function orWhere($condition, $operator, $value = null)
{
if ($value === null) {
$this->orwheres[] = new Expression($condition, "=", $operator);
} else {
$this->orwheres[] = new Expression($condition, $operator, $value);
}
return $this;
}
public function whereRaw(string $raw)
{
$this->wheres[] = $raw;
return $this;
}
public function orWhereRaw(string $raw)
{
$this->orwheres[] = $raw;
return $this;
}
public function find($id): mixed
{
$this->reset();
@@ -187,7 +210,12 @@ class QueryBuilder
{
$ret = array();
foreach ($data as $row) {
$model = new Model();
if ($this->classname != "") {
$model = new $this->classname();
} else {
$model = new Model();
}
$ret[] = $model->setPk($this->pk)->setTable($this->table)->fillData($row);
}
return new Collection($ret);
@@ -213,10 +241,16 @@ class QueryBuilder
$query = "SELECT " . $distinct . " " . $columns . " FROM " . $this->table ;
$where = $this->getWhere();
$Orwhere = $this->getWhere(QueryBuilder::MODE_OR);
$this->fillData($ret);
if ($where != "" && $Orwhere != "") {
$Orwhere = " OR " . $Orwhere;
}
if ($where != "") {
$query .= " WHERE " . $where;
$query .= " WHERE " . $where . $Orwhere;
}
$query .= $this->getClause("GROUP By", $this->groupby);
@@ -229,7 +263,7 @@ class QueryBuilder
private function fillData(Query &$query): void
{
foreach ($this->wheres as $expression) {
foreach (array_merge($this->wheres, $this->orwheres) as $expression) {
if ($expression instanceof Expression) {
if ($expression->hasData()) {
$query->addData($expression->getValue());
@@ -238,10 +272,18 @@ class QueryBuilder
}
}
private function getWhere(): string
private function getWhere(int $mode = QueryBuilder::MODE_AND): string
{
$where = "";
foreach ($this->wheres as $expression) {
$collection = match ($mode) {
QueryBuilder::MODE_AND => $this->wheres,
QueryBuilder::MODE_OR => $this->orwheres,
};
$keyword = match ($mode) {
QueryBuilder::MODE_AND => " AND ",
QueryBuilder::MODE_OR => " OR ",
};
foreach ($collection as $expression) {
$sw = "";
if ($expression instanceof Expression) {
$sw = $expression->raw();
@@ -252,7 +294,7 @@ class QueryBuilder
}
}
if ($where != "" && $sw != "") {
$where .= " AND ";
$where .= " $keyword ";
}
$where .= $sw;
}

View File

@@ -98,6 +98,10 @@ test("querybuilder", function() {
$qb->reset();
$rows = $qb->whereNotNull("col1")->get();
expect(count($rows))->toBe(2);
$qb->reset();
$rows = $qb->where("id",1)->orWhere("id",2)->get();
expect(count($rows))->toBe(2);
});
test("extending model",function()
@@ -112,6 +116,8 @@ test("extending model",function()
$row = $qbs->find(1);
expect($row->id)->toBe(1);
expect($row->col1)->toBe("test");
expect($row)->toBeInstanceOf(Test::class);
});
test("order by", function(){