From 64096261d58b6cf9e4ba7a77f0b136b10b83ca6b Mon Sep 17 00:00:00 2001 From: sheychen Date: Sat, 10 Jun 2017 17:19:03 +0200 Subject: [PATCH] First test --- LICENSE | 21 +++++ composer.json | 19 ++++ exemple/Databases.php | 27 ++++++ src/Connection.php | 74 +++++++++++++++ src/Database.php | 43 +++++++++ src/DatabaseException.php | 7 ++ src/Model.php | 193 ++++++++++++++++++++++++++++++++++++++ src/Request/Data.php | 21 +++++ src/Request/Request.php | 17 ++++ src/Request/Select.php | 95 +++++++++++++++++++ 10 files changed, 517 insertions(+) create mode 100644 LICENSE create mode 100644 composer.json create mode 100644 exemple/Databases.php create mode 100644 src/Connection.php create mode 100644 src/Database.php create mode 100644 src/DatabaseException.php create mode 100644 src/Model.php create mode 100644 src/Request/Data.php create mode 100644 src/Request/Request.php create mode 100644 src/Request/Select.php diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..59d50c5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 sheychen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..b383dab --- /dev/null +++ b/composer.json @@ -0,0 +1,19 @@ +{ + "name": "krutush/database", + "license": "MIT", + "authors": [ + { + "name": "sheychen", + "email": "contact@clementbois.fr" + } + ], + "require": { + "krutush/krutush": "dev-master", + "sheychen/inutils": "^1.1" + }, + "autoload": { + "psr-4": { + "Krutush\\Database\\": "src/" + } + } +} \ No newline at end of file diff --git a/exemple/Databases.php b/exemple/Databases.php new file mode 100644 index 0000000..d107e9c --- /dev/null +++ b/exemple/Databases.php @@ -0,0 +1,27 @@ + array( + 'driver' => 'mysql', + 'host' => 'localhost', + // 'port' => '3306', + 'schema' => 'mydatabase', + 'charset' => 'uft8', + 'username' => 'webuser', + 'password' => 'xxxxxxxxx', + 'options' => array( + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //Exceptions pour les erreurs sql + PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', //TODO deprecated remove on recent server + PDO::ATTR_PERSISTENT => true, //Connection persistente + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC //Pas d'index + ) + ), + 'admin' => array( + 'driver' => 'mysql', + 'host' => 'localhost', + // 'port' => '3306', + 'schema' => 'mydatabase', + 'charset' => 'uft8', + 'username' => 'admin', + 'password' => 'xxxxxxxxx', + 'options' => array() + ) +); \ No newline at end of file diff --git a/src/Connection.php b/src/Connection.php new file mode 100644 index 0000000..319dbe8 --- /dev/null +++ b/src/Connection.php @@ -0,0 +1,74 @@ +settings = include($path); + } + + public function connect(string $dbname = null){ + if(static::exists($dbname)) + throw new DatabaseException("Allready connect"); + + $dbname = static::parseName($dbname); + if(!isset($this->settings[$dbname])) + throw new DatabaseException('Can\'t find '.$dbname.' in settings'); + + static::$databases[$dbname] = new Database($this->settings[$dbname]); + return static::$databases[$dbname]; + } + + public function tryConnect(string $dbname = null, bool $quiet = false) { + try { + return $this->connect($dbname); + } catch (DatabaseException $e) { + return $quiet ? false : $e; + } + } + + public static function get(string $dbname = null){ + $dbname = static::parseName($dbname); + if(!static::exists($dbname)) + throw new DatabaseException('Can\'t find "'.$dbname.'"'); + + return static::$databases[$dbname]; + } + + public function getCreate(string $dbname = null){ + if(!static::exists($dbname)){ + $this->create($dbname); + } + return static::$databases[static::parseName($dbname)]; + } + + public static function tryGet(string $dbname = null, bool $quiet = false) { + try { + return static::get($dbname); + } catch (DatabaseException $e) { + return $quiet ? false : $e; + } + } + + public function tryGetCreate(string $dbname = null, bool $quiet = false) { + try { + return $this->getCreate($dbname); + } catch (DatabaseException $e) { + return $quiet ? false : $e; + } + } + + public static function exists(string $dbname = null){ + $dbname = static::parseName($dbname); + return isset(static::$databases[$dbname]); + } + + private static function parseName(string $dbname = null){ + return $dbname ?: 'default'; //Edit me + } +} \ No newline at end of file diff --git a/src/Database.php b/src/Database.php new file mode 100644 index 0000000..efd35f7 --- /dev/null +++ b/src/Database.php @@ -0,0 +1,43 @@ +pdo = new \PDO($dns, $settings['username'], $settings['password'], $settings['options']); + } + + public function exec(string $request){ + return $this->pdo->exec($request); + } + + public function prepare(string $request){ + return $this->pdo->prepare($request); + } + + public function execute(string $request, array $values = null, $row = false){ + $req = $this->prepare($request); + $req->execute($values); + if($row == false) + return $req->fetchAll(); + + return $req; + } + + public function select(array $fields = null){ + $select = new Request\Select($this); + if(isset($fields)) + return $select->fields($fields); + + return $select; + } + //TODO insert, update, delete +} \ No newline at end of file diff --git a/src/DatabaseException.php b/src/DatabaseException.php new file mode 100644 index 0000000..54229d0 --- /dev/null +++ b/src/DatabaseException.php @@ -0,0 +1,7 @@ +modify = true; + parent::__set($key, $value); + } + + /*=== CREATE ===*/ + + public static function fromRow($row, $all = true, $exception = true){ + if($row->rowCount() < 1){ + if($exception) + throw new \Exception('Create from Any Row'); + return; + } + + if($all){ + $res = array(); + while($data = $row->fetch()){ + $res[] = new static($data); + } + return $res; + }else{ + $data = $row->fetch(); + return new static($data); + } + } + + public static function fromData($data){ + $res = array(); + foreach($data as $element){ + $res[] = new static($element); + } + return $res; + } + + /*=== CONST ===*/ + + public static function getFields($exception = false){ + if(!isset(static::$FIELDS)){ + if($exception) + throw new \Exception('FIELDS not set'); + return; + } + + return static::$FIELDS; + } + + public static function getField($alias){ + $fields = static::getFields(); + if(!isset($fields[$alias])) + throw new \Exception('Can\'t find alias : '.$alias); + + return $fields[$alias]; + } + + public static function getID($real = true){ + if(static::$ID == null){ + if($real) + return static::getField('ID'); + + throw new \Exception('ID not set'); + } + + return $real == true ? static::getField(static::$ID) : static::$ID; + } + + public static function getREF($real = true){ + if(static::$REF == null){ + if($real) + return static::getField('REF'); + + throw new \Exception('REF not set'); + } + + return $real == true ? static::getField(static::$REF) : static::$REF; + } + + public static function getDATABASE(){ + return isset(static::$DATABASE) ? static::$DATABASE : null; + } + + /*=== QUERIES ===*/ + + public static function prepare(){ + $req = Connection::get(static::getDATABASE()) + ->select(static::getFields()) + ->from(static::$TABLE); + + if(isset(static::$INNER)) + $req = $req->join(static::$INNER); + + if(isset(static::$FILTER)) + $req = $req->where(static::$FILTER); + + if(isset(static::$ORDER)) + $req = $req->orderby(static::$ORDER); + + return static::postPrepare($req); + } + + public static function postPrepare($req){ return $req; } + + public static function row(array $values = null, $filters = null){ + $req = static::prepare(); + + if(isset($filters)) + $req = $req->where($filters, true); + + return $req->run($values); + } + + public static function find($id) { + return static::first(array($id), (static::getID().' = ?')); + } + + public static function findOrFail($id) { + return static::firstOrFail(array($id), (static::getID().' = ?')); + } + + public static function first(array $values = null, $filters = null) { + return static::fromRow(static::row($values, $filters), false, false); + } + + public static function firstOrFail(array $values = null, $filters = null) { + return static::fromRow(static::row($values, $filters), false); + } + + public static function all(array $values = null, $filters = null) { + return static::fromRow(static::row($values, $filters), true, false); + } + + public static function allOrFail(array $values = null, $filters = null) { + return static::fromRow(static::row($values, $filters)); + } + + public static function byRef($ref){ + return static::first(array($ref), (static::getREF().' = ?')); + } + + public static function byRefOrFail($ref){ + return static::firstOrFail(array($ref), (static::getREF().' = ?')); + } + + public static function resolveID($ref, $exception = false) { + $res = static::fromRow(static::row(array($ref), (static::getREF().' = ?')), false, $exception); + if(!isset($res)) + return; + + $id = static::getID(false); + return $res->$id; + } + + public static function exists(array $values = null, $filters = null){ + return static::first($values, $filters) !== null; + } + + //TODO clean + public static function count(array $values = null, $filters = null){ + $req = static::prepare(); + $req = $req->fields(array('COUNT(*)')); + + if(isset($filters)) + $req = $req->where($filters, true); + + $data = $req->run($values)->fetch(); + if(!isset($data['COUNT(*)'])) + return; + + return $data['COUNT(*)']; + } +} \ No newline at end of file diff --git a/src/Request/Data.php b/src/Request/Data.php new file mode 100644 index 0000000..4b180f8 --- /dev/null +++ b/src/Request/Data.php @@ -0,0 +1,21 @@ +values = array_merge($this->values, $values); + }else{ + $this->values = $values; + } + return $this; + } + + public function execute(string $sql, array $values = null){ + $values = $values ? ($this->values ? array_merge($this->values, $values) : $values) : $this->values; + return parent::execute($sql, $values); + } +} \ No newline at end of file diff --git a/src/Request/Request.php b/src/Request/Request.php new file mode 100644 index 0000000..47a125f --- /dev/null +++ b/src/Request/Request.php @@ -0,0 +1,17 @@ +db = $db; + } + + protected function execute(string $sql, array $values = null){ + return $this->db->execute($sql, $values, true); + } +} \ No newline at end of file diff --git a/src/Request/Select.php b/src/Request/Select.php new file mode 100644 index 0000000..3f2016c --- /dev/null +++ b/src/Request/Select.php @@ -0,0 +1,95 @@ +fields = $add ? array_merge($this->fields, $fields) : $fields; + return $this; + } + + public function from(string $table, bool $add = false): Select{ + $this->table = ($add && $this->table ? $this->table.', ' : '').$table; + return $this; + } + + public function join(string $joins, string $type = 'INNER', bool $add = false): Select{ + if(!in_array($type, array('INNER', 'LEFT', 'RIGHT'))) + throw new DatabaseException('Unknown JOIN type'); + $this->joins = ($add && $this->joins ? $this->joins."\n" : '').$type.' JOIN '.$joins; + return $this; + } + + public function where(string $where, bool $add = false): Select{ + $this->where = $add && $this->where ? '('.$this->where.') AND ('.$where.')' : $where; + return $this; + } + + public function groupby(string $group): Select{ + $this->group = $group; + return $this; + } + + public function orderby(string $order): Select{ + $this->order = $order; + return $this; + } + + public function limit(string $limit): Select{ + $this->limit = $limit; + return $this; + } + + public function offset(string $offset): Select{ + $this->offset = $offset; + return $this; + } + + public function sql(){ + if(!isset($this->table)) + throw new DatabaseException('Any table set'); + + $fields = '*'; + if(isset($this->fields)){ + $numItems = count($this->fields); + $i = 0; + $fields = ''; + foreach($this->fields as $key => $value){ + $fields .= $value; + if(is_string($key)) + $fields .= ' '.$key; + + if(++$i !== $numItems) //Not last + $fields .= ', '; + } + } + + $sql = 'SELECT '.$fields. + "\n".'FROM '.$this->table. + ($this->joins ? ("\n".$this->joins) : ''). + ($this->where ? ("\n".'WHERE '.$this->where) : ''). + ($this->group ? ("\n".'GROUP BY '.$this->group) : ''). + ($this->order ? ("\n".'ORDER BY '.$this->order) : ''). + ($this->limit ? ("\n".'LIMIT '.$this->limit) : ''). + ($this->offset ? (($this->limit ? '' : "\n".'LIMIT 18446744073709551615').' OFFSET '.$this->offset) : ''); + return $sql; + } + + public function run(array $values = null){ + return parent::execute($this->sql(), $values); + } +} \ No newline at end of file