move from old repository

This commit is contained in:
Jan-Niclas Loosen 2025-02-12 15:03:39 +01:00
parent b684096b4a
commit 29703314a3
19 changed files with 1097 additions and 0 deletions

49
Conditionable.php Normal file
View File

@ -0,0 +1,49 @@
<?php
namespace DatabaseHelper;
use DatabaseHelper\enums\Operator;
trait Conditionable
{
protected array $conditions = [];
protected Schema $schema;
public function where(string $col, string|Operator $operator, mixed $val): self {
return $this->addCondition($col, $operator, $val, "AND");
}
public function andWhere(string $col, string|Operator $operator, mixed $val): self {
return $this->addCondition($col, $operator, $val, "AND");
}
public function orWhere(string $col, string|Operator $operator, mixed $val): self {
return $this->addCondition($col, $operator, $val, "OR");
}
protected function addCondition(string $col, string|Operator $operator, mixed $val, string $prefix): self {
$this->schema->requireColumn($col);
// Convert the operator string to a ConditionOperator enum if needed.
if (is_string($operator))
$operator = Operator::fromString($operator);
$columnType = $this->schema->columnType($col);
$castedValue = $columnType->dbCast($val);
if (!empty($this->conditions))
$this->conditions[] = $prefix;
$this->conditions[] = "$col " . $operator->toString() . " $castedValue";
return $this;
}
public function isConditioned(): bool {
return !empty($this->conditions);
}
protected function combineConditions(): string {
if ($this->isConditioned())
return implode(" ", $this->conditions);
return "";
}
}

54
Database.php Normal file
View File

@ -0,0 +1,54 @@
<?php
namespace DatabaseHelper;
class Database
{
/**
* Creates a new TableBlueprint instance for the specified table name.
* @param string $tableName The name of the table to create.
* @return Table instance supporting method chaining
*/
public static function makeTable(string $tableName): Table {
return new Table($tableName);
}
public static function makeMigration(Schema $table): Migration {
// TODO: Implement makeMigration() method.
}
/**
* Creates a new QueryBuilder instance for the specified table.
* @param Schema $table The table to query on.
* @return Query instance supporting method chaining.
*/
public static function makeQuery(Schema $table): Query {
return new Query($table);
}
public static function makeDeletion(Schema $table): Deletion {
// TODO: Implement makeDeletion() method.
}
public static function makeInsertion(Schema $table): Insertion {
return new Insertion($table);
}
public static function makeUpdate(Schema $table): Update {
return new Update($table);
}
/**
* Adds the WordPress database prefix to table names if not already present.
* @param string ...$tableName Array of table names to process
* @return void
*/
public static function standardizeTableNames(string &...$tableName): void {
global $wpdb;
$dbPrefix = $wpdb->prefix;
foreach ($tableName as &$name)
if (!str_starts_with($name, $dbPrefix))
$name = $dbPrefix . $name;
}
}

62
Deletion.php Normal file
View File

@ -0,0 +1,62 @@
<?php
namespace DatabaseHelper;
use Exception;
use InvalidArgumentException;
class Deletion
{
use Conditionable;
protected Schema $table;
public function __construct(Schema $table) {
$this->table = $table;
}
/**
* Generates the SQL statement.
* @return string SQL query.
* @throws InvalidArgumentException
*/
public function toSql(): string {
$table = $this->table->name;
$whereClause = $this->combineConditions();
if (!$this->isConditioned())
throw new InvalidArgumentException("Deletions need to be conditioned.");
return esc_sql("DELETE FROM $table WHERE $whereClause");
}
/**
* Executes the DELETE query.
* @return int Number of affected rows.
* @throws Exception
*/
public function delete(): int {
global $wpdb;
$query = $this->toSql();
$result = $wpdb->query($query);
if ($result === false)
throw new Exception("Deletion failed: " . $wpdb->last_error . ".");
return intval($result);
}
/**
* Clears all entries from the table.
* @return int Number of affected rows.
* @throws Exception
*/
public function truncate(): int {
global $wpdb;
$table = $this->table->name;
$query = esc_sql("TRUNCATE TABLE $table");
$result = $wpdb->query($query);
if ($result === false)
throw new Exception("Truncation failed: " . $wpdb->last_error . ".");
return intval($result);
}
}

