Init
This commit is contained in:
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
vendor/
|
||||||
|
.phpunit.result.cache
|
||||||
|
!var/cache/.gitkeep
|
||||||
|
var/cache/*
|
||||||
|
!var/log/.gitkeep
|
||||||
|
var/log/*
|
||||||
|
.env
|
||||||
6
.phpcs.xml
Normal file
6
.phpcs.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ruleset>
|
||||||
|
<rule ref="PSR12"/>
|
||||||
|
<file>src/</file>
|
||||||
|
<arg name="colors"/>
|
||||||
|
</ruleset>
|
||||||
45
Makefile
Normal file
45
Makefile
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
COMPOSER ?= $(shell which composer)
|
||||||
|
|
||||||
|
.PHONY: init
|
||||||
|
init:
|
||||||
|
$(RM) -r .git
|
||||||
|
git init
|
||||||
|
|
||||||
|
.PHONY: up
|
||||||
|
up: install-vendor
|
||||||
|
|
||||||
|
.PHONY: install-vendor
|
||||||
|
install-vendor:
|
||||||
|
$(PHP) $(COMPOSER) install
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: clean-vendor clean-composerlock
|
||||||
|
|
||||||
|
.PHONY: clean-vendor
|
||||||
|
clean-vendor:
|
||||||
|
$(RM) -r ./vendor
|
||||||
|
|
||||||
|
.PHONY: clean-composerlock
|
||||||
|
clean-composerlock:
|
||||||
|
$(RM) composer.lock
|
||||||
|
|
||||||
|
.PHONY: unit-tests
|
||||||
|
unit-tests:
|
||||||
|
./vendor/bin/pest
|
||||||
|
|
||||||
|
.PHONY: unit-tests-coverage
|
||||||
|
unit-tests-coverage:
|
||||||
|
XDEBUG_MODE=coverage ./vendor/bin/pest --coverage
|
||||||
|
|
||||||
|
.PHONY: mutation
|
||||||
|
mutation:
|
||||||
|
./vendor/bin/infection --test-framework=pest --show-mutations
|
||||||
|
|
||||||
|
.PHONY: code-sniffer
|
||||||
|
code-sniffer:
|
||||||
|
./vendor/bin/phpcs
|
||||||
|
|
||||||
|
.PHONY: code-sniffer-fix
|
||||||
|
code-sniffer-fix:
|
||||||
|
./vendor/bin/phpcbf
|
||||||
|
|
||||||
32
composer.json
Normal file
32
composer.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "kletellier/pdowrapper",
|
||||||
|
"description": "Pdo Wrapper for php with ActiveRecord system",
|
||||||
|
"type": "library",
|
||||||
|
"require": {
|
||||||
|
"vlucas/phpdotenv": "^5.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"squizlabs/php_codesniffer": "^3.4",
|
||||||
|
"pestphp/pest": "^1.21",
|
||||||
|
"infection/infection": "^0.26.15"
|
||||||
|
},
|
||||||
|
"license": "MIT",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Kletellier\\PdoWrapper\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gregory Letellier",
|
||||||
|
"email": "gregory_letellier@hotmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"config": {
|
||||||
|
"allow-plugins": {
|
||||||
|
"infection/extension-installer": true,
|
||||||
|
"pestphp/pest-plugin": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
4453
composer.lock
generated
Normal file
4453
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
infection.json5
Normal file
17
infection.json5
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"$schema": "vendor/infection/infection/resources/schema.json",
|
||||||
|
"source": {
|
||||||
|
"directories": [
|
||||||
|
"src"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"phpUnit": {
|
||||||
|
"configDir": ""
|
||||||
|
},
|
||||||
|
"logs": {
|
||||||
|
"text": "./var/log/infection.log"
|
||||||
|
},
|
||||||
|
"mutators": {
|
||||||
|
"@default": true
|
||||||
|
}
|
||||||
|
}
|
||||||
22
phpunit.xml
Normal file
22
phpunit.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
colors="true"
|
||||||
|
cacheResultFile="./var/cache/"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Test Suite">
|
||||||
|
<directory suffix="Test.php">./tests</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<coverage processUncoveredFiles="true" cacheDirectory="./var/cache/">
|
||||||
|
<include>
|
||||||
|
<directory suffix=".php">./src</directory>
|
||||||
|
</include>
|
||||||
|
</coverage>
|
||||||
|
<php>
|
||||||
|
<env name="DB_TYPE" value="sqlite"/>
|
||||||
|
<env name="DB_DATABASE" value=":memory:"/>
|
||||||
|
</php>
|
||||||
|
</phpunit>
|
||||||
154
src/Db.php
Normal file
154
src/Db.php
Normal file
@@ -0,0 +1,154 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kletellier\PdoWrapper;
|
||||||
|
|
||||||
|
use Dotenv\Dotenv;
|
||||||
|
use PDO;
|
||||||
|
use PDOStatement;
|
||||||
|
|
||||||
|
class Db
|
||||||
|
{
|
||||||
|
protected PDO $pdo;
|
||||||
|
protected string $connstring;
|
||||||
|
private static $instance = null;
|
||||||
|
private string $type;
|
||||||
|
private ?string $user;
|
||||||
|
private ?string $password;
|
||||||
|
private string $database;
|
||||||
|
private ?string $port;
|
||||||
|
private ?string $host;
|
||||||
|
private string $error;
|
||||||
|
|
||||||
|
|
||||||
|
private function __construct($dir)
|
||||||
|
{
|
||||||
|
$this->error = "";
|
||||||
|
$this->loadEnv($dir);
|
||||||
|
$this->initPdo();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadEnv($dir)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$dotenv = Dotenv::createImmutable($dir);
|
||||||
|
$dotenv->load();
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
$this->error = $th->getMessage();
|
||||||
|
}
|
||||||
|
$this->parseEnv();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function parseEnv()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$this->type = isset($_ENV["DB_TYPE"]) ? $_ENV["DB_TYPE"] : null;
|
||||||
|
$this->user = isset($_ENV["DB_USER"]) ? $_ENV["DB_USER"] : null;
|
||||||
|
$this->host = isset($_ENV["DB_HOST"]) ? $_ENV["DB_HOST"] : null;
|
||||||
|
$this->password = isset($_ENV["DB_PASSWORD"]) ? $_ENV["DB_PASSWORD"] : null;
|
||||||
|
$this->database = isset($_ENV["DB_DATABASE"]) ? $_ENV["DB_DATABASE"] : null;
|
||||||
|
$this->port = isset($_ENV["DB_PORT"]) ? $_ENV["DB_PORT"] : null;
|
||||||
|
} catch (\Throwable $th) {
|
||||||
|
$this->error = $th->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function initPdo()
|
||||||
|
{
|
||||||
|
$this->getConnString();
|
||||||
|
$this->pdo = new PDO($this->connstring, $this->user, $this->password);
|
||||||
|
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function bindParams(PDOStatement $stmt, array $data): PDOStatement
|
||||||
|
{
|
||||||
|
$iParams = 1;
|
||||||
|
foreach ($data as $value) {
|
||||||
|
if ($value instanceof \DateTime) {
|
||||||
|
$stmt->bindValue($iParams, $value->format('Y-m-d H:i:s'), PDO::PARAM_STR);
|
||||||
|
} else {
|
||||||
|
switch (gettype($value)) {
|
||||||
|
case 'integer':
|
||||||
|
$stmt->bindValue($iParams, $value, PDO::PARAM_INT);
|
||||||
|
break;
|
||||||
|
case 'datetime':
|
||||||
|
$stmt->bindValue($iParams, $value, PDO::PARAM_STR);
|
||||||
|
break;
|
||||||
|
case 'boolean':
|
||||||
|
$stmt->bindValue($iParams, $value, PDO::PARAM_BOOL);
|
||||||
|
break;
|
||||||
|
case 'NULL':
|
||||||
|
$stmt->bindValue($iParams, $value, PDO::PARAM_NULL);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$stmt->bindValue($iParams, $value, PDO::PARAM_STR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$iParams++;
|
||||||
|
}
|
||||||
|
return $stmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getConnString()
|
||||||
|
{
|
||||||
|
$this->connstring = match ($this->type) {
|
||||||
|
"mysql" => "mysql:host=" . $this->host . ":" . $this->port . ";dbname=" . $this->database,
|
||||||
|
"sqlite" => "sqlite:" . $this->database,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public function executeRawQuery(string $rawquery): bool
|
||||||
|
{
|
||||||
|
$stmt = $this->pdo->prepare($rawquery);
|
||||||
|
return $stmt->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSelectQuery(Query $query): mixed
|
||||||
|
{
|
||||||
|
$stmt = $this->pdo->prepare($query->getQuery());
|
||||||
|
$stmt = $this->bindParams($stmt, $query->getData());
|
||||||
|
$stmt->execute();
|
||||||
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateQuery(Query $query): bool
|
||||||
|
{
|
||||||
|
$stmt = $this->pdo->prepare($query->getQuery());
|
||||||
|
$stmt = $this->bindParams($stmt, $query->getData());
|
||||||
|
return $stmt->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function insertQuery(Query $query): mixed
|
||||||
|
{
|
||||||
|
$stmt = $this->pdo->prepare($query->getQuery());
|
||||||
|
$stmt = $this->bindParams($stmt, $query->getData());
|
||||||
|
$ok = $stmt->execute();
|
||||||
|
if ($ok) {
|
||||||
|
return $this->pdo->lastInsertId();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function init($dir)
|
||||||
|
{
|
||||||
|
return self::retrieveInstance($dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function retrieveInstance($dir = __DIR__)
|
||||||
|
{
|
||||||
|
if (self::$instance == null) {
|
||||||
|
self::$instance = new Db($dir);
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getInstance()
|
||||||
|
{
|
||||||
|
return self::retrieveInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getError()
|
||||||
|
{
|
||||||
|
return $this->error;
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/Expression.php
Normal file
55
src/Expression.php
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kletellier\PdoWrapper;
|
||||||
|
|
||||||
|
class Expression
|
||||||
|
{
|
||||||
|
private $condition;
|
||||||
|
private $operator;
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
public function __construct($condition, $operator, $value)
|
||||||
|
{
|
||||||
|
$this->condition = $condition;
|
||||||
|
$this->operator = $operator;
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function raw(): string
|
||||||
|
{
|
||||||
|
return "(" . $this->condition . " " . $this->operator . " ? )";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCondition()
|
||||||
|
{
|
||||||
|
return $this->condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCondition($condition)
|
||||||
|
{
|
||||||
|
$this->condition = $condition;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOperator()
|
||||||
|
{
|
||||||
|
return $this->operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setOperator($operator)
|
||||||
|
{
|
||||||
|
$this->operator = $operator;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue($value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
97
src/Model.php
Normal file
97
src/Model.php
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kletellier\PdoWrapper;
|
||||||
|
|
||||||
|
class Model
|
||||||
|
{
|
||||||
|
protected mixed $values;
|
||||||
|
protected string $table;
|
||||||
|
protected string $pk;
|
||||||
|
private Db $db;
|
||||||
|
private bool $new;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->db = Db::getInstance();
|
||||||
|
$this->new = true;
|
||||||
|
$this->values = array();
|
||||||
|
$this->pk = "id";
|
||||||
|
$this->table = $this->getDefaultTableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTable(): string
|
||||||
|
{
|
||||||
|
return $this->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTable(string $table): self
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPk(): string
|
||||||
|
{
|
||||||
|
return $this->pk;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPk(string $pk): self
|
||||||
|
{
|
||||||
|
$this->pk = $pk;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fillData(mixed $data): self
|
||||||
|
{
|
||||||
|
$this->values = $data;
|
||||||
|
$this->new = false;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save(): bool
|
||||||
|
{
|
||||||
|
$ret = false;
|
||||||
|
$qb = $this->newQueryBuilder();
|
||||||
|
if ($this->new) {
|
||||||
|
$query = $qb->getPreparedQuery($this->values);
|
||||||
|
$id = $this->db->insertQuery($query);
|
||||||
|
if ($id !== false) {
|
||||||
|
$this->values[$this->pk] = $id;
|
||||||
|
$this->new = false;
|
||||||
|
$ret = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$query = $qb->getPreparedQuery($this->values, false);
|
||||||
|
$ret = $this->db->updateQuery($query);
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newQueryBuilder(): QueryBuilder
|
||||||
|
{
|
||||||
|
return new QueryBuilder($this->table, $this->pk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __set($name, $value): void
|
||||||
|
{
|
||||||
|
$this->values[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __get($name): mixed
|
||||||
|
{
|
||||||
|
if (isset($this->values[$name])) {
|
||||||
|
return $this->values[$name];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getDefaultTableName(): string
|
||||||
|
{
|
||||||
|
$className = get_class($this);
|
||||||
|
$classNameParts = explode('\\', $className);
|
||||||
|
$classNameWithoutNamespace = end($classNameParts);
|
||||||
|
$table = strtolower($classNameWithoutNamespace);
|
||||||
|
|
||||||
|
return $table;
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/Query.php
Normal file
43
src/Query.php
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kletellier\PdoWrapper;
|
||||||
|
|
||||||
|
class Query
|
||||||
|
{
|
||||||
|
public string $query;
|
||||||
|
public array $data;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->query = "";
|
||||||
|
$this->data = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addData($value)
|
||||||
|
{
|
||||||
|
$this->data[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getQuery(): string
|
||||||
|
{
|
||||||
|
return $this->query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setQuery(string $query)
|
||||||
|
{
|
||||||
|
$this->query = $query;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData(): array
|
||||||
|
{
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setData(array $data)
|
||||||
|
{
|
||||||
|
$this->data = $data;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
215
src/QueryBuilder.php
Normal file
215
src/QueryBuilder.php
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Kletellier\PdoWrapper;
|
||||||
|
|
||||||
|
class QueryBuilder
|
||||||
|
{
|
||||||
|
protected Db $db;
|
||||||
|
protected array $columns;
|
||||||
|
protected array $wheres;
|
||||||
|
protected array $orders;
|
||||||
|
protected string $table;
|
||||||
|
protected string $pk;
|
||||||
|
protected ?int $take;
|
||||||
|
protected ?int $offset;
|
||||||
|
protected string $raw_query;
|
||||||
|
|
||||||
|
public function __construct($table, $pk)
|
||||||
|
{
|
||||||
|
$this->table = $table;
|
||||||
|
$this->pk = $pk;
|
||||||
|
$this->db = Db::getInstance();
|
||||||
|
$this->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->columns = [];
|
||||||
|
$this->wheres = [];
|
||||||
|
$this->orders = [];
|
||||||
|
$this->offset = null;
|
||||||
|
$this->take = null;
|
||||||
|
$this->raw_query = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function raw(string $query)
|
||||||
|
{
|
||||||
|
$this->raw_query = $query;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function take(?int $nb)
|
||||||
|
{
|
||||||
|
$this->take = $nb;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offset(?int $offset)
|
||||||
|
{
|
||||||
|
$this->offset = $offset;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function orderBy($columns, $sort = "ASC")
|
||||||
|
{
|
||||||
|
if (is_array($columns)) {
|
||||||
|
foreach ($columns as $column) {
|
||||||
|
$this->orders[] = $column . " " . $sort;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->orders[] = $columns . " " . $sort;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function columns($columns)
|
||||||
|
{
|
||||||
|
if (is_array($columns)) {
|
||||||
|
$this->columns = array_merge($this->columns, $columns);
|
||||||
|
}
|
||||||
|
if (is_string($columns)) {
|
||||||
|
$this->columns[] = $columns;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function where($condition, $operator, $value = null)
|
||||||
|
{
|
||||||
|
if ($value === null) {
|
||||||
|
$this->wheres[] = new Expression($condition, "=", $operator);
|
||||||
|
} else {
|
||||||
|
$this->wheres[] = new Expression($condition, $operator, $value);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function find($id): mixed
|
||||||
|
{
|
||||||
|
$this->reset();
|
||||||
|
$expression = new Expression($this->pk, "=", $id);
|
||||||
|
$this->wheres = [$expression];
|
||||||
|
$this->columns = ["*"];
|
||||||
|
$data = $this->getData();
|
||||||
|
if (count($data) > 0) {
|
||||||
|
return $this->prepareModels($data)[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(): mixed
|
||||||
|
{
|
||||||
|
$data = $this->getData();
|
||||||
|
return $this->prepareModels($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreparedQuery(array $data, $insert = true): Query
|
||||||
|
{
|
||||||
|
$ret = new Query();
|
||||||
|
|
||||||
|
$columns = implode(",", array_keys($data));
|
||||||
|
$query = "";
|
||||||
|
|
||||||
|
if ($insert) {
|
||||||
|
$keys = implode(",", str_split(str_repeat("?", count($data))));
|
||||||
|
$query = "INSERT INTO " . $this->table . " (" . $columns . ") VALUES (" . $keys . ");";
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
$ret->addData($value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$query = "UPDATE " . $this->table . " SET ";
|
||||||
|
$up = "";
|
||||||
|
foreach ($data as $key => $value) {
|
||||||
|
if ($up != "") {
|
||||||
|
$up .= ", ";
|
||||||
|
}
|
||||||
|
$up .= $key . " = ? ";
|
||||||
|
$ret->addData($value);
|
||||||
|
}
|
||||||
|
$query .= $up . " WHERE " . $this->pk . " = ? ;";
|
||||||
|
$ret->addData($data[$this->pk]);
|
||||||
|
}
|
||||||
|
$ret->setQuery($query);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function prepareModels(mixed $data): mixed
|
||||||
|
{
|
||||||
|
$ret = array();
|
||||||
|
foreach ($data as $row) {
|
||||||
|
$model = new Model();
|
||||||
|
$ret[] = $model->setPk($this->pk)->setTable($this->table)->fillData($row);
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getData(): mixed
|
||||||
|
{
|
||||||
|
return $this->db->getSelectQuery($this->getQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getConstructedQuery(): Query
|
||||||
|
{
|
||||||
|
$ret = new Query();
|
||||||
|
$ret->setQuery("");
|
||||||
|
$ret->setData([]);
|
||||||
|
|
||||||
|
$columns = implode(",", $this->columns);
|
||||||
|
$where = "";
|
||||||
|
foreach ($this->wheres as $expression) {
|
||||||
|
$sw = $expression->raw();
|
||||||
|
$ret->addData($expression->getValue());
|
||||||
|
if ($where != "") {
|
||||||
|
$where .= " AND ";
|
||||||
|
}
|
||||||
|
$where .= $sw;
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = "SELECT " . $columns . " FROM " . $this->table ;
|
||||||
|
if ($where != "") {
|
||||||
|
$query .= " WHERE " . $where;
|
||||||
|
}
|
||||||
|
if (count($this->orders) > 0) {
|
||||||
|
$query .= " ORDER BY ";
|
||||||
|
$iOrder = 0;
|
||||||
|
foreach ($this->orders as $order) {
|
||||||
|
if ($iOrder > 0) {
|
||||||
|
$query .= ",";
|
||||||
|
}
|
||||||
|
$query .= $order;
|
||||||
|
$iOrder++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$query .= $this->getLimit();
|
||||||
|
|
||||||
|
$ret->setQuery($query);
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getLimit(): string
|
||||||
|
{
|
||||||
|
if ($this->take !== null || $this->offset !== null) {
|
||||||
|
$ret = "";
|
||||||
|
if ($this->take !== null) {
|
||||||
|
$ret = " LIMIT " . $this->take;
|
||||||
|
}
|
||||||
|
if ($this->offset !== null) {
|
||||||
|
$ret .= " OFFSET " . $this->offset;
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getQuery(): Query
|
||||||
|
{
|
||||||
|
if ($this->raw_query !== "") {
|
||||||
|
$query = new Query();
|
||||||
|
$query->setQuery($this->raw_query);
|
||||||
|
$query->setData([]);
|
||||||
|
return $query;
|
||||||
|
} else {
|
||||||
|
return $this->getConstructedQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
60
tests/DbTest.php
Normal file
60
tests/DbTest.php
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Kletellier\PdoWrapper\Db;
|
||||||
|
use Kletellier\PdoWrapper\Model;
|
||||||
|
use Kletellier\PdoWrapper\QueryBuilder;
|
||||||
|
|
||||||
|
test("create db",function () {
|
||||||
|
$dir = getcwd();
|
||||||
|
$db = Db::init($dir);
|
||||||
|
$ret = $db->executeRawQuery("CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT, col1 VARCHAR, date1 DATETIME);");
|
||||||
|
expect($ret)->toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("insert row",function () {
|
||||||
|
|
||||||
|
$row = new Model();
|
||||||
|
$row->setTable("test");
|
||||||
|
$row->col1 = "test";
|
||||||
|
$row->date1 = new \DateTime();
|
||||||
|
$ret = $row->save();
|
||||||
|
|
||||||
|
expect($ret)->toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("querybuilder", function() {
|
||||||
|
$qb = new QueryBuilder("test","id");
|
||||||
|
$row = $qb->find(1);
|
||||||
|
|
||||||
|
expect($row)->toBeObject();
|
||||||
|
expect($row->col1)->toBe("test");
|
||||||
|
expect($row->id)->toBe(1);
|
||||||
|
|
||||||
|
$qb->reset();
|
||||||
|
$rows = $qb->where("id",1)->columns("*")->get();
|
||||||
|
|
||||||
|
expect($rows)->toBeArray();
|
||||||
|
expect(count($rows))->toBe(1);
|
||||||
|
|
||||||
|
$qb->reset();
|
||||||
|
$rows = $qb->where("id",">",1)->columns("*")->get();
|
||||||
|
|
||||||
|
expect($rows)->toBeArray();
|
||||||
|
expect(count($rows))->toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("update row", function() {
|
||||||
|
$qb = new QueryBuilder("test","id");
|
||||||
|
$row = $qb->find(1);
|
||||||
|
|
||||||
|
$row->col1 = "test2";
|
||||||
|
$res = $row->save();
|
||||||
|
|
||||||
|
expect($res)->toBe(true);
|
||||||
|
|
||||||
|
$qb->reset();
|
||||||
|
$rows = $qb->where("id",1)->columns("*")->get();
|
||||||
|
expect($rows)->toBeArray();
|
||||||
|
expect(count($rows))->toBe(1);
|
||||||
|
expect($rows[0]->col1)->toBe("test2");
|
||||||
|
});
|
||||||
0
tests/Unit/.gitkeep
Normal file
0
tests/Unit/.gitkeep
Normal file
Reference in New Issue
Block a user