Skip to content

Commit 6159d29

Browse files
committed
Added postgres and sqlite support
1 parent f9d3a33 commit 6159d29

File tree

14 files changed

+610
-308
lines changed

14 files changed

+610
-308
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Ulole-ORM `3.1`
1+
# Ulole-ORM `3.2`
22

33
## Getting started
44
UloleORM is an Object Relation Mapper written in PHP.
@@ -54,12 +54,12 @@ class User {
5454
```php
5555
<?php
5656
UloleORM::database("main", new Database(
57-
'username',
58-
'password',
59-
'database',
60-
'host', /* PORT: default localhost */
61-
3306, /* PORT: default 3306 */
62-
'mysql' /* DRIVER: default mysql (Every PDO Driver usable. ) */
57+
username: 'root',
58+
password: '1234',
59+
database: 'testing',
60+
host: 'localhost',
61+
port: 3306,
62+
driver: 'mysql' // You can also use sqlite for testing or pgsql for postgres
6363
));
6464

6565
UloleORM::register(User::class);

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "interaapps/uloleorm",
3-
"version": "3.1.3",
3+
"version": "3.2.0",
44
"type": "library",
55
"authors": [
66
{

de/interaapps/ulole/orm/Database.php

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22

33
namespace de\interaapps\ulole\orm;
44

5+
use de\interaapps\ulole\orm\drivers\Driver;
6+
use de\interaapps\ulole\orm\drivers\MySQLDriver;
7+
use de\interaapps\ulole\orm\drivers\PostgresDriver;
8+
use de\interaapps\ulole\orm\drivers\SQLiteDriver;
59
use de\interaapps\ulole\orm\migration\Blueprint;
610
use PDO;
711
use PDOStatement;
812

913
class Database {
10-
private PDO $connection;
14+
private Driver $driver;
15+
16+
private static $driverFactories = [];
1117

1218
/**
1319
* @param string $username
@@ -17,61 +23,20 @@ class Database {
1723
* @param int $port
1824
* @param string $driver
1925
*/
20-
public function __construct(string $username, string|null $password = null, string|null $database = null, string $host = 'localhost', int $port = 3306, string $driver = "mysql") {
21-
if ($driver == "sqlite")
22-
$this->connection = new PDO($driver . ':' . $database);
23-
else
24-
$this->connection = new PDO($driver . ':host=' . $host . ';dbname=' . $database, $username, $password);
25-
}
26-
27-
public function getConnection(): PDO {
28-
return $this->connection;
26+
public function __construct(string $username = "", string|null $password = null, string|null $database = null, string $host = 'localhost', int|null $port = null, string $driver = "mysql") {
27+
$this->driver = self::getDriverFactories()[$driver]($username, $password, $database, $host, $port, $driver);
2928
}
3029

31-
public function query($sql): PDOStatement|bool {
32-
return $this->connection->query($sql);
30+
public function create(string $name, callable $callable, bool $ifNotExists = false): bool {
31+
return $this->driver->create($name, $callable);
3332
}
3433

35-
public function create(string $name, $callable, bool $ifNotExists = false): PDOStatement|bool {
36-
$blueprint = new Blueprint();
37-
$callable($blueprint);
38-
$sql = "CREATE TABLE " . ($ifNotExists ? "IF NOT EXISTS " : "") . "`" . $name . "` (\n";
39-
$sql .= implode(",\n", $blueprint->getQueries(true));
40-
$sql .= "\n) ENGINE = InnoDB;";
41-
42-
return $this->query($sql);
43-
}
44-
45-
public function edit(string $name, $callable): PDOStatement|bool {
46-
$statement = $this->connection->query("SHOW COLUMNS FROM " . $name . ";");
47-
$existingColumns = [];
48-
foreach ($statement->fetchAll(\PDO::FETCH_NUM) as $row) {
49-
$existingColumns[] = $row[0];
50-
}
51-
$blueprint = new Blueprint();
52-
$callable($blueprint);
53-
$sql = "ALTER TABLE `" . $name . "`";
54-
$comma = false;
55-
foreach ($blueprint->getQueries() as $column => $query) {
56-
if ($comma)
57-
$sql .= ", ";
58-
59-
if (in_array($column, $existingColumns))
60-
$sql .= (substr($query, 0, 4) === "DROP" ? "" : "CHANGE `" . $column . "` ") . $query;
61-
else
62-
$sql .= " ADD " . $query;
63-
64-
if (!$comma)
65-
$comma = true;
66-
}
67-
$sql .= ";";
68-
69-
return $this->query($sql);
34+
public function edit(string $name, callable $callable): bool {
35+
return $this->driver->edit($name, $callable);
7036
}
7137

72-
7338
public function drop(string $name): PDOStatement|bool {
74-
return $this->query("DROP TABLE `" . $name . "`;");
39+
return $this->driver->drop($name);
7540
}
7641

7742
public function autoMigrate(): Database {
@@ -85,4 +50,27 @@ public function autoMigrate(): Database {
8550
return $this;
8651
}
8752

88-
}
53+
public function getDriver(): Driver {
54+
return $this->driver;
55+
}
56+
57+
public static function setDriverFactory(string $name, callable $callable) {
58+
self::$driverFactories[$name] = $callable;
59+
}
60+
61+
public static function getDriverFactories(): array {
62+
return self::$driverFactories;
63+
}
64+
}
65+
66+
Database::setDriverFactory("mysql", function (string $username, string|null $password, string|null $database, string $host, int|null $port, string $driver) : Driver {
67+
return new MySQLDriver(new PDO($driver . ':host=' . $host. ':' . ($port ?? 3306) . ';dbname=' . $database, $username, $password));
68+
});
69+
70+
Database::setDriverFactory("pgsql", function (string $username, string|null $password, string|null $database, string $host, int|null $port, string $driver) : Driver {
71+
return new PostgresDriver(new PDO($driver . ':host=' . $host . ';dbname=' . $database, $username, $password));
72+
});
73+
74+
Database::setDriverFactory("sqlite", function (string $username, string|null $password, string|null $database, string $host, int|null $port, string $driver) : Driver {
75+
return new SQLiteDriver(new PDO($driver . ':' . $database));
76+
});

de/interaapps/ulole/orm/ModelInformation.php

Lines changed: 26 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use de\interaapps\ulole\orm\attributes\Identifier;
99
use de\interaapps\ulole\orm\attributes\Table;
1010
use de\interaapps\ulole\orm\attributes\UpdatedAt;
11+
use de\interaapps\ulole\orm\migration\Blueprint;
1112
use ReflectionClass;
1213
use ReflectionException;
1314

@@ -31,7 +32,7 @@ class ModelInformation {
3132
"int" => "INTEGER",
3233
"float" => "FLOAT",
3334
"string" => "TEXT",
34-
"bool" => "TINYINT"
35+
"bool" => "BOOL"
3536
];
3637

3738
/**
@@ -133,74 +134,51 @@ public function autoMigrate(array|null $databases = null): ModelInformation {
133134
$databases = UloleORM::getDatabases();
134135

135136
foreach ($databases as $database) {
136-
$tables = [];
137-
foreach ($database->query("SHOW TABLES;")->fetchAll() as $r) {
138-
$tables[] = $r[0];
139-
}
137+
$tables = $database->getDriver()->getTables();
140138

141139
$fields = $this->getFields();
142140

143141
$columns = array_map(function ($field) {
144142
$type = $field->getColumnAttribute()->sqlType;
145143
if ($type == null) {
146-
if (isset(self::PHP_SQL_TYPES[$field->getType()->getName()]))
144+
if (isset(self::PHP_SQL_TYPES[$field->getType()->getName()])) {
147145
$type = self::PHP_SQL_TYPES[$field->getType()->getName()];
146+
if ($type == "TEXT" && $field->getColumnAttribute()->size !== null)
147+
$type = "VARCHAR";
148+
}
148149
}
149150

150-
if ($field->getColumnAttribute()->size != null)
151-
$type .= "(" . $field->getColumnAttribute()->size . ")";
152-
153151
$isIdentifier = $this->getIdentifier() == $field->getFieldName();
154152

155153
return [
156154
"field" => $field->getFieldName(),
157155
"type" => $type,
158156
"hasIndex" => $field->getColumnAttribute()->index,
159157
"identifier" => $isIdentifier,
160-
"query" => "`" . $field->getFieldName() . "` "
161-
. $type
162-
. ($field->getType()->allowsNull() ? ' NULL' : ' NOT NULL')
163-
. ($field->getColumnAttribute()->unique ? ' UNIQUE' : '')
164-
. ($type == 'INTEGER' && $isIdentifier ? ' AUTO_INCREMENT' : '')
165-
];
166-
}, $fields);
158+
"blueprintHandler" => function (Blueprint $blueprint) use ($isIdentifier, $type, $field) {
159+
$col = $blueprint->custom($field->getFieldName(), $type, $field->getColumnAttribute()->size);
167160

168-
$indexes = array_filter($columns, fn($c) => $c["hasIndex"]);
161+
if ($type == "INTEGER" && $isIdentifier)
162+
$col->ai()->primary();
169163

170-
if (in_array($this->getName(), $tables)) {
171-
$existingFields = array_map(fn($f) => $f[0], $database->query('SHOW COLUMNS FROM ' . $this->getName() . ';')->fetchAll());
172-
$existingIndexes = array_map(fn($f) => $f[4], $database->query('SHOW INDEXES FROM ' . $this->getName() . ';')->fetchAll());
173-
174-
$q = "ALTER TABLE `" . $this->getName() . "` ";
175-
$changes = [];
176-
foreach ($columns as $column) {
177-
if (in_array($column['field'], $existingFields)) {
178-
$changes[] = "MODIFY COLUMN " . $column["query"];
179-
} else {
180-
$changes[] = "ADD " . $column["query"];
164+
if ($field->getColumnAttribute()->unique)
165+
$col->unqiue();
166+
167+
$col->nullable($field->getType()->allowsNull());
181168
}
182-
}
183-
foreach ($indexes as $index) {
184-
$index = $index["field"];
185-
if (!in_array($index, $existingIndexes))
186-
$changes[] = 'ADD INDEX (`' . $index . '`);';
187-
}
169+
];
170+
}, $fields);
188171

189-
$q .= implode(", ", $changes) . ';';
190-
$database->query($q);
172+
if (in_array($this->getName(), $tables)) {
173+
$database->edit($this->getName(), function (Blueprint $blueprint) use ($columns) {
174+
foreach ($columns as $column)
175+
$column["blueprintHandler"]($blueprint);
176+
});
191177
} else {
192-
$q = "CREATE TABLE " . $this->getName() . " (" .
193-
implode(', ', array_map(fn($c) => $c['query']
194-
. ($c['identifier'] ? ' PRIMARY KEY' : ''
195-
), $columns)
196-
);
197-
198-
if (count($indexes) > 0) {
199-
$q .= ", INDEX (" . implode(", ", array_map(fn($c) => $c["field"], $indexes)) . ")";
200-
}
201-
202-
$q .= ");";
203-
$database->query($q);
178+
$database->create($this->getName(), function (Blueprint $blueprint) use ($columns) {
179+
foreach ($columns as $column)
180+
$column["blueprintHandler"]($blueprint);
181+
});
204182
}
205183
}
206184

de/interaapps/ulole/orm/ORMModel.php

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,24 +49,14 @@ public function insert(string $database = 'main'): bool {
4949
}
5050
}
5151

52-
$query = 'INSERT INTO `' . UloleORM::getTableName(static::class) . '` (';
52+
$insertion = UloleORM::getDatabase($database)->getDriver()->insert(UloleORM::getTableName(static::class), $fields, $values);
5353

54-
foreach ($fields as $i => $field)
55-
$query .= ($i == 0 ? '' : ', ') . '`' . $field . '`';
54+
if ($insertion === false)
55+
return false;
5656

57-
$query .= ') VALUES (';
58-
59-
foreach ($values as $i => $value)
60-
$query .= ($i == 0 ? '' : ', ') . '?';
61-
$query .= ')';
62-
63-
$statement = UloleORM::getDatabase($database)->getConnection()->prepare($query);
64-
65-
$result = $statement->execute($values);
66-
$this->{UloleORM::getModelInformation(static::class)->getIdentifier()} = UloleORM::getDatabase($database)->getConnection()->lastInsertId();
67-
if ($result)
68-
$this->ormInternals_entryExists = true;
69-
return $result;
57+
$this->{UloleORM::getModelInformation(static::class)->getIdentifier()} = $insertion;
58+
$this->ormInternals_entryExists = true;
59+
return true;
7060
}
7161

7262
public function delete(string $database = 'main'): bool {

0 commit comments

Comments
 (0)