84
Insertion.php Normal file
View File

@ -0,0 +1,84 @@
<?php
namespace DatabaseHelper;
use InvalidArgumentException;
class Insertion
{
private Schema $table;
private array $currentRow = [];
private array $batchRows = [];
public function __construct(Schema $table) {
$this->table = $table;
}
/**
* Adds a single column-value pair to the row.
* @param string $col Column name.
* @param mixed $val Value to insert.
* @return Insertion Current instance for method chaining.
* @throws InvalidArgumentException
*/
public function data(string $col, mixed $val): Insertion {
if (!isset($this->table->columns[$col]))
throw new InvalidArgumentException("Column '$col' does not exist.");
$columnType = $this->table->columns[$col]['colType'];
$this->currentRow[$col] = $columnType->dbCast($val);
return $this;
}
/**
* Adds multiple column-value pairs to the row.
* @param array $data Associative array of column-value pairs.
* @return Insertion Current instance for method chaining.
* @throws InvalidArgumentException
*/
public function batchData(array $data): Insertion {
foreach ($data as $key => $value)
$this->data($key, $value);
return $this;
}
/**
* Finalizes the current row and stacks it for insertion.
* @return Insertion Current instance for method chaining.
*/
public function stack(): Insertion {
if (!empty($this->currentRow))
$this->stackForInsertion();
return $this;
}
private function stackForInsertion(): void {
$this->batchRows[] = $this->currentRow;
$this->currentRow = [];
}
/**
* Executes the insertion of all batched rows into the database.
* @throws InvalidArgumentException
*/
public function insert(): bool {
global $wpdb;
// Convert single to batch queries.
if (!empty($this->currentRow))
$this->stackForInsertion();
if (empty($this->batchRows))
throw new InvalidArgumentException("No data set for insertion.");
foreach ($this->batchRows as $row) {
if (!empty($row)) {
$result = $wpdb->insert($this->table->name, $row);
if ($result === false)
return false;
}
}
return true;
}
}

139
Migration.php Normal file
View File

