init commit

in it to delet it
This commit is contained in:
Malloc of Kuzkycyziklistan 2017-02-24 10:39:37 -06:00
parent f85e93b789
commit 8140d14f41
13 changed files with 360 additions and 0 deletions

3
.gitignore vendored
View file

@ -8,6 +8,9 @@ Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# PHPStorm folder
.idea/*
# Windows Installer files
*.cab
*.msi

4
.htaccess Normal file
View file

@ -0,0 +1,4 @@
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

67
AroMVC/AroModel.php Normal file
View file

@ -0,0 +1,67 @@
<?php
namespace AroMVC\Core;
abstract class AroModel {
protected $rawData = [];
protected $associations = [];
protected $hooks = [];
protected $index = "id";
protected $deleted = false;
public function __construct() {}
public static function withId(int $id) {
$new = new static();
$new->initialize();
return $new;
}
public static function withRow(array $row) {
$new = new static();
$new->initialize();
array_walk($row, function($v, $k) use (&$new) {
$new->rawData[strtolower($k)] = $v;
});
return $new;
}
protected abstract function initialize();
public function __get(string $name) {
$name = strtolower($name);
if(array_key_exists($name, $this->hooks))
return $this->hooks[$name]();
else if(array_key_exists($name, $this->associations))
return $this->rawData[$this->associations[$name]];
else if(array_key_exists($name, $this->rawData))
return $this->rawData[$name];
else return null;
}
public function __set(string $name, $value) {
$name = strtolower($name);
if(array_key_exists($name, $this->associations))
$rawData[$this->associations[$name]] = $value;
else if(array_key_exists($name, $this->rawData))
$rawData[$name] = $value;
else
throw new \Exception("Cannot set the value for property '$name'.");
}
protected function addHook(string $name, $func) {
$this->hooks[strtolower($name)] = $func;
}
protected function addAssociation(string $associationName, string $rawName) {
$this->associations[strtolower($associationName)] = strtolower($rawName);
}
protected function update() {
}
protected function delete() {
}
}

9
AroMVC/Database.php Normal file
View file

@ -0,0 +1,9 @@
<?php
namespace AroMVC\Core;
class Database {
private static $preparedQueries = [];
private static $rawQueries = [];
}

57
AroMVC/Queryable.php Normal file
View file

@ -0,0 +1,57 @@
<?php
namespace AroMVC\Core;
define("AMVC_QRY_SEL_FROM", 1);
define("AMVC_QRY_SEL_JOINS", 2);
define("AMVC_QRY_SEL_NEEDON", 4);
define("AMVC_QRY_SEL_WHERE", 8);
define("AMVC_QRY_SEL_GROUP", 16);
define("AMVC_QRY_SEL_HAVING", 32);
define("AMVC_QRY_SEL_ORDER", 64);
define("AMVC_QRY_SEL_LIMIT", 128);
abstract class Queryable {
protected $query = [];
protected $results = null;
protected $flags = 0;
protected $allowConditionals = true;
public function and(string $condition) {
if(!$this->allowConditionals)
throw new \Exception("Query type does not allow AND/OR subclauses");
array_push($this->query, "AND", $condition);
}
public function or(string $condition) {
if(!$this->allowConditionals)
throw new \Exception("Query type does not allow AND/OR subclauses");
array_push($this->query, "OR", $condition);
}
public function execute(array $params) {
// TODO execution logic
var_dump($this->query);
}
protected function setFlag(int $flag) {
$this->flags = $this->flags | $flag;
}
protected function clearFlag(int $flag) {
$this->flags = $this->flags & ~$flag;
}
protected function checkFlag(int $flag): bool {
return ($this->flags & $flag) != 0;
}
protected function checkPast(int $flag): bool {
return ~(($flag - 1) | $flag) & $this->flags != 0;
}
protected function checkForOrPast(int $flag): bool {
return $this->checkFlag($flag) || $this->checkPast($flag);
}
}

6
AroMVC/Router.php Normal file
View file

@ -0,0 +1,6 @@
<?php
namespace AroMVC\Core;
class Router {
}

163
AroMVC/Selectable.php Normal file
View file

@ -0,0 +1,163 @@
<?php
namespace AroMVC\Core;
class Selectable extends Queryable {
public function __construct($selection) {
if(is_array($selection))
$selection = implode(",", $selection);
$this->query = ["SELECT", $selection];
}
public function execute(array $params): Selectable {
if($this->checkFlag(AMVC_QRY_SEL_NEEDON))
throw new \Exception("JOIN clause declared in query with no matching ON clause");
if($this->checkFlag(AMVC_QRY_SEL_GROUP) && !$this->checkFlag(AMVC_QRY_SEL_ORDER)) {
if($this->checkFlag(AMVC_QRY_SEL_HAVING)) {
$having = array_search("HAVING", $this->query);
array_splice($this->query, $having + 2, 0, ["ORDER BY", "null"]);
} else {
$group = array_search("GROUP BY", $this->query);
array_splice($this->query, $group + 2, 0, ["ORDER BY", "null"]);
}
}
parent::execute($params);
return $this;
}
protected function checkFrom() {
if(!$this->checkFlag(AMVC_QRY_SEL_FROM))
throw new \Exception("FROM clause must come first in a SELECT query");
}
public function from(string $where): Selectable {
if($this->checkFlag(AMVC_QRY_SEL_FROM))
throw new \Exception("Cannot declare second FROM clause on a SELECT query");
$this->setFlag(AMVC_QRY_SEL_FROM);
array_push($this->query, "FROM", $where);
return $this;
}
public function join(string $type, string $table): Selectable {
$this->checkFrom();
if($this->checkPast(AMVC_QRY_SEL_JOINS))
throw new \Exception("Invalid JOIN clause, must proceed FROM clause");
$this->setFlag(AMVC_QRY_SEL_JOINS);
$this->setFlag(AMVC_QRY_SEL_NEEDON);
array_push($this->query, $type, $table);
return $this;
}
public function on(string $condition): Selectable {
if(!$this->checkFlag(AMVC_QRY_SEL_NEEDON))
throw new \Exception("Cannot declare ON clause without prior JOIN clause");
$this->clearFlag(AMVC_QRY_SEL_NEEDON);
array_push($this->query, "ON", $condition);
return $this;
}
public function using($columns): Selectable {
if(!$this->checkFlag(AMVC_QRY_SEL_NEEDON))
throw new \Exception("Cannot declare USING clause without prior JOIN clause");
if(is_array($columns))
$columns = implode(",", $columns);
$this->clearFlag(AMVC_QRY_SEL_NEEDON);
array_push($this->query, "USING", "({$columns})");
return $this;
}
public function where(string $condition): Selectable {
$this->checkFrom();
if($this->checkForOrPast(AMVC_QRY_SEL_WHERE))
throw new \Exception("Duplicate or misplaced WHERE clause in SELECT query");
$this->setFlag(AMVC_QRY_SEL_WHERE);
array_push($this->query, "WHERE", $condition);
return $this;
}
public function and(string $condition): Selectable {
if(!$this->checkFlag(AMVC_QRY_SEL_FROM))
throw new \Exception("Cannot use AND subclause until FROM clause has been declared in SELECT query");
parent::and($condition);
return $this;
}
public function or(string $condition): Selectable {
$this->checkFrom();
parent::or($condition);
return $this;
}
public function groupBy($columns): Selectable {
$this->checkFrom();
if($this->checkForOrPast(AMVC_QRY_SEL_GROUP))
throw new \Exception("Duplicate or misplaced GROUP BY clause in SELECT query");
if(is_array($columns))
$columns = implode(",", $columns);
$this->setFlag(AMVC_QRY_SEL_GROUP);
array_push($this->query, "GROUP BY", $columns);
return $this;
}
public function having(string $condition): Selectable {
$this->checkFrom();
if($this->checkForOrPast(AMVC_QRY_SEL_HAVING))
throw new \Exception("Duplicate or misplaced HAVING clause in SELECT query");
array_push($this->query, "HAVING", $condition);
return $this;
}
public function orderBy($columns): Selectable {
$this->checkFrom();
if($this->checkForOrPast(AMVC_QRY_SEL_ORDER))
throw new \Exception("Duplicate or misplaced ORDER BY clause in SELECT query");
if(is_array($columns))
$columns = implode(",", $columns);
$this->setFlag(AMVC_QRY_SEL_ORDER);
array_push($this->query, "ORDER BY", $columns);
return $this;
}
public function limit(int $count, int $offset = 0): Selectable {
$this->checkFrom();
if($this->checkForOrPast(AMVC_QRY_SEL_LIMIT))
throw new \Exception("Duplicate or misplaced LIMIT clause in SELECT query");
$this->setFlag(AMVC_QRY_SEL_LIMIT);
array_push($this->query, "LIMIT", "$offset,$count");
return $this;
}
public function asArray() {
if($this->results == null)
throw new \Exception("Cannot return results from a query that has not executed.");
return $this->results;
}
public function asModels($obj) {
if($this->results == null)
throw new \Exception("Cannot return results from a query that has not executed.");
$type = new \ReflectionClass($obj);
if(!$type->isSubclassOf("\\AroMVC\\Core\\AroModel"))
throw new \Exception("Cannot instantiate non-model object.");
foreach($this->results as $result)
yield $type->getMethod("withRow")->invoke(null, $result);
}
}

5
Controllers/Home.php Normal file
View file

@ -0,0 +1,5 @@
<?php
class Home {
}

7
Models/Company.php Normal file
View file

@ -0,0 +1,7 @@
<?php
namespace AroMVC\Models;
use \AroMVC\Core\AroModel;
class Company extends AroModel {
}

7
Models/State.php Normal file
View file

@ -0,0 +1,7 @@
<?php
namespace AroMVC\Models;
use \AroMVC\Core;
class State extends AroModel {
}

1
Views/Home/Index.php Normal file
View file

@ -0,0 +1 @@
<?php

18
auto.php Normal file
View file

@ -0,0 +1,18 @@
<?php
spl_autoload_register(function($class) {
$class = str_replace("_", "\\", $class);
$class = ltrim($class, '\\');
$parts = explode("\\", $class);
if($parts[0] == "AroMVC") {
if(count($parts) < 3)
die("Autoloader failed: malformed class name $class");
if($parts[1] == "Core")
require_once "AroMVC". DIRECTORY_SEPARATOR . $parts[2] .".php";
else if(in_array($parts[1], ["Controllers", "Models", "ViewModels"]))
require_once $parts[1]. DIRECTORY_SEPARATOR. $parts[2] .".php";
else
die("Autoloader failed: malformed class name $class");
}
});

13
index.php Normal file
View file

@ -0,0 +1,13 @@
<?php
namespace AroMVC;
include "auto.php";
use AroMVC\Core\Selectable;
use AroMVC\Models\Company;
$tmp = new Selectable("*");
$tmp->from("Companies")
->where("`name` = ?")
->or("`id` = ?")
->execute(["dekko", 12])
->asModels(new Company);