From a536a3bec4ed8512dd1c8c5c19e7fe4deb9e42f8 Mon Sep 17 00:00:00 2001 From: vlw Date: Wed, 25 Sep 2024 13:27:20 +0000 Subject: [PATCH 1/6] chore: rename of this package to "php-mysql" (#36) The name I gave this years ago "libmysqldriver" never sat right with me.. okay it might be considered a library for mysql but it's *definitely* not a driver. Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/36 Co-authored-by: vlw Co-committed-by: vlw --- README.md | 12 ++++++------ composer.json | 10 +++++----- src/MySQL.php | 4 ++-- src/Operators.php | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 60fc1b7..aa2b1c3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# php-libmysqldriver +# php-mysql -This library provides abstraction methods for common operations on MySQL-like databases like `SELECT`, `UPDATE`, and `INSERT` using method chaining for the various MySQL features. +This is a simple abstraction library for MySQL DML operations. For example: ```php @@ -17,16 +17,16 @@ SELECT $columns FROM $table WHERE $filter ORDER BY $order_by LIMIT $limit; ``` > [!IMPORTANT] -> This library is built on top of the PHP [`MySQL Improved`](https://www.php.net/manual/en/book.mysqli.php) extension and requires PHP 8.0 or newer. +> This library requires the [`MySQL Improved`](https://www.php.net/manual/en/book.mysqli.php) extension and requires PHP 8.0 or newer. ## Install from composer ``` -composer require victorwesterlund/libmysqldriver +composer require vlw/mysql ``` ```php -use libmysqldriver/MySQL; +use vlw\MySQL\MySQL; ``` # Example / Documentation @@ -53,7 +53,7 @@ id|beverage_type|beverage_name|beverage_size 3|tea|black|15 ```php -use libmysqldriver\MySQL; +use vlw\MySQL\MySQL; // Pass through: https://www.php.net/manual/en/mysqli.construct.php $db = new MySQL($host, $user, $pass, $db); diff --git a/composer.json b/composer.json index 294f3de..8394132 100644 --- a/composer.json +++ b/composer.json @@ -1,18 +1,18 @@ { - "name": "victorwesterlund/libmysqldriver", - "description": "Abstraction library for common mysqli features", + "name": "vlw/mysql", + "description": "Abstraction library for common MySQL/MariaDB DML operations with php-mysqli", "type": "library", - "license": "GPL-3.0-only", + "license": "GPL-3.0-or-later", "authors": [ { "name": "Victor Westerlund", - "email": "victor.vesterlund@gmail.com" + "email": "victor@vlw.se" } ], "minimum-stability": "dev", "autoload": { "psr-4": { - "libmysqldriver\\": "src/" + "vlw\\MySQL\\": "src/" } }, "require": {} diff --git a/src/MySQL.php b/src/MySQL.php index cf7e9ef..f5f56f1 100644 --- a/src/MySQL.php +++ b/src/MySQL.php @@ -1,6 +1,6 @@ Date: Wed, 25 Sep 2024 13:27:55 +0000 Subject: [PATCH 2/6] fix: remove `where()` method for database models (#37) This PR removes the `where()` method which I don't think is particularly useful and also very untested since I don't use it personally at all. It's also probably better to do in-model checking for table columns **before** sending it off to this library when required anyways. Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/37 Co-authored-by: vlw Co-committed-by: vlw --- README.md | 11 -------- src/MySQL.php | 69 --------------------------------------------------- 2 files changed, 80 deletions(-) diff --git a/README.md b/README.md index aa2b1c3..7d94867 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,6 @@ This is a simple abstraction library for MySQL DML operations. For example: ```php MySQL->for(string $table) - ->with(?array $model) ->where(?array ...$conditions) ->order(?array $order_by) ->limit(int|array|null $limit) @@ -367,13 +366,3 @@ $coffee = MySQL->for("beverages")->limit(3, 2)->select(["beverage_name", "bevera // ...etc ] ``` - ----- - -# Restrict affected/returned database columns to table model - -Chain and pass an array to `MySQL->with()` before a `select()`, `update()`, or `insert()` method to limit which columns will be returned/affected. It will use the **values** of the array so it can be either sequential or associative. - -**This method will cause `select()`, `update()`, and `insert()` to ignore any columns that are not present in the passed table model.** - -You can remove an already set table model by passing `null` to `MySQL->with()` diff --git a/src/MySQL.php b/src/MySQL.php index f5f56f1..7dd77a0 100644 --- a/src/MySQL.php +++ b/src/MySQL.php @@ -15,7 +15,6 @@ // Interface for MySQL_Driver with abstractions for data manipulation class MySQL extends mysqli { private string $table; - private ?array $model = null; private ?string $limit = null; private ?string $order_by = null; @@ -55,14 +54,6 @@ return array_map(fn($v): mixed => gettype($v) === "boolean" ? self::filter_boolean($v) : $v, $values); } - // Return value(s) that exist in $this->model - private function in_model(string|array $columns): ?array { - // Place string into array - $columns = is_array($columns) ? $columns : [$columns]; - // Return columns that exist in table model - return array_filter($columns, fn($col): string => in_array($col, $this->model)); - } - /* # Definers These methods are used to build an SQL query by chaining methods together. @@ -80,30 +71,6 @@ return $this; } - // Restrict query to array of column names - public function with(?array $model = null): self { - // Remove table model if empty - if (!$model) { - $this->model = null; - return $this; - } - - // Reset table model - $this->model = []; - - foreach ($model as $k => $v) { - // Column values must be strings - if (!is_string($v)) { - throw new Exception("Key {$k} must have a value of type string"); - } - - // Append column to model - $this->model[] = $v; - } - - return $this; - } - // Create a WHERE statement from filters public function where(?array ...$conditions): self { // Unset filters if null was passed @@ -128,10 +95,6 @@ // Create SQL string and append values to array for prepared statement foreach ($condition as $col => $operation) { - if ($this->model && !$this->in_model($col)) { - continue; - } - // Assume we want an equals comparison if value is not an array if (!is_array($operation)) { $operation = [Operators::EQUALS->value => $operation]; @@ -230,11 +193,6 @@ // Create array of columns from CSV $this->columns = is_array($columns) || is_null($columns) ? $columns : explode(",", $columns); - // Filter columns that aren't in the model if defiend - if ($columns && $this->model) { - $columns = $this->in_model($this->columns); - } - // Create CSV from columns or default to SQL NULL as a string $columns_sql = $this->columns ? implode(",", $this->columns) : "NULL"; @@ -257,16 +215,6 @@ public function update(array $entity): mysqli_result|bool { $this->throw_if_no_table(); - // Make constraint for table model if defined - if ($this->model) { - foreach (array_keys($entity) as $col) { - // Throw if column in entity does not exist in defiend table model - if (!in_array($col, $this->model)) { - throw new Exception("Column key '{$col}' does not exist in table model"); - } - } - } - // Create CSV string with Prepared Statement abbreviations from length of fields array. $changes = array_map(fn($column) => "{$column} = ?", array_keys($entity)); $changes = implode(",", $changes); @@ -291,11 +239,6 @@ public function insert(array $values): mysqli_result|bool { $this->throw_if_no_table(); - // A value for each column in table model must be provided - if ($this->model && count($values) !== count($this->model)) { - throw new Exception("Values length does not match columns in model"); - } - /* Use array keys from $values as columns to insert if array is associative. Treat statement as an all-columns INSERT if the $values array is sequential. @@ -317,18 +260,6 @@ public function delete(array ...$conditions): mysqli_result|bool { $this->throw_if_no_table(); - // Make constraint for table model if defined - if ($this->model) { - foreach ($conditions as $condition) { - foreach (array_keys($condition) as $col) { - // Throw if column in entity does not exist in defiend table model - if (!in_array($col, $this->model)) { - throw new Exception("Column key '{$col}' does not exist in table model"); - } - } - } - } - // Set DELETE WHERE conditions from arguments $this->where(...$conditions); From 619f43b3bfab9eb034dca3e54c7466055240c861 Mon Sep 17 00:00:00 2001 From: vlw Date: Wed, 25 Sep 2024 13:28:15 +0000 Subject: [PATCH 3/6] fix(doc): remove reference to removed method `flatten()` from README (#38) Closes #14 Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/38 Co-authored-by: vlw Co-committed-by: vlw --- README.md | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/README.md b/README.md index 7d94867..f4b76c5 100644 --- a/README.md +++ b/README.md @@ -107,24 +107,6 @@ $beverages = MySQL->for("beverages")->select(["beverage_name", "beverage_size"]) ] ``` -## Flatten array to single dimension - -If you don't want an array of arrays and would instead like to access each key value pair directly. Chain the `MySQL->flatten()` anywhere before `MySQL->select()`. -This will return the key value pairs of the first entry directly. - -> **Note** -> This method will not set `LIMIT 1` for you. It is recommended to chain `MySQL->limit(1)` anywhere before `MySQL->select()`. [You can read more about it here](https://github.com/VictorWesterlund/php-libmysqldriver/issues/14) - -```php -$coffee = MySQL->for("beverages")->limit(1)->flatten()->select(["beverage_name", "beverage_size"]); // SELECT beverage_name, beverage_size FROM beverages WHERE beverage_type = "coffee" LIMIT 1 -``` -```php -[ - "beverage_name" => "cappuccino", - "beverage_size" => 10 -] -``` - # INSERT Chain `MySQL->insert()` anywhere after a [`MySQL->for()`](#for) to append a new row to a database table. @@ -329,9 +311,6 @@ MySQL->limit( ): self; ``` -> **Note** -> You can also flatten to a single dimensional array from the first entity by chaining [`MySQL->flatten()`](#flatten-array-to-single-dimension) - ## Passing a single integer argument This will simply `LIMIT` the results returned to the integer passed From d5f1efb9b902722fa7d6f97366c8cfc307593342 Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Fri, 20 Dec 2024 10:59:02 +0000 Subject: [PATCH 4/6] feat: expose SQL class properties to protected scope (#39) Makes sense to make these accessible when extending the MySQL class. Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/39 --- src/MySQL.php | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/MySQL.php b/src/MySQL.php index 7dd77a0..3367d21 100644 --- a/src/MySQL.php +++ b/src/MySQL.php @@ -14,15 +14,13 @@ // Interface for MySQL_Driver with abstractions for data manipulation class MySQL extends mysqli { - private string $table; - - private ?string $limit = null; - private ?string $order_by = null; - private array $filter_values = []; - private ?string $filter_sql = null; - - // Array of last SELECT-ed columns public ?array $columns = null; + + protected string $table; + protected ?string $limit = null; + protected ?string $order_by = null; + protected array $filter_values = []; + protected ?string $filter_sql = null; // Pass constructor arguments to driver function __construct() { From 64c7bae3cf6124dcb64c9e8ef93425be3602e82a Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Thu, 16 Jan 2025 13:53:30 +0000 Subject: [PATCH 5/6] feat: add protected array property for where statement columns (#40) This PR adds a compliment for the `MySQL->filter_values` property but for filter columns which can be accessed from a protected scope with `MySQL->filter_columns` Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/40 --- src/MySQL.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/MySQL.php b/src/MySQL.php index 3367d21..8fe9ef8 100644 --- a/src/MySQL.php +++ b/src/MySQL.php @@ -19,6 +19,7 @@ protected string $table; protected ?string $limit = null; protected ?string $order_by = null; + protected array $filter_columns = []; protected array $filter_values = []; protected ?string $filter_sql = null; @@ -74,6 +75,7 @@ // Unset filters if null was passed if ($conditions === null) { $this->filter_sql = null; + $this->filter_columns = null; $this->filter_values = null; return $this; @@ -93,6 +95,8 @@ // Create SQL string and append values to array for prepared statement foreach ($condition as $col => $operation) { + $this->filter_columns[] = $col; + // Assume we want an equals comparison if value is not an array if (!is_array($operation)) { $operation = [Operators::EQUALS->value => $operation]; From e65c74797bce90e15a7ce7c87864350abaaf978f Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Thu, 30 Jan 2025 08:16:27 +0000 Subject: [PATCH 6/6] feat: add ORDER BY statement Enum (#41) Importable with: ```php use vlw\MySQL\Order ``` To be used with the `MySQL->order()` method, for example: ```php $db->for("table")->order(["column" => Order::ASC])->select("*"); ``` Reviewed-on: https://codeberg.org/vlw/php-mysql/pulls/41 --- src/Order.php | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/Order.php diff --git a/src/Order.php b/src/Order.php new file mode 100644 index 0000000..b216d63 --- /dev/null +++ b/src/Order.php @@ -0,0 +1,8 @@ +