From 78887576ef8afa6f7fe1fd901c0f9894e9b82d91 Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Thu, 30 Jan 2025 10:14:48 +0100 Subject: [PATCH] Squashed commit of the following: commit e65c74797bce90e15a7ce7c87864350abaaf978f Author: Victor Westerlund Date: Thu Jan 30 08:16:27 2025 +0000 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 commit 64c7bae3cf6124dcb64c9e8ef93425be3602e82a Author: Victor Westerlund Date: Thu Jan 16 13:53:30 2025 +0000 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 commit d5f1efb9b902722fa7d6f97366c8cfc307593342 Author: Victor Westerlund Date: Fri Dec 20 10:59:02 2024 +0000 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 commit 619f43b3bfab9eb034dca3e54c7466055240c861 Author: vlw Date: Wed Sep 25 13:28:15 2024 +0000 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 commit 1727247fa75d37ca2884960e604bdd8807e550c8 Author: vlw Date: Wed Sep 25 13:27:55 2024 +0000 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 commit a536a3bec4ed8512dd1c8c5c19e7fe4deb9e42f8 Author: vlw Date: Wed Sep 25 13:27:20 2024 +0000 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 | 44 ++++------------------- composer.json | 10 +++--- src/MySQL.php | 90 ++++++----------------------------------------- src/Operators.php | 2 +- src/Order.php | 2 +- 5 files changed, 24 insertions(+), 124 deletions(-) diff --git a/README.md b/README.md index 60fc1b7..f4b76c5 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,10 @@ -# 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 MySQL->for(string $table) - ->with(?array $model) ->where(?array ...$conditions) ->order(?array $order_by) ->limit(int|array|null $limit) @@ -17,16 +16,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 +52,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); @@ -108,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. @@ -330,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 @@ -367,13 +345,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/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 ba1baa0..ae86108 100644 --- a/src/MySQL.php +++ b/src/MySQL.php @@ -1,6 +1,6 @@ "`{$v}`", $input); } - // 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. @@ -86,35 +75,12 @@ 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 if ($conditions === null) { $this->filter_sql = null; + $this->filter_columns = null; $this->filter_values = null; return $this; @@ -134,9 +100,7 @@ // Create SQL string and append values to array for prepared statement foreach ($condition as $col => $operation) { - if ($this->model && !$this->in_model($col)) { - continue; - } + $this->filter_columns[] = $col; // Assume we want an equals comparison if value is not an array if (!is_array($operation)) { @@ -237,11 +201,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(",", self::array_wrap_accents($this->columns)) : "NULL"; @@ -264,16 +223,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); @@ -298,11 +247,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. @@ -324,18 +268,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); diff --git a/src/Operators.php b/src/Operators.php index 23f53dd..308c20b 100644 --- a/src/Operators.php +++ b/src/Operators.php @@ -1,6 +1,6 @@