From 6ef86c4fb9669abcf7738f59af76a21b49d90fc1 Mon Sep 17 00:00:00 2001 From: kekefreedog <70959083+kekefreedog@users.noreply.github.com> Date: Sat, 13 Jul 2024 15:37:14 +0200 Subject: [PATCH] Start to implement sql model for Mysql & Mariadb --- src/Driver/Model/Mariadb.php | 293 +++++++++ src/Driver/Model/Sql.php | 293 +++++++++ src/Library/Database/Driver/Mangodb.php | 2 +- src/Library/Database/Driver/Mariadb.php | 827 ++++++++++++++++++++++- src/Library/Database/Driver/Mysql.php | 831 +++++++++++++++++++++++- src/Model/App/Create.php | 8 + 6 files changed, 2245 insertions(+), 9 deletions(-) create mode 100644 src/Driver/Model/Mariadb.php diff --git a/src/Driver/Model/Mariadb.php b/src/Driver/Model/Mariadb.php new file mode 100644 index 0000000..21b1038 --- /dev/null +++ b/src/Driver/Model/Mariadb.php @@ -0,0 +1,293 @@ + + * @copyright 2022-2024 Kévin Zarshenas + */ +namespace CrazyPHP\Driver\Model; + +/** + * Dependances + */ +use CrazyPHP\Library\Database\Driver\Mariadb as MariadbModel; +use CrazyPHP\Interface\CrazyDriverModel; + +/** + * Crazy Driver Model Interface + * + * Interface for define compatible class with Driver Model (based on mongo or other model driver...) + * + * @package kzarshenas/crazyphp + * @author kekefreedog + * @copyright 2022-2024 Kévin Zarshenas + */ +class Mariadb extends CrazyDriverModel { + + /** Private parameters + ****************************************************** + */ + + /** @var Mysql Instance */ + public MariadbModel $mariadb; + + /** @var bool $attributesAsValues Indicate if attributes is set as values in current schema */ + # private bool $attributesAsValues = false; + + /** + * Constructor + * + * @return self + */ + public function __construct(...$inputs) { + + # Set name + $this->ingestParameters($inputs); + + # Sql connection + $this->newMariadb(); + + } + + /** Public mathods | Attributes + ****************************************************** + */ + + /** + * Set Attributes As Values + * + * Switch attributes to values + * + * @return self + */ + public function setAttributesAsValues():self { + + # Return self + return $this; + + } + + /** Public methods | Parser + ****************************************************** + */ + + /** + * Parse Id + * + * @param string|int $id Id to parse + * @param ?array $options Optionnal options + * @return self + */ + public function parseId(string|int $id, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Filters + * + * @param array $filters Filter to process + * @param ?array $options Optionnal options + * @return self + */ + public function parseFilter(?array $filters, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Sort + * + * @param null|array|string $sort Sort to process + * @param ?array $options Optionnal options + * @return self + */ + public function parseSort(null|array|string $sort, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Group + * + * @param array $group Group to process + * @param ?array $options Optionnal options + */ + public function parseGroup(?array $group, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Sql + * + * @param string $sql Sql query + * @param ?array $options Optionnal options + * @return self + */ + public function parseSql(string $sql, ?array $options = null):self { + + # Return self + return $this; + + } + + /** Public methods | Ingester + ****************************************************** + */ + + /** + * Ingest Data + * + * Import data in current driver + * + * @param array $data + * @param ?array $options Optionnal options + * @return self + */ + public function ingestData(array $data, ?array $options = null):self { + + # Return self + return $this; + + } + + /** Public methods | Pusher + ****************************************************** + */ + + /** + * Push to trash + * + * Put to trash current value + * + * @param ?array $options Optionnal options + * @param + */ + public function pushToTrash(?array $options = null):self { + + # Return self + return $this; + + } + + /** Public methods | Execute + ****************************************************** + */ + + /** + * Run + * + * Return data with given information + * + * @return array + */ + public function run():array { + + # Set result + $result = []; + + # Return result + return $result; + + } + + /** + * Count + * + * Return counted data with given information + * + * @return int + */ + public function count():int { + + # Set result + $result = 0; + + # Return result + return $result; + + } + + /** Public methods | tests + ****************************************************** + */ + + /** + * Force Summary + * + * Use for test for force summary argument value + * + * @param null|bool|array $input Summary state + * @return self + */ + public function forceSummary(null|bool|array $input = true):self { + + # Return self + return $this; + + } + + /** Private methods | Process + ****************************************************** + */ + + /** + * Page State Process + * + * Process result (input) for Page State by adding _metadata info... + * + * @param array $input + * @return array + */ + public function _pageStateProcess(array $input):array { + + # Set result + $result = []; + + # Return result + return $result; + + } + + /** + * Ingest Parameters + * + * @param array $inputs Inputs of the constructor + * @return void + */ + private function ingestParameters(array $inputs):void { + + } + + /** + * New Client + * + * New client connection to mongo db + * + * @return void + */ + private function newMariadb():void { + + # Get mongo db config + $this->mariadb = new MariadbModel(); + + # New client + $this->mariadb->newClient(); + + } + +} \ No newline at end of file diff --git a/src/Driver/Model/Sql.php b/src/Driver/Model/Sql.php index e69de29..2162b2c 100644 --- a/src/Driver/Model/Sql.php +++ b/src/Driver/Model/Sql.php @@ -0,0 +1,293 @@ + + * @copyright 2022-2024 Kévin Zarshenas + */ +namespace CrazyPHP\Driver\Model; + +/** + * Dependances + */ +use CrazyPHP\Library\Database\Driver\Mysql; +use CrazyPHP\Interface\CrazyDriverModel; + +/** + * Crazy Driver Model Interface + * + * Interface for define compatible class with Driver Model (based on mongo or other model driver...) + * + * @package kzarshenas/crazyphp + * @author kekefreedog + * @copyright 2022-2024 Kévin Zarshenas + */ +class Sql extends CrazyDriverModel { + + /** Private parameters + ****************************************************** + */ + + /** @var Mysql Instance */ + public Mysql $mysql; + + /** @var bool $attributesAsValues Indicate if attributes is set as values in current schema */ + # private bool $attributesAsValues = false; + + /** + * Constructor + * + * @return self + */ + public function __construct(...$inputs) { + + # Set name + $this->ingestParameters($inputs); + + # Sql connection + $this->newSql(); + + } + + /** Public mathods | Attributes + ****************************************************** + */ + + /** + * Set Attributes As Values + * + * Switch attributes to values + * + * @return self + */ + public function setAttributesAsValues():self { + + # Return self + return $this; + + } + + /** Public methods | Parser + ****************************************************** + */ + + /** + * Parse Id + * + * @param string|int $id Id to parse + * @param ?array $options Optionnal options + * @return self + */ + public function parseId(string|int $id, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Filters + * + * @param array $filters Filter to process + * @param ?array $options Optionnal options + * @return self + */ + public function parseFilter(?array $filters, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Sort + * + * @param null|array|string $sort Sort to process + * @param ?array $options Optionnal options + * @return self + */ + public function parseSort(null|array|string $sort, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Group + * + * @param array $group Group to process + * @param ?array $options Optionnal options + */ + public function parseGroup(?array $group, ?array $options = null):self { + + # Return self + return $this; + + } + + /** + * Parse Sql + * + * @param string $sql Sql query + * @param ?array $options Optionnal options + * @return self + */ + public function parseSql(string $sql, ?array $options = null):self { + + # Return self + return $this; + + } + + /** Public methods | Ingester + ****************************************************** + */ + + /** + * Ingest Data + * + * Import data in current driver + * + * @param array $data + * @param ?array $options Optionnal options + * @return self + */ + public function ingestData(array $data, ?array $options = null):self { + + # Return self + return $this; + + } + + /** Public methods | Pusher + ****************************************************** + */ + + /** + * Push to trash + * + * Put to trash current value + * + * @param ?array $options Optionnal options + * @param + */ + public function pushToTrash(?array $options = null):self { + + # Return self + return $this; + + } + + /** Public methods | Execute + ****************************************************** + */ + + /** + * Run + * + * Return data with given information + * + * @return array + */ + public function run():array { + + # Set result + $result = []; + + # Return result + return $result; + + } + + /** + * Count + * + * Return counted data with given information + * + * @return int + */ + public function count():int { + + # Set result + $result = 0; + + # Return result + return $result; + + } + + /** Public methods | tests + ****************************************************** + */ + + /** + * Force Summary + * + * Use for test for force summary argument value + * + * @param null|bool|array $input Summary state + * @return self + */ + public function forceSummary(null|bool|array $input = true):self { + + # Return self + return $this; + + } + + /** Private methods | Process + ****************************************************** + */ + + /** + * Page State Process + * + * Process result (input) for Page State by adding _metadata info... + * + * @param array $input + * @return array + */ + public function _pageStateProcess(array $input):array { + + # Set result + $result = []; + + # Return result + return $result; + + } + + /** + * Ingest Parameters + * + * @param array $inputs Inputs of the constructor + * @return void + */ + private function ingestParameters(array $inputs):void { + + } + + /** + * New Client + * + * New client connection to mongo db + * + * @return void + */ + private function newSql():void { + + # Get mongo db config + $this->mysql = new Mysql(); + + # New client + $this->mysql->newClient(); + + } + +} \ No newline at end of file diff --git a/src/Library/Database/Driver/Mangodb.php b/src/Library/Database/Driver/Mangodb.php index a5015a8..f84f2f9 100644 --- a/src/Library/Database/Driver/Mangodb.php +++ b/src/Library/Database/Driver/Mangodb.php @@ -343,7 +343,7 @@ public function getAllDatabases():array { * * Get Collection from database * - * @param string $database Name of the database (by default the first one in config file) + * @param string $database Name of the database (by default take the first one in config file) * @return array|null */ public function getAllCollections(string|Database $database = ""):array|null { diff --git a/src/Library/Database/Driver/Mariadb.php b/src/Library/Database/Driver/Mariadb.php index d1982b5..c117777 100644 --- a/src/Library/Database/Driver/Mariadb.php +++ b/src/Library/Database/Driver/Mariadb.php @@ -15,7 +15,12 @@ /** * Dependances */ +use CrazyPHP\Library\File\Config as FileConfig; use CrazyPHP\Interface\CrazyDatabaseDriver; +use CrazyPHP\Exception\CrazyException; +use Envms\FluentPDO\Query; +use PDOException; +use PDO; /** * Mariadb @@ -38,6 +43,11 @@ class Mariadb implements CrazyDatabaseDriver { */ public $client = null; + /** + * @var $manager Manager of current database + */ + public $manager = null; + /** * Constructor * @@ -47,7 +57,8 @@ class Mariadb implements CrazyDatabaseDriver { */ public function __construct() { - + # Get current conffig + $this->config = FileConfig::getValue(self::CONFIG_KEY); } @@ -63,9 +74,78 @@ public function __construct() { * @param string|int $user from option in Config > Database * @return self */ - public function newClient(string|int $user = ""):self { + public function newClient(string|int $user = 0):self { - # Return result + # Connection + $connection = []; + + # Check if root + if($user === "root"){ + + # Set login + $connection["login"] = $this->config["root"]["login"]; + + # Set passord + $connection["password"] = $this->config["root"]["password"]; + + }else + # Check user + if($user === "" || !array_key_exists($user, $this->config["users"])) + + # New Exception + throw new CrazyException( + "User \"$user\" can't be found...", + 500, + [ + "custom_code" => "mongodb-001", + ] + ); + + else + # Check if key + if(isset($this->config["users"][$user]) && !empty($this->config["users"][$user])){ + + # Set login + $connection["login"] = $this->config["users"][$user]["login"]; + + # Set passord + $connection["password"] = $this->config["users"][$user]["password"]; + + }else + + # New Exception + throw new CrazyException( + "User \"$user\" don't exists...", + 500, + [ + "custom_code" => "mongodb-002", + ] + ); + + # Get host + $connection["host"] = $this->config["host"]; + + # Datanbase name + $connection["database"] = $user === "root" ? + "admin" : + $this->config["database"][0]; + + + # Set database + + # Get port + $connection["port"] = $this->config["port"]; + + # Get connection string + $connectionArray = self::getConnectionArray($connection); + + # Set client + $this->client = new PDO(...$connectionArray); + + # Set manager + $this->manager = new Query($this->client); + + # Return self return $this; } @@ -87,6 +167,99 @@ public function newClient(string|int $user = ""):self { */ public function createUser(string $user = "", string $password = "", string|array $databases = [], string|array $options = []):self { + # Check client + if(!$this->manager) + + # New Exception + throw new CrazyException( + "Please execute \"newClient\" method before \"".__METHOD__."\" method...", + 500, + [ + "custom_code" => "mongodb-003", + ] + ); + + # Check user + if(!$user) + + # New Exception + throw new CrazyException( + "User parameter is empty...", + 500, + [ + "custom_code" => "mongodb-004", + ] + ); + + # Prepare query + $query = "CREATE USER :user IDENTIFIED BY :password"; + + # Prepate statment + $statment = $this->client->prepare($query); + + # Set user + $statment->bindParam(':user', $user); + + # Set password + $statment->bindParam(':password', $password); + + try { + + # Execute statment + $statment->execute(); + + } catch (PDOException $e) { + + throw new CrazyException( + "Error creating user: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-001", + ] + ); + + } + + # Check database + if(is_string($databases)) + + # Convert to array + $databases = [$databases]; + + # Iteration databases + foreach ($databases as $database) { + + # Prepare query + $query = "GRANT ALL PRIVILEGES ON $database.* TO :user"; + + # Prepare statment + $statment = $this->client->prepare($query); + + # Set user + $statment->bindParam(':user', $user); + + try { + + # Execute the grant statement + $statment->execute(); + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error granting privileges: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-002", + ] + ); + + } + } + + // Flush privileges + $this->client->exec("FLUSH PRIVILEGES"); + # Return result return $this; @@ -101,11 +274,602 @@ public function createUser(string $user = "", string $password = "", string|arra */ public function createUserFromConfig():self { + # Check client + if(!$this->client) + + # New Exception + throw new CrazyException( + "Please execute \"newClient\" method before \"".__METHOD__."\" method...", + 500, + [ + "custom_code" => "mariadb-003", + ] + ); + + # Set users + $users = $this->config["users"] ?? null; + + # Check users + if(!empty($users)) + + # Iteration of users + foreach($users as $user) + + # Create user + $this->createUser($user["login"], $user["password"]); + # Return result return $this; } + /** Public Methods | Database + ****************************************************** + */ + + /** + * Create Database + * + * @param string $options + * @return void + */ + public function createDatabase(string $option = "CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"):void { + + # Check client + if(!$this->client) + + # New Exception + throw new CrazyException( + "Please execute \"newClient\" method before \"".__METHOD__."\" method...", + 500, + [ + "custom_code" => "mariadb-004", + ] + ); + + # Switch to database + $database = $this->client->{$this->config["database"][0]}; + + # Prepare query + $query = "CREATE DATABASE IF NOT EXISTS $database"; + + # Check option + if (!empty($options)) + + # Append option to query + $query .= " $options"; + + try { + + $this->client->exec($query); + + } catch (PDOException $e) { + + throw new CrazyException( + "Error creating database: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-005", + ] + ); + + } + + } + + /** + * Create Table + * + * @param $table + * @param $schema + * @return mixed + */ + public function createTable($table, $value) { + + + + } + + /** + * Get All Tables + * + * Retrieve a list of all tables in a given database + * + * @param string $database Name of the database (by default take the first one in config file) + * @return array + */ + public function getAllTables(string $database = ""):array { + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Set result + $result = []; + + try { + + # Switch to the specified database + $this->client->exec("USE " . $database); + + # Execute the SHOW TABLES command + $statment = $this->client->query("SHOW TABLES"); + + # Fetch all table + $result = $statment->fetchAll(PDO::FETCH_COLUMN); + + } catch (PDOException $e) { + + throw new CrazyException( + "Error retrieving tables: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-006", + ] + ); + + } + + # Return result + return $result; + + } + + + /** + * Has Table + * + * Check if a specific table exists in a given database + * + * @param string $database Name of the database + * @param string $table Name of the table + * @return bool + */ + public function hasTable(string $table = "", string $database = ""): bool { + + # Set result + $result = false; + + # Check collection + if(!$table) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + try { + + # Preapre statment + $stmt = $this->client->prepare(" + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = :database AND TABLE_NAME = :table + "); + + # Set database + $stmt->bindParam(':database', $database); + + # Set table + $stmt->bindParam(':table', $table); + + # Execute + $stmt->execute(); + + # Get count + $count = $stmt->fetchColumn(); + + # Set result + $result = $count > 0; + + } catch (PDOException $e) { + + throw new CrazyException( + "Error checking table existence: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-007", + ] + ); + + } + + # Return result + return $result; + } + + /** + * Insert To Table + * + * Insert values to table + * + * @param string $table + * @param array $value + * @param string $database + * @param bool $createIfNotExists + * @param array $validator + */ + public function insertToTable(string $table, array $value, string $database = "", bool $createIfNotExists = false, array $validator = []) { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Check has + if(!$this->hasTable($table, $database)){ + + # Check if create + if(!$createIfNotExists) + + # Stop + return $result; + + # Create table + $this->createTable($table, $value); + + + } + try { + + // Insert chain + $result = $this->manager + ->insertInto($table) + ->values($value) + ->execute() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "An error occurred: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-008", + ] + ); + } + + # Return result + return $result; + + } + + /** + * Update One To Table + * + * Update one value into table + * + * @param string $table + * @param array $value + * @param int $id + * @param string $database + */ + public function updateOneToTable(string $table, array $value, int $id, string $database = "") { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + try { + + # Update table + $result = $this->manager + ->update($table) + ->set($value) + ->where('id', $id) + ->execute() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error updating item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-008", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Delete One To Table + * + * Delete one value to table + * + * @param string $table + * @param int $id + * @param string $database + */ + public function deleteOneToCollection(string $table, int $id, string $database = "") { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + try { + + # Update table + $result = $this->manager + ->deleteFrom($table) + ->where('id', $id) + ->execute() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error deleting item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Find + * + * Find values + * + * @param string $table + * @param string $database + * @param array $options = [ + * "filters":array, + * "sort":array + * "limit":array + * ] + */ + public function find(string $table, string $database, array $options = []):array|null { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Set filters + $filters = isset($options["filters"]) && is_array($options["filters"]) + ? $options["filters"] + : [] + ; + + try { + + # Update table + $result = $this->manager + ->from($table) + ->where($filters) + ->fetch() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error finding items: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Find One + * + * Find value + * + * @param string $table + * @param string $database + * @param array $options = [ + * "filters":array, + * "sort":array + * "limit":array + * ] + */ + public function findOne(string $table, string $database, array $options = []):array|null { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Set filters + $filters = isset($options["filters"]) && is_array($options["filters"]) + ? $options["filters"] + : [] + ; + + try { + + # Update table + $result = $this->manager + ->from($table) + ->where($filters) + ->limit(1) + ->fetch() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error finding item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Find Last One + * + * Find last value + * + * @param string $table + * @param string $database + * @param array $options = [ + * "filters":array, + * "sort":array + * "limit":array + * ] + */ + public function findLastOne(string $table, string $database, array $options = []):array|null { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Set filters + $filters = isset($options["filters"]) && is_array($options["filters"]) + ? $options["filters"] + : [] + ; + + try { + + # Update table + $result = $this->manager + ->from($table) + ->where($filters) + ->orderBy('id DESC') + ->limit(1) + ->fetch() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error finding last item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + /** Public Static Methods | Utilities ****************************************************** */ @@ -128,6 +892,63 @@ public static function test():bool { } + /** + * Get Connection Array + * + * Useful for connect to pdo + * + * @param array $options Option + * @return array + */ + public static function getConnectionArray(array $options = []):array { + + # Set result + $result = []; + + # Set dsn + $result[0] = + "mysql:host=".$options["host"].";". + ( + $options["port"] !== false + ? "port=".$options["port"] + : "" + ). + "dbname=".$options["database"] + ; + + # Check login + if($options["login"]){ + + # Set user + $result[1] = $options["login"]; + + # Check password + if($options["password"]) + + # Set password + $result[2] = $options["password"]; + + } + + # Return result + return $result; + + } + + /** Private Methods + ****************************************************** + */ + + private function _getDefaultDatabase():string { + + # Get result + $result = $this->config["database"][0]; + + # Return result + return $result; + + } + /** Public Static Methods ****************************************************** */ diff --git a/src/Library/Database/Driver/Mysql.php b/src/Library/Database/Driver/Mysql.php index 184906a..b7e7525 100644 --- a/src/Library/Database/Driver/Mysql.php +++ b/src/Library/Database/Driver/Mysql.php @@ -15,12 +15,17 @@ /** * Dependances */ +use CrazyPHP\Library\File\Config as FileConfig; use CrazyPHP\Interface\CrazyDatabaseDriver; +use CrazyPHP\Exception\CrazyException; +use Envms\FluentPDO\Query; +use PDOException; +use PDO; /** * Mysql * - * Driver for manipulate MySQL + * Driver for manipulate Mysql * * @package kzarshenas/crazyphp * @author kekefreedog @@ -38,6 +43,11 @@ class Mysql implements CrazyDatabaseDriver { */ public $client = null; + /** + * @var $manager Manager of current database + */ + public $manager = null; + /** * Constructor * @@ -47,7 +57,8 @@ class Mysql implements CrazyDatabaseDriver { */ public function __construct() { - + # Get current conffig + $this->config = FileConfig::getValue(self::CONFIG_KEY); } @@ -63,9 +74,78 @@ public function __construct() { * @param string|int $user from option in Config > Database * @return self */ - public function newClient(string|int $user = ""):self { + public function newClient(string|int $user = 0):self { - # Return result + # Connection + $connection = []; + + # Check if root + if($user === "root"){ + + # Set login + $connection["login"] = $this->config["root"]["login"]; + + # Set passord + $connection["password"] = $this->config["root"]["password"]; + + }else + # Check user + if($user === "" || !array_key_exists($user, $this->config["users"])) + + # New Exception + throw new CrazyException( + "User \"$user\" can't be found...", + 500, + [ + "custom_code" => "mongodb-001", + ] + ); + + else + # Check if key + if(isset($this->config["users"][$user]) && !empty($this->config["users"][$user])){ + + # Set login + $connection["login"] = $this->config["users"][$user]["login"]; + + # Set passord + $connection["password"] = $this->config["users"][$user]["password"]; + + }else + + # New Exception + throw new CrazyException( + "User \"$user\" don't exists...", + 500, + [ + "custom_code" => "mongodb-002", + ] + ); + + # Get host + $connection["host"] = $this->config["host"]; + + # Datanbase name + $connection["database"] = $user === "root" ? + "admin" : + $this->config["database"][0]; + + + # Set database + + # Get port + $connection["port"] = $this->config["port"]; + + # Get connection string + $connectionArray = self::getConnectionArray($connection); + + # Set client + $this->client = new PDO(...$connectionArray); + + # Set manager + $this->manager = new Query($this->client); + + # Return self return $this; } @@ -87,6 +167,99 @@ public function newClient(string|int $user = ""):self { */ public function createUser(string $user = "", string $password = "", string|array $databases = [], string|array $options = []):self { + # Check client + if(!$this->manager) + + # New Exception + throw new CrazyException( + "Please execute \"newClient\" method before \"".__METHOD__."\" method...", + 500, + [ + "custom_code" => "mongodb-003", + ] + ); + + # Check user + if(!$user) + + # New Exception + throw new CrazyException( + "User parameter is empty...", + 500, + [ + "custom_code" => "mongodb-004", + ] + ); + + # Prepare query + $query = "CREATE USER :user IDENTIFIED BY :password"; + + # Prepate statment + $statment = $this->client->prepare($query); + + # Set user + $statment->bindParam(':user', $user); + + # Set password + $statment->bindParam(':password', $password); + + try { + + # Execute statment + $statment->execute(); + + } catch (PDOException $e) { + + throw new CrazyException( + "Error creating user: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-001", + ] + ); + + } + + # Check database + if(is_string($databases)) + + # Convert to array + $databases = [$databases]; + + # Iteration databases + foreach ($databases as $database) { + + # Prepare query + $query = "GRANT ALL PRIVILEGES ON $database.* TO :user"; + + # Prepare statment + $statment = $this->client->prepare($query); + + # Set user + $statment->bindParam(':user', $user); + + try { + + # Execute the grant statement + $statment->execute(); + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error granting privileges: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-002", + ] + ); + + } + } + + // Flush privileges + $this->client->exec("FLUSH PRIVILEGES"); + # Return result return $this; @@ -101,11 +274,602 @@ public function createUser(string $user = "", string $password = "", string|arra */ public function createUserFromConfig():self { + # Check client + if(!$this->client) + + # New Exception + throw new CrazyException( + "Please execute \"newClient\" method before \"".__METHOD__."\" method...", + 500, + [ + "custom_code" => "mariadb-003", + ] + ); + + # Set users + $users = $this->config["users"] ?? null; + + # Check users + if(!empty($users)) + + # Iteration of users + foreach($users as $user) + + # Create user + $this->createUser($user["login"], $user["password"]); + # Return result return $this; } + /** Public Methods | Database + ****************************************************** + */ + + /** + * Create Database + * + * @param string $options + * @return void + */ + public function createDatabase(string $option = "CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"):void { + + # Check client + if(!$this->client) + + # New Exception + throw new CrazyException( + "Please execute \"newClient\" method before \"".__METHOD__."\" method...", + 500, + [ + "custom_code" => "mariadb-004", + ] + ); + + # Switch to database + $database = $this->client->{$this->config["database"][0]}; + + # Prepare query + $query = "CREATE DATABASE IF NOT EXISTS $database"; + + # Check option + if (!empty($options)) + + # Append option to query + $query .= " $options"; + + try { + + $this->client->exec($query); + + } catch (PDOException $e) { + + throw new CrazyException( + "Error creating database: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-005", + ] + ); + + } + + } + + /** + * Create Table + * + * @param $table + * @param $schema + * @return mixed + */ + public function createTable($table, $value) { + + + + } + + /** + * Get All Tables + * + * Retrieve a list of all tables in a given database + * + * @param string $database Name of the database (by default take the first one in config file) + * @return array + */ + public function getAllTables(string $database = ""):array { + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Set result + $result = []; + + try { + + # Switch to the specified database + $this->client->exec("USE " . $database); + + # Execute the SHOW TABLES command + $statment = $this->client->query("SHOW TABLES"); + + # Fetch all table + $result = $statment->fetchAll(PDO::FETCH_COLUMN); + + } catch (PDOException $e) { + + throw new CrazyException( + "Error retrieving tables: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-006", + ] + ); + + } + + # Return result + return $result; + + } + + + /** + * Has Table + * + * Check if a specific table exists in a given database + * + * @param string $database Name of the database + * @param string $table Name of the table + * @return bool + */ + public function hasTable(string $table = "", string $database = ""): bool { + + # Set result + $result = false; + + # Check collection + if(!$table) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + try { + + # Preapre statment + $stmt = $this->client->prepare(" + SELECT COUNT(*) + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_SCHEMA = :database AND TABLE_NAME = :table + "); + + # Set database + $stmt->bindParam(':database', $database); + + # Set table + $stmt->bindParam(':table', $table); + + # Execute + $stmt->execute(); + + # Get count + $count = $stmt->fetchColumn(); + + # Set result + $result = $count > 0; + + } catch (PDOException $e) { + + throw new CrazyException( + "Error checking table existence: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-007", + ] + ); + + } + + # Return result + return $result; + } + + /** + * Insert To Table + * + * Insert values to table + * + * @param string $table + * @param array $value + * @param string $database + * @param bool $createIfNotExists + * @param array $validator + */ + public function insertToTable(string $table, array $value, string $database = "", bool $createIfNotExists = false, array $validator = []) { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Check has + if(!$this->hasTable($table, $database)){ + + # Check if create + if(!$createIfNotExists) + + # Stop + return $result; + + # Create table + $this->createTable($table, $value); + + + } + try { + + // Insert chain + $result = $this->manager + ->insertInto($table) + ->values($value) + ->execute() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "An error occurred: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-008", + ] + ); + } + + # Return result + return $result; + + } + + /** + * Update One To Table + * + * Update one value into table + * + * @param string $table + * @param array $value + * @param int $id + * @param string $database + */ + public function updateOneToTable(string $table, array $value, int $id, string $database = "") { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + try { + + # Update table + $result = $this->manager + ->update($table) + ->set($value) + ->where('id', $id) + ->execute() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error updating item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-008", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Delete One To Table + * + * Delete one value to table + * + * @param string $table + * @param int $id + * @param string $database + */ + public function deleteOneToCollection(string $table, int $id, string $database = "") { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + try { + + # Update table + $result = $this->manager + ->deleteFrom($table) + ->where('id', $id) + ->execute() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error deleting item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Find + * + * Find values + * + * @param string $table + * @param string $database + * @param array $options = [ + * "filters":array, + * "sort":array + * "limit":array + * ] + */ + public function find(string $table, string $database, array $options = []):array|null { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Set filters + $filters = isset($options["filters"]) && is_array($options["filters"]) + ? $options["filters"] + : [] + ; + + try { + + # Update table + $result = $this->manager + ->from($table) + ->where($filters) + ->fetch() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error finding items: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Find One + * + * Find value + * + * @param string $table + * @param string $database + * @param array $options = [ + * "filters":array, + * "sort":array + * "limit":array + * ] + */ + public function findOne(string $table, string $database, array $options = []):array|null { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Set filters + $filters = isset($options["filters"]) && is_array($options["filters"]) + ? $options["filters"] + : [] + ; + + try { + + # Update table + $result = $this->manager + ->from($table) + ->where($filters) + ->limit(1) + ->fetch() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error finding item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + + /** + * Find Last One + * + * Find last value + * + * @param string $table + * @param string $database + * @param array $options = [ + * "filters":array, + * "sort":array + * "limit":array + * ] + */ + public function findLastOne(string $table, string $database, array $options = []):array|null { + + # Set result + $result = null; + + # Check input + if(!$table || empty($value) || !$database) + + # Return result + return $result; + + # Check database + if(!$database) + + # Get main database + $database = $this->_getDefaultDatabase(); + + # Use database + $this->client->exec("USE " . $database); + + # Set filters + $filters = isset($options["filters"]) && is_array($options["filters"]) + ? $options["filters"] + : [] + ; + + try { + + # Update table + $result = $this->manager + ->from($table) + ->where($filters) + ->orderBy('id DESC') + ->limit(1) + ->fetch() + ; + + } catch (PDOException $e) { + + # New exception + throw new CrazyException( + "Error finding last item: " . $e->getMessage(), + 500, + [ + "custom_code" => "mariadb-009", + ] + ); + + } + + # Return result + return $result; + + } + /** Public Static Methods | Utilities ****************************************************** */ @@ -128,6 +892,63 @@ public static function test():bool { } + /** + * Get Connection Array + * + * Useful for connect to pdo + * + * @param array $options Option + * @return array + */ + public static function getConnectionArray(array $options = []):array { + + # Set result + $result = []; + + # Set dsn + $result[0] = + "mysql:host=".$options["host"].";". + ( + $options["port"] !== false + ? "port=".$options["port"] + : "" + ). + "dbname=".$options["database"] + ; + + # Check login + if($options["login"]){ + + # Set user + $result[1] = $options["login"]; + + # Check password + if($options["password"]) + + # Set password + $result[2] = $options["password"]; + + } + + # Return result + return $result; + + } + + /** Private Methods + ****************************************************** + */ + + private function _getDefaultDatabase():string { + + # Get result + $result = $this->config["database"][0]; + + # Return result + return $result; + + } + /** Public Static Methods ****************************************************** */ @@ -152,6 +973,6 @@ public static function setup():void { /** * @const string CONFIG_KEY Config key for current database */ - public const CONFIG_KEY = "Database.collection.mysql"; + public const CONFIG_KEY = "Database.collection.mariadb"; } \ No newline at end of file diff --git a/src/Model/App/Create.php b/src/Model/App/Create.php index f5c2f62..ea06481 100644 --- a/src/Model/App/Create.php +++ b/src/Model/App/Create.php @@ -562,6 +562,14 @@ public function runDatabase():self { Composer::requirePackage("phpfastcache/mongodb-extension", true, false); } + + # Check if sql or mariadb in current app + if(in_array("mariadb", $databaseValues) || in_array("mysql", $databaseValues)){ + + # Compose requiere envms/fluentpdo + Composer::requirePackage("envms/fluentpdo", true, false); + + } # Return instance return $this;