Foreign, debug, datetime and ids
This commit is contained in:
parent
365f2ff580
commit
4fb305a1c2
|
@ -4,6 +4,8 @@ namespace Krutush\Database;
|
|||
|
||||
class Database{
|
||||
private $pdo;
|
||||
private $debug = false;
|
||||
private $requests = [];
|
||||
|
||||
public function __construct(array $settings){
|
||||
$dns = $settings['driver'] .
|
||||
|
@ -12,6 +14,7 @@ class Database{
|
|||
';dbname=' . $settings['schema'] .
|
||||
((isset($settings['charset'])) ? (';charset=' . $settings['charset']) : '');
|
||||
|
||||
$this->debug = isset($settings['debug']) ? $settings['debug'] : false;
|
||||
$this->pdo = new \PDO($dns, $settings['username'], $settings['password'], $settings['options']);
|
||||
}
|
||||
|
||||
|
@ -20,6 +23,9 @@ class Database{
|
|||
}
|
||||
|
||||
public function prepare(string $request){
|
||||
if($this->debug)
|
||||
$this->requests[] = $request;
|
||||
|
||||
return $this->pdo->prepare($request);
|
||||
}
|
||||
|
||||
|
@ -72,8 +78,12 @@ class Database{
|
|||
return $drop;
|
||||
}
|
||||
|
||||
public function getLastInsertId(){
|
||||
public function getLastInsertId(): int{
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
public function getRequests(): array{
|
||||
return $this->requests;
|
||||
}
|
||||
//TODO update, delete
|
||||
}
|
|
@ -14,9 +14,15 @@ class Model{
|
|||
/** @var string */
|
||||
public const TABLE = null;
|
||||
|
||||
/** @var array
|
||||
* @example ['id' => ['column' => 'idColumn', 'type' => 'int', 'not_null' => true, 'primary' => true, 'custom' => 'AUTO_INCREMENT']] */
|
||||
/** @var array */
|
||||
public const FIELDS = [];
|
||||
/*[
|
||||
'id' => ['column' => 'idColumn', 'type' => 'int', 'not_null' => true, 'primary' => true, 'custom' => 'AUTO_INCREMENT'],
|
||||
'owner' => ['type' => 'int', 'foreign' => ['model' => UserModel::class, 'field' => 'id', 'on_delete' => 'cascade', 'on_update' => 'set null']]
|
||||
]*/
|
||||
|
||||
/** @var string */
|
||||
public const ID = 'id';
|
||||
|
||||
/** @var array
|
||||
* @example ['id' => ['value' => 1, 'modified' => false]] */
|
||||
|
@ -127,6 +133,10 @@ class Model{
|
|||
return isset($options['column']) ? $options['column'] : $field;
|
||||
}
|
||||
|
||||
public static function getID(): string{
|
||||
return static::getColumn(static::ID);
|
||||
}
|
||||
|
||||
public static function getColumns(bool $sql = true): array{
|
||||
$fields = static::getFields();
|
||||
$columns = [];
|
||||
|
@ -172,11 +182,19 @@ class Model{
|
|||
public function getModifiedValues(){
|
||||
$values = [];
|
||||
foreach ($this->fields as $field => $data) {
|
||||
if($data['modified']) $values[] = $data['value'];
|
||||
if($data['modified'])
|
||||
$values[] = $data['value'];
|
||||
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
public function unmodify(){
|
||||
foreach($this->fields as $field => $data){
|
||||
$this->fields[$field]['modified'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrimaryValues(){
|
||||
$values = [];
|
||||
foreach ($this->fields as $field => $data) {
|
||||
|
@ -207,6 +225,15 @@ class Model{
|
|||
case 'bit':
|
||||
$data = boolval($data); //MAYBE: E_NOTICE on strange types
|
||||
break;
|
||||
case 'date':
|
||||
$data = (is_a($data, \DateTime::class) ? $data : new \DateTime(strval($data)))->format('Y-m-d');
|
||||
break;
|
||||
case 'time':
|
||||
$data = (is_a($data, \DateTime::class) ? $data : new \DateTime(strval($data)))->format('H:i:s');
|
||||
break;
|
||||
case 'datetime':
|
||||
$data = (is_a($data, \DateTime::class) ? $data : new \DateTime(strval($data)))->format('Y-m-d H:i:s');
|
||||
break;
|
||||
default:
|
||||
throw new DatabaseException('unknown type in field : '.$field);
|
||||
break;
|
||||
|
@ -244,8 +271,13 @@ class Model{
|
|||
return $req;
|
||||
}
|
||||
|
||||
public function runInsert(){
|
||||
return static::insert()->run($this->getValues());
|
||||
public function runInsert(bool $forceID = true){
|
||||
$insert = static::insert();
|
||||
$res = $insert->run($this->getValues());
|
||||
if($forceID)
|
||||
$this->{static::ID} = Connection::get(static::DATABASE)->getLastInsertID();
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function runUpdate(){
|
||||
|
@ -253,7 +285,9 @@ class Model{
|
|||
->update(static::getModifiedColumns())
|
||||
->table(static::TABLE)
|
||||
->where(implode(' AND ', array_map(function($field){ return $field.' = ?'; }, static::getPrimaryColumns())))
|
||||
->run(array_merge($this->getModifiedValues(), $this->getPrimaryValues()));
|
||||
->run(array_merge($this->getModifiedValues(true), $this->getPrimaryValues()));
|
||||
$this->unmodify();
|
||||
return $this;
|
||||
}
|
||||
|
||||
public static function create(): Request\Create{
|
||||
|
@ -261,14 +295,42 @@ class Model{
|
|||
->create(static::TABLE);
|
||||
|
||||
foreach (static::getFields() as $field => $options) {
|
||||
$column = static::getColumn($field);
|
||||
$req->column(
|
||||
static::getColumn($field),
|
||||
$column,
|
||||
$options['type'],
|
||||
isset($options['lenght']) ? $options['lenght'] : null,
|
||||
isset($options['not_null']) && $options['not_null'],
|
||||
isset($options['primary']) && $options['primary'],
|
||||
isset($options['unique']) && $options['unique'],
|
||||
isset($options['custom']) ? $options['custom'] : null);
|
||||
|
||||
if(isset($options['primary']) && $options['primary'])
|
||||
$req->primary($column);
|
||||
|
||||
if(isset($options['unique']) && $options['unique'])
|
||||
$req->unique($column);
|
||||
|
||||
if(isset($options['foreign'])){
|
||||
$foreign = $options['foreign'];
|
||||
|
||||
$model = null;
|
||||
|
||||
if(is_array($foreign)){
|
||||
if(!isset($foreign['model']))
|
||||
throw new DatabaseException('Any model for foreign in field '.$field);
|
||||
|
||||
$model = $foreign['model'];
|
||||
}else{
|
||||
$model = $foreign;
|
||||
}
|
||||
if(!class_exists($model))
|
||||
throw new DatabaseException('Can\'t find class '.$model.' for foreign in field '.$field);
|
||||
|
||||
$req->foreign($column, $model::TABLE,
|
||||
$model::getColumn(isset($foreign['field']) ? $foreign['field'] : $model::ID),
|
||||
isset($foreign['index']) ? $foreign['index'] : true,
|
||||
isset($foreign['on_delete']) ? $foreign['on_delete'] : null,
|
||||
isset($foreign['on_update']) ? $foreign['on_update'] : null);
|
||||
}
|
||||
}
|
||||
|
||||
return $req;
|
||||
|
@ -325,13 +387,11 @@ class Model{
|
|||
return $data['count'];
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Manager ids
|
||||
public static function find($id) {
|
||||
public static function find($id): ?self{
|
||||
return static::first(array($id), (static::getID().' = ?'));
|
||||
}
|
||||
|
||||
public static function findOrFail($id) {
|
||||
public static function findOrFail($id): self{
|
||||
return static::firstOrFail(array($id), (static::getID().' = ?'));
|
||||
}*/
|
||||
}
|
||||
}
|
|
@ -10,19 +10,49 @@ class Create extends Request{
|
|||
protected $columns = [];
|
||||
protected $primary = [];
|
||||
protected $unique = [];
|
||||
protected $index = [];
|
||||
protected $foreign = [];
|
||||
|
||||
public function table(string $table): Create{
|
||||
$this->table = $table;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function column(string $name, string $type, int $lenght = null, bool $not_null = false, bool $primary = false, bool $unique = false, string $more = null): Create{
|
||||
public function column(string $name, string $type, int $lenght = null, bool $not_null = false, string $more = null): Create{ //Really ?
|
||||
$this->columns[] = '`'.$name.'` '.$type.($lenght ? '('.$lenght.')' : '').($not_null ? ' NOT NULL' : '').(isset($more) ? ' '.$more : '');
|
||||
if($primary)
|
||||
$this->primary[] = '`'.$name.'`';
|
||||
return $this;
|
||||
}
|
||||
|
||||
if($unique)
|
||||
$this->unique[$name] = [$name];
|
||||
public function primary(string $name): Create{
|
||||
$this->primary[] = '`'.$name.'`';
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function unique(string $name): Create{
|
||||
$this->unique[$name] = ['`'.$name.'`'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function uniques(string $name, array $columns): Create{
|
||||
$this->unique[$name] = [$columns];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function index(string $name): Create{
|
||||
$this->index[$name] = ['`'.$name.'`'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function indexs(string $name, array $columns): Create{
|
||||
$this->index[$name] = [$columns];
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function foreign(string $name, string $table, string $column, bool $index = true, string $on_delete = null, string $on_update = null): Create{ //TODO: complex foreign
|
||||
if($index)
|
||||
$this->index($name);
|
||||
|
||||
$this->foreign[$name] = compact('name', 'table', 'column', 'on_delete', 'on_update');
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -35,7 +65,19 @@ class Create extends Request{
|
|||
|
||||
$uniques = [];
|
||||
foreach ($this->unique as $name => $columns) {
|
||||
$uniques[] = 'CONSTRAINT UC_'.ucfirst(strtolower($name)).' UNIQUE ('.implode(', ', $columns).')';
|
||||
$uniques[] = 'CONSTRAINT `UQ_'.ucfirst(strtolower($this->table)).'_'.ucfirst(strtolower($name)).'` UNIQUE ('.implode(', ', $columns).')';
|
||||
}
|
||||
|
||||
$indexs = [];
|
||||
foreach ($this->index as $name => $columns) {
|
||||
$indexs[] = 'INDEX `ID_'.ucfirst(strtolower($this->table)).'_'.ucfirst(strtolower($name)).'` ('.implode(', ', $columns).')';
|
||||
}
|
||||
|
||||
$foreigns = [];
|
||||
foreach ($this->foreign as $name => $options) {
|
||||
$foreigns[] = 'CONSTRAINT `FK_'.ucfirst(strtolower($this->table)).'_'.ucfirst(strtolower($name)).'` FOREIGN KEY (`'.$options['name'].'`) REFERENCES `'.$options['table'].'` (`'.$options['column'].'`)'.
|
||||
(isset($options['on_delete']) ? 'ON DELETE '.$options['on_delete'] : '').
|
||||
(isset($options['on_update']) ? 'ON UPDATE '.$options['on_update'] : '');
|
||||
}
|
||||
|
||||
return 'CREATE TABLE `'.$this->table.'`('."\n".
|
||||
|
@ -43,9 +85,11 @@ class Create extends Request{
|
|||
array_merge(
|
||||
$this->columns,
|
||||
(empty($this->primary) ? [] : [
|
||||
'CONSTRAINT PK_'.ucfirst(strtolower(strtok($this->table, ' '))).' PRIMARY KEY ('.implode(', ', $this->primary).')'
|
||||
'CONSTRAINT `PK_'.ucfirst(strtolower(strtok($this->table, ' '))).'` PRIMARY KEY ('.implode(', ', $this->primary).')'
|
||||
]),
|
||||
$uniques
|
||||
$indexs,
|
||||
$uniques,
|
||||
$foreigns
|
||||
)
|
||||
)."\n)";
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Krutush\Database\Request;
|
|||
|
||||
use Krutush\Database\Database;
|
||||
|
||||
class Request{
|
||||
class Request{ //TODO: escape and slugify
|
||||
protected $db;
|
||||
|
||||
public function __construct(Database $db){
|
||||
|
|
Loading…
Reference in New Issue