First test
commit
64096261d5
|
@ -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.
|
|
@ -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/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php return array(
|
||||
'default' => 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()
|
||||
)
|
||||
);
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Krutush\Database;
|
||||
|
||||
class Connection{
|
||||
protected static $databases = array();
|
||||
|
||||
protected $settings;
|
||||
|
||||
public function __construct(string $path = null){
|
||||
if(isset($path))
|
||||
$this->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
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace Krutush\Database;
|
||||
|
||||
class Database{
|
||||
private $pdo;
|
||||
|
||||
public function __construct(array $settings){
|
||||
$dns = $settings['driver'] .
|
||||
':host=' . $settings['host'] .
|
||||
((isset($settings['port'])) ? (';port=' . $settings['port']) : '') .
|
||||
';dbname=' . $settings['schema'] .
|
||||
((isset($settings['charset'])) ? (';charset=' . $settings['charset']) : '');
|
||||
|
||||
$this->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
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Krutush\Database;
|
||||
|
||||
use \Exception;
|
||||
|
||||
class DatabaseException extends Exception {}
|
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
|
||||
namespace Krutush\Database;
|
||||
|
||||
use Inutils\Storage\Container;
|
||||
|
||||
//TODO extends
|
||||
//TODO protected to const php7
|
||||
//TODO add model links
|
||||
|
||||
class Model extends Container{
|
||||
protected static $DATABASE = null;
|
||||
protected static $TABLE = null;
|
||||
protected static $FIELDS = null;
|
||||
protected static $ID = null;
|
||||
protected static $REF = null;
|
||||
protected static $FILTER = null;
|
||||
protected static $INNER = null;
|
||||
protected static $ORDER = null;
|
||||
|
||||
protected $modify = false;
|
||||
|
||||
public function __set($key, $value){
|
||||
//TODO Check format
|
||||
$this->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(*)'];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace MVC\Database\Request;
|
||||
|
||||
class Data extends Request{
|
||||
protected $values;
|
||||
|
||||
public function values(array $values, bool $add = false){
|
||||
if($add){
|
||||
$this->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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace MVC\Database\Request;
|
||||
|
||||
use MVC\Database\Database;
|
||||
|
||||
class Request{
|
||||
protected $db;
|
||||
|
||||
public function __construct(Database $db){
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
protected function execute(string $sql, array $values = null){
|
||||
return $this->db->execute($sql, $values, true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace MVC\Database\Request;
|
||||
|
||||
//TODO: Split in traits
|
||||
//TODO: Add INTO
|
||||
//TODO: Add UNION
|
||||
use Krutush\Database\DatabaseException;
|
||||
|
||||
class Select extends Data{
|
||||
protected $fields;
|
||||
protected $table;
|
||||
protected $where;
|
||||
protected $group;
|
||||
protected $order;
|
||||
protected $limit;
|
||||
protected $offset;
|
||||
protected $joins;
|
||||
|
||||
public function fields(array $fields = null, bool $add = false): Select{
|
||||
$this->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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue