Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#Active repository forked from usmanhalalit

# Pixie Query Builder [![Build Status](https://travis-ci.org/usmanhalalit/pixie.png?branch=master)](https://travis-ci.org/usmanhalalit/pixie)
A lightweight, expressive, framework agnostic query builder for PHP it can also be referred as a Database Abstraction Layer. Pixie supports MySQL, SQLite and PostgreSQL and it takes care of query sanitization, table prefixing and many other things with a unified API. At least PHP 5.3 is required.

Expand All @@ -8,6 +10,7 @@ It has some advanced features like:
- Sub Queries
- Nested Queries
- Multiple Database Connections.
- Added support for table creation/mutation

The syntax is quite similar to Laravel's query builder.

Expand Down
23 changes: 11 additions & 12 deletions src/Pixie/EventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function removeEvent($event, $table = ':any')
* @param $event
* @return mixed
*/
public function fireEvents($queryBuilder, $event)
public function fireEvents($queryBuilder, $event, &$args = array())
{
$statements = $queryBuilder->getStatements();
$tables = isset($statements['tables']) ? $statements['tables'] : array();
Expand All @@ -77,22 +77,21 @@ public function fireEvents($queryBuilder, $event)
array_unshift($tables, ':any');

// Fire all events
$counter = 0;
foreach ($tables as $table) {
// Fire before events for :any table
if ($action = $this->getEvent($event, $table)) {
// Make an event id, with event type and table
$eventId = $event . $table;

// Fire event
$handlerParams = func_get_args();
unset($handlerParams[1]); // we do not need $event
// Add to fired list
$this->firedEvents[] = $eventId;
$result = call_user_func_array($action, $handlerParams);
if (!is_null($result)) {
return $result;
};
$eventId = $event . $table;
$params = array($queryBuilder, $tables[$counter + 1], &$args);
// Add to fired list
$this->firedEvents[] = $eventId;
$result = call_user_func_array($action, $params);
if (!is_null($result)) {
return $result;
};
}
$counter++;
}
}
}
224 changes: 223 additions & 1 deletion src/Pixie/QueryBuilder/Adapters/BaseAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,228 @@ public function delete($statements)

return compact('sql', 'bindings');
}

/*
* Create table and returns full query
*
* @param $statements
*
* @return array
* @throws Exception
*/
public function createTable($statements)
{
if (!isset($statements['tables'])) {
throw new Exception('No table specified', 3);
}

if (!isset($statements['columns'])) {
throw new Exception('No columns specified', 3);
}

$table = end($statements['tables']);

$criteria = "(";
for($i = 0; $i < count($statements["columns"]);$i++)
{
$statement = $statements["columns"][$i];
$values = $this->createDynamicCollectionOfValuesForStatement($statement);
$criteria .= $this->createCriteriaForStatement($values, "name datatype(size) constraint", ($i < (count($statements["columns"]) - 1)));
}
$criteria .= ")";

$sqlArray = array('CREATE TABLE', $this->wrapSanitizer($table), $criteria);
$sql = $this->concatenateQuery($sqlArray, ' ', false);
$bindings = array();
return compact('sql', 'bindings');
}

/*
* using the str_ireplace make it possible to replace names by array keys which are the same as in the format
*/
private function createCriteriaForStatement($values, $format, $addCommaToEnd)
{
if (empty($values)) {
throw new Exception('No values specified', 3);
}

$format = $this->addCommaIfNeeded($format, $addCommaToEnd);
return str_ireplace(array_keys($values), $values, $format);
}

/*
* Adding comma to format when its not last item
*/
private function addCommaIfNeeded($format, $addCommaToEnd)
{
if($addCommaToEnd) {
return $format . ", ";
}
return $format;
}

/*
* Alter table and returns full query
* @param $statements
*
* @return array
* @throws Exception
*/
public function alterTable($statements)
{
$totalColumns = count($statements["columns"]);

if (!isset($statements['tables'])) {
throw new Exception('No table specified', 3);
}

if (!isset($statements['columns']) || $totalColumns <= 0) {
throw new Exception('No columns specified', 3);
}

$table = end($statements['tables']);
$criteria = "";
if($totalColumns > 1) {
//Batch
for($i = 0; $i < $totalColumns;$i++)
{
$statement = $statements["columns"][$i];
$criteria .= $this->getAlterTableColumnCriteriaForBatchStatement($statement, ($i < ($totalColumns - 1)));
}
} else {
$statement = $statements["columns"][0];
//Single
$criteria = $this->getAlterTableColumnCriteriaForSingleStatement($statement);
}

$sqlArray = array('ALTER TABLE', $this->wrapSanitizer($table), $criteria);
$sql = $this->concatenateQuery($sqlArray, ' ', false);
$bindings = array();
return compact('sql', 'bindings');
}

/*
* Returns criteria when add/modify one column
*/
private function getAlterTableColumnCriteriaForSingleStatement($statement)
{
switch(strtolower($statement['action']))
{
case "add":
$values = $this->createDynamicCollectionOfValuesForStatement($statement);
return $this->createCriteriaForStatement($values, "ADD COLUMN name datatype(size) constraint", false);
case "modify":
$values = $this->createDynamicCollectionOfValuesForStatement($statement);
return $this->createCriteriaForStatement($values, "MODIFY COLUMN name datatype(size) constraint", false);
case "rename":
$values = $this->createDynamicCollectionOfValuesForStatement($statement, array("old_name", "new_name"));
return $this->createCriteriaForStatement($values, "CHANGE old_name new_name datatype(size) constraint", false);
case "drop":
$values = $this->createDynamicCollectionOfValuesForStatement($statement);
return $this->createCriteriaForStatement($values, "DROP COLUMN name ", false);
default:
throw new Exception('No unknown action is query specified.', 3);
break;
}
}

/*
* Returns criteria when multiple columns mutated in the table
*/
private function getAlterTableColumnCriteriaForBatchStatement($statement, $addCommaToEnd)
{
switch(strtolower($statement['action']))
{
case "add":
$values = $this->createDynamicCollectionOfValuesForStatement($statement);
return $this->createCriteriaForStatement($values, "ADD name datatype(size) constraint", $addCommaToEnd);
case "modify":
$values = $this->createDynamicCollectionOfValuesForStatement($statement);
return $this->createCriteriaForStatement($values, "MODIFY COLUMN name datatype(size) constraint", $addCommaToEnd);
case "rename":
$values = $this->createDynamicCollectionOfValuesForStatement($statement, array("old_name", "new_name"));
return $this->createCriteriaForStatement($values, "CHANGE old_name new_name datatype(size) constraint", $addCommaToEnd);
case "drop":
$values = $this->createDynamicCollectionOfValuesForStatement($statement);
return $this->createCriteriaForStatement($values, "DROP name ", $addCommaToEnd);
default:
throw new Exception('No unknown action is query specified.', 3);
break;
}
}

/*
* Creates an array where the values are transformed in the correct format, like uppercasing or sanitize
*/
private function createDynamicCollectionOfValuesForStatement($statement, $sanitizeNames = array("name"), $uppercaseNames = array("datatype", "constraint"))
{
$values = array();
foreach($statement as $key => $value)
{
if($key == "action")
continue;

if(is_array($value)) {
$value = implode(" ", $value);
}

if(in_array($key, $sanitizeNames)) {
$values[$key] = $this->wrapSanitizer($value);
} elseif(in_array($key, $uppercaseNames)) {
$values[$key] = strtoupper($value);
} elseif(is_numeric($value)) {
$values[$key] = (int)$value;
} else {
$values[$key] = $value;
}
}
return $values;
}

/*
* Drops a table from database
* @param $statements
*
* @return array
* @throws Exception
*/
public function dropTable($statements)
{
if (!isset($statements['tables'])) {
throw new Exception('No table specified', 3);
}

$table = end($statements['tables']);

$sqlArray = array('DROP TABLE', $this->wrapSanitizer($table));
$sql = $this->concatenateQuery($sqlArray, ' ', false);
$bindings = array();

return compact('sql', 'bindings');
}

/*
* Renames a table in the database
* @param $statements
*
* @return array
* @throws Exception
*/
public function renameTable($statements)
{
if (!isset($statements['tables'])) {
throw new Exception('No table specified', 3);
}

$table_new = end($statements['tables']);
$table_old = prev($statements['tables']);

$sqlArray = array('RENAME TABLE', $this->wrapSanitizer($table_old), "TO", $this->wrapSanitizer($table_new));
$sql = $this->concatenateQuery($sqlArray, ' ', false);
$bindings = array();

return compact('sql', 'bindings');
}

/**
* Array concatenating method, like implode.
Expand Down Expand Up @@ -534,4 +756,4 @@ protected function buildJoin($statements)

return $sql;
}
}
}
Loading