@ -0,0 +1,139 @@
<?php
namespace DatabaseHelper;
use DatabaseHelper\enums\Propagation;
use DatabaseHelper\enums\Type;
use InvalidArgumentException;
class Migration
{
protected Schema $table;
protected array $columnsToAdd = [];
protected array $columnsToModify = [];
protected array $columnsToDrop = [];
protected array $primaryKey = null;
protected array $foreignKeysToAdd = [];
protected array $foreignKeysToDrop = [];
public function __construct(Schema $table) {
$this->table = $table->copy();
}
public function addColumn(string $name, Type $type, mixed $default = null, bool $isNullable = false, bool $isUnique = false): Migration {
$this->table->columns[$name] = [
'name' => $name,
'type' => $type,
'default' => $default,
'isNullable' => $isNullable,
'isUnique' => $isUnique
];
$this->columnsToAdd[] = $name;
return $this;
}
public function modifyColumn(string $name, Type $type, mixed $default = null, bool $isNullable = false, bool $isUnique = false): Migration {
if (!isset($this->table->columns[$name])) {
throw new InvalidArgumentException("Column $name does not exist.");
}
$this->table->columns[$name] = [
'name' => $name,
'type' => $type,
'default' => $default,
'isNullable' => $isNullable,
'isUnique' => $isUnique
];
$this->columnsToModify[] = $name;
return $this;
}
public function dropColumn(string $name): Migration {
if (!isset($this->table->columns[$name])) {
throw new InvalidArgumentException("Column $name does not exist.");
}
unset($this->table->columns[$name]);
$this->columnsToDrop[] = $name;
return $this;
}
public function changePrimaryKey(string $name, bool $autoInc = false): Migration {
if (!isset($this->table->columns[$name])) {
throw new InvalidArgumentException("Column $name does not exist.");
}
$this->table->primaryKey = [
'name' => $name,
'autoInc' => $autoInc
];
$this->primaryKey = $name;
return $this;
}
public function addForeignKey(string $column, string $referencedTable, string $referencedColumn, Propagation $onDelete, Propagation $onUpdate): Migration {
if (!isset($this->table->columns[$column])) {
throw new InvalidArgumentException("Column $column does not exist.");
}
$this->table->foreignKeys[$column] = [
'referencedTable' => $referencedTable,
'referencedColumn' => $referencedColumn,
'onDelete' => $onDelete,
'onUpdate' => $onUpdate
];
$this->foreignKeysToAdd[] = $column;
return $this;
}
public function dropForeignKey(string $name): Migration {
if (!isset($this->table->foreignKeys[$name])) {
throw new InvalidArgumentException("Foreign key $name does not exist.");
}
unset($this->table->foreignKeys[$name]);
$this->foreignKeysToDrop[] = $name;
return $this;
}
public function toSql(): string {
$sql = "ALTER TABLE `{$this->table->name}` ";
$statements = [];
foreach ($this->columnsToAdd as $name) {
$col = $this->table->columns[$name];
$statements[] = "ADD COLUMN `{$col['name']}` {$col['type']->toString()}" .
($col['isNullable'] ? "" : " NOT NULL") .
($col['isUnique'] ? " UNIQUE" : "") .
($col['default'] !== null ? " DEFAULT " . (is_string($col['default']) ? "'{$col['default']}'" : $col['default']) : "");
}
foreach ($this->columnsToModify as $name) {
$col = $this->table->columns[$name];
$statements[] = "MODIFY COLUMN `{$col['name']}` {$col['type']->toString()}" .
($col['isNullable'] ? "" : " NOT NULL") .
($col['isUnique'] ? " UNIQUE" : "") .
($col['default'] !== null ? " DEFAULT " . (is_string($col['default']) ? "'{$col['default']}'" : $col['default']) : "");
}
foreach ($this->columnsToDrop as $name) {
$statements[] = "DROP COLUMN `$name`";
}
foreach ($this->foreignKeysToDrop as $name) {
$statements[] = "DROP FOREIGN KEY `$name`";
}
foreach ($this->foreignKeysToAdd as $column) {
$fk = $this->table->foreignKeys[$column];
$statements[] = "ADD CONSTRAINT `fk_{$column}` FOREIGN KEY (`$column`) REFERENCES `{$fk['referencedTable']}` (`{$fk['referencedColumn']}`) ON DELETE {$fk['onDelete']->toString()} ON UPDATE {$fk['onUpdate']->toString()}";
}
return $sql . implode(", ", $statements) . ";";
}
public function drop(): null {
}
public function migrate(): Schema {
global $wpdb;
$sql = $this->toSql();
$wpdb->query($sql);
return $this->table;
}
}

109
Query.php Normal file
View File

@ -0,0 +1,109 @@
<?php
namespace DatabaseHelper;
use DatabaseHelper\enums\Join;
use DatabaseHelper\enums\Order;
use http\Exception\InvalidArgumentException;
use SimplePie\Exception;
class Query
{
use Conditionable;
protected Schema $schema;
protected array $columns = ['*'];
protected array $joins = [];
public array $orderBy;
public function __construct(Schema $table) {
$this->schema = $table;
}
public function select(string ...$cols): Query {
if (!empty($cols))
$this->columns = $cols;
foreach ($cols as $col)
$this->schema->requireColumn($col);
return $this;
}
public function orderBy(string $col, Order $order): Query {
$this->schema->requireColumn($col);
$this->orderBy = [
'name' => $col,
'order' => $order
];
return $this;
}
public function join(Schema $other, Join $join): Query {
$foreignKey = null;
if($this->schema->existsReference($other))
$foreignKey = $this->schema->foreignKeys[$other->name];
if ($other->existsReference($this->schema))
$foreignKey = $other->foreignKeys[$this->schema->name];
if (is_null($foreignKey))
throw new InvalidArgumentException('Joins can only applied to referencing columns.');
// TODO: Implement include instead of merge
$this->schema->include($other);
$this->joins[] = [
'table' => $other->name,
'type' => $join
];
return $this;
}
protected function isOrdered(): bool {
return !empty($this->orderBy);
}
protected function isJoined(): bool {
return !empty($this->joins);
}
public function toSql(): string {
// Build the SELECT clause.
$columns = implode(", ", $this->columns);
$primaryTable = $this->schema->name;
$sqlStatement = "SELECT $columns FROM $primaryTable";
// Append join clauses, if any.
if ($this->isJoined()) {
foreach ($this->joins as $join) {
$sqlStatement .= " " . $join['type']->toString() . " NATURAL JOIN " . $join['table'];
}
}
// Append the WHERE clause if conditions exist.
if ($this->isConditioned()) {
$whereClause = $this->combineConditions();
$sqlStatement .= " WHERE $whereClause";
}
// Append the ORDER BY clause if ordering is set.
if ($this->isOrdered()) {
$orderClause = $this->orderBy['name'] . ' ' . $this->orderBy['order'];
$sqlStatement .= " ORDER BY $orderClause";
}
return esc_sql($sqlStatement);
}
public function query(): array {
global $wpdb;
$query = $this->toSql();
$results = $wpdb->get_results($query, ARRAY_A);
return $this->castResults($results);
}
protected function castResults(array $results): array {
foreach ($results as &$row)
foreach ($row as $column => &$value)
if (isset($this->columnTypes[$column]))
$value = $this->columnTypes[$column]->valCast($value);
return $results;
}
}

