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
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: usmanhalalit
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
dist: trusty
sudo: false


language: php

php:
- 5.4
- 5.5
- 7.0

Expand Down
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# 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.
**This project is Not Actively Maintained but most of the features are fully working and there are no major security issues, I'm just not giving it much time.**


# Pixie Query Builder

[![Build Status](https://travis-ci.org/usmanhalalit/pixie.svg?branch=master)](https://travis-ci.org/usmanhalalit/pixie)
[![Total Downloads](https://poser.pugx.org/usmanhalalit/pixie/downloads)](https://packagist.org/packages/usmanhalalit/pixie)
[![Daily Downloads](https://poser.pugx.org/usmanhalalit/pixie/d/daily)](https://packagist.org/packages/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.

It has some advanced features like:

Expand All @@ -17,7 +26,7 @@ The syntax is quite similar to Laravel's query builder.
require 'vendor/autoload.php';

// Create a connection, once only.
$config = array(
$config = [
'driver' => 'mysql', // Db driver
'host' => 'localhost',
'database' => 'your-database',
Expand All @@ -26,11 +35,11 @@ $config = array(
'charset' => 'utf8', // Optional
'collation' => 'utf8_unicode_ci', // Optional
'prefix' => 'cb_', // Table prefix, optional
'options' => array( // PDO constructor options, optional
'options' => [ // PDO constructor options, optional
PDO::ATTR_TIMEOUT => 5,
PDO::ATTR_EMULATE_PREPARES => false,
),
);
],
];

new \Pixie\Connection('mysql', $config, 'QB');
```
Expand Down Expand Up @@ -86,7 +95,7 @@ Library on [Packagist](https://packagist.org/packages/usmanhalalit/pixie).
- [Connection](#connection)
- [Alias](#alias)
- [Multiple Connection](#alias)
- [SQLite and PostgreSQL Config Sample](sqlite-and-postgresql-config-sample)
- [SQLite and PostgreSQL Config Sample](#sqlite-and-postgresql-config-sample)
- [Query](#query)
- [**Select**](#select)
- [Get Easily](#get-easily)
Expand Down Expand Up @@ -159,7 +168,7 @@ new \Pixie\Connection('mysql', $config, 'MyAlias');
When not using an alias you can instantiate the QueryBuilder handler separately, helpful for Dependency Injection and Testing.

```PHP
$connection = new \Pixie\Connection('mysql', $config));
$connection = new \Pixie\Connection('mysql', $config);
$qb = new \Pixie\QueryBuilder\QueryBuilderHandler($connection);

$query = $qb->table('my_table')->where('name', '=', 'Sana');
Expand Down Expand Up @@ -489,7 +498,7 @@ If you wish to manually commit or rollback your changes, you can use the
`commit()` and `rollback()` methods accordingly:

```PHP
QB::transaction(function (qb) {
QB::transaction(function ($qb) {
$qb->table('my_table')->insert(array(/* data... */));

$qb->commit(); // to commit the changes (data would be saved)
Expand Down Expand Up @@ -621,7 +630,7 @@ QB::registerEvent('after-delete', 'my_table', function($queryBuilder, $queryObje

Pixie passes the current instance of query builder as first parameter of your closure so you can build queries with this object, you can do anything like usual query builder (`QB`).

If something other than `null` is returned from the `before-*` query handler, the value will be result of execution and DB will not be actually queried (and thus, corresponding `after-*` handler will not be called ether).
If something other than `null` is returned from the `before-*` query handler, the value will be result of execution and DB will not be actually queried (and thus, corresponding `after-*` handler will not be called either).

Only on `after-*` events you get three parameters: **first** is the query builder, **third** is the execution time as float and **the second** varies:

Expand Down Expand Up @@ -656,4 +665,4 @@ Here are some cases where Query Events can be extremely helpful:
___
If you find any typo then please edit and send a pull request.

© 2016 [Muhammad Usman](http://usman.it/). Licensed under MIT license.
© 2020 [Muhammad Usman](http://usman.it/). Licensed under MIT license.
10 changes: 5 additions & 5 deletions src/Pixie/QueryBuilder/Adapters/BaseAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ public function select($statements)
}

// Limit and offset
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';
$offset = isset($statements['offset']) ? 'OFFSET ' . $statements['offset'] : '';
$limit = isset($statements['limit']) ? 'LIMIT ' . (int) $statements['limit'] : '';
$offset = isset($statements['offset']) ? 'OFFSET ' . (int) $statements['offset'] : '';

// Having
list($havingCriteria, $havingBindings) = $this->buildCriteriaWithType($statements, 'havings', 'HAVING');
Expand Down Expand Up @@ -164,7 +164,7 @@ private function doInsert($statements, array $data, $type)
$bindings = array_merge($bindings, $updateBindings);
}

$sql = $this->concatenateQuery($sqlArray, ' ', false);
$sql = $this->concatenateQuery($sqlArray);

return compact('sql', 'bindings');
}
Expand Down Expand Up @@ -272,7 +272,7 @@ public function update($statements, array $data)
$limit
);

$sql = $this->concatenateQuery($sqlArray, ' ', false);
$sql = $this->concatenateQuery($sqlArray);

$bindings = array_merge($bindings, $whereBindings);
return compact('sql', 'bindings');
Expand Down Expand Up @@ -301,7 +301,7 @@ public function delete($statements)
$limit = isset($statements['limit']) ? 'LIMIT ' . $statements['limit'] : '';

$sqlArray = array('DELETE FROM', $this->wrapSanitizer($table), $whereCriteria);
$sql = $this->concatenateQuery($sqlArray, ' ', false);
$sql = $this->concatenateQuery($sqlArray);
$bindings = $whereBindings;

return compact('sql', 'bindings');
Expand Down
53 changes: 33 additions & 20 deletions src/Pixie/QueryBuilder/QueryBuilderHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class QueryBuilderHandler
protected $statements = array();

/**
* @var \PDO
* @var PDO
*/
protected $pdo;

Expand All @@ -47,14 +47,15 @@ class QueryBuilderHandler
*
* @var array
*/
protected $fetchParameters = array(\PDO::FETCH_OBJ);
protected $fetchParameters = array(PDO::FETCH_OBJ);

/**
* @param null|\Pixie\Connection $connection
*
* @throws \Pixie\Exception
* @param int $fetchMode
* @throws Exception
*/
public function __construct(Connection $connection = null)
public function __construct(Connection $connection = null, $fetchMode = PDO::FETCH_OBJ)
{
if (is_null($connection)) {
if (!$connection = Connection::getStoredConnection()) {
Expand All @@ -68,6 +69,8 @@ public function __construct(Connection $connection = null)
$this->adapter = $this->connection->getAdapter();
$this->adapterConfig = $this->connection->getAdapterConfig();

$this->setFetchMode($fetchMode);

if (isset($this->adapterConfig['prefix'])) {
$this->tablePrefix = $this->adapterConfig['prefix'];
}
Expand Down Expand Up @@ -102,21 +105,21 @@ public function setFetchMode($mode)
*/
public function asObject($className, $constructorArgs = array())
{
return $this->setFetchMode(\PDO::FETCH_CLASS, $className, $constructorArgs);
return $this->setFetchMode(PDO::FETCH_CLASS, $className, $constructorArgs);
}

/**
* @param null|\Pixie\Connection $connection
*
* @return static
* @return QueryBuilderHandler
* @throws Exception
*/
public function newQuery(Connection $connection = null)
{
if (is_null($connection)) {
$connection = $this->connection;
}

return new static($connection);
return new static($connection, $this->getFetchMode());
}

/**
Expand Down Expand Up @@ -156,7 +159,8 @@ public function statement($sql, $bindings = array())
/**
* Get all rows
*
* @return \stdClass|null
* @return \stdClass|array
* @throws Exception
*/
public function get()
{
Expand Down Expand Up @@ -259,17 +263,17 @@ protected function aggregate($type)
}

if (is_array($row[0])) {
return (int) $row[0]['field'];
return (int)$row[0]['field'];
} elseif (is_object($row[0])) {
return (int) $row[0]->field;
return (int)$row[0]->field;
}

return 0;
}

/**
* @param string $type
* @param array $dataToBePassed
* @param array $dataToBePassed
*
* @return mixed
* @throws Exception
Expand All @@ -291,7 +295,7 @@ public function getQuery($type = 'select', $dataToBePassed = array())

/**
* @param QueryBuilderHandler $queryBuilder
* @param null $alias
* @param null $alias
*
* @return Raw
*/
Expand Down Expand Up @@ -440,10 +444,10 @@ public function delete()
}

/**
* @param $tables Single table or multiple tables as an array or as
* multiple parameters
* @param string|array $tables Single table or array of tables
*
* @return static
* @return QueryBuilderHandler
* @throws Exception
*/
public function table($tables)
{
Expand All @@ -453,7 +457,7 @@ public function table($tables)
$tables = func_get_args();
}

$instance = new static($this->connection);
$instance = new static($this->connection, $this->getFetchMode());
$tables = $this->addTablePrefix($tables, false);
$instance->addStatement('tables', $tables);
return $instance;
Expand Down Expand Up @@ -791,7 +795,7 @@ public function join($table, $key, $operator = null, $value = null, $type = 'inn
// Build a new JoinBuilder class, keep it by reference so any changes made
// in the closure should reflect here
$joinBuilder = $this->container->build('\\Pixie\\QueryBuilder\\JoinBuilder', array($this->connection));
$joinBuilder = & $joinBuilder;
$joinBuilder = &$joinBuilder;
// Call the closure with our new joinBuilder object
$key($joinBuilder);
$table = $this->addTablePrefix($table, false);
Expand Down Expand Up @@ -1012,7 +1016,7 @@ public function getEvent($event, $table = ':any')

/**
* @param $event
* @param string $table
* @param string $table
* @param callable $action
*
* @return void
Expand All @@ -1030,7 +1034,7 @@ public function registerEvent($event, $table, \Closure $action)

/**
* @param $event
* @param string $table
* @param string $table
*
* @return void
*/
Expand Down Expand Up @@ -1061,4 +1065,13 @@ public function getStatements()
{
return $this->statements;
}

/**
* @return int will return PDO Fetch mode
*/
public function getFetchMode()
{
return !empty($this->fetchParameters) ?
current($this->fetchParameters) : PDO::FETCH_OBJ;
}
}
17 changes: 16 additions & 1 deletion tests/Pixie/QueryBuilderBehaviorTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php namespace Pixie;

use Mockery as m;
use Pixie\QueryBuilder\QueryBuilderHandler;

class QueryBuilderTest extends TestCase
{
Expand Down Expand Up @@ -302,4 +302,19 @@ public function testIsPossibleToUseSubqueryInWhereNotClause()
$query->getQuery()->getRawSql()
);
}

public function testYouCanSetFetchModeFromConstructorAsOptionalParameter()
{
$selectedFetchMode = \PDO::FETCH_ASSOC;
$builder = new QueryBuilderHandler($this->mockConnection, $selectedFetchMode);
$this->assertEquals($selectedFetchMode, $builder->getFetchMode());
}

public function testFetchModeSelectedWillBeMaintainedBetweenInstances(){
$selectedFetchMode = \PDO::FETCH_ASSOC;
$builder = new QueryBuilderHandler($this->mockConnection, $selectedFetchMode);
$newBuilder = $builder->table('stuff');

$this->assertEquals($selectedFetchMode, $newBuilder->getFetchMode());
}
}