First test

master
sheychen 2017-06-10 17:19:03 +02:00
commit 64096261d5
10 changed files with 517 additions and 0 deletions

21
LICENSE Normal file
View File

@ -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.

19
composer.json Normal file
View File

@ -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/"
}
}
}

27
exemple/Databases.php Normal file
View File

@ -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()
)
);

74
src/Connection.php Normal file
View File

@ -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
}
}

43
src/Database.php Normal file
View File

@ -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
}

View File

@ -0,0 +1,7 @@
<?php
namespace Krutush\Database;
use \Exception;
class DatabaseException extends Exception {}

193
src/Model.php Normal file
View File

@ -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(*)'];
}
}

21
src/Request/Data.php Normal file
View File

@ -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);
}
}

17
src/Request/Request.php Normal file
View File

@ -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);
}
}

95
src/Request/Select.php Normal file
View File

@ -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);
}
}