78
Schema.php Normal file
View File

@ -0,0 +1,78 @@
<?php
namespace DatabaseHelper;
use DatabaseHelper\enums\Charset;
use DatabaseHelper\enums\Collation;
use DatabaseHelper\enums\Engine;
use http\Exception\InvalidArgumentException;
class Schema
{
public string $name = '';
public array $columns = [];
public array $primaryKey = [];
public array $foreignKeys = [];
public Engine $engine = Engine::INNODB;
public Charset $charset = Charset::UTF8;
public Collation $collation = Collation::UTF8_GENERAL_CI;
public function __construct(string $name) {
$this->name = $name;
}
public function requireColumn(string $col): void {
if (!$this->existsColumn($col))
throw new InvalidArgumentException("Column '$col' is not defined.");
}
public function existsColumn(string $col): bool {
return isset($this->columns[$col]);
}
public function existsReference(Schema $schema): bool {
foreach ($this->foreignKeys as $foreignKey)
if ($foreignKey['table'] == $schema->name)
return true;
return false;
}
public function columnType(string $col) {
return $this->columns[$col]['type'];
}
public function primaryKey() {
return $this->columns['primary']['name'];
}
/**
* Creates a deep copy of this instance.
* @return Schema
*/
public function copy(): Schema {
$copy = new Schema($this->name);
$copy->columns = genericDeepCopy($this->columns);
$copy->primaryKey = genericDeepCopy($this->primaryKey);
$copy->foreignKeys = genericDeepCopy($this->foreignKeys);
$copy->engine = $this->engine;
$copy->charset = $this->charset;
$copy->collation = $this->collation;
return $copy;
}
public function include(Schema $other): void {
// Create a copy of the other schema.
$otherCopy = $other->copy();
// Add any column that isn't already defined.
foreach ($otherCopy->columns as $colName => $colDef)
if (!isset($this->columns[$colName]))
$this->columns[$colName] = $colDef;
// Add any foreign key that doesn't already exist.
foreach ($other->foreignKeys as $colName => $foreignKey)
if (!isset($this->foreignKeys[$colName]))
$this->foreignKeys[$colName] = $foreignKey;
}
}

131
Table.php Normal file
View File

