mirror of
https://codeberg.org/vlw/php-mysql.git
synced 2025-09-14 00:33:41 +02:00
Squashed commit of the following:
commite65c74797b
Author: Victor Westerlund <victor@vlw.se> 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 commit64c7bae3cf
Author: Victor Westerlund <victor@vlw.se> 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 commitd5f1efb9b9
Author: Victor Westerlund <victor@vlw.se> 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 commit619f43b3bf
Author: vlw <victor@vlw.se> 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 <victor@vlw.se> Co-committed-by: vlw <victor@vlw.se> commit1727247fa7
Author: vlw <victor@vlw.se> 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 <victor@vlw.se> Co-committed-by: vlw <victor@vlw.se> commita536a3bec4
Author: vlw <victor@vlw.se> 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 <victor@vlw.se> Co-committed-by: vlw <victor@vlw.se>
This commit is contained in:
parent
1da21b4b33
commit
78887576ef
5 changed files with 24 additions and 124 deletions
44
README.md
44
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()`
|
||||
|
|
|
@ -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": {}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace libmysqldriver;
|
||||
namespace vlw\MySQL;
|
||||
|
||||
use Exception;
|
||||
|
||||
|
@ -8,25 +8,22 @@
|
|||
use mysqli_stmt;
|
||||
use mysqli_result;
|
||||
|
||||
use libmysqldriver\Order;
|
||||
use libmysqldriver\Operators;
|
||||
use vlw\MySQL\Operators;
|
||||
|
||||
require_once "Order.php";
|
||||
require_once "Operators.php";
|
||||
|
||||
// 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;
|
||||
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_columns = [];
|
||||
protected array $filter_values = [];
|
||||
protected ?string $filter_sql = null;
|
||||
|
||||
// Pass constructor arguments to driver
|
||||
function __construct() {
|
||||
parent::__construct(...func_get_args());
|
||||
|
@ -61,14 +58,6 @@
|
|||
return array_map(fn(mixed $v): string => "`{$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);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace libmysqldriver;
|
||||
namespace vlw\MySQL;
|
||||
|
||||
enum Operators: string {
|
||||
// Logical
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace libmysqldriver;
|
||||
namespace vlw\MySQL;
|
||||
|
||||
enum Order: string {
|
||||
case ASC = "ASC";
|
||||
|
|
Loading…
Add table
Reference in a new issue