Skip to content

Commit 785e90a

Browse files
authored
[Feat] Support Database Schema Builder (#112)
* feat: database schema builder * formatting * change visibility * change visibility * add test db schema * feat: create tabel * make api more readable * feat: build column with chain why * add more datatype * feat add drop table * add constrait in column data type * strict_types * support unique attribute * formatting * Remove static MyPDO::dsn * add database name in create drop table - formatting - adding database name in create and drop table - fixing naming paramater - remove raw excute query - adding real database test for schema database * excluded real databse test in github action check * pass phpstan level max 😎 * add trucate table (refresh table) * add store engine * formatting * add raw constraint * add blueprint shorthand MySchema create table
1 parent d6e803c commit 785e90a

27 files changed

+1185
-26
lines changed

src/System/Database/MyPDO.php

+16-12
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class MyPDO
1616
*
1717
* @var array<string, string>
1818
*/
19-
private $configs;
19+
protected $configs;
2020

2121
/**
2222
* @param array<string, string> $configs
@@ -29,29 +29,33 @@ public function __construct(array $configs)
2929
$pass = $configs['password'];
3030

3131
$this->configs = $configs;
32+
$dsn = "mysql:host=$host;dbname=$database_name";
33+
$this->useDsn($dsn, $user, $pass);
34+
}
35+
36+
/**
37+
* Singleton pattern implemnt for Databese connation.
38+
*
39+
* @return self
40+
*/
41+
public function instance()
42+
{
43+
return $this;
44+
}
3245

33-
// konfigurasi driver
34-
$dsn = "mysql:host=$host;dbname=$database_name";
46+
protected function useDsn(string $dsn, string $user, string $pass)
47+
{
3548
$option = [
3649
\PDO::ATTR_PERSISTENT => true,
3750
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
3851
];
3952

40-
// menjalankan koneksi daabase
4153
try {
4254
$this->dbh = new \PDO($dsn, $user, $pass, $option);
4355
} catch (\PDOException $e) {
4456
throw new \Exception($e->getMessage());
4557
}
46-
}
4758

48-
/**
49-
* Singleton pattern implemnt for Databese connation.
50-
*
51-
* @return self
52-
*/
53-
public function instance()
54-
{
5559
return $this;
5660
}
5761

src/System/Database/MySchema.php

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database;
6+
7+
use System\Database\MySchema\Create;
8+
use System\Database\MySchema\Drop;
9+
use System\Database\MySchema\MyPDO;
10+
use System\Database\MySchema\Table\Create as CreateTable;
11+
use System\Database\MySchema\Table\Truncate;
12+
13+
class MySchema
14+
{
15+
/** @var MyPDO PDO property */
16+
private $pdo;
17+
18+
public function __construct(MyPDO $pdo)
19+
{
20+
$this->pdo = $pdo;
21+
}
22+
23+
public function create(): Create
24+
{
25+
return new Create($this->pdo);
26+
}
27+
28+
public function drop(): Drop
29+
{
30+
return new Drop($this->pdo);
31+
}
32+
33+
public function refresh(string $table_name): Truncate
34+
{
35+
$database_name = $this->pdo->configs()['database_name'];
36+
37+
return new Truncate($database_name, $table_name, $this->pdo);
38+
}
39+
40+
public function table(string $table_name, callable $blueprint): CreateTable
41+
{
42+
$database_name = $this->pdo->configs()['database_name'];
43+
$columns = new CreateTable($database_name, $table_name, $this->pdo);
44+
$blueprint($columns);
45+
46+
return $columns;
47+
}
48+
}
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database\MySchema;
6+
7+
/** Proxy for create database and table */
8+
class Create
9+
{
10+
/** @var MyPDO */
11+
private $pdo;
12+
13+
public function __construct(MyPDO $pdo)
14+
{
15+
$this->pdo = $pdo;
16+
}
17+
18+
public function database(string $database_name): DB\Create
19+
{
20+
return new DB\Create($database_name, $this->pdo);
21+
}
22+
23+
public function table(string $table_name): Table\Create
24+
{
25+
$database_name = $this->pdo->configs()['database_name'];
26+
27+
return new Table\Create($database_name, $table_name, $this->pdo);
28+
}
29+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database\MySchema\DB;
6+
7+
use System\Database\MySchema\MyPDO;
8+
use System\Database\MySchema\Query;
9+
use System\Database\MySchema\Traits\ConditionTrait;
10+
11+
class Create extends Query
12+
{
13+
use ConditionTrait;
14+
15+
/** @var string */
16+
private $database_name;
17+
18+
public function __construct(string $database_name, MyPDO $pdo)
19+
{
20+
$this->database_name = $database_name;
21+
$this->pdo = $pdo;
22+
}
23+
24+
protected function builder(): string
25+
{
26+
$conditon = $this->join([$this->if_exists, $this->database_name]);
27+
28+
return 'CREATE DATABASE ' . $conditon . ';';
29+
}
30+
}
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database\MySchema\DB;
6+
7+
use System\Database\MySchema\MyPDO;
8+
use System\Database\MySchema\Query;
9+
use System\Database\MySchema\Traits\ConditionTrait;
10+
11+
class Drop extends Query
12+
{
13+
use ConditionTrait;
14+
15+
/** @var string */
16+
private $database_name;
17+
18+
public function __construct(string $database_name, MyPDO $pdo)
19+
{
20+
$this->database_name = $database_name;
21+
$this->pdo = $pdo;
22+
}
23+
24+
protected function builder(): string
25+
{
26+
$conditon = $this->join([$this->if_exists, $this->database_name]);
27+
28+
return 'DROP DATABASE ' . $conditon . ';';
29+
}
30+
}

src/System/Database/MySchema/Drop.php

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database\MySchema;
6+
7+
/** Proxy for drop database and table */
8+
class Drop
9+
{
10+
/** @var MyPDO */
11+
private $pdo;
12+
13+
public function __construct(MyPDO $pdo)
14+
{
15+
$this->pdo = $pdo;
16+
}
17+
18+
public function database(string $database_name): DB\Drop
19+
{
20+
return new DB\Drop($database_name, $this->pdo);
21+
}
22+
23+
public function table(string $table_name): Table\Drop
24+
{
25+
$database_name = $this->pdo->configs()['database_name'];
26+
27+
return new Table\Drop($database_name, $table_name, $this->pdo);
28+
}
29+
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database\MySchema;
6+
7+
use System\Database\MyPDO as BasePDO;
8+
9+
class MyPDO extends BasePDO
10+
{
11+
/**
12+
* @param array<string, string> $configs
13+
*/
14+
public function __construct(array $configs)
15+
{
16+
$host = $configs['host'];
17+
$user = $configs['user'];
18+
$pass = $configs['password'];
19+
20+
$this->configs = $configs;
21+
$dsn = "mysql:host=$host;charset=utf8mb4";
22+
$this->useDsn($dsn, $user, $pass);
23+
}
24+
}
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database\MySchema;
6+
7+
abstract class Query
8+
{
9+
/** @var MyPDO PDO property */
10+
protected $pdo;
11+
12+
public function __toString()
13+
{
14+
return $this->builder();
15+
}
16+
17+
protected function builder(): string
18+
{
19+
return '';
20+
}
21+
22+
public function execute(): bool
23+
{
24+
return $this->pdo->query($this->builder())->execute();
25+
}
26+
27+
/**
28+
* Helper: join condition into string.
29+
*
30+
* @param string[] $array
31+
*/
32+
protected function join(array $array, string $sperator = ' '): string
33+
{
34+
return implode(
35+
$sperator,
36+
array_filter($array, fn ($item) => $item !== '')
37+
);
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace System\Database\MySchema\Table\Attributes;
6+
7+
class Constraint
8+
{
9+
/** @var string */
10+
private $data_type;
11+
/** @var string */
12+
private $null_able;
13+
/** @var string */
14+
private $default;
15+
/** @var string */
16+
private $auto_increment;
17+
/** @var string */
18+
private $raw;
19+
20+
public function __construct(string $data_type)
21+
{
22+
$this->data_type = $data_type;
23+
$this->null_able = '';
24+
$this->default = '';
25+
$this->auto_increment = '';
26+
$this->raw = '';
27+
}
28+
29+
public function __toString()
30+
{
31+
return $this->query();
32+
}
33+
34+
private function query(): string
35+
{
36+
$collumn = [
37+
$this->data_type,
38+
$this->null_able,
39+
$this->default,
40+
$this->auto_increment,
41+
$this->raw,
42+
];
43+
44+
return implode(' ', array_filter($collumn, fn ($item) => $item !== ''));
45+
}
46+
47+
public function notNull(bool $null = true): self
48+
{
49+
$this->null_able = $null ? 'NOT NULL' : '';
50+
51+
return $this;
52+
}
53+
54+
public function null(bool $null = true): self
55+
{
56+
return $this->notNull(!$null);
57+
}
58+
59+
public function default(string $default): self
60+
{
61+
$this->default = "'$default'";
62+
63+
return $this;
64+
}
65+
66+
public function autoIncrement(bool $incremnet): self
67+
{
68+
$this->auto_increment = $incremnet ? 'AUTO_INCREMENT' : '';
69+
70+
return $this;
71+
}
72+
73+
public function increment(bool $incremnet): self
74+
{
75+
return $this->autoIncrement($incremnet);
76+
}
77+
78+
public function raw(string $raw): self
79+
{
80+
$this->raw = $raw;
81+
82+
return $this;
83+
}
84+
}

0 commit comments

Comments
 (0)