@ -0,0 +1,131 @@
<?php
namespace DatabaseHelper;
use DatabaseHelper\enums\Propagation;
use DatabaseHelper\enums\Charset;
use DatabaseHelper\enums\Collation;
use DatabaseHelper\enums\Type;
use DatabaseHelper\enums\Engine;
use InvalidArgumentException;
class Table
{
protected Schema $table;
public function __construct(string $tableName) {
Database::standardizeTableNames($tableName);
$this->table = new Schema($tableName);
}
public function column(string $name, Type $type, mixed $default = null, bool $isNullable = false, bool $isUnique = false): Table {
$this->table->columns[$name] = [
'name' => $name,
'default' => $default,
'type' => $type,
'isNullable' => $isNullable,
'isUnique' => $isUnique
];
return $this;
}
public function primary(string $name, Type $type, bool $autoInc = false): Table {
if(isset($this->primaryKey))
throw new InvalidArgumentException('Primary column already exists.');
$this->table->primaryKey = [
'name' => $name,
'autoInc' => $autoInc
];
return $this->column($name, $type);
}
public function reference(Schema $foreignTable, Propagation $onDelete = Propagation::CASCADE, Propagation $onUpdate = Propagation::CASCADE): Table {
$name = $foreignTable->primaryKey();
if(isset($this->columns[$name]))
throw new InvalidArgumentException('Column name already exists.');
$this->table->foreignKeys[$name] = [
'name' => $name,
'table' => $foreignTable->name,
'onDelete' => $onDelete,
'onUpdate' => $onUpdate
];
$this->table->columns[$name] = $foreignTable->columns[$name];
return $this;
}
public function engine(Engine $engine): Table {
$this->table->engine = $engine;
return $this;
}
public function charset(Charset $charset): Table {
$this->table->charset = $charset;
return $this;
}
public function collation(Collation $collation): Table {
$this->table->collation = $collation;
return $this;
}
/**
* Generates the SQL statement.
* @return string SQL query.
* @throws InvalidArgumentException
*/
public function toSql(): string {
$primaryKey = $this->table->primaryKey();
$sql = "CREATE TABLE `{$this->table->name}` (\n";
$sql .= " PRIMARY KEY (`$primaryKey`),\n";
foreach ($this->table->columns as $col) {
if ($col['name'] !== $primaryKey) {
$sql .= " `{$col['name']}` {$col['type']->toString()}";
// Handle nulls, uniqueness, and defaults
if (!$col['isNullable'])
$sql .= " NOT NULL";
if ($col['isUnique'])
$sql .= " UNIQUE";
if ($col['default'] !== null) {
$default = is_string($col['default']) ? "'{$col['default']}'" : $col['default'];
$sql .= " DEFAULT $default";
}
$sql .= ",\n";
}
}
// Add secondary constraints if present
foreach ($this->table->foreignKeys as $key) {
$sql .= " FOREIGN KEY (`{$key['name']}`) REFERENCES `{$key['table']}` (`{$key['name']}`)";
$sql .= " ON DELETE {$key['onDelete']->toString()} ON UPDATE {$key['onUpdate']->toString()},\n";
}
// Close the SQL string and add constraints
$sql = rtrim($sql, ",\n") . "\n) ";
$sql .= "ENGINE={$this->table->engine->toString()} ";
$sql .= "CHARSET={$this->table->charset->toString()} ";
$sql -= "COLLATE={$this->table->collation->toString()};";
return esc_sql($sql);
}
public function create(): Schema {
global $wpdb;
if (empty($this->primaryKey))
throw new InvalidArgumentException('A primary key must be defined.');
$table_name = $wpdb->prefix . $this->table->name;
if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") !== $table_name) {
$sql = $this->toSql();
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
return $this->table;
}
}

69
Update.php Normal file
View File

@ -0,0 +1,69 @@
<?php
namespace DatabaseHelper;
use DatabaseHelper\enums\Type;
use DatabaseHelper\enums\Operator;
use InvalidArgumentException;
class Update
{
use Conditionable;
protected Schema $table;
protected array $values = [];
public function __construct(Schema $table) {
$this->table = $table;
}
/**
* Sets a new value for a column.
* @param string $col Column name.
* @param mixed $val Value to set.
* @return self Current instance for method chaining.
* @throws InvalidArgumentException
*/
public function set(string $col, mixed $val): self {
$this->table->requireColumn($col);
$columnType = $this->table->columnType($col);
$castedValue = $columnType->dbCast($val);
$this->values[$col] = $castedValue;
return $this;
}
/**
* Generates the SQL statement.
* @return string SQL query.
* @throws InvalidArgumentException
*/
public function toSql(): string {
if (empty($this->values))
throw new InvalidArgumentException("No values have been set for the Update.");
$table = $this->table->name;
$setParts = [];
foreach ($this->values as $col => $value)
$setParts[] = "$col = $value";
$setClause = implode(", ", $setParts);
// FINAL SQL STATEMENT
$sqlStatement = "UPDATE $table SET $setClause";
if($this->isConditioned()) {
$whereClause = $this->combineConditions();
$sqlStatement .= " WHERE $whereClause";
}
return esc_sql($sqlStatement);
}
/**
* Executes the SQL UPDATE query.
* @return bool Returns true on success.
*/
public function update(): bool {
global $wpdb;
$query = $this->toSql();
$result = $wpdb->query($query);
return boolval($result);
}
}

42
build.php Normal file
View File

@ -0,0 +1,42 @@
<?php
// Helpers
function genericDeepCopy(mixed $data): mixed {
if (is_array($data)) {
$copy = [];
foreach ($data as $key => $value)
$copy[$key] = genericDeepCopy($value);
return $copy;
}
elseif (is_object($data)) {
// If the object supports a copy method.
if (method_exists($data, 'copy'))
return $data->copy();
// Use PHP's clone as fallback.
return clone $data;
}
else {
// Scalar variables.
return $data;
}
}
// Require all enums
require './enums/Propagation.php';
require './enums/Operator.php';
require './enums/Order.php';
require './enums/Charset.php';
require './enums/Collation.php';
require './enums/Type.php';
require './enums/Engine.php';
require './enums/Join.php';
// Require all classes
require './Database.php';
require './Conditionable.php';
require './Deletion.php';
require './Insertion.php';
require './Migration.php';
require './Query.php';
require './Schema.php';
require './Table.php';
require './Update.php';

40
enums/Charset.php Normal file
View File

@ -0,0 +1,40 @@
<?php
namespace DatabaseHelper\enums;
enum Charset
{
case UTF8;
case UTF8MB4;
case LATIN1;
case ASCII;
case UTF16;
case UTF32;
case LATIN2;
case LATIN5;
case CP1251;
case CP850;
case TIS620;
case GREEK;
case HEBREW;
case BINARY;
public function toString(): string {
return match ($this) {
self::UTF8 => 'utf8',
self::UTF8MB4 => 'utf8mb4',
self::LATIN1 => 'latin1',
self::ASCII => 'ascii',
self::UTF16 => 'utf16',
self::UTF32 => 'utf32',
self::LATIN2 => 'latin2',
self::LATIN5 => 'latin5',
self::CP1251 => 'cp1251',
self::CP850 => 'cp850',
self::TIS620 => 'tis620',
self::GREEK => 'greek',
self::HEBREW => 'hebrew',
self::BINARY => 'binary',
};
}
}

32
enums/Collation.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace DatabaseHelper\enums;
enum Collation
{
case UTF8_GENERAL_CI;
case UTF8_UNICODE_CI;
case UTF8_SPANISH_CI;
case UTF8MB4_UNICODE_CI;
case UTF8MB4_GENERAL_CI;
case UTF8MB4_UNICODE_520_CI;
case LATIN1_SWEDISH_CI;
case UTF8MB4_BIN;
case UTF8_BIN;
case LATIN1_BIN;
public function toString(): string {
return match ($this) {
self::UTF8_GENERAL_CI => 'utf8_general_ci',
self::UTF8_UNICODE_CI => 'utf8_unicode_ci',
self::UTF8_SPANISH_CI => 'utf8_spanish_ci',
self::UTF8MB4_UNICODE_CI => 'utf8mb4_unicode_ci',
self::UTF8MB4_GENERAL_CI => 'utf8mb4_general_ci',
self::UTF8MB4_UNICODE_520_CI => 'utf8mb4_unicode_520_ci',
self::LATIN1_SWEDISH_CI => 'latin1_swedish_ci',
self::UTF8MB4_BIN => 'utf8mb4_bin',
self::UTF8_BIN => 'utf8_bin',
self::LATIN1_BIN => 'latin1_bin',
};
}
}

15
enums/Engine.php Normal file
View File

@ -0,0 +1,15 @@
<?php
namespace DatabaseHelper\enums;
enum Engine
{
case INNODB;
case MYISAM;
public function toString(): string {
return match ($this) {
self::INNODB => 'InnoDB',
self::MYISAM => 'MyISAM',
};
}
}

20
enums/Join.php Normal file
View File

@ -0,0 +1,20 @@
<?php
namespace DatabaseHelper\enums;
enum Join
{
case INNER;
case LEFT;
case RIGHT;
case FULL;
public function toString(): string {
return match ($this) {
self::INNER => 'INNER JOIN',
self::LEFT => 'LEFT JOIN',
self::RIGHT => 'RIGHT JOIN',
self::FULL => 'FULL JOIN',
};
}
}

37
enums/Operator.php Normal file
View File

@ -0,0 +1,37 @@
<?php
namespace DatabaseHelper\enums;
use InvalidArgumentException;
enum Operator
{
case EQUAL;
case NOT_EQUAL;
case GREATER;
case GREATER_EQUAL;
case LESS;
case LESS_EQUAL;
public static function fromString(string $operator): self {
return match ($operator) {
'=' => self::EQUAL,
'!=' => self::NOT_EQUAL,
'>' => self::GREATER,
'>=' => self::GREATER_EQUAL,
'<' => self::LESS,
'<=' => self::LESS_EQUAL,
default => throw new InvalidArgumentException("Invalid operator: $operator"),
};
}
public function toString(): string {
return match ($this) {
self::EQUAL => '=',
self::NOT_EQUAL => '!=',
self::GREATER => '>',
self::GREATER_EQUAL => '>=',
self::LESS => '<',
self::LESS_EQUAL => '<=',
};
}
}

16
enums/Order.php Normal file
View File

@ -0,0 +1,16 @@
<?php
namespace DatabaseHelper\enums;
enum Order
{
case ASC;
case DESC;
public function toString(): string {
return match ($this) {
self::ASC => 'ASC',
self::DESC => 'DESC',
};
}
}

21
enums/Propagation.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace DatabaseHelper\enums;
enum Propagation
{
case CASCADE;
case SET_NULL;
case NO_ACTION;
case RESTRICT;
case SET_DEFAULT;
public function toString(): string {
return match ($this) {
self::CASCADE => 'CASCADE',
self::SET_NULL => 'SET NULL',
self::NO_ACTION => 'NO ACTION',
self::RESTRICT => 'RESTRICT',
self::SET_DEFAULT => 'SET DEFAULT',
};
}
}

46
enums/Type.php Normal file
View File

@ -0,0 +1,46 @@
<?php
namespace DatabaseHelper\enums;
use DateTime;
enum Type
{
case INT;
case FLOAT;
case STRING;
case BOOL;
case ARRAY;
case DATE;
public function valCast(mixed $value): mixed {
return match ($this) {
self::INT => (int) $value,
self::FLOAT => (float) $value,
self::STRING => (string) $value,
self::BOOL => filter_var($value, FILTER_VALIDATE_BOOLEAN),
self::ARRAY => is_array($value) ? $value : (json_decode($value, true) ?? []),
self::DATE => $value instanceof DateTime ? $value : (strtotime($value) ? new DateTime($value) : null),
};
}
public function dbCast(mixed $value): mixed {
return match ($this) {
self::INT => intval($value),
self::FLOAT => floatval($value),
self::STRING => esc_sql($value),
self::BOOL => filter_var($value, FILTER_VALIDATE_BOOLEAN) ? "TRUE" : "FALSE",
self::ARRAY => json_encode($value),
self::DATE => $value instanceof DateTime ? $value->format('Y-m-d H:i:s') : json_encode($value)
};
}
public function toString(): string {
return match ($this) {
self::INT => 'INTEGER',
self::FLOAT => 'FLOAT',
self::STRING => 'VARCHAR(255)',
self::BOOL => 'BOOLEAN',
self::ARRAY => 'JSON',
self::DATE => 'DATETIME',
};
}
}

53
index.php Normal file
View File

@ -0,0 +1,53 @@
<?php
/**
* Plugin Name: Database Helper
* Version: 1.0
* Author: Jan-Niclas Loosen (Loosen-IT and Designraketen GmbH)
* Author URI: https://example.com
* License: MIT
*/
use DatabaseHelper\Database;
use DatabaseHelper\enums\Order;
use DatabaseHelper\enums\Type;
try {
require 'build.php';
$table = Database::makeTable('testing-table')
->primary('col-primary', Type::INT, autoInc: true)
->column('col-one', Type::BOOL)
->column('col-two', Type::STRING)
->create();
$batches = [
[
['col-one', true],
['col-two', 'EXPLODING!!!']
],
[
['col-one', false],
['col-two', 'EXPLODING!!!']
],
];
$batchInsert = Database::makeInsertion($table);
foreach($batches as $batch) {
$batchInsert->batchData($batch)->stack();
}
$batchInsert->insert();
Database::makeUpdate($table)
->where('col-primary', '=', 1)
->set('col-one', false)
->update();
$results = Database::makeQuery($table)
->select('col-primary', 'col-one')
->where('col-one', '=', true)
->orderBy('col-one', Order::DESC)
->query();
}
catch ( Exception $e ) {
echo $e->getMessage();
}