diff --git a/app/app.php b/app/app.php
index c4e18d0..9d915b3 100644
--- a/app/app.php
+++ b/app/app.php
@@ -1,9 +1,15 @@
"10.90.1.201",
@@ -24,25 +30,61 @@ $dbNiimko = new Database(
$dbconfig['user'],
$dbconfig['password']
);
+$builder = new GenericBuilder();
+$params = ['vuz', 'n', 'n'];
+$query = $builder->select()
+ ->setTable('s_vuzes')
+ ->setColumns(['org_id' => 'kod', 'site'])
+ ->where('AND')
+ ->equals('ootype', 'vuz')
+ ->equals('deleted', 'n')
+ ->equals('fake', 'n')
+ ->end();
+$sql = $builder->write($query);
+$sites = $dbNiimko->executeQuery($sql, $params);
-$client = new Client();
-$response = $client->get('https://marsu.ru/sveden/education/eduChislen.php');
-$html = $response->getBody()->getContents();
-$parser = new ContingentParser($html, '//tr[@itemprop="eduChislen"]//');
+// print_r($sites);
+// $sites = [ ['site' => "http://marsu.ru"], ['site' => "http://voenmeh.ru"], ['site' => "http://angtu.ru"] ];
+$i = 0;
+foreach ($sites as $site) {
+ try {
+ $client = new Client();
-$contingent = $parser->getDataTable();
-$specializations = $dbNiimko->selectWhere('s_specs', ['id', 'kod'], ['oopkodes' => 'gos3p']);
+ $route = "{$site['site']}/sveden/education/";
+ $route = str_replace("http","https", $route);
+ $route = str_replace("www.","", $route);
+ print(++$i.". Current url: $route\n");
-foreach ($contingent as $key => $con) {
- $needle = $con['spec_code'];
- foreach ($specializations as $spec) {
- if ($needle == $spec['kod']) {
- $contingent[$key] += ['spec_id' => $spec['id']];
- }
+ $response = $client->get($route);
+ print("StatusCode: ".$response->getStatusCode() . "\n");
+
+ $html = $response->getBody()->getContents();
+ $parser = new ContingentParser($html, '//tr[@itemprop="eduChislen"]//');
+ $contingent = $parser->getDataTable();
+ print_r($contingent);
+ } catch (ClientException $e) {
+ $response = $e->getCode();
+ } catch (RequestException $e) {
+ $response = $e->getCode();
+ } catch (ConnectException $e) {
+ $response = $e->getCode();
+ } catch (ServerException $e) {
+ $response = $e->getCode();
}
}
+
+// $specializations = $dbNiimko->selectWhere('s_specs', ['id', 'kod'], ['oopkodes' => 'gos3p']);
+
+// foreach ($contingent as $key => $con) {
+// $needle = $con['spec_code'];
+// foreach ($specializations as $spec) {
+// if ($needle == $spec['kod']) {
+// $contingent[$key] += ['spec_id' => $spec['id']];
+// }
+// }
+// }
+
+// Чтобы не дублировались в базе
// $dbOpendata->insert('sveden_education_contingent', $data);
-// $dbOpendata = $db->select('sveden_education_contingent');
-echo "
";
-print_r($contingent);
-echo "
";
\ No newline at end of file
+// $dbOpendata->update('sveden_education_contingent', $specializations);
+// $data = $dbOpendata->select('sveden_education_contingent');
\ No newline at end of file
diff --git a/app/library/ContingentParser.php b/app/library/ContingentParser.php
index 1b9a898..d6c5549 100644
--- a/app/library/ContingentParser.php
+++ b/app/library/ContingentParser.php
@@ -20,7 +20,7 @@ class ContingentParser
"numberBMF" => "th",
"numberP" => "th",
"numberPF" => "th",
- "numberAll" => "th"
+ "numberAll" => ["th", "td"]
];
public function __construct(string $html, string $template)
@@ -36,7 +36,14 @@ class ContingentParser
{
$data = array();
foreach (self::FIELDS as $field => $tag) {
- $data[$field] = $this->xpath->query($this->template . $tag . "[@itemprop=\"$field\"]");
+ if (!is_array($tag)) {
+ $data[$field] = $this->xpath->query($this->template . $tag . "[@itemprop=\"$field\"]");
+ } else {
+ $x = $this->xpath->query($this->template . $tag[0] . "[@itemprop=\"$field\"]");
+ $y = $this->xpath->query($this->template . $tag[1] . "[@itemprop=\"$field\"]");
+ $data[$field] = $x > $y ? $x : $y;
+ }
+
}
return $data;
}
@@ -46,7 +53,7 @@ class ContingentParser
$data = $this->parse();
$records = array();
- for ($i = 0; $i < $data['numberAll']->length; $i++) {
+ for ($i = 0; $i < $data['eduCode']->length; $i++) {
$contingentRow = new ContingentRow(
$data['eduCode']->item($i)->textContent,
$data['eduName']->item($i)->textContent,
diff --git a/app/library/Database.php b/app/library/Database.php
index ac17fbe..2055f7b 100644
--- a/app/library/Database.php
+++ b/app/library/Database.php
@@ -1,9 +1,8 @@
prepare($sql);
-
- foreach ($data as $key => $row) {
- try {
- $stmt->bindParam(":$key", $row[$key]);
- $stmt->execute();
- } catch (PDOException $e) {
- echo "Ошибка запроса: " . $e->getMessage() . "\n";
+ try {
+ $stmt = $this->prepare($sql);
+ for ($i = 0; $i < count($params); $i++) {
+ $stmt->bindParam(":v".$i+1, $params[$i]);
}
- }
- }
-
- public function select(string $table) : array|null
- {
- $stmt = $this->prepare("SELECT * FROM $table");
- try {
$stmt->execute();
$array = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
- echo "Ошибка запроса: " . $e->getMessage() . "\n";
- } finally {
- return $array;
- }
- }
-
- public function selectWhere(
- string $table,
- array $atributes,
- array $filters
- ) : array|null {
- // Строим запрос
- $sql = "SELECT ";
- foreach ($atributes as $atribute) {
- $sql .= "$atribute,";
- }
- $sql = substr_replace($sql," ", -1);
- $sql .= "FROM $table WHERE ";
- foreach ($filters as $key => $filter) {
- $sql .= "$key = :$key ";
- }
- $stmt = $this->prepare($sql);
- foreach ($filters as $key => $filter) {
- $stmt->bindParam(":$key", $filter);
- }
- // Выполняем
- try {
- $stmt->execute();
- $array = $stmt->fetchAll(PDO::FETCH_ASSOC);
- } catch (PDOException $e) {
- echo "Ошибка запроса: " . $e->getMessage() . "\n";
+ echo "Ошибка запроса: " . $e->getMessage() . "\n";
} finally {
return $array;
}
diff --git a/composer.json b/composer.json
index 04f79aa..69b9953 100644
--- a/composer.json
+++ b/composer.json
@@ -1,6 +1,7 @@
{
"require": {
- "guzzlehttp/guzzle": "^7.0"
+ "guzzlehttp/guzzle": "^7.0",
+ "nilportugues/sql-query-builder": "^1.8"
},
"autoload": {
"psr-4": {
diff --git a/composer.lock b/composer.lock
index 69b85e3..3d26275 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "045658d81f6d9d3243e731dda7bf04d1",
+ "content-hash": "9f2bc33681a074e74e50dc6856b08313",
"packages": [
{
"name": "guzzlehttp/guzzle",
@@ -331,6 +331,133 @@
],
"time": "2024-07-18T11:15:46+00:00"
},
+ {
+ "name": "nilportugues/sql-query-builder",
+ "version": "1.8.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nilportugues/php-sql-query-builder.git",
+ "reference": "cc3401099328ddfad54b2b801e38e05a50da11bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nilportugues/php-sql-query-builder/zipball/cc3401099328ddfad54b2b801e38e05a50da11bd",
+ "reference": "cc3401099328ddfad54b2b801e38e05a50da11bd",
+ "shasum": ""
+ },
+ "require": {
+ "nilportugues/sql-query-formatter": "~1.2",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "~1.9",
+ "nilportugues/php_backslasher": "~0.2",
+ "phpunit/phpunit": "4.*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "NilPortugues\\Sql\\QueryBuilder\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nil Portugués Calderó",
+ "email": "contact@nilportugues.com",
+ "homepage": "http://nilportugues.com",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Woody Gilk",
+ "email": "woody.gilk@gmail.com",
+ "homepage": "http://shadowhand.me/",
+ "role": "Contributor"
+ }
+ ],
+ "description": "An elegant lightweight and efficient SQL QueryInterface BuilderInterface supporting bindings and complicated query generation.",
+ "homepage": "http://nilportugues.com",
+ "keywords": [
+ "builder",
+ "mysql",
+ "orm",
+ "query",
+ "query builder",
+ "sql"
+ ],
+ "support": {
+ "issues": "https://github.com/nilportugues/php-sql-query-builder/issues",
+ "source": "https://github.com/nilportugues/php-sql-query-builder/tree/1.8.0"
+ },
+ "time": "2020-04-07T22:51:47+00:00"
+ },
+ {
+ "name": "nilportugues/sql-query-formatter",
+ "version": "v1.2.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nilportugues/sql-query-formatter.git",
+ "reference": "a539162a13e3217827237d5809fbaf25e136dc0e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nilportugues/sql-query-formatter/zipball/a539162a13e3217827237d5809fbaf25e136dc0e",
+ "reference": "a539162a13e3217827237d5809fbaf25e136dc0e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "~1.9",
+ "nilportugues/php_backslasher": "~0.2",
+ "phpunit/phpunit": "4.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "NilPortugues\\Sql\\QueryFormatter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nil Portugués Calderó",
+ "email": "contact@nilportugues.com",
+ "homepage": "http://nilportugues.com",
+ "role": "Lead Developer"
+ }
+ ],
+ "description": "A very lightweight PHP class that reformats unreadable and computer-generated SQL query statements to human-friendly, readable text.",
+ "homepage": "http://nilportugues.com",
+ "keywords": [
+ "format",
+ "formatter",
+ "mysql",
+ "parser",
+ "query",
+ "reformat",
+ "sql",
+ "sql server",
+ "tokenizer"
+ ],
+ "support": {
+ "issues": "https://github.com/nilportugues/sql-query-formatter/issues",
+ "source": "https://github.com/nilportugues/sql-query-formatter/tree/master"
+ },
+ "time": "2015-11-02T23:24:39+00:00"
+ },
{
"name": "psr/http-client",
"version": "1.0.3",
diff --git a/create_table.sql b/create_table.sql
index 3efe479..7bd26af 100644
--- a/create_table.sql
+++ b/create_table.sql
@@ -1,6 +1,6 @@
create table sveden_education_contingent
(
- id int not null primary key,
+ id serial not null primary key,
org_id int null,
spec_id int null,
spec_code varchar(100) null comment 'Код',
diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php
index 63d5de3..05d55f7 100644
--- a/vendor/composer/autoload_psr4.php
+++ b/vendor/composer/autoload_psr4.php
@@ -8,6 +8,8 @@ $baseDir = dirname($vendorDir);
return array(
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'),
+ 'NilPortugues\\Sql\\QueryFormatter\\' => array($vendorDir . '/nilportugues/sql-query-formatter/src'),
+ 'NilPortugues\\Sql\\QueryBuilder\\' => array($vendorDir . '/nilportugues/sql-query-builder/src'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php
index b5198f5..e64d005 100644
--- a/vendor/composer/autoload_static.php
+++ b/vendor/composer/autoload_static.php
@@ -18,6 +18,11 @@ class ComposerStaticInit045658d81f6d9d3243e731dda7bf04d1
'Psr\\Http\\Message\\' => 17,
'Psr\\Http\\Client\\' => 16,
),
+ 'N' =>
+ array (
+ 'NilPortugues\\Sql\\QueryFormatter\\' => 32,
+ 'NilPortugues\\Sql\\QueryBuilder\\' => 30,
+ ),
'G' =>
array (
'GuzzleHttp\\Psr7\\' => 16,
@@ -41,6 +46,14 @@ class ComposerStaticInit045658d81f6d9d3243e731dda7bf04d1
array (
0 => __DIR__ . '/..' . '/psr/http-client/src',
),
+ 'NilPortugues\\Sql\\QueryFormatter\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/nilportugues/sql-query-formatter/src',
+ ),
+ 'NilPortugues\\Sql\\QueryBuilder\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/nilportugues/sql-query-builder/src',
+ ),
'GuzzleHttp\\Psr7\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 33ee6ad..9b2e1d4 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -334,6 +334,139 @@
],
"install-path": "../guzzlehttp/psr7"
},
+ {
+ "name": "nilportugues/sql-query-builder",
+ "version": "1.8.0",
+ "version_normalized": "1.8.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nilportugues/php-sql-query-builder.git",
+ "reference": "cc3401099328ddfad54b2b801e38e05a50da11bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nilportugues/php-sql-query-builder/zipball/cc3401099328ddfad54b2b801e38e05a50da11bd",
+ "reference": "cc3401099328ddfad54b2b801e38e05a50da11bd",
+ "shasum": ""
+ },
+ "require": {
+ "nilportugues/sql-query-formatter": "~1.2",
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "~1.9",
+ "nilportugues/php_backslasher": "~0.2",
+ "phpunit/phpunit": "4.*"
+ },
+ "time": "2020-04-07T22:51:47+00:00",
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "NilPortugues\\Sql\\QueryBuilder\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nil Portugués Calderó",
+ "email": "contact@nilportugues.com",
+ "homepage": "http://nilportugues.com",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Woody Gilk",
+ "email": "woody.gilk@gmail.com",
+ "homepage": "http://shadowhand.me/",
+ "role": "Contributor"
+ }
+ ],
+ "description": "An elegant lightweight and efficient SQL QueryInterface BuilderInterface supporting bindings and complicated query generation.",
+ "homepage": "http://nilportugues.com",
+ "keywords": [
+ "builder",
+ "mysql",
+ "orm",
+ "query",
+ "query builder",
+ "sql"
+ ],
+ "support": {
+ "issues": "https://github.com/nilportugues/php-sql-query-builder/issues",
+ "source": "https://github.com/nilportugues/php-sql-query-builder/tree/1.8.0"
+ },
+ "install-path": "../nilportugues/sql-query-builder"
+ },
+ {
+ "name": "nilportugues/sql-query-formatter",
+ "version": "v1.2.2",
+ "version_normalized": "1.2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nilportugues/sql-query-formatter.git",
+ "reference": "a539162a13e3217827237d5809fbaf25e136dc0e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nilportugues/sql-query-formatter/zipball/a539162a13e3217827237d5809fbaf25e136dc0e",
+ "reference": "a539162a13e3217827237d5809fbaf25e136dc0e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "fabpot/php-cs-fixer": "~1.9",
+ "nilportugues/php_backslasher": "~0.2",
+ "phpunit/phpunit": "4.*"
+ },
+ "time": "2015-11-02T23:24:39+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "NilPortugues\\Sql\\QueryFormatter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nil Portugués Calderó",
+ "email": "contact@nilportugues.com",
+ "homepage": "http://nilportugues.com",
+ "role": "Lead Developer"
+ }
+ ],
+ "description": "A very lightweight PHP class that reformats unreadable and computer-generated SQL query statements to human-friendly, readable text.",
+ "homepage": "http://nilportugues.com",
+ "keywords": [
+ "format",
+ "formatter",
+ "mysql",
+ "parser",
+ "query",
+ "reformat",
+ "sql",
+ "sql server",
+ "tokenizer"
+ ],
+ "support": {
+ "issues": "https://github.com/nilportugues/sql-query-formatter/issues",
+ "source": "https://github.com/nilportugues/sql-query-formatter/tree/master"
+ },
+ "install-path": "../nilportugues/sql-query-formatter"
+ },
{
"name": "psr/http-client",
"version": "1.0.3",
diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php
index 135a978..509cc99 100644
--- a/vendor/composer/installed.php
+++ b/vendor/composer/installed.php
@@ -1,9 +1,9 @@
array(
'name' => '__root__',
- 'pretty_version' => '1.0.0+no-version-set',
- 'version' => '1.0.0.0',
- 'reference' => null,
+ 'pretty_version' => 'dev-main',
+ 'version' => 'dev-main',
+ 'reference' => '0b56cd37b55c2d4efaa3a70b1487cae267d9c700',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -11,9 +11,9 @@
),
'versions' => array(
'__root__' => array(
- 'pretty_version' => '1.0.0+no-version-set',
- 'version' => '1.0.0.0',
- 'reference' => null,
+ 'pretty_version' => 'dev-main',
+ 'version' => 'dev-main',
+ 'reference' => '0b56cd37b55c2d4efaa3a70b1487cae267d9c700',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -46,6 +46,24 @@
'aliases' => array(),
'dev_requirement' => false,
),
+ 'nilportugues/sql-query-builder' => array(
+ 'pretty_version' => '1.8.0',
+ 'version' => '1.8.0.0',
+ 'reference' => 'cc3401099328ddfad54b2b801e38e05a50da11bd',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../nilportugues/sql-query-builder',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
+ 'nilportugues/sql-query-formatter' => array(
+ 'pretty_version' => 'v1.2.2',
+ 'version' => '1.2.2.0',
+ 'reference' => 'a539162a13e3217827237d5809fbaf25e136dc0e',
+ 'type' => 'library',
+ 'install_path' => __DIR__ . '/../nilportugues/sql-query-formatter',
+ 'aliases' => array(),
+ 'dev_requirement' => false,
+ ),
'psr/http-client' => array(
'pretty_version' => '1.0.3',
'version' => '1.0.3.0',
diff --git a/vendor/nilportugues/sql-query-builder/.coveralls.yml b/vendor/nilportugues/sql-query-builder/.coveralls.yml
new file mode 100644
index 0000000..a23b747
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/.coveralls.yml
@@ -0,0 +1 @@
+repo_token: LFYrNmWM52pVO2g5dKuvf8NXd9mQLukDM
diff --git a/vendor/nilportugues/sql-query-builder/.gitignore b/vendor/nilportugues/sql-query-builder/.gitignore
new file mode 100644
index 0000000..16730ad
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/.gitignore
@@ -0,0 +1,4 @@
+build/
+vendor/
+bin/
+composer.lock
diff --git a/vendor/nilportugues/sql-query-builder/.travis.yml b/vendor/nilportugues/sql-query-builder/.travis.yml
new file mode 100644
index 0000000..0ca744d
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/.travis.yml
@@ -0,0 +1,22 @@
+language: php
+php:
+ - "5.6"
+ - "7.0"
+ - "7.1"
+ - "7.2"
+ - "7.3"
+ - "7.4"
+
+before_script:
+ - composer install
+
+script:
+ - bin/phpunit --coverage-text
+
+matrix:
+ allow_failures:
+ - php: "hhvm"
+branches:
+ only:
+ - master
+
diff --git a/vendor/nilportugues/sql-query-builder/CHANGELOG.md b/vendor/nilportugues/sql-query-builder/CHANGELOG.md
new file mode 100644
index 0000000..b0f5a2b
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/CHANGELOG.md
@@ -0,0 +1,41 @@
+# Changelog
+
+## Unreleased
+
+### Added
+
+- Added parentQuery field to Select Object
+- New test for orderBy method in Select Class
+
+### Altered
+
+- Changed orderBy method logic in Select Class. Now every select query has access to his parent object. You can manipulate sequence of your orderBy clause.
+
+## 1.0.2 - TBA
+
+### Added
+
+- Added @shadowhand (Woody Gilk) to the **composer.json** under authors.
+- Comments for queries using the **setComment** method.
+- Table aliasing.
+
+### Altered
+
+- Changed PSR-0 loading to PSR-4.
+- Changed the class loading in GenericBuilder. Now a classmap is used to load the query builder classes only when required.
+- Changed test method names to camelCase format.
+- Normalized the way select, insert and update behave internally.
+
+
+## 1.0.1 - 2014-09-23
+
+### Altered
+- Big change in class loading to reducing memory usage.
+
+## 1.0.0 - 2014-09-13
+
+- First stable release
+
+## 0.0.5-alpha - 2014-07-01
+
+- Initial release
diff --git a/vendor/nilportugues/sql-query-builder/CONTRIBUTING.md b/vendor/nilportugues/sql-query-builder/CONTRIBUTING.md
new file mode 100644
index 0000000..3677a2c
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/CONTRIBUTING.md
@@ -0,0 +1,33 @@
+Contributing
+============
+
+First of all, **thank you** for contributing, **you are awesome**!
+
+Here are a few rules to follow in order to ease code reviews, and discussions before
+maintainers accept and merge your work.
+
+You MUST follow the [PSR-1](http://www.php-fig.org/psr/1/) and
+[PSR-2](http://www.php-fig.org/psr/2/). If you don't know about any of them, you
+should really read the recommendations. Can't wait? Use the [PHP-CS-Fixer
+tool](http://cs.sensiolabs.org/).
+
+You MUST run the test suite.
+
+You MUST write (or update) unit tests.
+
+You SHOULD write documentation.
+
+Please, write [commit messages that make
+sense](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
+and [rebase your branch](http://git-scm.com/book/en/Git-Branching-Rebasing)
+before submitting your Pull Request.
+
+One may ask you to [squash your
+commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)
+too. This is used to "clean" your Pull Request before merging it (we don't want
+commits such as `fix tests`, `fix 2`, `fix 3`, etc.).
+
+Also, while creating your Pull Request on GitHub, you MUST write a description
+which gives the context and/or explains why you are creating it.
+
+Thank you!
diff --git a/vendor/nilportugues/sql-query-builder/LICENSE.txt b/vendor/nilportugues/sql-query-builder/LICENSE.txt
new file mode 100644
index 0000000..797681d
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Nil Portugués Calderó
+
+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.
diff --git a/vendor/nilportugues/sql-query-builder/README.md b/vendor/nilportugues/sql-query-builder/README.md
new file mode 100644
index 0000000..6a8d538
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/README.md
@@ -0,0 +1,1159 @@
+SQL Query Builder
+=================
+
+[](https://travis-ci.org/nilportugues/php-sql-query-builder) [](https://coveralls.io/r/nilportugues/sql-query-builder) [](https://scrutinizer-ci.com/g/nilportugues/sql-query-builder/?branch=master) [](https://insight.sensiolabs.com/projects/89ec1003-4227-43a2-8432-67a9fc2d3ba3) [](https://packagist.org/packages/nilportugues/sql-query-builder) [](https://packagist.org/packages/nilportugues/sql-query-builder) [](https://packagist.org/packages/nilportugues/sql-query-builder)
+[](https://paypal.me/nilportugues)
+
+An elegant lightweight and efficient SQL Query Builder with fluid interface SQL syntax supporting bindings and complicated query generation. **Works without establishing a connection to the database.**
+
+
+
+* [1. Installation](#block1)
+* [2. The Builder](#block2)
+ * [2.1. Generic Builder](#block2.1)
+ * [2.2. MySQL Builder](#block2.2)
+ * [2.3. Human Readable Output](#block2.3)
+* [3. Building Queries](#block3)
+ * [3.1. SELECT Statement](#block3.1)
+ * [3.1.1. Basic SELECT statement](#block3.1.1)
+ * [3.1.2. Aliased SELECT statement](#block3.1.2)
+ * [3.1.3. SELECT with WHERE statement](#block3.1.3)
+ * [3.1.4. Complex WHERE conditions](#block3.1.4)
+ * [3.1.5. JOIN & LEFT/RIGHT/INNER/CROSS JOIN SELECT statements](#block3.1.5)
+ * [3.1.6. COUNT rows](#block3.1.6)
+ * [3.2. INSERT Statement](#block3.2)
+ * [3.2.1. Basic INSERT statement](#block3.2.1)
+ * [3.3. UPDATE Statement](#block3.3)
+ * [3.3.1. Basic UPDATE statement](#block3.3.1)
+ * [3.3.2. Elaborated UPDATE statement](#block3.3.2)
+ * [3.4. DELETE Statement](#block3.4)
+ * [3.4.1. Empty table with DELETE statement](#block3.4.1)
+ * [3.4.2. Basic DELETE statement](#block3.4.2)
+ * [3.4.3. Elaborated DELETE statement](#block3.4.3)
+ * [3.5. INTERSECT Statement](#block3.5)
+ * [3.6. MINUS Statement](#block3.6)
+ * [3.7. UNION Statement](#block3.7)
+ * [3.8. UNION ALL Statement](#block3.8)
+* [4. Advanced Quering](#block4)
+ * [4.1. Filtering using WHERE](#block4.1)
+ * [4.1.1. Changing WHERE logical operator](#block4.2)
+ * [4.1.2. Writing complicated WHERE conditions](#block4.2)
+ * [4.3. Grouping with GROUP BY and HAVING](#block4.3)
+ * [4.3.1 Available HAVING operators](#block4.3.1)
+ * [4.4. Changing HAVING logical operator](#block4.4)
+ * [4.5. Columns as SELECT statements](#block4.5)
+ * [4.6. Columns being Values](#block4.6)
+ * [4.7. Columns using FUNCTIONS](#block4.7)
+* [5. Commenting queries](#block5)
+* [6. Quality Code](#block6)
+* [7. Author](#block7)
+* [8. License](#block8)
+
+
+
+## 1. Installation [↑](#index_block)
+The recommended way to install the SQL Query Builder is through [Composer](http://getcomposer.org). Run the following command to install it:
+
+```sh
+php composer.phar require nilportugues/sql-query-builder
+```
+
+
+## 2. The Builder [↑](#index_block)
+
+The SQL Query Builder allows to generate complex SQL queries standard using the `SQL-2003` dialect (default) and the `MySQL` dialect, that extends the `SQL-2003` dialect.
+
+
+### 2.1. Generic Builder [↑](#index_block)
+The Generic Query Builder is the default builder for this class and writes standard SQL-2003.
+
+**All column aliases are escaped using the `'` sign by default.**
+
+#### Usage:
+```php
+select()->setTable('user');
+
+echo $builder->write($query);
+```
+#### Output:
+```sql
+SELECT user.* FROM user
+```
+
+
+### 2.2. MySQL Builder [↑](#index_block)
+The MySQL Query Builder has its own class, that inherits from the SQL-2003 builder. All columns will be wrapped with the tilde **`** sign.
+
+**All table and column aliases are escaped using the tilde sign by default.**
+
+#### Usage:
+```php
+select()->setTable('user');
+
+echo $builder->write($query);
+```
+#### Output:
+```sql
+SELECT user.* FROM `user`
+```
+
+
+#### 2.3. Human Readable Output [↑](#index_block)
+
+Both Generic and MySQL Query Builder can write complex SQL queries.
+
+Every developer out there needs at some point revising the output of a complicated query, the SQL Query Builder includes a human-friendly output method, and therefore the `writeFormatted` method is there to aid the developer when need.
+
+Keep in mind `writeFormatted` is to be avoided at all cost in production mode as it adds unneeded overhead due to parsing and re-formatting of the generated statement.
+
+#### Usage:
+```php
+select()->setTable('user');
+
+echo $builder->writeFormatted($query);
+
+```
+#### Output:
+```sql
+SELECT
+ user.*
+FROM
+ user
+```
+
+More complicated examples can be found in the documentation.
+
+
+
+## 3. Building Queries [↑](#index_block)
+
+
+### 3.1. SELECT Statement [↑](#index_block)
+
+
+
+
+#### 3.1.1. Basic SELECT statement [↑](#index_block)
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns(['user_id','name','email']);
+
+echo $builder->write($query);
+```
+#### Output:
+```sql
+SELECT user.user_id, user.name, user.email FROM user
+```
+
+
+#### 3.1.2. Aliased SELECT statement [↑](#index_block)
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns(['userId' => 'user_id', 'username' => 'name', 'email' => 'email']);
+
+echo $builder->write($query);
+```
+#### Output:
+```sql
+SELECT user.user_id AS 'userId', user.name AS 'username', user.email AS 'email' FROM user
+```
+
+#### 3.1.3. SELECT with WHERE statement [↑](#index_block)
+
+Default logical operator for filtering using `WHERE` conditions is `AND`.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns([
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email'
+ ])
+ ->where()
+ ->greaterThan('user_id', 5)
+ ->notLike('username', 'John')
+ ->end();
+
+echo $builder->writeFormatted($query);
+```
+#### Output:
+```sql
+SELECT
+ user.user_id AS 'userId',
+ user.name AS 'username',
+ user.email AS 'email'
+FROM
+ user
+WHERE
+ (user.user_id < :v1)
+ AND (user.username NOT LIKE :v2)
+```
+
+
+#### 3.1.4. Complex WHERE conditions [↑](#index_block)
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->where()
+ ->equals('user_id', 1)
+ ->equals('user_id', 2)
+ ->subWhere("OR")
+ ->lessThan($column, 10)
+ ->greaterThan('user_id', 100)
+ ->end();
+
+echo $builder->writeFormatted($query);
+```
+
+#### Output:
+```sql
+SELECT
+ user.*
+FROM
+ user
+WHERE
+ (user.user_id = :v1)
+ AND (user.user_id = :v2)
+ AND (
+ (user.user_id < :v3)
+ OR (user.user_id > :v4)
+ )
+```
+
+
+#### 3.1.5. JOIN & LEFT/RIGHT/INNER/CROSS JOIN SELECT statements [↑](#index_block)
+
+Syntax for `JOIN`, `LEFT JOIN`, `RIGHT JOIN`, `INNER JOIN`, `CROSS JOIN` work the exactly same way.
+
+Here's an example selecting both table and joined table columns and doing sorting using columns from both the table and the joined table.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns([
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at'
+ ])
+ ->orderBy('user_id', OrderBy::DESC)
+ ->leftJoin(
+ 'news', //join table
+ 'user_id', //origin table field used to join
+ 'author_id', //join column
+ ['newsTitle' => 'title', 'body', 'created_at', 'updated_at']
+ )
+ ->on()
+ ->equals('author_id', 1); //enforcing a condition on the join column
+
+$query
+ ->where()
+ ->greaterThan('user_id', 5)
+ ->notLike('username', 'John')
+ ->end();
+
+$query
+ ->orderBy('created_at', OrderBy::DESC);
+
+echo $builder->writeFormatted($query);
+```
+#### Output:
+```sql
+SELECT
+ user.user_id AS 'userId',
+ user.name AS 'username',
+ user.email AS 'email',
+ user.created_at,
+ news.title AS 'newsTitle',
+ news.body,
+ news.created_at,
+ news.updated_at
+FROM
+ user
+LEFT JOIN
+ news
+ ON
+ (news.author_id = user.user_id)
+ AND (news.author_id = :v1)
+WHERE
+ (user.user_id < :v2)
+ AND (user.username NOT LIKE :v3)
+ORDER BY
+ user.user_id DESC,
+ news.created_at DESC;
+```
+
+
+#### 3.1.6. COUNT rows [↑](#index_block)
+Counting rows comes in 3 possible ways, using the ALL selector `*`, stating a column or stating a column and its alias.
+
+#### 3.1.6.1. Count using ALL selector
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->count()
+
+echo $builder->write($query);
+```
+
+#### Output:
+```sql
+SELECT COUNT(*) FROM user;
+```
+
+#### 3.1.6.2. Count using column as a selector
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->count('user_id')
+
+echo $builder->write($query);
+```
+
+#### Output:
+```sql
+SELECT COUNT(user.user_id) FROM user;
+```
+
+#### 3.1.6.3. Count using column as a selector
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->count('user_id', 'total_users')
+
+echo $builder->write($query);
+```
+
+#### Output:
+```sql
+SELECT COUNT(user.user_id) AS 'total_users' FROM user;
+```
+
+
+### 3.2. INSERT Statement [↑](#index_block)
+
+The `INSERT` statement is really straightforward.
+
+
+#### 3.2.1 Basic INSERT statement [↑](#index_block)
+
+#### Usage:
+```php
+insert()
+ ->setTable('user')
+ ->setValues([
+ 'user_id' => 1,
+ 'name' => 'Nil',
+ 'contact' => 'contact@nilportugues.com',
+ ]);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+
+#### Output
+```sql
+INSERT INTO user (user.user_id, user.name, user.contact) VALUES (:v1, :v2, :v3)
+```
+
+```php
+[':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com'];
+```
+
+
+### 3.3. UPDATE Statement [↑](#index_block)
+
+The `UPDATE` statement works just like expected, set the values and the conditions to match the row and you're set.
+
+Examples provided below.
+
+
+#### 3.3.1 Basic UPDATE statement [↑](#index_block)
+Important including the the `where` statement is critical, or all table rows will be replaced with the provided values if the statement is executed.
+
+#### Usage:
+```php
+update()
+ ->setTable('user')
+ ->setValues([
+ 'user_id' => 1,
+ 'name' => 'Nil',
+ 'contact' => 'contact@nilportugues.com'
+ ])
+ ->where()
+ ->equals('user_id', 1)
+ ->end();
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+UPDATE
+ user
+SET
+ user.user_id = :v1,
+ user.name = :v2,
+ user.contact = :v3
+WHERE
+ (user.user_id = :v4)
+```
+```php
+[':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com', ':v4' => 1];
+```
+
+#### 3.3.2. Elaborated UPDATE statement [↑](#index_block)
+
+#### Usage:
+```php
+update()
+ ->setTable('user')
+ ->setValues([
+ 'name' => 'UpdatedName',
+ ]);
+
+$query
+ ->where()
+ ->like('username', '%N')
+ ->between('user_id', 1, 2000)
+ ->end();
+
+$query
+ ->orderBy('user_id', OrderBy::ASC)
+ ->limit(1);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+UPDATE
+ user
+SET
+ user.name = :v1
+WHERE
+ (user.username LIKE :v2)
+ AND (user.user_id BETWEEN :v3 AND :v4)
+ORDER BY
+ user.user_id ASC
+LIMIT :v5
+```
+
+
+### 3.4. DELETE Statement [↑](#index_block)
+
+The `DELETE` statement is used just like `UPDATE`, but no values are set.
+
+Examples provided below.
+
+
+#### 3.4.1. Empty table with DELETE statement [↑](#index_block)
+
+#### Usage:
+```php
+delete()
+ ->setTable('user');
+
+$sql = $builder->write($query);
+```
+#### Output:
+```sql
+DELETE FROM user
+```
+
+
+#### 3.4.2. Basic DELETE statement [↑](#index_block)
+Important including the the `where` statement is critical, or all table rows will be deleted with the provided values if the statement is executed.
+
+#### Usage:
+```php
+delete()
+ ->setTable('user');
+
+$query
+ ->where()
+ ->equals('user_id', 100)
+ ->end();
+
+$query
+ ->limit(1);
+
+$sql = $builder->write($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+DELETE FROM user WHERE (user.user_id = :v1) LIMIT :v2
+```
+```php
+[':v1' => 100, ':v2' => 1];
+```
+
+#### 3.4.2. Elaborated DELETE statement [↑](#index_block)
+
+#### Usage:
+```php
+delete()
+ ->setTable('user');
+
+$query
+ ->where()
+ ->like('username', '%N')
+ ->between('user_id', 1, 2000)
+ ->end();
+
+$query
+ ->orderBy('user_id', OrderBy::ASC)
+ ->limit(1);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+DELETE FROM
+ user
+WHERE
+ (user.username LIKE :v1)
+ AND (user.user_id BETWEEN :v2 AND :v3)
+ORDER BY
+ user.user_id ASC
+LIMIT :v4
+```
+
+
+
+
+### 3.5. INTERSECT Statement [↑](#index_block)
+
+***
+ INTERSECT is not supported by MySQL.
+ Same results can be achieved by using INNER JOIN statement instead.
+***
+
+The `INTERSECT` statement is really straightforward.
+
+
+#### 3.5.1 Basic INTERSECT statement [↑](#index_block)
+
+#### Usage:
+```php
+select()->setTable('user');
+$select2 = $builder->select()->setTable('user_emails');
+
+$query = $builder->intersect()
+ ->add($select1)
+ ->add($select2);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+
+#### Output
+```sql
+SELECT user.* FROM user
+INTERSECT
+SELECT user_email.* FROM user_email
+```
+
+
+
+### 3.6. MINUS Statement [↑](#index_block)
+
+***
+ MINUS is not supported by MySQL.
+ Same results can be achieved by using a LEFT JOIN statement
+ in combination with an IS NULL or NOT IN condition instead.
+***
+
+The `MINUS` statement is really straightforward.
+
+
+#### 3.6.1 Basic MINUS statement [↑](#index_block)
+
+#### Usage:
+```php
+select()->setTable('user');
+$select2 = $builder->select()->setTable('user_emails');
+
+$query = $builder->minus($select1, $select2);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+
+#### Output
+```sql
+SELECT user.* FROM user
+MINUS
+SELECT user_email.* FROM user_email
+```
+
+
+
+### 3.7. UNION Statement [↑](#index_block)
+
+The `UNION` statement is really straightforward.
+
+
+#### 3.7.1 Basic UNION statement [↑](#index_block)
+
+#### Usage:
+```php
+select()->setTable('user');
+$select2 = $builder->select()->setTable('user_emails');
+
+$query = $builder->union()
+ ->add($select1)
+ ->add($select2);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+
+#### Output
+```sql
+SELECT user.* FROM user
+UNION
+SELECT user_email.* FROM user_email
+```
+
+
+### 3.8. UNION ALL Statement [↑](#index_block)
+
+The `UNION ALL` statement is really straightforward.
+
+
+#### 3.8.1 Basic UNION ALL statement [↑](#index_block)
+
+#### Usage:
+```php
+select()->setTable('user');
+$select2 = $builder->select()->setTable('user_emails');
+
+$query = $builder->unionAll()
+ ->add($select1)
+ ->add($select2);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+
+#### Output
+```sql
+SELECT user.* FROM user
+UNION ALL
+SELECT user_email.* FROM user_email
+```
+
+
+
+
+## 4. Advanced Quering [↑](#index_block)
+
+
+### 4.1. Filtering using WHERE [↑](#index_block)
+The following operators are available for filtering using WHERE conditionals:
+
+```php
+public function subWhere($operator = 'OR');
+public function equals($column, $value);
+public function notEquals($column, $value);
+public function greaterThan($column, $value);
+public function greaterThanOrEqual($column, $value);
+public function lessThan($column, $value);
+public function lessThanOrEqual($column, $value);
+public function like($column, $value);
+public function notLike($column, $value);
+public function match(array $columns, array $values);
+public function matchBoolean(array $columns, array $values);
+public function matchWithQueryExpansion(array $columns, array $values);
+public function in($column, array $values);
+public function notIn($column, array $values);
+public function between($column, $a, $b);
+public function notBetween($column, $a, $b);
+public function isNull($column);
+public function isNotNull($column);
+public function exists(Select $select);
+public function notExists(Select $select);
+public function addBitClause($column, $value);
+public function asLiteral($literal);
+```
+
+
+### 4.2. Changing WHERE logical operator [↑](#index_block)
+
+`WHERE` default's operator must be changed passing to the `where` method the logical operator `OR`.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->where('OR')
+ ->equals('user_id', 1)
+ ->like('name', '%N%')
+ ->end();
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+SELECT user.* FROM user WHERE (user.user_id = :v1) OR (user.name LIKE :v2)
+```
+
+
+### 4.3. Grouping with GROUP BY and HAVING [↑](#index_block)
+
+Default logical operator for joining more than one `HAVING` condition is `AND`.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns([
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at'
+ ])
+ ->groupBy(['user_id', 'name'])
+ ->having()
+ ->equals('user_id', 1)
+ ->equals('user_id', 2);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+SELECT
+ user.user_id AS 'userId',
+ user.name AS 'username',
+ user.email AS 'email',
+ user.created_at
+FROM
+ user
+GROUP BY
+ user.user_id, user.name
+HAVING
+ (user.user_id = :v1)
+ AND (user.user_id = :v2)
+```
+
+
+#### 4.3.1 Available HAVING operators [↑](#index_block)
+Same operators used in the WHERE statement are available for HAVING operations.
+
+
+### 4.4. Changing HAVING logical operator [↑](#index_block)
+
+`HAVING` default's operator must be changed passing to the `having` method the logical operator `OR`.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns([
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at'
+ ])
+ ->groupBy(['user_id', 'name'])
+ ->having('OR')
+ ->equals('user_id', 1)
+ ->equals('user_id', 2);
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+SELECT
+ user.user_id AS 'userId',
+ user.name AS 'username',
+ user.email AS 'email',
+ user.created_at
+FROM
+ user
+GROUP BY
+ user.user_id, user.name
+HAVING
+ (user.user_id = :v1)
+ OR (user.user_id = :v2)
+```
+
+
+### 4.5. Columns as SELECT statements [↑](#index_block)
+
+Sometimes, a column needs to be set as a column. SQL Query Builder got you covered on this one too! Check the example below.
+
+#### Usage:
+```php
+select()
+ ->setTable('role')
+ ->setColumns(array('role_name'))
+ ->limit(1)
+ ->where()
+ ->equals('role_id', 3);
+
+$query = $builder->select()
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setSelectAsColumn(array('user_role' => $selectRole))
+ ->setSelectAsColumn(array($selectRole))
+ ->where()
+ ->equals('user_id', 4)
+ ->end();
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+SELECT
+ user.user_id,
+ user.username,
+ (
+ SELECT
+ role.role_name
+ FROM
+ role
+ WHERE
+ (role.role_id = :v1)
+ LIMIT :v2, :v3
+ ) AS 'user_role',
+ (
+ SELECT
+ role.role_name
+ FROM
+ role
+ WHERE
+ (role.role_id = :v4)
+ LIMIT :v5, :v6
+ ) AS 'role'
+FROM
+ user
+WHERE
+ (user.user_id = :v7)
+```
+
+
+### 4.6. Columns being Values [↑](#index_block)
+
+There are time where you need to force the same column structure (eg: UNIONs) even when lacking of a column or value. Forcing column with values gets you covered.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setValueAsColumn('10', 'priority')
+ ->where()
+ ->equals('user_id', 1)
+ ->end();
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+#### Output:
+```sql
+SELECT
+ user.user_id,
+ user.username,
+ :v1 AS 'priority'
+FROM
+ user
+WHERE
+ (user.user_id = :v2)
+```
+
+
+### 4.7. Columns using FUNCTIONS [↑](#index_block)
+
+Example for MAX function.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setFunctionAsColumn('MAX', array('user_id'), 'max_id')
+ ->where()
+ ->equals('user_id', 1)
+ ->end();
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+
+#### Output:
+```sql
+SELECT
+ user.user_id,
+ user.username,
+ MAX(user_id) AS 'max_id'
+FROM
+ user
+WHERE
+ (user.user_id = :v1)
+```
+
+Example for CURRENT_TIMESTAMP function.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setFunctionAsColumn('CURRENT_TIMESTAMP', array(), 'server_time')
+ ->where()
+ ->equals('user_id', 1)
+ ->end();
+
+$sql = $builder->writeFormatted($query);
+$values = $builder->getValues();
+```
+
+#### Output:
+```sql
+SELECT
+ user.user_id,
+ user.username,
+ CURRENT_TIMESTAMP AS 'server_time'
+FROM
+ user
+WHERE
+ (user.user_id = :v1)
+```
+
+
+## 5. Commenting queries [↑](#index_block)
+The query builder allows adding comments to all query methods by using the `setComment` method.
+
+Some useful use cases examples can be :
+
+ - Explain difficult queries or why of its existence.
+ - Finding slow queries from its comments.
+
+#### Usage:
+```php
+select()
+ ->setTable('user')
+ ->setComment('This is a comment');
+
+$sql = $builder->write($query);
+```
+
+#### Output:
+```sql
+-- This is a comment
+SELECT user.* FROM user
+```
+
+
+## 6. Quality Code [↑](#index_block)
+Testing has been done using PHPUnit and [Travis-CI](https://travis-ci.org). All code has been tested to be compatible from PHP 5.4 up to PHP 5.6 and [HHVM](http://hhvm.com/).
+
+To run the test suite, you need [Composer](http://getcomposer.org):
+
+```bash
+ php composer.phar install --dev
+ php bin/phpunit
+```
+
+
+
+## 7. Author [↑](#index_block)
+Nil Portugués Calderó
+
+ -
+ - [http://nilportugues.com](http://nilportugues.com)
+
+
+
+## 8. License [↑](#index_block)
+SQL Query Builder is licensed under the MIT license.
+
+```
+Copyright (c) 2014 Nil Portugués Calderó
+
+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.
+```
diff --git a/vendor/nilportugues/sql-query-builder/composer.json b/vendor/nilportugues/sql-query-builder/composer.json
new file mode 100644
index 0000000..81134b0
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/composer.json
@@ -0,0 +1,53 @@
+{
+ "name":"nilportugues/sql-query-builder",
+ "description":"An elegant lightweight and efficient SQL QueryInterface BuilderInterface supporting bindings and complicated query generation.",
+ "keywords": [ "sql", "mysql", "query", "builder", "query builder", "orm"],
+ "type":"library",
+ "license":"MIT",
+ "homepage":"http://nilportugues.com",
+ "authors":
+ [
+ {
+ "name":"Nil Portugués Calderó",
+ "email":"contact@nilportugues.com",
+ "homepage":"http://nilportugues.com",
+ "role":"Lead Developer"
+ },
+ {
+ "name":"Woody Gilk",
+ "email":"woody.gilk@gmail.com",
+ "homepage":"http://shadowhand.me/",
+ "role":"Contributor"
+ }
+ ],
+ "autoload":{
+ "psr-4":{
+ "NilPortugues\\Sql\\QueryBuilder\\":"src/"
+ }
+ },
+ "autoload-dev":{
+ "psr-4":{
+ "NilPortugues\\Tests\\Sql\\QueryBuilder\\":"tests/"
+ }
+ },
+ "require":
+ {
+ "php": ">=5.5",
+ "nilportugues/sql-query-formatter": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*",
+ "fabpot/php-cs-fixer": "~1.9",
+ "nilportugues/php_backslasher": "~0.2"
+ },
+ "config":
+ {
+ "bin-dir": "bin"
+ },
+ "minimum-stability": "stable",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/phpunit.xml.dist b/vendor/nilportugues/sql-query-builder/phpunit.xml.dist
new file mode 100644
index 0000000..659e6c8
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/phpunit.xml.dist
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./tests
+
+
+
+
+
+ ./
+
+ ./vendor/
+ ./tests/
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/BuilderException.php b/vendor/nilportugues/sql-query-builder/src/Builder/BuilderException.php
new file mode 100644
index 0000000..c65caaa
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/BuilderException.php
@@ -0,0 +1,18 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder;
+
+/**
+ * Class BuilderException.
+ */
+final class BuilderException extends \Exception
+{
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/BuilderInterface.php b/vendor/nilportugues/sql-query-builder/src/Builder/BuilderInterface.php
new file mode 100644
index 0000000..9498a2b
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/BuilderInterface.php
@@ -0,0 +1,33 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryInterface;
+
+/**
+ * Interface BuilderInterface.
+ */
+interface BuilderInterface
+{
+ /**
+ * @param QueryInterface $query
+ *
+ * @return string
+ */
+ public function write(QueryInterface $query);
+
+ /**
+ * @param QueryInterface $query
+ *
+ * @return string
+ */
+ public function writeFormatted(QueryInterface $query);
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/GenericBuilder.php b/vendor/nilportugues/sql-query-builder/src/Builder/GenericBuilder.php
new file mode 100644
index 0000000..f31df44
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/GenericBuilder.php
@@ -0,0 +1,401 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder;
+
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory;
+use NilPortugues\Sql\QueryBuilder\Manipulation\AbstractBaseQuery;
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryInterface;
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryFactory;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\Table;
+
+/**
+ * Class Generic.
+ */
+class GenericBuilder implements BuilderInterface
+{
+ /**
+ * The placeholder parameter bag.
+ *
+ * @var \NilPortugues\Sql\QueryBuilder\Builder\Syntax\PlaceholderWriter
+ */
+ protected $placeholderWriter;
+
+ /**
+ * The Where writer.
+ *
+ * @var \NilPortugues\Sql\QueryBuilder\Builder\Syntax\WhereWriter
+ */
+ protected $whereWriter;
+
+ /**
+ * The SQL formatter.
+ *
+ * @var \NilPortugues\Sql\QueryFormatter\Formatter
+ */
+ protected $sqlFormatter;
+
+ /**
+ * Class namespace for the query pretty output formatter.
+ * Required to create the instance only if required.
+ *
+ * @var string
+ */
+ protected $sqlFormatterClass = 'NilPortugues\Sql\QueryFormatter\Formatter';
+
+ /**
+ * Array holding the writers for each query part. Methods are called upon request and stored in
+ * the $queryWriterInstances array.
+ *
+ * @var array
+ */
+ protected $queryWriterArray = [
+ 'SELECT' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createSelectWriter',
+ 'INSERT' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createInsertWriter',
+ 'UPDATE' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createUpdateWriter',
+ 'DELETE' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createDeleteWriter',
+ 'INTERSECT' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createIntersectWriter',
+ 'MINUS' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createMinusWriter',
+ 'UNION' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createUnionWriter',
+ 'UNION ALL' => '\NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory::createUnionAllWriter',
+ ];
+
+ /**
+ * Array that stores instances of query writers.
+ *
+ * @var array
+ */
+ protected $queryWriterInstances = [
+ 'SELECT' => null,
+ 'INSERT' => null,
+ 'UPDATE' => null,
+ 'DELETE' => null,
+ 'INTERSECT' => null,
+ 'MINUS' => null,
+ 'UNION' => null,
+ 'UNION ALL' => null,
+ ];
+
+ /**
+ * Creates writers.
+ */
+ public function __construct()
+ {
+ $this->placeholderWriter = WriterFactory::createPlaceholderWriter();
+ }
+
+ /**
+ * @param string $table
+ * @param array $columns
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\Select
+ */
+ public function select($table = null, array $columns = null)
+ {
+ return $this->injectBuilder(QueryFactory::createSelect($table, $columns));
+ }
+
+ /**
+ * @param \NilPortugues\Sql\QueryBuilder\Manipulation\AbstractBaseQuery
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\AbstractBaseQuery
+ */
+ protected function injectBuilder(AbstractBaseQuery $query)
+ {
+ return $query->setBuilder($this);
+ }
+
+ /**
+ * @param string $table
+ * @param array $values
+ *
+ *@return AbstractBaseQuery
+ */
+ public function insert($table = null, array $values = null)
+ {
+ return $this->injectBuilder(QueryFactory::createInsert($table, $values));
+ }
+
+ /**
+ * @param string $table
+ * @param array $values
+ *
+ *@return AbstractBaseQuery
+ */
+ public function update($table = null, array $values = null)
+ {
+ return $this->injectBuilder(QueryFactory::createUpdate($table, $values));
+ }
+
+ /**
+ * @param string $table
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\Delete
+ */
+ public function delete($table = null)
+ {
+ return $this->injectBuilder(QueryFactory::createDelete($table));
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\Intersect
+ */
+ public function intersect()
+ {
+ return QueryFactory::createIntersect();
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\Union
+ */
+ public function union()
+ {
+ return QueryFactory::createUnion();
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\UnionAll
+ */
+ public function unionAll()
+ {
+ return QueryFactory::createUnionAll();
+ }
+
+ /**
+ * @param \NilPortugues\Sql\QueryBuilder\Manipulation\Select $first
+ * @param \NilPortugues\Sql\QueryBuilder\Manipulation\Select $second
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\Minus
+ */
+ public function minus(Select $first, Select $second)
+ {
+ return QueryFactory::createMinus($first, $second);
+ }
+
+ /**
+ * @return array
+ */
+ public function getValues()
+ {
+ return $this->placeholderWriter->get();
+ }
+
+ /**
+ * Returns a SQL string in a readable human-friendly format.
+ *
+ * @param QueryInterface $query
+ *
+ * @return string
+ */
+ public function writeFormatted(QueryInterface $query)
+ {
+ if (null === $this->sqlFormatter) {
+ $this->sqlFormatter = (new \ReflectionClass($this->sqlFormatterClass))->newInstance();
+ }
+
+ return $this->sqlFormatter->format($this->write($query));
+ }
+
+ /**
+ * @param QueryInterface $query
+ * @param bool $resetPlaceholders
+ *
+ * @return string
+ *
+ * @throws \RuntimeException
+ */
+ public function write(QueryInterface $query, $resetPlaceholders = true)
+ {
+ if ($resetPlaceholders) {
+ $this->placeholderWriter->reset();
+ }
+
+ $queryPart = $query->partName();
+
+ if (false === empty($this->queryWriterArray[$queryPart])) {
+ $this->createQueryObject($queryPart);
+
+ return $this->queryWriterInstances[$queryPart]->write($query);
+ }
+
+ throw new \RuntimeException('Query builder part not defined.');
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return string
+ */
+ public function writeJoin(Select $select)
+ {
+ if (null === $this->whereWriter) {
+ $this->whereWriter = WriterFactory::createWhereWriter($this, $this->placeholderWriter);
+ }
+
+ $sql = ($select->getJoinType()) ? "{$select->getJoinType()} " : '';
+ $sql .= 'JOIN ';
+ $sql .= $this->writeTableWithAlias($select->getTable());
+ $sql .= ' ON ';
+ $sql .= $this->whereWriter->writeWhere($select->getJoinCondition());
+
+ return $sql;
+ }
+
+ /**
+ * @param Table $table
+ *
+ * @return string
+ */
+ public function writeTableWithAlias(Table $table)
+ {
+ $alias = ($table->getAlias()) ? " AS {$this->writeTableAlias($table->getAlias())}" : '';
+ $schema = ($table->getSchema()) ? "{$table->getSchema()}." : '';
+
+ return $schema.$this->writeTableName($table).$alias;
+ }
+
+ /**
+ * @param $alias
+ *
+ * @return mixed
+ */
+ public function writeTableAlias($alias)
+ {
+ return $alias;
+ }
+
+ /**
+ * Returns the table name.
+ *
+ * @param Table $table
+ *
+ * @return string
+ */
+ public function writeTableName(Table $table)
+ {
+ return $table->getName();
+ }
+
+ /**
+ * @param string $alias
+ *
+ * @return string
+ */
+ public function writeColumnAlias($alias)
+ {
+ return sprintf('"%s"', $alias);
+ }
+
+ /**
+ * @param Table $table
+ *
+ * @return string
+ */
+ public function writeTable(Table $table)
+ {
+ $schema = ($table->getSchema()) ? "{$table->getSchema()}." : '';
+
+ return $schema.$this->writeTableName($table);
+ }
+
+ /**
+ * @param array $values
+ *
+ * @return array
+ */
+ public function writeValues(array &$values)
+ {
+ \array_walk(
+ $values,
+ function (&$value) {
+ $value = $this->writePlaceholderValue($value);
+ }
+ );
+
+ return $values;
+ }
+
+ /**
+ * @param $value
+ *
+ * @return string
+ */
+ public function writePlaceholderValue($value)
+ {
+ return $this->placeholderWriter->add($value);
+ }
+
+ /**
+ * @param $operator
+ *
+ * @return string
+ */
+ public function writeConjunction($operator)
+ {
+ return ' '.$operator.' ';
+ }
+
+ /**
+ * @return string
+ */
+ public function writeIsNull()
+ {
+ return ' IS NULL';
+ }
+
+ /**
+ * @return string
+ */
+ public function writeIsNotNull()
+ {
+ return ' IS NOT NULL';
+ }
+
+ /**
+ * Returns the column name.
+ *
+ * @param Column $column
+ *
+ * @return string
+ */
+ public function writeColumnName(Column $column)
+ {
+ $name = $column->getName();
+
+ if ($name === Column::ALL) {
+ return $this->writeColumnAll();
+ }
+
+ return $name;
+ }
+
+ /**
+ * @return string
+ */
+ protected function writeColumnAll()
+ {
+ return '*';
+ }
+
+ /**
+ * @param string $queryPart
+ */
+ protected function createQueryObject($queryPart)
+ {
+ if (null === $this->queryWriterInstances[$queryPart]) {
+ $this->queryWriterInstances[$queryPart] = \call_user_func_array(
+ \explode('::', $this->queryWriterArray[$queryPart]),
+ [$this, $this->placeholderWriter]
+ );
+ }
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/MySqlBuilder.php b/vendor/nilportugues/sql-query-builder/src/Builder/MySqlBuilder.php
new file mode 100644
index 0000000..a81bdf0
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/MySqlBuilder.php
@@ -0,0 +1,91 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\Table;
+
+/**
+ * Class MySqlBuilder.
+ */
+class MySqlBuilder extends GenericBuilder
+{
+ /**
+ * {@inheritdoc}
+ *
+ * @param Column $column
+ *
+ * @return string
+ */
+ public function writeColumnName(Column $column)
+ {
+ if ($column->isAll()) {
+ return '*';
+ }
+
+ if (false !== strpos($column->getName(), '(')) {
+ return parent::writeColumnName($column);
+ }
+
+ return $this->wrapper(parent::writeColumnName($column));
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param Table $table
+ *
+ * @return string
+ */
+ public function writeTableName(Table $table)
+ {
+ return $this->wrapper(parent::writeTableName($table));
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param $alias
+ *
+ * @return string
+ */
+ public function writeTableAlias($alias)
+ {
+ return $this->wrapper(parent::writeTableAlias($alias));
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @param $alias
+ *
+ * @return string
+ */
+ public function writeColumnAlias($alias)
+ {
+ return $this->wrapper($alias);
+ }
+
+ /**
+ * @param $string
+ * @param string $char
+ *
+ * @return string
+ */
+ protected function wrapper($string, $char = '`')
+ {
+ if (0 === strlen($string)) {
+ return '';
+ }
+
+ return $char.$string.$char;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/AbstractBaseWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/AbstractBaseWriter.php
new file mode 100644
index 0000000..470bbeb
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/AbstractBaseWriter.php
@@ -0,0 +1,96 @@
+
+ * Date: 12/24/14
+ * Time: 1:14 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\AbstractBaseQuery;
+
+/**
+ * Class AbstractBaseWriter.
+ */
+abstract class AbstractBaseWriter
+{
+ /**
+ * @var GenericBuilder
+ */
+ protected $writer;
+
+ /**
+ * @var PlaceholderWriter
+ */
+ protected $placeholderWriter;
+
+ /**
+ * @var ColumnWriter
+ */
+ protected $columnWriter;
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholder
+ */
+ public function __construct(GenericBuilder $writer, PlaceholderWriter $placeholder)
+ {
+ $this->writer = $writer;
+ $this->placeholderWriter = $placeholder;
+
+ $this->columnWriter = WriterFactory::createColumnWriter($writer, $placeholder);
+ }
+
+ /**
+ * @param AbstractBaseQuery $class
+ *
+ * @return string
+ */
+ public static function writeQueryComment(AbstractBaseQuery $class)
+ {
+ $comment = '';
+ if ('' !== $class->getComment()) {
+ $comment = $class->getComment();
+ }
+
+ return $comment;
+ }
+
+ /**
+ * @param AbstractBaseQuery $class
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ * @param array $parts
+ */
+ public static function writeWhereCondition(
+ AbstractBaseQuery $class,
+ $writer, PlaceholderWriter
+ $placeholderWriter,
+ array &$parts
+ ) {
+ if (!is_null($class->getWhere())) {
+ $whereWriter = WriterFactory::createWhereWriter($writer, $placeholderWriter);
+ $parts[] = "WHERE {$whereWriter->writeWhere($class->getWhere())}";
+ }
+ }
+
+ /**
+ * @param AbstractBaseQuery $class
+ * @param PlaceholderWriter $placeholderWriter
+ * @param array $parts
+ */
+ public static function writeLimitCondition(
+ AbstractBaseQuery $class,
+ PlaceholderWriter $placeholderWriter,
+ array &$parts
+ ) {
+ if (!is_null($class->getLimitStart())) {
+ $start = $placeholderWriter->add($class->getLimitStart());
+ $parts[] = "LIMIT {$start}";
+ }
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/AbstractSetWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/AbstractSetWriter.php
new file mode 100644
index 0000000..8558c32
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/AbstractSetWriter.php
@@ -0,0 +1,51 @@
+
+ * Date: 12/24/14
+ * Time: 12:55 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Syntax\QueryPartInterface;
+
+/**
+ * Class AbstractSetWriter.
+ */
+abstract class AbstractSetWriter
+{
+ /**
+ * @var GenericBuilder
+ */
+ protected $writer;
+
+ /**
+ * @param GenericBuilder $writer
+ */
+ public function __construct(GenericBuilder $writer)
+ {
+ $this->writer = $writer;
+ }
+
+ /**
+ * @param QueryPartInterface $setClass
+ * @param string $setOperation
+ * @param $glue
+ *
+ * @return string
+ */
+ protected function abstractWrite(QueryPartInterface $setClass, $setOperation, $glue)
+ {
+ $selects = [];
+
+ foreach ($setClass->$setOperation() as $select) {
+ $selects[] = $this->writer->write($select, false);
+ }
+
+ return \implode("\n".$glue."\n", $selects);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/ColumnWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/ColumnWriter.php
new file mode 100644
index 0000000..999db08
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/ColumnWriter.php
@@ -0,0 +1,162 @@
+
+ * Date: 6/12/14
+ * Time: 1:28 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+
+/**
+ * Class ColumnWriter.
+ */
+class ColumnWriter
+{
+ /**
+ * @var \NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder
+ */
+ protected $writer;
+
+ /**
+ * @var PlaceholderWriter
+ */
+ protected $placeholderWriter;
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ */
+ public function __construct(GenericBuilder $writer, PlaceholderWriter $placeholderWriter)
+ {
+ $this->writer = $writer;
+ $this->placeholderWriter = $placeholderWriter;
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return array
+ */
+ public function writeSelectsAsColumns(Select $select)
+ {
+ $selectAsColumns = $select->getColumnSelects();
+
+ if (!empty($selectAsColumns)) {
+ $selectWriter = WriterFactory::createSelectWriter($this->writer, $this->placeholderWriter);
+ $selectAsColumns = $this->selectColumnToQuery($selectAsColumns, $selectWriter);
+ }
+
+ return $selectAsColumns;
+ }
+
+ /**
+ * @param array $selectAsColumns
+ * @param SelectWriter $selectWriter
+ *
+ * @return mixed
+ */
+ protected function selectColumnToQuery(array &$selectAsColumns, SelectWriter $selectWriter)
+ {
+ \array_walk(
+ $selectAsColumns,
+ function (&$column) use (&$selectWriter) {
+ $keys = \array_keys($column);
+ $key = \array_pop($keys);
+
+ $values = \array_values($column);
+ $value = $values[0];
+
+ if (\is_numeric($key)) {
+ /* @var Column $value */
+ $key = $this->writer->writeTableName($value->getTable());
+ }
+ $column = $selectWriter->selectToColumn($key, $value);
+ }
+ );
+
+ return $selectAsColumns;
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return array
+ */
+ public function writeValueAsColumns(Select $select)
+ {
+ $valueAsColumns = $select->getColumnValues();
+ $newColumns = [];
+
+ if (!empty($valueAsColumns)) {
+ foreach ($valueAsColumns as $alias => $value) {
+ $value = $this->writer->writePlaceholderValue($value);
+ $newValueColumn = array($alias => $value);
+
+ $newColumns[] = SyntaxFactory::createColumn($newValueColumn, null);
+ }
+ }
+
+ return $newColumns;
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return array
+ */
+ public function writeFuncAsColumns(Select $select)
+ {
+ $funcAsColumns = $select->getColumnFuncs();
+ $newColumns = [];
+
+ if (!empty($funcAsColumns)) {
+ foreach ($funcAsColumns as $alias => $value) {
+ $funcName = $value['func'];
+ $funcArgs = (!empty($value['args'])) ? '('.implode(', ', $value['args']).')' : '';
+
+ $newFuncColumn = array($alias => $funcName.$funcArgs);
+ $newColumns[] = SyntaxFactory::createColumn($newFuncColumn, null);
+ }
+ }
+
+ return $newColumns;
+ }
+
+ /**
+ * @param Column $column
+ *
+ * @return string
+ */
+ public function writeColumnWithAlias(Column $column)
+ {
+ if (($alias = $column->getAlias()) && !$column->isAll()) {
+ return $this->writeColumn($column).' AS '.$this->writer->writeColumnAlias($alias);
+ }
+
+ return $this->writeColumn($column);
+ }
+
+ /**
+ * @param Column $column
+ *
+ * @return string
+ */
+ public function writeColumn(Column $column)
+ {
+ $alias = $column->getTable()->getAlias();
+ $table = ($alias) ? $this->writer->writeTableAlias($alias) : $this->writer->writeTable($column->getTable());
+
+ $columnString = (empty($table)) ? '' : "{$table}.";
+ $columnString .= $this->writer->writeColumnName($column);
+
+ return $columnString;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/DeleteWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/DeleteWriter.php
new file mode 100644
index 0000000..f75c456
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/DeleteWriter.php
@@ -0,0 +1,57 @@
+
+ * Date: 6/11/14
+ * Time: 1:50 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Delete;
+
+/**
+ * Class DeleteWriter.
+ */
+class DeleteWriter
+{
+ /**
+ * @var GenericBuilder
+ */
+ protected $writer;
+
+ /**
+ * @var PlaceholderWriter
+ */
+ protected $placeholderWriter;
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholder
+ */
+ public function __construct(GenericBuilder $writer, PlaceholderWriter $placeholder)
+ {
+ $this->writer = $writer;
+ $this->placeholderWriter = $placeholder;
+ }
+
+ /**
+ * @param Delete $delete
+ *
+ * @return string
+ */
+ public function write(Delete $delete)
+ {
+ $table = $this->writer->writeTable($delete->getTable());
+ $parts = array("DELETE FROM {$table}");
+
+ AbstractBaseWriter::writeWhereCondition($delete, $this->writer, $this->placeholderWriter, $parts);
+ AbstractBaseWriter::writeLimitCondition($delete, $this->placeholderWriter, $parts);
+ $comment = AbstractBaseWriter::writeQueryComment($delete);
+
+ return $comment.implode(' ', $parts);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/InsertWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/InsertWriter.php
new file mode 100644
index 0000000..b464137
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/InsertWriter.php
@@ -0,0 +1,103 @@
+
+ * Date: 6/11/14
+ * Time: 1:51 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Insert;
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryException;
+
+/**
+ * Class InsertWriter.
+ */
+class InsertWriter
+{
+ /**
+ * @var GenericBuilder
+ */
+ protected $writer;
+
+ /**
+ * @var ColumnWriter
+ */
+ protected $columnWriter;
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholder
+ */
+ public function __construct(GenericBuilder $writer, PlaceholderWriter $placeholder)
+ {
+ $this->writer = $writer;
+ $this->columnWriter = WriterFactory::createColumnWriter($this->writer, $placeholder);
+ }
+
+ /**
+ * @param Insert $insert
+ *
+ * @throws QueryException
+ *
+ * @return string
+ */
+ public function write(Insert $insert)
+ {
+ $columns = $insert->getColumns();
+
+ if (empty($columns)) {
+ throw new QueryException('No columns were defined for the current schema.');
+ }
+
+ $columns = $this->writeQueryColumns($columns);
+ $values = $this->writeQueryValues($insert->getValues());
+ $table = $this->writer->writeTable($insert->getTable());
+ $comment = AbstractBaseWriter::writeQueryComment($insert);
+
+ return $comment."INSERT INTO {$table} ($columns) VALUES ($values)";
+ }
+
+ /**
+ * @param $columns
+ *
+ * @return string
+ */
+ protected function writeQueryColumns($columns)
+ {
+ return $this->writeCommaSeparatedValues($columns, $this->columnWriter, 'writeColumn');
+ }
+
+ /**
+ * @param $collection
+ * @param $writer
+ * @param string $method
+ *
+ * @return string
+ */
+ protected function writeCommaSeparatedValues($collection, $writer, $method)
+ {
+ \array_walk(
+ $collection,
+ function (&$data) use ($writer, $method) {
+ $data = $writer->$method($data);
+ }
+ );
+
+ return \implode(', ', $collection);
+ }
+
+ /**
+ * @param $values
+ *
+ * @return string
+ */
+ protected function writeQueryValues($values)
+ {
+ return $this->writeCommaSeparatedValues($values, $this->writer, 'writePlaceholderValue');
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/IntersectWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/IntersectWriter.php
new file mode 100644
index 0000000..e96f3d0
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/IntersectWriter.php
@@ -0,0 +1,29 @@
+
+ * Date: 9/12/14
+ * Time: 7:15 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Intersect;
+
+/**
+ * Class IntersectWriter.
+ */
+class IntersectWriter extends AbstractSetWriter
+{
+ /**
+ * @param Intersect $intersect
+ *
+ * @return string
+ */
+ public function write(Intersect $intersect)
+ {
+ return $this->abstractWrite($intersect, 'getIntersects', Intersect::INTERSECT);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/MinusWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/MinusWriter.php
new file mode 100644
index 0000000..6fd9c13
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/MinusWriter.php
@@ -0,0 +1,46 @@
+
+ * Date: 9/12/14
+ * Time: 7:15 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Minus;
+
+/**
+ * Class MinusWriter.
+ */
+class MinusWriter
+{
+ /**
+ * @var GenericBuilder
+ */
+ protected $writer;
+
+ /**
+ * @param GenericBuilder $writer
+ */
+ public function __construct(GenericBuilder $writer)
+ {
+ $this->writer = $writer;
+ }
+
+ /**
+ * @param Minus $minus
+ *
+ * @return string
+ */
+ public function write(Minus $minus)
+ {
+ $first = $this->writer->write($minus->getFirst());
+ $second = $this->writer->write($minus->getSecond());
+
+ return $first."\n".Minus::MINUS."\n".$second;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/PlaceholderWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/PlaceholderWriter.php
new file mode 100644
index 0000000..de78f09
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/PlaceholderWriter.php
@@ -0,0 +1,147 @@
+
+ * Date: 6/4/14
+ * Time: 12:02 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+/**
+ * Class PlaceholderWriter.
+ */
+class PlaceholderWriter
+{
+ /**
+ * @var int
+ */
+ protected $counter = 1;
+
+ /**
+ * @var array
+ */
+ protected $placeholders = [];
+
+ /**
+ * @return array
+ */
+ public function get()
+ {
+ return $this->placeholders;
+ }
+
+ /**
+ * @return $this
+ */
+ public function reset()
+ {
+ $this->counter = 1;
+ $this->placeholders = [];
+
+ return $this;
+ }
+
+ /**
+ * @param $value
+ *
+ * @return string
+ */
+ public function add($value)
+ {
+ $placeholderKey = ':v'.$this->counter;
+ $this->placeholders[$placeholderKey] = $this->setValidSqlValue($value);
+
+ ++$this->counter;
+
+ return $placeholderKey;
+ }
+
+ /**
+ * @param $value
+ *
+ * @return string
+ */
+ protected function setValidSqlValue($value)
+ {
+ $value = $this->writeNullSqlString($value);
+ $value = $this->writeStringAsSqlString($value);
+ $value = $this->writeBooleanSqlString($value);
+
+ return $value;
+ }
+
+ /**
+ * @param $value
+ *
+ * @return string
+ */
+ protected function writeNullSqlString($value)
+ {
+ if (\is_null($value) || (\is_string($value) && empty($value))) {
+ $value = $this->writeNull();
+ }
+
+ return $value;
+ }
+
+ /**
+ * @return string
+ */
+ protected function writeNull()
+ {
+ return 'NULL';
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return string
+ */
+ protected function writeStringAsSqlString($value)
+ {
+ if (\is_string($value)) {
+ $value = $this->writeString($value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return string
+ */
+ protected function writeString($value)
+ {
+ return $value;
+ }
+
+ /**
+ * @param string $value
+ *
+ * @return string
+ */
+ protected function writeBooleanSqlString($value)
+ {
+ if (\is_bool($value)) {
+ $value = $this->writeBoolean($value);
+ }
+
+ return $value;
+ }
+
+ /**
+ * @param bool $value
+ *
+ * @return string
+ */
+ protected function writeBoolean($value)
+ {
+ $value = \filter_var($value, FILTER_VALIDATE_BOOLEAN);
+
+ return ($value) ? '1' : '0';
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/SelectWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/SelectWriter.php
new file mode 100644
index 0000000..b124bfe
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/SelectWriter.php
@@ -0,0 +1,397 @@
+
+ * Date: 6/11/14
+ * Time: 1:50 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy;
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+
+/**
+ * Class SelectWriter.
+ */
+class SelectWriter extends AbstractBaseWriter
+{
+ /**
+ * @param $alias
+ * @param Select $select
+ *
+ * @return Column
+ */
+ public function selectToColumn($alias, Select $select)
+ {
+ $selectAsColumn = $this->write($select);
+
+ if (!empty($selectAsColumn)) {
+ $selectAsColumn = '('.$selectAsColumn.')';
+ }
+
+ $column = array($alias => $selectAsColumn);
+
+ return SyntaxFactory::createColumn($column, null);
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return string
+ */
+ public function write(Select $select)
+ {
+ if ($select->isJoinSelect()) {
+ return $this->writer->writeJoin($select);
+ }
+
+ return $this->writeSelectQuery($select);
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return string
+ */
+ protected function writeSelectQuery(Select $select)
+ {
+ $parts = ['SELECT'];
+
+ if ($select->isDistinct()) {
+ $parts[] = 'DISTINCT';
+ }
+
+ $this->writeSelectColumns($select, $parts);
+ $this->writeSelectFrom($select, $parts);
+ $this->writeSelectJoins($select, $parts);
+ $this->writeSelectWhere($select, $parts);
+ $this->writeSelectGroupBy($select, $parts);
+ $this->writeSelectHaving($select, $parts);
+ $this->writeSelectOrderBy($select, $parts);
+ $this->writeSelectLimit($select, $parts);
+
+ return AbstractBaseWriter::writeQueryComment($select).implode(' ', \array_filter($parts));
+ }
+
+ /**
+ * @param Select $select
+ * @param string[] $parts
+ *
+ * @return $this
+ */
+ public function writeSelectColumns(Select $select, array &$parts)
+ {
+ if ($select->isCount() === false) {
+ $columns = $this->writeColumnAlias(
+ $select->getAllColumns(),
+ $this->columnWriter->writeSelectsAsColumns($select),
+ $this->columnWriter->writeValueAsColumns($select),
+ $this->columnWriter->writeFuncAsColumns($select)
+ );
+
+ $parts = \array_merge($parts, [implode(', ', $columns)]);
+
+ return $this;
+ }
+
+ $columns = $select->getColumns();
+ $column = \array_pop($columns);
+ $columnList = $column->getName();
+
+ $parts = \array_merge($parts, [$columnList]);
+
+ return $this;
+ }
+
+ /**
+ * @param $tableColumns
+ * @param $selectAsColumns
+ * @param $valueAsColumns
+ * @param $funcAsColumns
+ *
+ * @return array
+ */
+ protected function writeColumnAlias($tableColumns, $selectAsColumns, $valueAsColumns, $funcAsColumns)
+ {
+ $columns = \array_merge($tableColumns, $selectAsColumns, $valueAsColumns, $funcAsColumns);
+
+ \array_walk(
+ $columns,
+ function (&$column) {
+ $column = $this->columnWriter->writeColumnWithAlias($column);
+ }
+ );
+
+ return $columns;
+ }
+
+ /**
+ * @param Select $select
+ * @param string[] $parts
+ *
+ * @return $this
+ */
+ public function writeSelectFrom(Select $select, array &$parts)
+ {
+ $parts = \array_merge(
+ $parts,
+ ['FROM '.$this->writer->writeTableWithAlias($select->getTable())]
+ );
+
+ return $this;
+ }
+
+ /**
+ * @param Select $select
+ * @param array $parts
+ *
+ * @return $this
+ */
+ public function writeSelectJoins(Select $select, array &$parts)
+ {
+ $parts = \array_merge(
+ $parts,
+ [$this->writeSelectAggrupation($select, $this->writer, 'getAllJoins', 'writeJoin', ' ')]
+ );
+
+ return $this;
+ }
+
+ /**
+ * @param Select $select
+ * @param $writer
+ * @param string $getMethod
+ * @param string $writeMethod
+ * @param string $glue
+ * @param string $prepend
+ *
+ * @return string
+ */
+ protected function writeSelectAggrupation(Select $select, $writer, $getMethod, $writeMethod, $glue, $prepend = '')
+ {
+ $str = '';
+ $joins = $select->$getMethod();
+
+ if (!empty($joins)) {
+ \array_walk(
+ $joins,
+ function (&$join) use ($writer, $writeMethod) {
+ $join = $writer->$writeMethod($join);
+ }
+ );
+
+ $str = $prepend.implode($glue, $joins);
+ }
+
+ return $str;
+ }
+
+ /**
+ * @param Select $select
+ * @param array $parts
+ *
+ * @return $this
+ */
+ public function writeSelectWhere(Select $select, array &$parts)
+ {
+ $str = '';
+ $wheres = $this->writeSelectWheres($select->getAllWheres());
+ $wheres = \array_filter($wheres);
+
+ if (\count($wheres) > 0) {
+ $str = 'WHERE ';
+ $separator = ' '.$this->writer->writeConjunction($select->getWhereOperator()).' ';
+
+ $str .= \implode($separator, $wheres);
+ }
+
+ $parts = \array_merge($parts, [$str]);
+
+ return $this;
+ }
+
+ /**
+ * @param array $wheres
+ *
+ * @return array
+ */
+ protected function writeSelectWheres(array $wheres)
+ {
+ $whereWriter = WriterFactory::createWhereWriter($this->writer, $this->placeholderWriter);
+
+ \array_walk(
+ $wheres,
+ function (&$where) use (&$whereWriter) {
+
+ $where = $whereWriter->writeWhere($where);
+ }
+ );
+
+ return $wheres;
+ }
+
+ /**
+ * @param Select $select
+ * @param array $parts
+ *
+ * @return $this
+ */
+ public function writeSelectGroupBy(Select $select, array &$parts)
+ {
+ $groupBy = $this->writeSelectAggrupation(
+ $select,
+ $this->columnWriter,
+ 'getGroupBy',
+ 'writeColumn',
+ ', ',
+ 'GROUP BY '
+ );
+
+ $parts = \array_merge($parts, [$groupBy]);
+
+ return $this;
+ }
+
+ /**
+ * @param Select $select
+ * @param array $parts
+ *
+ * @return $this
+ */
+ public function writeSelectHaving(Select $select, array &$parts)
+ {
+ $str = '';
+ $havingArray = $select->getAllHavings();
+
+ if (\count($havingArray) > 0) {
+ $placeholder = $this->placeholderWriter;
+ $writer = $this->writer;
+
+ $str = 'HAVING ';
+ $separator = ' '.$select->getHavingOperator().' ';
+ $havingArray = $this->getHavingConditions($havingArray, $select, $writer, $placeholder);
+
+ $str .= \implode($separator, $havingArray);
+ }
+
+ $parts = \array_merge($parts, [$str]);
+
+ return $this;
+ }
+
+ /**
+ * @param array $havingArray
+ * @param Select $select
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholder
+ *
+ * @return mixed
+ */
+ protected function getHavingConditions(
+ array &$havingArray,
+ Select $select,
+ GenericBuilder $writer,
+ PlaceholderWriter $placeholder
+ ) {
+ \array_walk(
+ $havingArray,
+ function (&$having) use ($select, $writer, $placeholder) {
+
+ $whereWriter = WriterFactory::createWhereWriter($writer, $placeholder);
+ $clauses = $whereWriter->writeWhereClauses($having);
+ $having = \implode($this->writer->writeConjunction($select->getHavingOperator()), $clauses);
+ }
+ );
+
+ return $havingArray;
+ }
+
+ /**
+ * @param Select $select
+ * @param array $parts
+ *
+ * @return $this
+ */
+ protected function writeSelectOrderBy(Select $select, array &$parts)
+ {
+ $str = '';
+ if (\count($select->getAllOrderBy())) {
+ $orderByArray = $select->getAllOrderBy();
+ \array_walk(
+ $orderByArray,
+ function (&$orderBy) {
+ $orderBy = $this->writeOrderBy($orderBy);
+ }
+ );
+
+ $str = 'ORDER BY ';
+ $str .= \implode(', ', $orderByArray);
+ }
+
+ $parts = \array_merge($parts, [$str]);
+
+ return $this;
+ }
+
+ /**
+ * @param OrderBy $orderBy
+ *
+ * @return string
+ */
+ public function writeOrderBy(OrderBy $orderBy)
+ {
+ $column = $this->columnWriter->writeColumn($orderBy->getColumn());
+
+ return $column.' '.$orderBy->getDirection();
+ }
+
+ /**
+ * @param Select $select
+ * @param array $parts
+ *
+ * @return $this
+ */
+ protected function writeSelectLimit(Select $select, array &$parts)
+ {
+ $mask = $this->getStartingLimit($select).$this->getLimitCount($select);
+
+ $limit = '';
+
+ if ($mask !== '00') {
+ $start = $this->placeholderWriter->add($select->getLimitStart());
+ $count = $this->placeholderWriter->add($select->getLimitCount());
+
+ $limit = "LIMIT {$start}, {$count}";
+ }
+
+ $parts = \array_merge($parts, [$limit]);
+
+ return $this;
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return string
+ */
+ protected function getStartingLimit(Select $select)
+ {
+ return (null === $select->getLimitStart() || 0 == $select->getLimitStart()) ? '0' : '1';
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return string
+ */
+ protected function getLimitCount(Select $select)
+ {
+ return (null === $select->getLimitCount()) ? '0' : '1';
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UnionAllWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UnionAllWriter.php
new file mode 100644
index 0000000..1b733de
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UnionAllWriter.php
@@ -0,0 +1,29 @@
+
+ * Date: 9/12/14
+ * Time: 7:15 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\UnionAll;
+
+/**
+ * Class UnionAllWriter.
+ */
+class UnionAllWriter extends AbstractSetWriter
+{
+ /**
+ * @param UnionAll $unionAll
+ *
+ * @return string
+ */
+ public function write(UnionAll $unionAll)
+ {
+ return $this->abstractWrite($unionAll, 'getUnions', UnionAll::UNION_ALL);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UnionWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UnionWriter.php
new file mode 100644
index 0000000..44c8e34
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UnionWriter.php
@@ -0,0 +1,29 @@
+
+ * Date: 9/12/14
+ * Time: 7:15 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Union;
+
+/**
+ * Class UnionWriter.
+ */
+class UnionWriter extends AbstractSetWriter
+{
+ /**
+ * @param Union $union
+ *
+ * @return string
+ */
+ public function write(Union $union)
+ {
+ return $this->abstractWrite($union, 'getUnions', Union::UNION);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UpdateWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UpdateWriter.php
new file mode 100644
index 0000000..b6ad0f1
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/UpdateWriter.php
@@ -0,0 +1,67 @@
+
+ * Date: 6/11/14
+ * Time: 1:51 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryException;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Update;
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+
+/**
+ * Class UpdateWriter.
+ */
+class UpdateWriter extends AbstractBaseWriter
+{
+ /**
+ * @param Update $update
+ *
+ * @throws QueryException
+ *
+ * @return string
+ */
+ public function write(Update $update)
+ {
+ $values = $update->getValues();
+ if (empty($values)) {
+ throw new QueryException('No values to update in Update query.');
+ }
+
+ $parts = array(
+ 'UPDATE '.$this->writer->writeTable($update->getTable()).' SET ',
+ $this->writeUpdateValues($update),
+ );
+
+ AbstractBaseWriter::writeWhereCondition($update, $this->writer, $this->placeholderWriter, $parts);
+ AbstractBaseWriter::writeLimitCondition($update, $this->placeholderWriter, $parts);
+ $comment = AbstractBaseWriter::writeQueryComment($update);
+
+ return $comment.implode(' ', $parts);
+ }
+
+ /**
+ * @param Update $update
+ *
+ * @return string
+ */
+ protected function writeUpdateValues(Update $update)
+ {
+ $assigns = [];
+ foreach ($update->getValues() as $column => $value) {
+ $newColumn = array($column);
+ $column = $this->columnWriter->writeColumn(SyntaxFactory::createColumn($newColumn, $update->getTable()));
+
+ $value = $this->writer->writePlaceholderValue($value);
+
+ $assigns[] = "$column = $value";
+ }
+
+ return \implode(', ', $assigns);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/WhereWriter.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/WhereWriter.php
new file mode 100644
index 0000000..aa2345a
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/WhereWriter.php
@@ -0,0 +1,400 @@
+ '(MATCH({{columnNames}}) AGAINST({{columnValues}}))',
+ 'boolean' => '(MATCH({{columnNames}}) AGAINST({{columnValues}} IN BOOLEAN MODE))',
+ 'query_expansion' => '(MATCH({{columnNames}}) AGAINST({{columnValues}} WITH QUERY EXPANSION))',
+ ];
+
+ /**
+ * @param Where $where
+ *
+ * @return string
+ */
+ public function writeWhere(Where $where)
+ {
+ $clauses = $this->writeWhereClauses($where);
+ $clauses = \array_filter($clauses);
+
+ if (empty($clauses)) {
+ return '';
+ }
+
+ return \implode($this->writer->writeConjunction($where->getConjunction()), $clauses);
+ }
+
+ /**
+ * @param Where $where
+ *
+ * @return array
+ */
+ public function writeWhereClauses(Where $where)
+ {
+ $whereArray = [];
+
+ $this->writeWhereMatches($where, $whereArray);
+ $this->writeWhereIns($where, $whereArray);
+ $this->writeWhereNotIns($where, $whereArray);
+ $this->writeWhereBetweens($where, $whereArray);
+ $this->writeWhereNotBetweens($where, $whereArray);
+ $this->writeWhereComparisons($where, $whereArray);
+ $this->writeWhereIsNulls($where, $whereArray);
+ $this->writeWhereIsNotNulls($where, $whereArray);
+ $this->writeWhereBooleans($where, $whereArray);
+ $this->writeExists($where, $whereArray);
+ $this->writeNotExists($where, $whereArray);
+ $this->writeSubWheres($where, $whereArray);
+
+ return $whereArray;
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereMatches(Where $where, array &$whereArray)
+ {
+ $matches = [];
+
+ foreach ($where->getMatches() as $values) {
+ $columns = SyntaxFactory::createColumns($values['columns'], $where->getTable());
+ $columnNames = $this->getColumnNames($columns);
+
+ $columnValues = array(\implode(' ', $values['values']));
+ $columnValues = \implode(', ', $this->writer->writeValues($columnValues));
+
+ $matches[] = \str_replace(
+ ['{{columnNames}}', '{{columnValues}}'],
+ [$columnNames, $columnValues],
+ $this->matchMode[$values['mode']]
+ );
+ }
+
+ $whereArray = \array_merge($whereArray, $matches);
+ }
+
+ /**
+ * @param $columns
+ *
+ * @return string
+ */
+ protected function getColumnNames($columns)
+ {
+ $columnNames = [];
+ foreach ($columns as &$column) {
+ $columnNames[] = $this->columnWriter->writeColumn($column);
+ }
+
+ return \implode(', ', $columnNames);
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereIns(Where $where, array &$whereArray)
+ {
+ $whereArray = \array_merge(
+ $whereArray,
+ $this->writeWhereIn($where, 'getIns', 'IN')
+ );
+ }
+
+ /**
+ * @param Where $where
+ * @param string $method
+ * @param string $operation
+ *
+ * @return array
+ */
+ protected function writeWhereIn(Where $where, $method, $operation)
+ {
+ $collection = [];
+
+ foreach ($where->$method() as $column => $values) {
+ $newColumn = array($column);
+ $column = SyntaxFactory::createColumn($newColumn, $where->getTable());
+ $column = $this->columnWriter->writeColumn($column);
+
+ $values = $this->writer->writeValues($values);
+ $values = \implode(', ', $values);
+
+ $collection[] = "({$column} $operation ({$values}))";
+ }
+
+ return $collection;
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereNotIns(Where $where, array &$whereArray)
+ {
+ $whereArray = \array_merge(
+ $whereArray,
+ $this->writeWhereIn($where, 'getNotIns', 'NOT IN')
+ );
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereBetweens(Where $where, array &$whereArray)
+ {
+ $between = $where->getBetweens();
+ \array_walk(
+ $between,
+ function (&$between) {
+
+ $between = '('
+ .$this->columnWriter->writeColumn($between['subject'])
+ .' BETWEEN '
+ .$this->writer->writePlaceholderValue($between['a'])
+ .' AND '
+ .$this->writer->writePlaceholderValue($between['b'])
+ .')';
+ }
+ );
+
+ $whereArray = \array_merge($whereArray, $between);
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereNotBetweens(Where $where, array &$whereArray)
+ {
+ $between = $where->getNotBetweens();
+ \array_walk(
+ $between,
+ function (&$between) {
+
+ $between = '('
+ .$this->columnWriter->writeColumn($between['subject'])
+ .' NOT BETWEEN '
+ .$this->writer->writePlaceholderValue($between['a'])
+ .' AND '
+ .$this->writer->writePlaceholderValue($between['b'])
+ .')';
+ }
+ );
+
+ $whereArray = \array_merge($whereArray, $between);
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereComparisons(Where $where, array &$whereArray)
+ {
+ $comparisons = $where->getComparisons();
+ \array_walk(
+ $comparisons,
+ function (&$comparison) {
+
+ if (!is_array($comparison)) {
+ return;
+ }
+
+ $str = $this->writeWherePartialCondition($comparison['subject']);
+ $str .= $this->writer->writeConjunction($comparison['conjunction']);
+ $str .= $this->writeWherePartialCondition($comparison['target']);
+
+ $comparison = "($str)";
+ }
+ );
+
+ $whereArray = \array_merge($whereArray, $comparisons);
+ }
+
+ /**
+ * @param $subject
+ *
+ * @return string
+ */
+ protected function writeWherePartialCondition(&$subject)
+ {
+ if ($subject instanceof Column) {
+ $str = $this->columnWriter->writeColumn($subject);
+ } elseif ($subject instanceof Select) {
+ $selectWriter = WriterFactory::createSelectWriter($this->writer, $this->placeholderWriter);
+ $str = '('.$selectWriter->write($subject).')';
+ } else {
+ $str = $this->writer->writePlaceholderValue($subject);
+ }
+
+ return $str;
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereIsNulls(Where $where, array &$whereArray)
+ {
+ $whereArray = \array_merge(
+ $whereArray,
+ $this->writeWhereIsNullable($where, 'getNull', 'writeIsNull')
+ );
+ }
+
+ /**
+ * @param Where $where
+ * @param string $getMethod
+ * @param string $writeMethod
+ *
+ * @return array
+ */
+ protected function writeWhereIsNullable(Where $where, $getMethod, $writeMethod)
+ {
+ $collection = $where->$getMethod();
+
+ \array_walk(
+ $collection,
+ function (&$collection) use ($writeMethod) {
+ $collection =
+ '('.$this->columnWriter->writeColumn($collection['subject'])
+ .$this->writer->$writeMethod().')';
+ }
+ );
+
+ return $collection;
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereIsNotNulls(Where $where, array &$whereArray)
+ {
+ $whereArray = \array_merge(
+ $whereArray,
+ $this->writeWhereIsNullable($where, 'getNotNull', 'writeIsNotNull')
+ );
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeWhereBooleans(Where $where, array &$whereArray)
+ {
+ $booleans = $where->getBooleans();
+ $placeholderWriter = $this->placeholderWriter;
+
+ \array_walk(
+ $booleans,
+ function (&$boolean) use (&$placeholderWriter) {
+ $column = $this->columnWriter->writeColumn($boolean['subject']);
+ $value = $this->placeholderWriter->add($boolean['value']);
+
+ $boolean = '(ISNULL('.$column.', 0) = '.$value.')';
+ }
+ );
+
+ $whereArray = \array_merge($whereArray, $booleans);
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeExists(Where $where, array &$whereArray)
+ {
+ $whereArray = \array_merge(
+ $whereArray,
+ $this->writeExistence($where, 'getExists', 'EXISTS')
+ );
+ }
+
+ /**
+ * @param Where $where
+ * @param string $method
+ * @param string $operation
+ *
+ * @return array
+ */
+ protected function writeExistence(Where $where, $method, $operation)
+ {
+ $exists = [];
+
+ foreach ($where->$method() as $select) {
+ $exists[] = "$operation (".$this->writer->write($select, false).')';
+ }
+
+ return $exists;
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeNotExists(Where $where, array &$whereArray)
+ {
+ $whereArray = \array_merge(
+ $whereArray,
+ $this->writeExistence($where, 'getNotExists', 'NOT EXISTS')
+ );
+ }
+
+ /**
+ * @param Where $where
+ * @param array $whereArray
+ *
+ * @return array
+ */
+ protected function writeSubWheres(Where $where, array &$whereArray)
+ {
+ $subWheres = $where->getSubWheres();
+
+ \array_walk(
+ $subWheres,
+ function (&$subWhere) {
+ $subWhere = "({$this->writeWhere($subWhere)})";
+ }
+ );
+
+ $whereArray = \array_merge($whereArray, $subWheres);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/WriterFactory.php b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/WriterFactory.php
new file mode 100644
index 0000000..8a85ecc
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Builder/Syntax/WriterFactory.php
@@ -0,0 +1,133 @@
+
+ * Date: 6/12/14
+ * Time: 2:11 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+
+/**
+ * Class WriterFactory.
+ */
+final class WriterFactory
+{
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ *
+ * @return ColumnWriter
+ */
+ public static function createColumnWriter(GenericBuilder $writer, PlaceholderWriter $placeholderWriter)
+ {
+ return new ColumnWriter($writer, $placeholderWriter);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ *
+ * @return WhereWriter
+ */
+ public static function createWhereWriter(GenericBuilder $writer, PlaceholderWriter $placeholderWriter)
+ {
+ return new WhereWriter($writer, $placeholderWriter);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ *
+ * @return SelectWriter
+ */
+ public static function createSelectWriter(GenericBuilder $writer, PlaceholderWriter $placeholderWriter)
+ {
+ return new SelectWriter($writer, $placeholderWriter);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ *
+ * @return InsertWriter
+ */
+ public static function createInsertWriter(GenericBuilder $writer, PlaceholderWriter $placeholderWriter)
+ {
+ return new InsertWriter($writer, $placeholderWriter);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ *
+ * @return UpdateWriter
+ */
+ public static function createUpdateWriter(GenericBuilder $writer, PlaceholderWriter $placeholderWriter)
+ {
+ return new UpdateWriter($writer, $placeholderWriter);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ * @param PlaceholderWriter $placeholderWriter
+ *
+ * @return DeleteWriter
+ */
+ public static function createDeleteWriter(GenericBuilder $writer, PlaceholderWriter $placeholderWriter)
+ {
+ return new DeleteWriter($writer, $placeholderWriter);
+ }
+
+ /**
+ * @return PlaceholderWriter
+ */
+ public static function createPlaceholderWriter()
+ {
+ return new PlaceholderWriter();
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ *
+ * @return IntersectWriter
+ */
+ public static function createIntersectWriter(GenericBuilder $writer)
+ {
+ return new IntersectWriter($writer);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ *
+ * @return MinusWriter
+ */
+ public static function createMinusWriter(GenericBuilder $writer)
+ {
+ return new MinusWriter($writer);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ *
+ * @return UnionWriter
+ */
+ public static function createUnionWriter(GenericBuilder $writer)
+ {
+ return new UnionWriter($writer);
+ }
+
+ /**
+ * @param GenericBuilder $writer
+ *
+ * @return UnionAllWriter
+ */
+ public static function createUnionAllWriter(GenericBuilder $writer)
+ {
+ return new UnionAllWriter($writer);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractBaseQuery.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractBaseQuery.php
new file mode 100644
index 0000000..a9845a2
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractBaseQuery.php
@@ -0,0 +1,277 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy;
+use NilPortugues\Sql\QueryBuilder\Syntax\QueryPartInterface;
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+use NilPortugues\Sql\QueryBuilder\Syntax\Table;
+use NilPortugues\Sql\QueryBuilder\Syntax\Where;
+// Builder injects itself into query for convestion to SQL string.
+use NilPortugues\Sql\QueryBuilder\Builder\BuilderInterface;
+
+/**
+ * Class AbstractBaseQuery.
+ */
+abstract class AbstractBaseQuery implements QueryInterface, QueryPartInterface
+{
+ /**
+ * @var string
+ */
+ protected $comment = '';
+
+ /**
+ * @var \NilPortugues\Sql\QueryBuilder\Builder\BuilderInterface
+ */
+ protected $builder;
+
+ /**
+ * @var string
+ */
+ protected $table;
+
+ /**
+ * @var string
+ */
+ protected $whereOperator = 'AND';
+
+ /**
+ * @var Where
+ */
+ protected $where;
+
+ /**
+ * @var array
+ */
+ protected $joins = [];
+
+ /**
+ * @var int
+ */
+ protected $limitStart;
+
+ /**
+ * @var int
+ */
+ protected $limitCount;
+
+ /**
+ * @var array
+ */
+ protected $orderBy = [];
+
+ /**
+ * @return Where
+ */
+ protected function filter()
+ {
+ if (!isset($this->where)) {
+ $this->where = QueryFactory::createWhere($this);
+ }
+
+ return $this->where;
+ }
+
+ /**
+ * Stores the builder that created this query.
+ *
+ * @param BuilderInterface $builder
+ *
+ * @return $this
+ */
+ final public function setBuilder(BuilderInterface $builder)
+ {
+ $this->builder = $builder;
+
+ return $this;
+ }
+
+ /**
+ * @return BuilderInterface
+ *
+ * @throws \RuntimeException when builder has not been injected
+ */
+ final public function getBuilder()
+ {
+ if (!$this->builder) {
+ throw new \RuntimeException('Query builder has not been injected with setBuilder');
+ }
+
+ return $this->builder;
+ }
+
+ /**
+ * Converts this query into an SQL string by using the injected builder.
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ try {
+ return $this->getSql();
+ } catch (\Exception $e) {
+ return \sprintf('[%s] %s', \get_class($e), $e->getMessage());
+ }
+ }
+
+ /**
+ * Converts this query into an SQL string by using the injected builder.
+ * Optionally can return the SQL with formatted structure.
+ *
+ * @param bool $formatted
+ *
+ * @return string
+ */
+ public function getSql($formatted = false)
+ {
+ if ($formatted) {
+ return $this->getBuilder()->writeFormatted($this);
+ }
+
+ return $this->getBuilder()->write($this);
+ }
+
+ /**
+ * @return string
+ */
+ abstract public function partName();
+
+ /**
+ * @return Where
+ */
+ public function getWhere()
+ {
+ return $this->where;
+ }
+
+ /**
+ * @param Where $where
+ *
+ * @return $this
+ */
+ public function setWhere(Where $where)
+ {
+ $this->where = $where;
+
+ return $this;
+ }
+
+ /**
+ * @return Table
+ */
+ public function getTable()
+ {
+ $newTable = array($this->table);
+
+ return \is_null($this->table) ? null : SyntaxFactory::createTable($newTable);
+ }
+
+ /**
+ * @param string $table
+ *
+ * @return $this
+ */
+ public function setTable($table)
+ {
+ $this->table = (string) $table;
+
+ return $this;
+ }
+
+ /**
+ * @param string $whereOperator
+ *
+ * @return Where
+ */
+ public function where($whereOperator = 'AND')
+ {
+ if (!isset($this->where)) {
+ $this->where = $this->filter();
+ }
+
+ $this->where->conjunction($whereOperator);
+
+ return $this->where;
+ }
+
+ /**
+ * @return string
+ */
+ public function getWhereOperator()
+ {
+ if (!isset($this->where)) {
+ $this->where = $this->filter();
+ }
+
+ return $this->where->getConjunction();
+ }
+
+ /**
+ * @param string $column
+ * @param string $direction
+ * @param null $table
+ *
+ * @return $this
+ */
+ public function orderBy($column, $direction = OrderBy::ASC, $table = null)
+ {
+ $newColumn = array($column);
+ $column = SyntaxFactory::createColumn($newColumn, \is_null($table) ? $this->getTable() : $table);
+ $this->orderBy[] = new OrderBy($column, $direction);
+
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLimitCount()
+ {
+ return $this->limitCount;
+ }
+
+ /**
+ * @return int
+ */
+ public function getLimitStart()
+ {
+ return $this->limitStart;
+ }
+
+ /**
+ * @param string $comment
+ *
+ * @return $this
+ */
+ public function setComment($comment)
+ {
+ // Make each line of the comment prefixed with "--",
+ // and remove any trailing whitespace.
+ $comment = '-- '.str_replace("\n", "\n-- ", \rtrim($comment));
+
+ // Trim off any trailing "-- ", to ensure that the comment is valid.
+ $this->comment = \rtrim($comment, '- ');
+
+ if ($this->comment) {
+ $this->comment .= "\n";
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getComment()
+ {
+ return $this->comment;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractCreationalQuery.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractCreationalQuery.php
new file mode 100644
index 0000000..10b83ff
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractCreationalQuery.php
@@ -0,0 +1,57 @@
+
+ * Date: 12/24/14
+ * Time: 12:30 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Class AbstractCreationalQuery.
+ */
+abstract class AbstractCreationalQuery extends AbstractBaseQuery
+{
+ /**
+ * @var array
+ */
+ protected $values = [];
+
+ /**
+ * @param string $table
+ * @param array $values
+ */
+ public function __construct($table = null, array $values = null)
+ {
+ if (isset($table)) {
+ $this->setTable($table);
+ }
+
+ if (!empty($values)) {
+ $this->setValues($values);
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function getValues()
+ {
+ return $this->values;
+ }
+
+ /**
+ * @param array $values
+ *
+ * @return $this
+ */
+ public function setValues(array $values)
+ {
+ $this->values = $values;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractSetQuery.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractSetQuery.php
new file mode 100644
index 0000000..bb4b18b
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/AbstractSetQuery.php
@@ -0,0 +1,80 @@
+
+ * Date: 12/24/14
+ * Time: 12:30 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\QueryPartInterface;
+
+/**
+ * Class AbstractSetQuery.
+ */
+abstract class AbstractSetQuery implements QueryInterface, QueryPartInterface
+{
+ /**
+ * @var array
+ */
+ protected $union = [];
+
+ /**
+ * @param Select $select
+ *
+ * @return $this
+ */
+ public function add(Select $select)
+ {
+ $this->union[] = $select;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getUnions()
+ {
+ return $this->union;
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Table
+ */
+ public function getTable()
+ {
+ throw new QueryException(
+ \sprintf('%s does not support tables', $this->partName())
+ );
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function getWhere()
+ {
+ throw new QueryException(
+ \sprintf('%s does not support WHERE.', $this->partName())
+ );
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function where()
+ {
+ throw new QueryException(
+ \sprintf('%s does not support the WHERE statement.', $this->partName())
+ );
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/ColumnQuery.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/ColumnQuery.php
new file mode 100644
index 0000000..8a1ff6d
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/ColumnQuery.php
@@ -0,0 +1,263 @@
+
+ * Date: 12/25/14
+ * Time: 12:12 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy;
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+
+/**
+ * Class ColumnQuery.
+ */
+class ColumnQuery
+{
+ /**
+ * @var array
+ */
+ protected $columns = [];
+
+ /**
+ * @var array
+ */
+ protected $columnSelects = [];
+
+ /**
+ * @var array
+ */
+ protected $columnValues = [];
+
+ /**
+ * @var array
+ */
+ protected $columnFuncs = [];
+
+ /**
+ * @var bool
+ */
+ protected $isCount = false;
+
+ /**
+ * @var Select
+ */
+ protected $select;
+
+ /**
+ * @var JoinQuery
+ */
+ protected $joinQuery;
+
+ /**
+ * @param Select $select
+ * @param JoinQuery $joinQuery
+ * @param array $columns
+ */
+ public function __construct(Select $select, JoinQuery $joinQuery, array $columns = null)
+ {
+ $this->select = $select;
+ $this->joinQuery = $joinQuery;
+
+ if (!isset($columns)) {
+ $columns = array(Column::ALL);
+ }
+
+ if (\count($columns)) {
+ $this->setColumns($columns);
+ }
+ }
+
+ /**
+ * @param $start
+ * @param int $count
+ *
+ * @return Select
+ */
+ public function limit($start, $count = 0)
+ {
+ return $this->select->limit($start, $count);
+ }
+
+ /**
+ * @param string $whereOperator
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function where($whereOperator = 'AND')
+ {
+ return $this->select->where($whereOperator);
+ }
+
+ /**
+ * @param string $column
+ * @param string $direction
+ * @param null $table
+ *
+ * @return Select
+ */
+ public function orderBy($column, $direction = OrderBy::ASC, $table = null)
+ {
+ return $this->select->orderBy($column, $direction, $table);
+ }
+
+ /**
+ * @param string[] $columns
+ *
+ * @return Select
+ */
+ public function groupBy(array $columns)
+ {
+ return $this->select->groupBy($columns);
+ }
+
+ /**
+ * Allows setting a Select query as a column value.
+ *
+ * @param array $column
+ *
+ * @return $this
+ */
+ public function setSelectAsColumn(array $column)
+ {
+ $this->columnSelects[] = $column;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumnSelects()
+ {
+ return $this->columnSelects;
+ }
+
+ /**
+ * Allows setting a value to the select statement.
+ *
+ * @param string $value
+ * @param string $alias
+ *
+ * @return $this
+ */
+ public function setValueAsColumn($value, $alias)
+ {
+ $this->columnValues[$alias] = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumnValues()
+ {
+ return $this->columnValues;
+ }
+
+ /**
+ * Allows calculation on columns using predefined SQL functions.
+ *
+ * @param string $funcName
+ * @param string[] $arguments
+ * @param string $alias
+ *
+ * @return $this
+ */
+ public function setFunctionAsColumn($funcName, array $arguments, $alias)
+ {
+ $this->columnFuncs[$alias] = ['func' => $funcName, 'args' => $arguments];
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumnFuncs()
+ {
+ return $this->columnFuncs;
+ }
+
+ /**
+ * @param string $columnName
+ * @param string $alias
+ *
+ * @return $this
+ */
+ public function count($columnName = '*', $alias = '')
+ {
+ $table = $this->select->getTable();
+
+ $count = 'COUNT(';
+ $count .= ($columnName !== '*') ? "$table.{$columnName}" : '*';
+ $count .= ')';
+
+ if (isset($alias) && \strlen($alias) > 0) {
+ $count .= ' AS "'.$alias.'"';
+ }
+
+ $this->columns = array($count);
+ $this->isCount = true;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isCount()
+ {
+ return $this->isCount;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllColumns()
+ {
+ $columns = $this->getColumns();
+
+ foreach ($this->joinQuery->getJoins() as $join) {
+ $joinCols = $join->getAllColumns();
+ $columns = \array_merge($columns, $joinCols);
+ }
+
+ return $columns;
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Column
+ *
+ * @throws QueryException
+ */
+ public function getColumns()
+ {
+ if (\is_null($this->select->getTable())) {
+ throw new QueryException('No table specified for the Select instance');
+ }
+
+ return SyntaxFactory::createColumns($this->columns, $this->select->getTable());
+ }
+
+ /**
+ * Sets the column names used to write the SELECT statement.
+ * If key is set, key is the column's alias. Value is always the column names.
+ *
+ * @param array $columns
+ *
+ * @return $this
+ */
+ public function setColumns(array $columns)
+ {
+ $this->columns = $columns;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/Delete.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/Delete.php
new file mode 100644
index 0000000..0609d73
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/Delete.php
@@ -0,0 +1,60 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Class Delete.
+ */
+class Delete extends AbstractBaseQuery
+{
+ /**
+ * @var int
+ */
+ protected $limitStart;
+
+ /**
+ * @param string $table
+ */
+ public function __construct($table = null)
+ {
+ if (isset($table)) {
+ $this->setTable($table);
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'DELETE';
+ }
+
+ /**
+ * @return int
+ */
+ public function getLimitStart()
+ {
+ return $this->limitStart;
+ }
+
+ /**
+ * @param int $start
+ *
+ * @return $this
+ */
+ public function limit($start)
+ {
+ $this->limitStart = $start;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/Insert.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/Insert.php
new file mode 100644
index 0000000..79503ff
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/Insert.php
@@ -0,0 +1,37 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+
+/**
+ * Class Insert.
+ */
+class Insert extends AbstractCreationalQuery
+{
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'INSERT';
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumns()
+ {
+ $columns = \array_keys($this->values);
+
+ return SyntaxFactory::createColumns($columns, $this->getTable());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/Intersect.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/Intersect.php
new file mode 100644
index 0000000..66b77bf
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/Intersect.php
@@ -0,0 +1,84 @@
+
+ * Date: 9/12/14
+ * Time: 7:11 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\QueryPartInterface;
+
+/**
+ * Class Intersect.
+ */
+class Intersect implements QueryInterface, QueryPartInterface
+{
+ const INTERSECT = 'INTERSECT';
+
+ /**
+ * @var array
+ */
+ protected $intersect = [];
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'INTERSECT';
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return $this
+ */
+ public function add(Select $select)
+ {
+ $this->intersect[] = $select;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getIntersects()
+ {
+ return $this->intersect;
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Table
+ */
+ public function getTable()
+ {
+ throw new QueryException('INTERSECT does not support tables');
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function getWhere()
+ {
+ throw new QueryException('INTERSECT does not support WHERE.');
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function where()
+ {
+ throw new QueryException('INTERSECT does not support the WHERE statement.');
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/JoinQuery.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/JoinQuery.php
new file mode 100644
index 0000000..8ddbbd2
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/JoinQuery.php
@@ -0,0 +1,308 @@
+
+ * Date: 12/25/14
+ * Time: 11:41 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Where;
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+
+/**
+ * Class JoinQuery.
+ */
+class JoinQuery
+{
+ const JOIN_LEFT = 'LEFT';
+ const JOIN_RIGHT = 'RIGHT';
+ const JOIN_INNER = 'INNER';
+ const JOIN_CROSS = 'CROSS';
+
+ /**
+ * @var Where
+ */
+ protected $joinCondition;
+
+ /**
+ * @var bool
+ */
+ protected $isJoin = false;
+
+ /**
+ * @var string
+ */
+ protected $joinType;
+
+ /**
+ * @var array
+ */
+ protected $joins = [];
+
+ /**
+ * @var Select
+ */
+ protected $select;
+
+ /**
+ * @param Select $select
+ */
+ public function __construct(Select $select)
+ {
+ $this->select = $select;
+ }
+
+ /**
+ * @param string $table
+ *
+ * @return $this
+ */
+ public function setTable($table)
+ {
+ $this->select->setTable($table);
+
+ return $this;
+ }
+
+ /**
+ * @param string $table
+ * @param mixed $selfColumn
+ * @param mixed $refColumn
+ * @param string[] $columns
+ *
+ * @return Select
+ */
+ public function leftJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->join($table, $selfColumn, $refColumn, $columns, self::JOIN_LEFT);
+ }
+
+ /**
+ * @param string $table
+ * @param mixed $selfColumn
+ * @param mixed $refColumn
+ * @param string[] $columns
+ * @param string $joinType
+ *
+ * @return Select
+ */
+ public function join(
+ $table,
+ $selfColumn = null,
+ $refColumn = null,
+ $columns = [],
+ $joinType = null
+ ) {
+ if (!isset($this->joins[$table])) {
+ $select = QueryFactory::createSelect($table);
+ $select->setColumns($columns);
+ $select->setJoinType($joinType);
+ $select->setParentQuery($this->select);
+ $this->addJoin($select, $selfColumn, $refColumn);
+ }
+
+ return $this->joins[$table];
+ }
+
+ /**
+ * @param Select $select
+ * @param mixed $selfColumn
+ * @param mixed $refColumn
+ *
+ * @return Select
+ */
+ public function addJoin(Select $select, $selfColumn, $refColumn)
+ {
+ $select->isJoin(true);
+ $table = $select->getTable()->getName();
+
+ if (!isset($this->joins[$table])) {
+ if (!$selfColumn instanceof Column) {
+ $newColumn = array($selfColumn);
+ $selfColumn = SyntaxFactory::createColumn(
+ $newColumn,
+ $this->select->getTable()
+ );
+ }
+
+ $select->joinCondition()->equals($refColumn, $selfColumn);
+ $this->joins[$table] = $select;
+ }
+
+ return $this->joins[$table];
+ }
+
+ /**
+ * Transforms Select in a joint.
+ *
+ * @param bool $isJoin
+ *
+ * @return $this
+ */
+ public function setJoin($isJoin = true)
+ {
+ $this->isJoin = $isJoin;
+
+ return $this;
+ }
+
+ /**
+ * @param string $table
+ * @param mixed $selfColumn
+ * @param mixed $refColumn
+ * @param string[] $columns
+ *
+ * @internal param null $selectClass
+ *
+ * @return Select
+ */
+ public function rightJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->join($table, $selfColumn, $refColumn, $columns, self::JOIN_RIGHT);
+ }
+
+ /**
+ * @param string $table
+ * @param mixed $selfColumn
+ * @param mixed $refColumn
+ * @param string[] $columns
+ *
+ * @return Select
+ */
+ public function crossJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->join($table, $selfColumn, $refColumn, $columns, self::JOIN_CROSS);
+ }
+
+ /**
+ * @param string $table
+ * @param mixed $selfColumn
+ * @param mixed $refColumn
+ * @param string[] $columns
+ *
+ * @return Select
+ */
+ public function innerJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->join($table, $selfColumn, $refColumn, $columns, self::JOIN_INNER);
+ }
+
+ /**
+ * Alias to joinCondition.
+ *
+ * @return Where
+ */
+ public function on()
+ {
+ return $this->joinCondition();
+ }
+
+ /**
+ * WHERE constrains used for the ON clause of a (LEFT/RIGHT/INNER/CROSS) JOIN.
+ *
+ * @return Where
+ */
+ public function joinCondition()
+ {
+ if (!isset($this->joinCondition)) {
+ $this->joinCondition = QueryFactory::createWhere($this->select);
+ }
+
+ return $this->joinCondition;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isJoinSelect()
+ {
+ return $this->isJoin;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isJoin()
+ {
+ return $this->isJoin;
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function getJoinCondition()
+ {
+ return $this->joinCondition;
+ }
+
+ /**
+ * @param \NilPortugues\Sql\QueryBuilder\Syntax\Where $joinCondition
+ *
+ * @return $this
+ */
+ public function setJoinCondition($joinCondition)
+ {
+ $this->joinCondition = $joinCondition;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getJoinType()
+ {
+ return $this->joinType;
+ }
+
+ /**
+ * @param string $joinType
+ *
+ * @return $this
+ */
+ public function setJoinType($joinType)
+ {
+ $this->joinType = $joinType;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getJoins()
+ {
+ return $this->joins;
+ }
+
+ /**
+ * @param array $joins
+ *
+ * @return $this
+ */
+ public function setJoins($joins)
+ {
+ $this->joins = $joins;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllJoins()
+ {
+ $joins = $this->joins;
+
+ foreach ($this->joins as $join) {
+ $joins = \array_merge($joins, $join->getAllJoins());
+ }
+
+ return $joins;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/Minus.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/Minus.php
new file mode 100644
index 0000000..a551e11
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/Minus.php
@@ -0,0 +1,95 @@
+
+ * Date: 9/12/14
+ * Time: 7:11 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\QueryPartInterface;
+
+/**
+ * Class Minus.
+ */
+class Minus implements QueryInterface, QueryPartInterface
+{
+ const MINUS = 'MINUS';
+
+ /**
+ * @var Select
+ */
+ protected $first;
+
+ /**
+ * @var Select
+ */
+ protected $second;
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'MINUS';
+ }
+
+ /***
+ * @param Select $first
+ * @param Select $second
+ */
+ public function __construct(Select $first, Select $second)
+ {
+ $this->first = $first;
+ $this->second = $second;
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\Select
+ */
+ public function getFirst()
+ {
+ return $this->first;
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Manipulation\Select
+ */
+ public function getSecond()
+ {
+ return $this->second;
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Table
+ */
+ public function getTable()
+ {
+ throw new QueryException('MINUS does not support tables');
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function getWhere()
+ {
+ throw new QueryException('MINUS does not support WHERE.');
+ }
+
+ /**
+ * @throws QueryException
+ *
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function where()
+ {
+ throw new QueryException('MINUS does not support the WHERE statement.');
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryException.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryException.php
new file mode 100644
index 0000000..657212a
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryException.php
@@ -0,0 +1,18 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Class QueryException.
+ */
+final class QueryException extends \Exception
+{
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryFactory.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryFactory.php
new file mode 100644
index 0000000..7f49856
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryFactory.php
@@ -0,0 +1,107 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Where;
+
+/**
+ * Class QueryFactory.
+ */
+final class QueryFactory
+{
+ /**
+ * @param string $table
+ * @param array $columns
+ *
+ * @return Select
+ */
+ public static function createSelect($table = null, array $columns = null)
+ {
+ return new Select($table, $columns);
+ }
+
+ /**
+ * @param string $table
+ * @param array $values
+ *
+ * @return Insert
+ */
+ public static function createInsert($table = null, array $values = null)
+ {
+ return new Insert($table, $values);
+ }
+
+ /**
+ * @param string $table
+ * @param array $values
+ *
+ * @return Update
+ */
+ public static function createUpdate($table = null, array $values = null)
+ {
+ return new Update($table, $values);
+ }
+
+ /**
+ * @param string $table
+ *
+ * @return Delete
+ */
+ public static function createDelete($table = null)
+ {
+ return new Delete($table);
+ }
+
+ /**
+ * @param QueryInterface $query
+ *
+ * @return Where
+ */
+ public static function createWhere(QueryInterface $query)
+ {
+ return new Where($query);
+ }
+
+ /**
+ * @return Intersect
+ */
+ public static function createIntersect()
+ {
+ return new Intersect();
+ }
+
+ /**
+ * @param Select $first
+ * @param Select $second
+ *
+ * @return Minus
+ */
+ public static function createMinus(Select $first, Select $second)
+ {
+ return new Minus($first, $second);
+ }
+
+ /**
+ * @return Union
+ */
+ public static function createUnion()
+ {
+ return new Union();
+ }
+
+ /**
+ * @return UnionAll
+ */
+ public static function createUnionAll()
+ {
+ return new UnionAll();
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryInterface.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryInterface.php
new file mode 100644
index 0000000..809d517
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/QueryInterface.php
@@ -0,0 +1,37 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Interface QueryInterface.
+ */
+interface QueryInterface
+{
+ /**
+ * @return string
+ */
+ public function partName();
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Table
+ */
+ public function getTable();
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function getWhere();
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Where
+ */
+ public function where();
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/Select.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/Select.php
new file mode 100644
index 0000000..1580df4
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/Select.php
@@ -0,0 +1,546 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\SyntaxFactory;
+use NilPortugues\Sql\QueryBuilder\Syntax\Table;
+use NilPortugues\Sql\QueryBuilder\Syntax\Where;
+use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy;
+
+/**
+ * Class Select.
+ */
+class Select extends AbstractBaseQuery
+{
+ /**
+ * @var Table
+ */
+ protected $table;
+
+ /**
+ * @var array
+ */
+ protected $groupBy = [];
+
+ /**
+ * @var string
+ */
+ protected $camelCaseTableName = '';
+
+ /**
+ * @var Where
+ */
+ protected $having;
+
+ /**
+ * @var string
+ */
+ protected $havingOperator = 'AND';
+
+ /**
+ * @var bool
+ */
+ protected $isDistinct = false;
+
+ /**
+ * @var Where
+ */
+ protected $where;
+
+ /**
+ * @var JoinQuery
+ */
+ protected $joinQuery;
+
+ /**
+ * @var ColumnQuery
+ */
+ protected $columnQuery;
+
+ /**
+ * @var ParentQuery
+ */
+ protected $parentQuery;
+
+ /**
+ * @param string $table
+ * @param array $columns
+ */
+ public function __construct($table = null, array $columns = null)
+ {
+ if (isset($table)) {
+ $this->setTable($table);
+ }
+
+ $this->joinQuery = new JoinQuery($this);
+ $this->columnQuery = new ColumnQuery($this, $this->joinQuery, $columns);
+ }
+
+ /**
+ * This __clone method will create an exact clone but without the object references due to the fact these
+ * are lost in the process of serialization and un-serialization.
+ *
+ * @return Select
+ */
+ public function __clone()
+ {
+ return \unserialize(\serialize($this));
+ }
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'SELECT';
+ }
+
+ /**
+ * @param string $table
+ * @param string $selfColumn
+ * @param string $refColumn
+ * @param string[] $columns
+ *
+ * @return Select
+ */
+ public function leftJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->joinQuery->leftJoin($table, $selfColumn, $refColumn, $columns);
+ }
+
+ /**
+ * @param string $table
+ * @param string $selfColumn
+ * @param string $refColumn
+ * @param string[] $columns
+ * @param string $joinType
+ *
+ * @return Select
+ */
+ public function join(
+ $table,
+ $selfColumn = null,
+ $refColumn = null,
+ $columns = [],
+ $joinType = null
+ ) {
+ return $this->joinQuery->join($table, $selfColumn, $refColumn, $columns, $joinType);
+ }
+
+ /**
+ * WHERE constrains used for the ON clause of a (LEFT/RIGHT/INNER/CROSS) JOIN.
+ *
+ * @return Where
+ */
+ public function joinCondition()
+ {
+ return $this->joinQuery->joinCondition();
+ }
+
+ /**
+ * @param Select $select
+ * @param string $selfColumn
+ * @param string $refColumn
+ *
+ * @return Select
+ */
+ public function addJoin(Select $select, $selfColumn, $refColumn)
+ {
+ return $this->joinQuery->addJoin($select, $selfColumn, $refColumn);
+ }
+
+ /**
+ * Transforms Select in a joint.
+ *
+ * @param bool $isJoin
+ *
+ * @return JoinQuery
+ */
+ public function isJoin($isJoin = true)
+ {
+ return $this->joinQuery->setJoin($isJoin);
+ }
+
+ /**
+ * @param string $table
+ * @param string $selfColumn
+ * @param string $refColumn
+ * @param string[] $columns
+ *
+ * @internal param null $selectClass
+ *
+ * @return Select
+ */
+ public function rightJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->joinQuery->rightJoin($table, $selfColumn, $refColumn, $columns);
+ }
+
+ /**
+ * @param string $table
+ * @param string $selfColumn
+ * @param string $refColumn
+ * @param string[] $columns
+ *
+ * @return Select
+ */
+ public function crossJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->joinQuery->crossJoin($table, $selfColumn, $refColumn, $columns);
+ }
+
+ /**
+ * @param string $table
+ * @param string $selfColumn
+ * @param string $refColumn
+ * @param string[] $columns
+ *
+ * @return Select
+ */
+ public function innerJoin($table, $selfColumn = null, $refColumn = null, $columns = [])
+ {
+ return $this->joinQuery->innerJoin($table, $selfColumn, $refColumn, $columns);
+ }
+
+ /**
+ * Alias to joinCondition.
+ *
+ * @return Where
+ */
+ public function on()
+ {
+ return $this->joinQuery->joinCondition();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isJoinSelect()
+ {
+ return $this->joinQuery->isJoin();
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllColumns()
+ {
+ return $this->columnQuery->getAllColumns();
+ }
+
+ /**
+ * @return \NilPortugues\Sql\QueryBuilder\Syntax\Column
+ *
+ * @throws QueryException
+ */
+ public function getColumns()
+ {
+ return $this->columnQuery->getColumns();
+ }
+
+ /**
+ * Sets the column names used to write the SELECT statement.
+ * If key is set, key is the column's alias. Value is always the column names.
+ *
+ * @param string[] $columns
+ *
+ * @return ColumnQuery
+ */
+ public function setColumns(array $columns)
+ {
+ return $this->columnQuery->setColumns($columns);
+ }
+
+ /**
+ * Allows setting a Select query as a column value.
+ *
+ * @param array $column
+ *
+ * @return ColumnQuery
+ */
+ public function setSelectAsColumn(array $column)
+ {
+ return $this->columnQuery->setSelectAsColumn($column);
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumnSelects()
+ {
+ return $this->columnQuery->getColumnSelects();
+ }
+
+ /**
+ * Allows setting a value to the select statement.
+ *
+ * @param string $value
+ * @param string $alias
+ *
+ * @return ColumnQuery
+ */
+ public function setValueAsColumn($value, $alias)
+ {
+ return $this->columnQuery->setValueAsColumn($value, $alias);
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumnValues()
+ {
+ return $this->columnQuery->getColumnValues();
+ }
+
+ /**
+ * Allows calculation on columns using predefined SQL functions.
+ *
+ * @param string $funcName
+ * @param string[] $arguments
+ * @param string $alias
+ *
+ * @return ColumnQuery
+ */
+ public function setFunctionAsColumn($funcName, array $arguments, $alias)
+ {
+ return $this->columnQuery->setFunctionAsColumn($funcName, $arguments, $alias);
+ }
+
+ /**
+ * @return array
+ */
+ public function getColumnFuncs()
+ {
+ return $this->columnQuery->getColumnFuncs();
+ }
+
+ /**
+ * Returns all the Where conditions to the BuilderInterface class in order to write the SQL WHERE statement.
+ *
+ * @return array
+ */
+ public function getAllWheres()
+ {
+ return $this->getAllOperation($this->where, 'getAllWheres');
+ }
+
+ /**
+ * @param null|Where $data
+ * @param string $operation
+ *
+ * @return array
+ */
+ protected function getAllOperation($data, $operation)
+ {
+ $collection = [];
+
+ if (!is_null($data)) {
+ $collection[] = $data;
+ }
+
+ foreach ($this->joinQuery->getJoins() as $join) {
+ $collection = \array_merge($collection, $join->$operation());
+ }
+
+ return $collection;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllHavings()
+ {
+ return $this->getAllOperation($this->having, 'getAllHavings');
+ }
+
+ /**
+ * @param string $columnName
+ * @param string $alias
+ *
+ * @return ColumnQuery
+ */
+ public function count($columnName = '*', $alias = '')
+ {
+ return $this->columnQuery->count($columnName, $alias);
+ }
+
+ /**
+ * @return bool
+ */
+ public function isCount()
+ {
+ return $this->columnQuery->isCount();
+ }
+
+ /**
+ * @param int $start
+ * @param $count
+ *
+ * @return $this
+ */
+ public function limit($start, $count = 0)
+ {
+ $this->limitStart = $start;
+ $this->limitCount = $count;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllJoins()
+ {
+ return $this->joinQuery->getAllJoins();
+ }
+
+ /**
+ * @return array
+ */
+ public function getGroupBy()
+ {
+ return SyntaxFactory::createColumns($this->groupBy, $this->getTable());
+ }
+
+ /**
+ * @param string[] $columns
+ *
+ * @return $this
+ */
+ public function groupBy(array $columns)
+ {
+ $this->groupBy = $columns;
+
+ return $this;
+ }
+
+ /**
+ * @return Where
+ */
+ public function getJoinCondition()
+ {
+ return $this->joinQuery->getJoinCondition();
+ }
+
+ /**
+ * @return string
+ */
+ public function getJoinType()
+ {
+ return $this->joinQuery->getJoinType();
+ }
+
+ /**
+ * @param string|null $joinType
+ *
+ * @return $this
+ */
+ public function setJoinType($joinType)
+ {
+ $this->joinQuery->setJoinType($joinType);
+
+ return $this;
+ }
+
+ /**
+ * @param $havingOperator
+ *
+ * @throws QueryException
+ *
+ * @return Where
+ */
+ public function having($havingOperator = 'AND')
+ {
+ if (!isset($this->having)) {
+ $this->having = QueryFactory::createWhere($this);
+ }
+
+ if (!in_array($havingOperator, array(Where::CONJUNCTION_AND, Where::CONJUNCTION_OR))) {
+ throw new QueryException(
+ "Invalid conjunction specified, must be one of AND or OR, but '".$havingOperator."' was found."
+ );
+ }
+
+ $this->havingOperator = $havingOperator;
+
+ return $this->having;
+ }
+
+ /**
+ * @return string
+ */
+ public function getHavingOperator()
+ {
+ return $this->havingOperator;
+ }
+
+ /**
+ * @return $this
+ */
+ public function distinct()
+ {
+ $this->isDistinct = true;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isDistinct()
+ {
+ return $this->isDistinct;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllOrderBy()
+ {
+ return $this->orderBy;
+ }
+
+ /**
+ * @return ParentQuery
+ */
+ public function getParentQuery()
+ {
+ return $this->parentQuery;
+ }
+
+ /**
+ * @param Select $parentQuery
+ *
+ * @return $this
+ */
+ public function setParentQuery(Select $parentQuery)
+ {
+ $this->parentQuery = $parentQuery;
+
+ return $this;
+ }
+
+ /**
+ * @param string $column
+ * @param string $direction
+ * @param null $table
+ *
+ * @return $this
+ */
+ public function orderBy($column, $direction = OrderBy::ASC, $table = null)
+ {
+ $current = parent::orderBy($column, $direction, $table);
+ if ($this->getParentQuery() != null) {
+ $this->getParentQuery()->orderBy($column, $direction, \is_null($table) ? $this->getTable() : $table);
+ }
+ return $current;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/Union.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/Union.php
new file mode 100644
index 0000000..1f9af8b
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/Union.php
@@ -0,0 +1,27 @@
+
+ * Date: 9/12/14
+ * Time: 7:11 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Class Union.
+ */
+class Union extends AbstractSetQuery
+{
+ const UNION = 'UNION';
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'UNION';
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/UnionAll.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/UnionAll.php
new file mode 100644
index 0000000..c5360b0
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/UnionAll.php
@@ -0,0 +1,27 @@
+
+ * Date: 9/12/14
+ * Time: 7:11 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Class UnionAll.
+ */
+class UnionAll extends AbstractSetQuery
+{
+ const UNION_ALL = 'UNION ALL';
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'UNION ALL';
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Manipulation/Update.php b/vendor/nilportugues/sql-query-builder/src/Manipulation/Update.php
new file mode 100644
index 0000000..9093669
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Manipulation/Update.php
@@ -0,0 +1,55 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Class Update.
+ */
+class Update extends AbstractCreationalQuery
+{
+ /**
+ * @var int
+ */
+ protected $limitStart;
+
+ /**
+ * @var array
+ */
+ protected $orderBy = [];
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'UPDATE';
+ }
+
+ /**
+ * @return int
+ */
+ public function getLimitStart()
+ {
+ return $this->limitStart;
+ }
+
+ /**
+ * @param int $start
+ *
+ * @return $this
+ */
+ public function limit($start)
+ {
+ $this->limitStart = $start;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Syntax/Column.php b/vendor/nilportugues/sql-query-builder/src/Syntax/Column.php
new file mode 100644
index 0000000..aa244f9
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Syntax/Column.php
@@ -0,0 +1,139 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryException;
+
+/**
+ * Class Column.
+ */
+class Column implements QueryPartInterface
+{
+ const ALL = '*';
+
+ /**
+ * @var Table
+ */
+ protected $table;
+
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $alias;
+
+ /**
+ * @param string $name
+ * @param string $table
+ * @param string $alias
+ */
+ public function __construct($name, $table, $alias = '')
+ {
+ $this->setName($name);
+ $this->setTable($table);
+ $this->setAlias($alias);
+ }
+
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'COLUMN';
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return $this
+ */
+ public function setName($name)
+ {
+ $this->name = (string) $name;
+
+ return $this;
+ }
+
+ /**
+ * @return Table
+ */
+ public function getTable()
+ {
+ return $this->table;
+ }
+
+ /**
+ * @param string $table
+ *
+ * @return $this
+ */
+ public function setTable($table)
+ {
+ $newTable = array($table);
+ $this->table = SyntaxFactory::createTable($newTable);
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAlias()
+ {
+ return $this->alias;
+ }
+
+ /**
+ * @param null|string $alias
+ *
+ * @return $this
+ *
+ * @throws QueryException
+ */
+ public function setAlias($alias)
+ {
+ if (0 == \strlen($alias)) {
+ $this->alias = null;
+
+ return $this;
+ }
+
+ if ($this->isAll()) {
+ throw new QueryException("Can't use alias because column name is ALL (*)");
+ }
+
+ $this->alias = (string) $alias;
+
+ return $this;
+ }
+
+ /**
+ * Check whether column name is '*' or not.
+ *
+ * @return bool
+ */
+ public function isAll()
+ {
+ return $this->getName() == self::ALL;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Syntax/OrderBy.php b/vendor/nilportugues/sql-query-builder/src/Syntax/OrderBy.php
new file mode 100644
index 0000000..35214b3
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Syntax/OrderBy.php
@@ -0,0 +1,92 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Syntax;
+
+/**
+ * Class OrderBy.
+ */
+class OrderBy
+{
+ const ASC = 'ASC';
+ const DESC = 'DESC';
+
+ /**
+ * @var Column
+ */
+ protected $column;
+
+ /**
+ * @var string
+ */
+ protected $direction;
+
+ /**
+ * @var bool
+ */
+ protected $useAlias;
+
+ /**
+ * @param Column $column
+ * @param string $direction
+ */
+ public function __construct(Column $column, $direction)
+ {
+ $this->setColumn($column);
+ $this->setDirection($direction);
+ }
+
+ /**
+ * @return Column
+ */
+ public function getColumn()
+ {
+ return $this->column;
+ }
+
+ /**
+ * @param Column $column
+ *
+ * @return $this
+ */
+ public function setColumn($column)
+ {
+ $this->column = $column;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDirection()
+ {
+ return $this->direction;
+ }
+
+ /**
+ * @param string $direction
+ *
+ * @throws \InvalidArgumentException
+ *
+ * @return $this
+ */
+ public function setDirection($direction)
+ {
+ if (!in_array($direction, array(self::ASC, self::DESC))) {
+ throw new \InvalidArgumentException(
+ "Specified direction '$direction' is not allowed. Only ASC or DESC are allowed."
+ );
+ }
+ $this->direction = $direction;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Syntax/QueryPartInterface.php b/vendor/nilportugues/sql-query-builder/src/Syntax/QueryPartInterface.php
new file mode 100644
index 0000000..2368225
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Syntax/QueryPartInterface.php
@@ -0,0 +1,22 @@
+
+ * Date: 6/8/14
+ * Time: 5:32 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Syntax;
+
+/**
+ * Interface QueryPartInterface.
+ */
+interface QueryPartInterface
+{
+ /**
+ * @return string
+ */
+ public function partName();
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Syntax/SyntaxFactory.php b/vendor/nilportugues/sql-query-builder/src/Syntax/SyntaxFactory.php
new file mode 100644
index 0000000..21032dc
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Syntax/SyntaxFactory.php
@@ -0,0 +1,93 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Syntax;
+
+/**
+ * Class SyntaxFactory.
+ */
+final class SyntaxFactory
+{
+ /**
+ * Creates a collection of Column objects.
+ *
+ * @param array $arguments
+ * @param Table|null $table
+ *
+ * @return array
+ */
+ public static function createColumns(array &$arguments, $table = null)
+ {
+ $createdColumns = [];
+
+ foreach ($arguments as $index => $column) {
+ if (!is_object($column)) {
+ $newColumn = array($column);
+ $column = self::createColumn($newColumn, $table);
+ if (!is_numeric($index)) {
+ $column->setAlias($index);
+ }
+
+ $createdColumns[] = $column;
+ } else if ($column instanceof Column) {
+ $createdColumns[] = $column;
+ }
+ }
+
+ return \array_filter($createdColumns);
+ }
+
+ /**
+ * Creates a Column object.
+ *
+ * @param array $argument
+ * @param null|Table $table
+ *
+ * @return Column
+ */
+ public static function createColumn(array &$argument, $table = null)
+ {
+ $columnName = \array_values($argument);
+ $columnName = $columnName[0];
+
+ $columnAlias = \array_keys($argument);
+ $columnAlias = $columnAlias[0];
+
+ if (\is_numeric($columnAlias) || \strpos($columnName, '*') !== false) {
+ $columnAlias = null;
+ }
+
+ return new Column($columnName, (string) $table, $columnAlias);
+ }
+
+ /**
+ * Creates a Table object.
+ *
+ * @param string[] $table
+ *
+ * @return Table
+ */
+ public static function createTable($table)
+ {
+ $tableName = $table;
+ if (\is_array($table)) {
+ $tableName = \current($table);
+ $tableAlias = \key($table);
+ }
+
+ $newTable = new Table($tableName);
+
+ if (isset($tableAlias) && !is_numeric($tableAlias)) {
+ $newTable->setAlias($tableAlias);
+ }
+
+ return $newTable;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Syntax/Table.php b/vendor/nilportugues/sql-query-builder/src/Syntax/Table.php
new file mode 100644
index 0000000..22c0a08
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Syntax/Table.php
@@ -0,0 +1,138 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Syntax;
+
+/**
+ * Class Table.
+ */
+class Table
+{
+ /**
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * @var string
+ */
+ protected $alias;
+
+ /**
+ * @var string
+ */
+ protected $schema;
+
+ /**
+ * @var bool
+ */
+ protected $view = false;
+
+ /**
+ * @param $name
+ * @param string $schema
+ */
+ public function __construct($name, $schema = null)
+ {
+ $this->name = $name;
+
+ if (!is_null($schema)) {
+ $this->schema = $schema;
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return (string) $this->name;
+ }
+
+ /**
+ * @param bool $view
+ *
+ * @return $this
+ */
+ public function setView($view)
+ {
+ $this->view = $view;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isView()
+ {
+ return $this->view;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAlias()
+ {
+ return $this->alias;
+ }
+
+ /**
+ * @return string
+ */
+ public function getCompleteName()
+ {
+ $alias = ($this->alias) ? " AS {$this->alias}" : '';
+ $schema = ($this->schema) ? "{$this->schema}." : '';
+
+ return $schema.$this->name.$alias;
+ }
+
+ /**
+ * @param string $alias
+ *
+ * @return $this
+ */
+ public function setAlias($alias)
+ {
+ $this->alias = $alias;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSchema()
+ {
+ return $this->schema;
+ }
+
+ /**
+ * @param string
+ * @param string $schema
+ *
+ * @return $this
+ */
+ public function setSchema($schema)
+ {
+ $this->schema = $schema;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/src/Syntax/Where.php b/vendor/nilportugues/sql-query-builder/src/Syntax/Where.php
new file mode 100644
index 0000000..94d6e4d
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/src/Syntax/Where.php
@@ -0,0 +1,646 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryBuilder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryException;
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryFactory;
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryInterface;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class Where.
+ */
+class Where
+{
+ const OPERATOR_GREATER_THAN_OR_EQUAL = '>=';
+ const OPERATOR_GREATER_THAN = '>';
+ const OPERATOR_LESS_THAN_OR_EQUAL = '<=';
+ const OPERATOR_LESS_THAN = '<';
+ const OPERATOR_LIKE = 'LIKE';
+ const OPERATOR_NOT_LIKE = 'NOT LIKE';
+ const OPERATOR_EQUAL = '=';
+ const OPERATOR_NOT_EQUAL = '<>';
+ const CONJUNCTION_AND = 'AND';
+ const CONJUNCTION_AND_NOT = 'AND NOT';
+ const CONJUNCTION_OR = 'OR';
+ const CONJUNCTION_OR_NOT = 'OR NOT';
+ const CONJUNCTION_EXISTS = 'EXISTS';
+ const CONJUNCTION_NOT_EXISTS = 'NOT EXISTS';
+
+ /**
+ * @var array
+ */
+ protected $comparisons = [];
+
+ /**
+ * @var array
+ */
+ protected $betweens = [];
+
+ /**
+ * @var array
+ */
+ protected $isNull = [];
+
+ /**
+ * @var array
+ */
+ protected $isNotNull = [];
+
+ /**
+ * @var array
+ */
+ protected $booleans = [];
+
+ /**
+ * @var array
+ */
+ protected $match = [];
+
+ /**
+ * @var array
+ */
+ protected $ins = [];
+
+ /**
+ * @var array
+ */
+ protected $notIns = [];
+
+ /**
+ * @var array
+ */
+ protected $subWheres = [];
+
+ /**
+ * @var string
+ */
+ protected $conjunction = self::CONJUNCTION_AND;
+
+ /**
+ * @var QueryInterface
+ */
+ protected $query;
+
+ /**
+ * @var Table
+ */
+ protected $table;
+
+ /**
+ * @var array
+ */
+ protected $exists = [];
+
+ /**
+ * @var array
+ */
+ protected $notExists = [];
+
+ /**
+ * @var array
+ */
+ protected $notBetweens = [];
+
+ /**
+ * @param QueryInterface $query
+ */
+ public function __construct(QueryInterface $query)
+ {
+ $this->query = $query;
+ }
+
+ /**
+ * Deep copy for nested references.
+ *
+ * @return mixed
+ */
+ public function __clone()
+ {
+ return \unserialize(\serialize($this));
+ }
+
+ /**
+ * @return bool
+ */
+ public function isEmpty()
+ {
+ $empty = \array_merge(
+ $this->comparisons,
+ $this->booleans,
+ $this->betweens,
+ $this->isNotNull,
+ $this->isNull,
+ $this->ins,
+ $this->notIns,
+ $this->subWheres,
+ $this->exists
+ );
+
+ return 0 == \count($empty);
+ }
+
+ /**
+ * @return string
+ */
+ public function getConjunction()
+ {
+ return $this->conjunction;
+ }
+
+ /**
+ * @param string $operator
+ *
+ * @return $this
+ *
+ * @throws QueryException
+ */
+ public function conjunction($operator)
+ {
+ if (false === \in_array(
+ $operator,
+ [self::CONJUNCTION_AND, self::CONJUNCTION_OR, self::CONJUNCTION_OR_NOT, self::CONJUNCTION_AND_NOT]
+ )
+ ) {
+ throw new QueryException(
+ "Invalid conjunction specified, must be one of AND or OR, but '".$operator."' was found."
+ );
+ }
+ $this->conjunction = $operator;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getSubWheres()
+ {
+ return $this->subWheres;
+ }
+
+ /**
+ * @param $operator
+ *
+ * @return Where
+ */
+ public function subWhere($operator = 'OR')
+ {
+ /** @var Where $filter */
+ $filter = QueryFactory::createWhere($this->query);
+ $filter->conjunction($operator);
+ $filter->setTable($this->getTable());
+
+ $this->subWheres[] = $filter;
+
+ return $filter;
+ }
+
+ /**
+ * @return Table
+ */
+ public function getTable()
+ {
+ return $this->query->getTable();
+ }
+
+ /**
+ * Used for subWhere query building.
+ *
+ * @param Table $table string
+ *
+ * @return $this
+ */
+ public function setTable($table)
+ {
+ $this->table = $table;
+
+ return $this;
+ }
+
+ /**
+ * equals alias.
+ *
+ * @param $column
+ * @param int $value
+ *
+ * @return static
+ */
+ public function eq($column, $value)
+ {
+ return $this->equals($column, $value);
+ }
+
+ /**
+ * @param $column
+ * @param $value
+ *
+ * @return static
+ */
+ public function equals($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_EQUAL);
+ }
+
+ /**
+ * @param $column
+ * @param $value
+ * @param string $operator
+ *
+ * @return $this
+ */
+ protected function compare($column, $value, $operator)
+ {
+ $column = $this->prepareColumn($column);
+
+ $this->comparisons[] = [
+ 'subject' => $column,
+ 'conjunction' => $operator,
+ 'target' => $value,
+ ];
+
+ return $this;
+ }
+
+ /**
+ * @param $column
+ *
+ * @return Column|Select
+ */
+ protected function prepareColumn($column)
+ {
+ //This condition handles the "Select as a a column" special case.
+ //or when compare column is customized.
+ if ($column instanceof Select || $column instanceof Column) {
+ return $column;
+ }
+
+ $newColumn = [$column];
+
+ return SyntaxFactory::createColumn($newColumn, $this->getTable());
+ }
+
+ /**
+ * @param string $column
+ * @param int $value
+ *
+ * @return static
+ */
+ public function notEquals($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_NOT_EQUAL);
+ }
+
+ /**
+ * @param string $column
+ * @param int $value
+ *
+ * @return static
+ */
+ public function greaterThan($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_GREATER_THAN);
+ }
+
+ /**
+ * @param string $column
+ * @param int $value
+ *
+ * @return static
+ */
+ public function greaterThanOrEqual($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_GREATER_THAN_OR_EQUAL);
+ }
+
+ /**
+ * @param string $column
+ * @param int $value
+ *
+ * @return static
+ */
+ public function lessThan($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_LESS_THAN);
+ }
+
+ /**
+ * @param string $column
+ * @param int $value
+ *
+ * @return static
+ */
+ public function lessThanOrEqual($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_LESS_THAN_OR_EQUAL);
+ }
+
+ /**
+ * @param string $column
+ * @param $value
+ *
+ * @return static
+ */
+ public function like($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_LIKE);
+ }
+
+ /**
+ * @param string $column
+ * @param int $value
+ *
+ * @return static
+ */
+ public function notLike($column, $value)
+ {
+ return $this->compare($column, $value, self::OPERATOR_NOT_LIKE);
+ }
+
+ /**
+ * @param string[] $columns
+ * @param mixed[] $values
+ *
+ * @return static
+ */
+ public function match(array $columns, array $values)
+ {
+ return $this->genericMatch($columns, $values, 'natural');
+ }
+
+ /**
+ * @param string[] $columns
+ * @param mixed[] $values
+ * @param string $mode
+ *
+ * @return $this
+ */
+ protected function genericMatch(array &$columns, array &$values, $mode)
+ {
+ $this->match[] = [
+ 'columns' => $columns,
+ 'values' => $values,
+ 'mode' => $mode,
+ ];
+
+ return $this;
+ }
+
+ /**
+ * @param string $literal
+ *
+ * @return $this
+ */
+ public function asLiteral($literal)
+ {
+ $this->comparisons[] = $literal;
+
+ return $this;
+ }
+
+ /**
+ * @param string[] $columns
+ * @param mixed[] $values
+ *
+ * @return $this
+ */
+ public function matchBoolean(array $columns, array $values)
+ {
+ return $this->genericMatch($columns, $values, 'boolean');
+ }
+
+ /**
+ * @param string[] $columns
+ * @param mixed[] $values
+ *
+ * @return $this
+ */
+ public function matchWithQueryExpansion(array $columns, array $values)
+ {
+ return $this->genericMatch($columns, $values, 'query_expansion');
+ }
+
+ /**
+ * @param string $column
+ * @param int[] $values
+ *
+ * @return $this
+ */
+ public function in($column, array $values)
+ {
+ $this->ins[$column] = $values;
+
+ return $this;
+ }
+
+ /**
+ * @param string $column
+ * @param int[] $values
+ *
+ * @return $this
+ */
+ public function notIn($column, array $values)
+ {
+ $this->notIns[$column] = $values;
+
+ return $this;
+ }
+
+ /**
+ * @param string $column
+ * @param int $a
+ * @param int $b
+ *
+ * @return $this
+ */
+ public function between($column, $a, $b)
+ {
+ $column = $this->prepareColumn($column);
+ $this->betweens[] = ['subject' => $column, 'a' => $a, 'b' => $b];
+
+ return $this;
+ }
+
+ /**
+ * @param string $column
+ * @param int $a
+ * @param int $b
+ *
+ * @return $this
+ */
+ public function notBetween($column, $a, $b)
+ {
+ $column = $this->prepareColumn($column);
+ $this->notBetweens[] = ['subject' => $column, 'a' => $a, 'b' => $b];
+
+ return $this;
+ }
+
+ /**
+ * @param string $column
+ *
+ * @return static
+ */
+ public function isNull($column)
+ {
+ $column = $this->prepareColumn($column);
+ $this->isNull[] = ['subject' => $column];
+
+ return $this;
+ }
+
+ /**
+ * @param string $column
+ *
+ * @return $this
+ */
+ public function isNotNull($column)
+ {
+ $column = $this->prepareColumn($column);
+ $this->isNotNull[] = ['subject' => $column];
+
+ return $this;
+ }
+
+ /**
+ * @param string $column
+ * @param int $value
+ *
+ * @return $this
+ */
+ public function addBitClause($column, $value)
+ {
+ $column = $this->prepareColumn($column);
+ $this->booleans[] = ['subject' => $column, 'value' => $value];
+
+ return $this;
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return $this
+ */
+ public function exists(Select $select)
+ {
+ $this->exists[] = $select;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getExists()
+ {
+ return $this->exists;
+ }
+
+ /**
+ * @param Select $select
+ *
+ * @return $this
+ */
+ public function notExists(Select $select)
+ {
+ $this->notExists[] = $select;
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNotExists()
+ {
+ return $this->notExists;
+ }
+
+ /**
+ * @return array
+ */
+ public function getMatches()
+ {
+ return $this->match;
+ }
+
+ /**
+ * @return array
+ */
+ public function getIns()
+ {
+ return $this->ins;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNotIns()
+ {
+ return $this->notIns;
+ }
+
+ /**
+ * @return array
+ */
+ public function getBetweens()
+ {
+ return $this->betweens;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNotBetweens()
+ {
+ return $this->notBetweens;
+ }
+
+ /**
+ * @return array
+ */
+ public function getBooleans()
+ {
+ return $this->booleans;
+ }
+
+ /**
+ * @return array
+ */
+ public function getComparisons()
+ {
+ return $this->comparisons;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNotNull()
+ {
+ return $this->isNotNull;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNull()
+ {
+ return $this->isNull;
+ }
+
+ /**
+ * @return QueryInterface
+ */
+ public function end()
+ {
+ return $this->query;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/GenericBuilderTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/GenericBuilderTest.php
new file mode 100644
index 0000000..86eafd2
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/GenericBuilderTest.php
@@ -0,0 +1,284 @@
+
+ * Date: 6/16/14
+ * Time: 8:56 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+class GenericBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ *
+ */
+ public function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateSelectObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Select';
+ $this->assertInstanceOf($className, $this->writer->select());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateInsertObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Insert';
+ $this->assertInstanceOf($className, $this->writer->insert());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUpdateObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Update';
+ $this->assertInstanceOf($className, $this->writer->update());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateDeleteObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Delete';
+ $this->assertInstanceOf($className, $this->writer->delete());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateIntersectObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Intersect';
+ $this->assertInstanceOf($className, $this->writer->intersect());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateMinusObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Minus';
+ $this->assertInstanceOf($className, $this->writer->minus(new Select('table1'), new Select('table2')));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUnionObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Union';
+ $this->assertInstanceOf($className, $this->writer->union());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUnionAllObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\UnionAll';
+ $this->assertInstanceOf($className, $this->writer->unionAll());
+ }
+
+ /**
+ * @test
+ */
+ public function itCanAcceptATableNameForSelectInsertUpdateDeleteQueries()
+ {
+ $table = 'user';
+ $queries = [
+ 'select' => $this->writer->select($table),
+ 'insert' => $this->writer->insert($table),
+ 'update' => $this->writer->update($table),
+ 'delete' => $this->writer->delete($table),
+ ];
+
+ foreach ($queries as $type => $query) {
+ $this->assertEquals($table, $query->getTable()->getName(), "Checking table in $type query");
+ }
+ }
+
+ /**
+ * @test
+ */
+ public function itCanAcceptATableAndColumnsForSelect()
+ {
+ $table = 'user';
+ $columns = ['id', 'role'];
+ $expected = <<writer->select($table, $columns);
+ $this->assertSame($expected, $this->writer->writeFormatted($select));
+ }
+
+ /**
+ * @test
+ */
+ public function itCanAcceptATableAndValuesForInsert()
+ {
+ $table = 'user';
+ $values = ['id' => 1, 'role' => 'admin'];
+ $expected = <<writer->insert($table, $values);
+ $this->assertSame($expected, $this->writer->writeFormatted($insert));
+ }
+
+ /**
+ * @test
+ */
+ public function itCanAcceptATableAndValuesForUpdate()
+ {
+ $table = 'user';
+ $values = ['id' => 1, 'role' => 'super-admin'];
+ $expected = <<writer->update($table, $values);
+ $this->assertSame($expected, $this->writer->writeFormatted($update));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldOutputHumanReadableQuery()
+ {
+ $selectRole = $this->writer->select();
+ $selectRole
+ ->setTable('role')
+ ->setColumns(array('role_name'))
+ ->limit(1)
+ ->where()
+ ->equals('role_id', 3);
+
+ $select = $this->writer->select();
+ $select->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setSelectAsColumn(array('user_role' => $selectRole))
+ ->setSelectAsColumn(array($selectRole))
+ ->where()
+ ->equals('user_id', 4);
+
+ $expected = <<assertSame($expected, $this->writer->writeFormatted($select));
+ }
+
+ /**
+ * @test
+ */
+ public function it_should_inject_the_builder()
+ {
+ $query = $this->writer->select();
+
+ $this->assertSame($this->writer, $query->getBuilder());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteWhenGettingSql()
+ {
+ $query = $this->writer->select()
+ ->setTable('user');
+
+ $expected = $this->writer->write($query);
+
+ $this->assertSame($expected, $query->getSql());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteFormattedWhenGettingFormattedSql()
+ {
+ $query = $this->writer->select()
+ ->setTable('user');
+
+ $formatted = true;
+ $expected = $this->writer->writeFormatted($query);
+
+ $this->assertSame($expected, $query->getSql($formatted));
+ }
+ /**
+ * @test
+ */
+ public function itShouldWriteSqlWhenCastToString()
+ {
+ $query = $this->writer->select()
+ ->setTable('user');
+
+ $expected = $this->writer->write($query);
+
+ $this->assertSame($expected, (string) $query);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/MySqlBuilderTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/MySqlBuilderTest.php
new file mode 100644
index 0000000..da9288f
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/MySqlBuilderTest.php
@@ -0,0 +1,74 @@
+
+ * Date: 6/4/14
+ * Time: 12:40 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder;
+
+use NilPortugues\Sql\QueryBuilder\Builder\MySqlBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class MySqlBuilderTest.
+ */
+class MySqlBuilderTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var MySqlBuilder
+ */
+ protected $writer;
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new MySqlBuilder();
+ }
+
+ /**
+ *
+ */
+ protected function tearDown()
+ {
+ $this->writer = null;
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWrapTableNames()
+ {
+ $query = new Select('user');
+
+ $expected = 'SELECT `user`.* FROM `user`';
+ $this->assertSame($expected, $this->writer->write($query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWrapColumnNames()
+ {
+ $query = new Select('user', array('user_id', 'name'));
+
+ $expected = 'SELECT `user`.`user_id`, `user`.`name` FROM `user`';
+ $this->assertSame($expected, $this->writer->write($query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWrapColumnAlias()
+ {
+ $query = new Select('user', array('userId' => 'user_id', 'name' => 'name'));
+
+ $expected = 'SELECT `user`.`user_id` AS `userId`, `user`.`name` AS `name` FROM `user`';
+ $this->assertSame($expected, $this->writer->write($query));
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/ColumnWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/ColumnWriterTest.php
new file mode 100644
index 0000000..a8eb8e9
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/ColumnWriterTest.php
@@ -0,0 +1,187 @@
+
+ * Date: 9/12/14
+ * Time: 10:45 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\ColumnWriter;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\PlaceholderWriter;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+
+/**
+ * Class ColumnWriterTest.
+ */
+class ColumnWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var ColumnWriter
+ */
+ private $columnWriter;
+
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var Select
+ */
+ private $query;
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ $this->query = new Select();
+ $this->columnWriter = new ColumnWriter(new GenericBuilder(), new PlaceholderWriter());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteColumn()
+ {
+ $column = new Column('user_id', 'user');
+
+ $result = $this->columnWriter->writeColumn($column);
+
+ $this->assertSame('user.user_id', $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteValueAsColumns()
+ {
+ $select = new Select('user');
+ $select->setValueAsColumn('1', 'user_id');
+
+ $result = $this->columnWriter->writeValueAsColumns($select);
+
+ $this->assertInstanceOf('NilPortugues\Sql\QueryBuilder\Syntax\Column', $result[0]);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteFuncAsColumns()
+ {
+ $select = new Select('user');
+ $select->setFunctionAsColumn('MAX', ['user_id'], 'max_value');
+
+ $result = $this->columnWriter->writeFuncAsColumns($select);
+
+ $this->assertInstanceOf('NilPortugues\Sql\QueryBuilder\Syntax\Column', $result[0]);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteColumnWithAlias()
+ {
+ $column = new Column('user_id', 'user', 'userId');
+
+ $result = $this->columnWriter->writeColumnWithAlias($column);
+
+ $this->assertSame('user.user_id AS "userId"', $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteColumnAsASelectStatement()
+ {
+ $selectRole = new Select();
+ $selectRole
+ ->setTable('role')
+ ->setColumns(array('role_name'))
+ ->limit(1)
+ ->where()
+ ->equals('role_id', 3);
+
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setSelectAsColumn(array('user_role' => $selectRole))
+ ->setSelectAsColumn(array($selectRole))
+ ->where()
+ ->equals('user_id', 4);
+
+ $expected = 'SELECT user.user_id, user.username, '.
+ '(SELECT role.role_name FROM role WHERE (role.role_id = :v1) LIMIT :v2, :v3) AS "user_role", '.
+ '(SELECT role.role_name FROM role WHERE (role.role_id = :v4) LIMIT :v5, :v6) AS "role" '.
+ 'FROM user WHERE (user.user_id = :v7)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 3, ':v2' => 1, ':v3' => 0, ':v4' => 3, ':v5' => 1, ':v6' => 0, ':v7' => 4);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteColumnAsAValueStatement()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setValueAsColumn('10', 'priority')
+ ->where()
+ ->equals('user_id', 1);
+
+ $expected = 'SELECT user.user_id, user.username, :v1 AS "priority" FROM user WHERE (user.user_id = :v2)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 10, ':v2' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteColumnAsAFuncWithBracketsStatement()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setFunctionAsColumn('MAX', array('user_id'), 'max_id')
+ ->where()
+ ->equals('user_id', 1);
+
+ $expected = 'SELECT user.user_id, user.username, MAX(user_id) AS "max_id" FROM user WHERE (user.user_id = :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteColumnAsAFuncWithoutBracketsStatement()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'username'))
+ ->setFunctionAsColumn('CURRENT_TIMESTAMP', array(), 'server_time')
+ ->where()
+ ->equals('user_id', 1);
+
+ $expected = 'SELECT user.user_id, user.username, CURRENT_TIMESTAMP AS "server_time" FROM user WHERE (user.user_id = :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/DeleteWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/DeleteWriterTest.php
new file mode 100644
index 0000000..3ecfec0
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/DeleteWriterTest.php
@@ -0,0 +1,106 @@
+
+ * Date: 9/12/14
+ * Time: 10:45 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Delete;
+
+/**
+ * Class DeleteWriterTest.
+ */
+class DeleteWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var Delete
+ */
+ private $query;
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ $this->query = new Delete();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteDeleteAllTableContentsQuery()
+ {
+ $this->query->setTable('user');
+
+ $expected = 'DELETE FROM user';
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteDeleteRowLimit1()
+ {
+ $this->query
+ ->setTable('user')
+ ->limit(1);
+
+ $expected = 'DELETE FROM user LIMIT :v1';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteCommentInQuery()
+ {
+ $this->query
+ ->setTable('user')
+ ->setComment('This is a comment');
+
+ $expected = <<assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteDeleteRowWithWhereConditionAndLimit1()
+ {
+ $this->query->setTable('user');
+
+ $conditions = $this->query->where();
+ $conditions
+ ->equals('user_id', 10)
+ ->equals('user_id', 20)
+ ->equals('user_id', 30);
+
+ $this->query->limit(1);
+
+ $expected = <<assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 10, ':v2' => 20, ':v3' => 30, ':v4' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/InsertWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/InsertWriterTest.php
new file mode 100644
index 0000000..ea41333
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/InsertWriterTest.php
@@ -0,0 +1,104 @@
+
+ * Date: 9/12/14
+ * Time: 10:45 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Insert;
+
+/**
+ * Class InsertWriterTest.
+ */
+class InsertWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var Insert
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $exceptionClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ $this->query = new Insert();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowQueryExceptionBecauseNoColumnsWereDefined()
+ {
+ $this->setExpectedException($this->exceptionClass, 'No columns were defined for the current schema.');
+
+ $this->query->setTable('user');
+ $this->writer->write($this->query);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteInsertQuery()
+ {
+ $valueArray = array(
+ 'user_id' => 1,
+ 'name' => 'Nil',
+ 'contact' => 'contact@nilportugues.com',
+ );
+
+ $this->query
+ ->setTable('user')
+ ->setValues($valueArray);
+
+ $expected = 'INSERT INTO user (user.user_id, user.name, user.contact) VALUES (:v1, :v2, :v3)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ $this->assertEquals(\array_values($valueArray), \array_values($this->query->getValues()));
+
+ $expected = array(':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteCommentInQuery()
+ {
+ $valueArray = array(
+ 'user_id' => 1,
+ 'name' => 'Nil',
+ 'contact' => 'contact@nilportugues.com',
+ );
+
+ $this->query
+ ->setTable('user')
+ ->setComment('This is a comment')
+ ->setValues($valueArray);
+
+ $expected = "-- This is a comment\n".'INSERT INTO user (user.user_id, user.name, user.contact) VALUES (:v1, :v2, :v3)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ $this->assertEquals(\array_values($valueArray), \array_values($this->query->getValues()));
+
+ $expected = array(':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/IntersectWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/IntersectWriterTest.php
new file mode 100644
index 0000000..cb1aef2
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/IntersectWriterTest.php
@@ -0,0 +1,118 @@
+
+ * Date: 9/12/14
+ * Time: 7:34 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\IntersectWriter;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Intersect;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class IntersectWriterTest.
+ */
+class IntersectWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var IntersectWriter
+ */
+ private $intersectWriter;
+
+ /**
+ *
+ */
+ public function setUp()
+ {
+ $this->intersectWriter = new IntersectWriter(new GenericBuilder());
+ $this->writer = new GenericBuilder();
+ }
+
+ public function tearDown()
+ {
+ $this->intersectWriter = null;
+ $this->writer = null;
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteIntersect()
+ {
+ $intersect = new Intersect();
+
+ $intersect->add(new Select('user'));
+ $intersect->add(new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->intersectWriter->write($intersect));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteIntersectFromGenericBuilder()
+ {
+ $intersect = $this->writer->intersect();
+
+ $intersect->add(new Select('user'));
+ $intersect->add(new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->writer->write($intersect));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldNotResetPlaceholders()
+ {
+ $select1 = (new Select('table1'))
+ ->where()
+ ->between('column', 1, 2)
+ ->end();
+
+ $select2 = (new Select('table2'))
+ ->where()
+ ->between('column', 3, 4)
+ ->end();
+
+ $union = (new Intersect())
+ ->add($select1)
+ ->add($select2);
+
+ $expectedSql = << 1,
+ ':v2' => 2,
+ ':v3' => 3,
+ ':v4' => 4,
+ ];
+
+ $this->assertEquals($expectedSql, $this->writer->write($union));
+ $this->assertEquals($expectedParams, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/MinusWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/MinusWriterTest.php
new file mode 100644
index 0000000..32bee93
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/MinusWriterTest.php
@@ -0,0 +1,77 @@
+
+ * Date: 9/12/14
+ * Time: 7:34 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\MinusWriter;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Minus;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class MinusWriterTest.
+ */
+class MinusWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var MinusWriter
+ */
+ private $minusWriter;
+
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ *
+ */
+ public function setUp()
+ {
+ $this->minusWriter = new MinusWriter(new GenericBuilder());
+ $this->writer = new GenericBuilder();
+ }
+
+ public function tearDown()
+ {
+ $this->minusWriter = null;
+ $this->writer = null;
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteMinus()
+ {
+ $minus = new Minus(new Select('user'), new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->minusWriter->write($minus));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUnionAllFromGenericBuilder()
+ {
+ $minus = $this->writer->minus(new Select('user'), new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->writer->write($minus));
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/PlaceholderWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/PlaceholderWriterTest.php
new file mode 100644
index 0000000..f9d6a6d
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/PlaceholderWriterTest.php
@@ -0,0 +1,72 @@
+
+ * Date: 9/12/14
+ * Time: 10:46 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\PlaceholderWriter;
+
+/**
+ * Class PlaceholderWriterTest.
+ */
+class PlaceholderWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var PlaceholderWriter
+ */
+ private $writer;
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new PlaceholderWriter();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddValueAndReturnPlaceholder()
+ {
+ $result = $this->writer->add(1);
+ $this->assertEquals(':v1', $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAddValueAndGetReturnsArrayHoldingPlaceholderData()
+ {
+ $this->writer->add(1);
+ $this->assertEquals(array(':v1' => 1), $this->writer->get());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTranslatePhpNullToSqlNullValue()
+ {
+ $this->writer->add('');
+ $this->writer->add(null);
+
+ $this->assertEquals(array(':v1' => 'NULL', ':v2' => 'NULL'), $this->writer->get());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTranslatePhpBoolToSqlBoolValue()
+ {
+ $this->writer->add(true);
+ $this->writer->add(false);
+
+ $this->assertEquals(array(':v1' => 1, ':v2' => 0), $this->writer->get());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/SelectWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/SelectWriterTest.php
new file mode 100644
index 0000000..834e065
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/SelectWriterTest.php
@@ -0,0 +1,625 @@
+
+ * Date: 9/12/14
+ * Time: 10:46 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+
+/**
+ * Class SelectWriterTest.
+ */
+class SelectWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var Select
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $exceptionClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ $this->query = new Select();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeCloneableWithoutKeepingReferences()
+ {
+ $query1 = new Select('user');
+ $query2 = clone $query1;
+ $query2->setTable('users');
+
+ $this->assertFalse($query1->getTable() == $query2->getTable());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeConstructedWithConstructor()
+ {
+ $this->query = new Select('user');
+
+ $expected = 'SELECT user.* FROM user';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteCommentInQuery()
+ {
+ $this->query = new Select('user');
+ $this->query->setComment('This is a comment');
+
+ $expected = <<assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionWhenGettingColumnsButNoTableIsSet()
+ {
+ $this->setExpectedException($this->exceptionClass);
+
+ $this->query = new Select();
+ $this->query->getColumns();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeConstructedWithConstructorWithColumns()
+ {
+ $this->query = new Select('user', array('user_id', 'name'));
+
+ $expected = 'SELECT user.user_id, user.name FROM user';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSelectAll()
+ {
+ $this->query->setTable('user');
+
+ $expected = 'SELECT user.* FROM user';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSelectAllDistinct()
+ {
+ $this->query->setTable('user')->distinct();
+
+ $expected = 'SELECT DISTINCT user.* FROM user';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSelectAllWithLimit1()
+ {
+ $this->query->setTable('user')->limit(1);
+
+ $expected = 'SELECT user.* FROM user LIMIT :v1, :v2';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 0);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSelectAllWithLimit1Offset2()
+ {
+ $this->query->setTable('user')->limit(1, 2);
+
+ $expected = 'SELECT user.* FROM user LIMIT :v1, :v2';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSelectAllGetFirst20()
+ {
+ $this->query->setTable('user')->limit(0, 20);
+
+ $expected = 'SELECT user.* FROM user LIMIT :v1, :v2';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 0, ':v2' => 20);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowColumnAlias()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id', // Alias -> column name
+ 'username' => 'name',
+ 'email' => 'email',
+ )
+ );
+
+ $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email" FROM user';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowColumnOrder()
+ {
+ $this->query
+ ->setTable('user')
+ ->orderBy('user_id', OrderBy::ASC);
+
+ $expected = 'SELECT user.* FROM user ORDER BY user.user_id ASC';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowColumnOrderUsingColumnAlias()
+ {
+ $tableName = 'user';
+ $this->query
+ ->setTable($tableName)
+ ->setColumns(
+ array(
+ 'userId' => 'user_id', // Alias -> column name
+ 'username' => 'name',
+ 'email' => 'email',
+ )
+ )
+ ->orderBy('user_id', OrderBy::ASC)
+ ->orderBy('email', OrderBy::DESC);
+
+ $expected =
+ 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email" FROM '.
+ 'user ORDER BY user.user_id ASC, user.email DESC';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoALeftJoin()
+ {
+ $this->query
+ ->setTable('user')
+ ->leftJoin('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'));
+
+ $expected = 'SELECT user.*, news.title, news.body, news.created_at, news.updated_at FROM user LEFT JOIN '.
+ 'news ON (news.author_id = user.user_id)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoARightJoin()
+ {
+ $this->query
+ ->setTable('user')
+ ->rightJoin('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'));
+
+ $expected = 'SELECT user.*, news.title, news.body, news.created_at, news.updated_at FROM user RIGHT JOIN '.
+ 'news ON (news.author_id = user.user_id)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoAInnerJoin()
+ {
+ $this->query
+ ->setTable('user')
+ ->innerJoin('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'));
+
+ $expected = 'SELECT user.*, news.title, news.body, news.created_at, news.updated_at FROM user INNER JOIN '.
+ 'news ON (news.author_id = user.user_id)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoACrossJoin()
+ {
+ $this->query
+ ->setTable('user')
+ ->crossJoin('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'));
+
+ $expected = 'SELECT user.*, news.title, news.body, news.created_at, news.updated_at FROM user CROSS JOIN '.
+ 'news ON (news.author_id = user.user_id)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoALeftJoinWithOrderByOnJoinedTable()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at',
+ )
+ )
+ ->orderBy('user_id', OrderBy::DESC)
+ ->leftJoin('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'))
+ ->orderBy('created_at', OrderBy::DESC);
+
+ $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email", user.created_at,'.
+ ' news.title, news.body, news.created_at, news.updated_at FROM user LEFT JOIN news ON (news.author_id '.
+ '= user.user_id) ORDER BY user.user_id DESC, news.created_at DESC';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoAJoin()
+ {
+ $this->query
+ ->setTable('user')
+ ->join('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'));
+
+ $expected = 'SELECT user.*, news.title, news.body, news.created_at, news.updated_at FROM user JOIN '.
+ 'news ON (news.author_id = user.user_id)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoAJoinWithOrderByOnJoinedTable()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at',
+ )
+ )
+ ->orderBy('user_id', OrderBy::DESC)
+ ->join('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'))
+ ->orderBy('created_at', OrderBy::DESC);
+
+ $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email", user.created_at,'.
+ ' news.title, news.body, news.created_at, news.updated_at FROM user JOIN news ON (news.author_id ='.
+ ' user.user_id) ORDER BY user.user_id DESC, news.created_at DESC';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoAJoinWithCustomColumns()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at',
+ )
+ )
+ ->orderBy('user_id', OrderBy::DESC)
+ ->join('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'))
+ ->orderBy('created_at', OrderBy::DESC)
+ ->join('articles', new Column('news_id', 'article'), new Column('id', 'news'));
+
+ $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email", user.created_at,'.
+ ' news.title, news.body, news.created_at, news.updated_at FROM user JOIN news ON (news.author_id ='.
+ ' user.user_id) JOIN articles ON (news.id = article.news_id) ORDER BY user.user_id DESC, news.created_at DESC';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoAnAddWithMultipleJoins()
+ {
+ $this->query->setTable('user');
+
+ for ($i = 1; $i <= 5; ++$i) {
+ //Select QueryInterface for "news" table
+ $select = new Select();
+ $select
+ ->setTable('news'.$i)
+ ->setColumns(array('title'.$i));
+
+ //Select query for user table, being joined with "newsX" select.
+ $this->query->addJoin($select, 'user_id', 'author_id'.$i);
+ }
+
+ $expected = 'SELECT user.*, news1.title1, news2.title2, news3.title3, news4.title4, news5.title5 '.
+ 'FROM user JOIN news1 ON (news1.author_id1 = user.user_id) JOIN news2 ON (news2.author_id2 = user.user_id)'.
+ ' JOIN news3 ON (news3.author_id3 = user.user_id) JOIN news4 ON (news4.author_id4 = user.user_id) '.
+ 'JOIN news5 ON (news5.author_id5 = user.user_id)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToOn()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at',
+ )
+ )
+ ->orderBy('user_id', OrderBy::DESC)
+ ->join('news', 'user_id', 'author_id', array('title', 'body', 'created_at', 'updated_at'))
+ ->orderBy('created_at', OrderBy::DESC)
+ ->on()
+ ->eq('author_id', 1);
+
+ $this->query->limit(1, 10);
+
+ $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email", user.created_at,'.
+ ' news.title, news.body, news.created_at, news.updated_at FROM user JOIN news ON '.
+ '(news.author_id = user.user_id) AND (news.author_id = :v1) ORDER BY '.
+ 'user.user_id DESC, news.created_at DESC LIMIT :v2, :v3';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 1, ':v3' => 10);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToCountTotalRows()
+ {
+ $this->query
+ ->setTable('user')
+ ->count()
+ ->groupBy(array('user_id', 'name'))
+ ->having()
+ ->equals('user_id', 1)
+ ->equals('user_id', 2);
+
+ $expected = 'SELECT COUNT(*) FROM user GROUP BY user.user_id, user.name HAVING (user.user_id = :v1) AND (user.user_id = :v2)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToCountTotalRowsSettingDefaultColumn()
+ {
+ $this->query
+ ->setTable('user')
+ ->count('user_id')
+ ->groupBy(array('user_id', 'name'))
+ ->having()
+ ->equals('user_id', 1)
+ ->equals('user_id', 2);
+
+ $expected = 'SELECT COUNT(user.user_id) FROM user GROUP BY user.user_id, user.name HAVING (user.user_id = :v1) AND (user.user_id = :v2)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToCountTotalRowsSettingDefaultColumnWithAlias()
+ {
+ $this->query
+ ->setTable('user')
+ ->count('user_id', 'total_users')
+ ->groupBy(array('user_id', 'name'))
+ ->having()
+ ->equals('user_id', 1)
+ ->equals('user_id', 2);
+
+ $expected = 'SELECT COUNT(user.user_id) AS "total_users" FROM user GROUP BY user.user_id, user.name HAVING (user.user_id = :v1) AND (user.user_id = :v2)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToGroupByOperator()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at',
+ )
+ )
+ ->groupBy(array('user_id', 'name'))
+ ->having()
+ ->equals('user_id', 1)
+ ->equals('user_id', 2);
+
+ $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email", user.created_at'.
+ ' FROM user GROUP BY user.user_id, user.name HAVING (user.user_id = :v1) AND (user.user_id = :v2)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionInvalidHavingConjunction()
+ {
+ $this->setExpectedException($this->exceptionClass);
+
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at',
+ )
+ )
+ ->groupBy(array('user_id', 'name'))
+ ->having('AAAAAAAAAAAAAAAA');
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToSetHavingOperatorToOr()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(
+ array(
+ 'userId' => 'user_id',
+ 'username' => 'name',
+ 'email' => 'email',
+ 'created_at',
+ )
+ )
+ ->groupBy(array('user_id', 'name'))
+ ->having('OR')
+ ->equals('user_id', 1)
+ ->equals('user_id', 2);
+
+ $expected = 'SELECT user.user_id AS "userId", user.name AS "username", user.email AS "email", user.created_at'.
+ ' FROM user GROUP BY user.user_id, user.name HAVING (user.user_id = :v1) OR (user.user_id = :v2)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowSelectQueryToActAsAColumn()
+ {
+ $table1 = new Select('Table1');
+ $table1
+ ->where()
+ ->equals('table1_id', 1);
+
+ $table2 = new Select('Table2');
+ $table2
+ ->where()
+ ->eq($table1, 2);
+
+ $expected = 'SELECT Table2.* FROM Table2 WHERE ((SELECT Table1.* FROM Table1 '.
+ 'WHERE (Table1.table1_id = :v1)) = :v2)';
+
+ $this->assertSame($expected, $this->writer->write($table2));
+
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteJoin()
+ {
+ $this->query
+ ->isJoin(true)
+ ->setTable('user')
+ ->on()
+ ->equals('user_id', 1);
+
+ $expected = 'JOIN user ON (user.user_id = :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UnionAllWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UnionAllWriterTest.php
new file mode 100644
index 0000000..fbcd3ea
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UnionAllWriterTest.php
@@ -0,0 +1,118 @@
+
+ * Date: 9/12/14
+ * Time: 7:34 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\UnionAllWriter;
+use NilPortugues\Sql\QueryBuilder\Manipulation\UnionAll;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class UnionAllWriterTest.
+ */
+class UnionAllWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var UnionAllWriter
+ */
+ private $unionAllWriter;
+
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ *
+ */
+ public function setUp()
+ {
+ $this->unionAllWriter = new UnionAllWriter(new GenericBuilder());
+ $this->writer = new GenericBuilder();
+ }
+
+ public function tearDown()
+ {
+ $this->unionAllWriter = null;
+ $this->writer = null;
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUnionAll()
+ {
+ $union = new UnionAll();
+
+ $union->add(new Select('user'));
+ $union->add(new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->unionAllWriter->write($union));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUnionAllFromGenericBuilder()
+ {
+ $unionAll = $this->writer->unionAll();
+
+ $unionAll->add(new Select('user'));
+ $unionAll->add(new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->writer->write($unionAll));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldNotResetPlaceholders()
+ {
+ $select1 = (new Select('table1'))
+ ->where()
+ ->between('column', 1, 2)
+ ->end();
+
+ $select2 = (new Select('table2'))
+ ->where()
+ ->between('column', 3, 4)
+ ->end();
+
+ $union = (new UnionAll())
+ ->add($select1)
+ ->add($select2);
+
+ $expectedSql = << 1,
+ ':v2' => 2,
+ ':v3' => 3,
+ ':v4' => 4,
+ ];
+
+ $this->assertEquals($expectedSql, $this->writer->write($union));
+ $this->assertEquals($expectedParams, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UnionWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UnionWriterTest.php
new file mode 100644
index 0000000..6d6c2d3
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UnionWriterTest.php
@@ -0,0 +1,118 @@
+
+ * Date: 9/12/14
+ * Time: 7:34 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\UnionWriter;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Union;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class UnionWriterTest.
+ */
+class UnionWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var UnionWriter
+ */
+ private $unionWriter;
+
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ *
+ */
+ public function setUp()
+ {
+ $this->unionWriter = new UnionWriter(new GenericBuilder());
+ $this->writer = new GenericBuilder();
+ }
+
+ public function tearDown()
+ {
+ $this->unionWriter = null;
+ $this->writer = null;
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUnion()
+ {
+ $union = new Union();
+
+ $union->add(new Select('user'));
+ $union->add(new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->unionWriter->write($union));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUnionFromGenericBuilder()
+ {
+ $unionAll = $this->writer->union();
+
+ $unionAll->add(new Select('user'));
+ $unionAll->add(new Select('user_email'));
+
+ $expected = <<assertEquals($expected, $this->writer->write($unionAll));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldNotResetPlaceholders()
+ {
+ $select1 = (new Select('table1'))
+ ->where()
+ ->between('column', 1, 2)
+ ->end();
+
+ $select2 = (new Select('table2'))
+ ->where()
+ ->between('column', 3, 4)
+ ->end();
+
+ $union = (new Union())
+ ->add($select1)
+ ->add($select2);
+
+ $expectedSql = << 1,
+ ':v2' => 2,
+ ':v3' => 3,
+ ':v4' => 4,
+ ];
+
+ $this->assertEquals($expectedSql, $this->writer->write($union));
+ $this->assertEquals($expectedParams, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UpdateWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UpdateWriterTest.php
new file mode 100644
index 0000000..9001ec2
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/UpdateWriterTest.php
@@ -0,0 +1,140 @@
+
+ * Date: 9/12/14
+ * Time: 10:47 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Update;
+
+/**
+ * Class UpdateWriterTest.
+ */
+class UpdateWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var array
+ */
+ private $valueArray = array();
+
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var Update
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $exceptionClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ $this->query = new Update();
+
+ $this->valueArray = array(
+ 'user_id' => 1,
+ 'name' => 'Nil',
+ 'contact' => 'contact@nilportugues.com',
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowQueryException()
+ {
+ $this->setExpectedException($this->exceptionClass);
+
+ $this->query->setTable('user');
+ $this->writer->write($this->query);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUpdateQuery()
+ {
+ $this->query
+ ->setTable('user')
+ ->setValues($this->valueArray);
+
+ $expected = 'UPDATE user SET user.user_id = :v1, user.name = :v2, user.contact = :v3';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToWriteCommentInQuery()
+ {
+ $this->query
+ ->setTable('user')
+ ->setValues($this->valueArray)
+ ->setComment('This is a comment');
+
+ $expected = <<assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUpdateQueryWithWhereConstrain()
+ {
+ $this->query
+ ->setTable('user')
+ ->setValues($this->valueArray)
+ ->where()
+ ->equals('user_id', 1);
+
+ $expected = 'UPDATE user SET user.user_id = :v1, user.name = :v2, user.contact = :v3 WHERE (user.user_id = :v4)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com', ':v4' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteUpdateQueryWithWhereConstrainAndLimit1()
+ {
+ $this->query
+ ->setTable('user')
+ ->setValues($this->valueArray)
+ ->where()
+ ->equals('user_id', 1);
+
+ $this->query->limit(1);
+
+ $expected = 'UPDATE user SET user.user_id = :v1, user.name = :v2, user.contact = :v3 WHERE (user.user_id = :v4) LIMIT :v5';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 'Nil', ':v3' => 'contact@nilportugues.com', ':v4' => 1, ':v5' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/WhereWriterTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/WhereWriterTest.php
new file mode 100644
index 0000000..da4f70f
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/WhereWriterTest.php
@@ -0,0 +1,561 @@
+
+ * Date: 9/13/14
+ * Time: 12:46 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class WhereWriterTest.
+ */
+class WhereWriterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var Select
+ */
+ private $query;
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ $this->query = new Select();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowWhereConditions()
+ {
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->equals('user_id', 1)
+ ->like('name', '%N%');
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id = :v1) AND (user.name LIKE :v2)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => '%N%');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowWhereOrConditions()
+ {
+ $this->query
+ ->setTable('user')
+ ->where('OR')
+ ->equals('user_id', 1)
+ ->like('name', '%N%');
+
+ $this->assertSame('OR', $this->query->getWhereOperator());
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id = :v1) OR (user.name LIKE :v2)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => '%N%');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementNotBeEqualTo()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->notEquals($column, $value);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id <> :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementBeGreaterThan()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->greaterThan($column, $value);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id > :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementBeGreaterThanOrEqual()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->greaterThanOrEqual($column, $value);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id >= :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementBeLessThan()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->lessThan($column, $value);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id < :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementBeLessThanOrEqual()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->lessThanOrEqual($column, $value);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id <= :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementBeLike()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->like($column, $value);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id LIKE :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementBeNotLike()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->notLike($column, $value);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id NOT LIKE :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementAccumulateInConditions()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->in($column, array(1, 2, 3));
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id IN (:v1, :v2, :v3))';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 2, ':v3' => 3);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementAccumulateNotInConditions()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->notIn($column, array(1, 2, 3));
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id NOT IN (:v1, :v2, :v3))';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 2, ':v3' => 3);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementWriteBetweenConditions()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->between($column, 1, 2);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id BETWEEN :v1 AND :v2)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementWriteNotBetweenConditions()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->notBetween($column, 1, 2);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id NOT BETWEEN :v1 AND :v2)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 2);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementSetNullValueCondition()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->isNull($column);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id IS NULL)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array();
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementSetIsNotNullValueCondition()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->isNotNull($column);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id IS NOT NULL)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array();
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementSetBitClauseValueCondition()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->addBitClause($column, 1);
+
+ $expected = 'SELECT user.* FROM user WHERE (ISNULL(user.user_id, 0) = :v1)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToLetWhereStatementSubconditions()
+ {
+ $column = 'user_id';
+
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->equals($column, 1)
+ ->equals($column, 2)
+ ->subWhere('OR')
+ ->lessThan($column, 10)
+ ->greaterThan($column, 100);
+
+ $expected = 'SELECT user.* FROM user WHERE (user.user_id = :v1) AND (user.user_id = :v2) '.
+ 'AND ((user.user_id < :v3) OR (user.user_id > :v4))';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => 2, ':v3' => 10, ':v4' => 100);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowSelectWhereButNotWriteCondition()
+ {
+ $table1 = new Select('Table1');
+ $table1
+ ->where();
+
+ $expected = 'SELECT Table1.* FROM Table1';
+ $this->assertSame($expected, $this->writer->write($table1));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowHavingConditions()
+ {
+ $this->query
+ ->setTable('user')
+ ->having()
+ ->greaterThan('user_id', 1)
+ ->like('name', '%N%');
+
+ $expected = 'SELECT user.* FROM user HAVING (user.user_id > :v1) AND (user.name LIKE :v2)';
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 1, ':v2' => '%N%');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToUseSelectStatementsInWhere()
+ {
+ $selectRole = new Select();
+ $selectRole
+ ->setTable('role')
+ ->setColumns(array('role_name'))
+ ->limit(1)
+ ->where()
+ ->equals('role_id', 3);
+
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'role_id'))
+ ->where()
+ ->equals('role_id', $selectRole);
+
+ $expected = 'SELECT user.user_id, user.role_id FROM user WHERE '.
+ '(user.role_id = (SELECT role.role_name FROM role WHERE (role.role_id = :v1) LIMIT :v2, :v3))';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 3, ':v2' => 1, ':v3' => 0);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToSelectWithFullMatchSearchUsingMatchInNaturalMode()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'role_id'))
+ ->where()
+ ->match(array('username', 'email'), array('Nil'));
+
+ $expected = 'SELECT user.user_id, user.role_id FROM user '.
+ 'WHERE (MATCH(user.username, user.email) AGAINST(:v1))';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 'Nil');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToSelectWithFullMatchSearchUsingMatchInBooleanMode()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'role_id'))
+ ->where()
+ ->matchBoolean(array('username', 'email'), array('Nil'));
+
+ $expected = 'SELECT user.user_id, user.role_id FROM user '.
+ 'WHERE (MATCH(user.username, user.email) AGAINST(:v1 IN BOOLEAN MODE))';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 'Nil');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToSelectWithFullMatchSearchUsingMatchInQueryExpansionMode()
+ {
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'role_id'))
+ ->where()
+ ->matchWithQueryExpansion(array('username', 'email'), array('Nil'));
+
+ $expected = 'SELECT user.user_id, user.role_id FROM user '.
+ 'WHERE (MATCH(user.username, user.email) AGAINST(:v1 WITH QUERY EXPANSION))';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 'Nil');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoWhereExists()
+ {
+ $select = new Select('banned_user');
+ $select->where()->equals('user_id', 1);
+
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'role_id'))
+ ->where()
+ ->exists($select)
+ ->equals('user', 'Nil');
+
+ $expected = 'SELECT user.user_id, user.role_id FROM user WHERE (user.user = :v1) AND '.
+ 'EXISTS (SELECT banned_user.* FROM banned_user WHERE (banned_user.user_id = :v2))';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 'Nil', ':v2' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToDoWhereNotExists()
+ {
+ $select = new Select('banned_user');
+ $select->where()->equals('user_id', 1);
+
+ $this->query
+ ->setTable('user')
+ ->setColumns(array('user_id', 'role_id'))
+ ->where()
+ ->notExists($select)
+ ->equals('user', 'Nil');
+
+ $expected = 'SELECT user.user_id, user.role_id FROM user WHERE (user.user = :v1) AND '.
+ 'NOT EXISTS (SELECT banned_user.* FROM banned_user WHERE (banned_user.user_id = :v2))';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => 'Nil', ':v2' => 1);
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAllowWhereConditionAsLiteral()
+ {
+ $this->query
+ ->setTable('user')
+ ->where()
+ ->asLiteral('(username is not null and status=:status)')
+ ->notEquals('name', '%N%');
+
+ $expected = 'SELECT user.* FROM user WHERE (username is not null and status=:status) AND (user.name <> :v1)';
+
+ $this->assertSame($expected, $this->writer->write($this->query));
+
+ $expected = array(':v1' => '%N%');
+ $this->assertEquals($expected, $this->writer->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/WriterFactoryTest.php b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/WriterFactoryTest.php
new file mode 100644
index 0000000..11f88b3
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Builder/Syntax/WriterFactoryTest.php
@@ -0,0 +1,150 @@
+
+ * Date: 9/12/14
+ * Time: 10:47 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Builder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\PlaceholderWriter;
+use NilPortugues\Sql\QueryBuilder\Builder\Syntax\WriterFactory;
+
+/**
+ * Class WriterFactoryTest.
+ */
+class WriterFactoryTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var PlaceholderWriter
+ */
+ private $placeholder;
+
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ *
+ */
+ public function setUp()
+ {
+ $this->writer = new GenericBuilder();
+ $this->placeholder = new PlaceholderWriter();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateColumnWriter()
+ {
+ $writer = WriterFactory::createColumnWriter($this->writer, $this->placeholder);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\ColumnWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateWhereWriter()
+ {
+ $writer = WriterFactory::createWhereWriter($this->writer, $this->placeholder);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\WhereWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateSelectWriter()
+ {
+ $writer = WriterFactory::createSelectWriter($this->writer, $this->placeholder);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\SelectWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateInsertWriter()
+ {
+ $writer = WriterFactory::createInsertWriter($this->writer, $this->placeholder);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\InsertWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUpdateWriter()
+ {
+ $writer = WriterFactory::createUpdateWriter($this->writer, $this->placeholder);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\UpdateWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateDeleteWriter()
+ {
+ $writer = WriterFactory::createDeleteWriter($this->writer, $this->placeholder);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\DeleteWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreatePlaceholderWriter()
+ {
+ $writer = WriterFactory::createPlaceholderWriter();
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\PlaceholderWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateIntersectWriter()
+ {
+ $writer = WriterFactory::createIntersectWriter($this->writer);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\IntersectWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateMinusWriter()
+ {
+ $writer = WriterFactory::createMinusWriter($this->writer);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\MinusWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUnion()
+ {
+ $writer = WriterFactory::createUnionWriter($this->writer);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\UnionWriter', \get_class($writer));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUnionAll()
+ {
+ $writer = WriterFactory::createUnionAllWriter($this->writer);
+
+ $this->assertSame('NilPortugues\Sql\QueryBuilder\Builder\Syntax\UnionAllWriter', \get_class($writer));
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/BaseQueryTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/BaseQueryTest.php
new file mode 100644
index 0000000..e8f0518
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/BaseQueryTest.php
@@ -0,0 +1,74 @@
+
+ * Date: 6/7/14
+ * Time: 11:44 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+/**
+ * Class BaseQueryTest.
+ */
+class BaseQueryTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var \NilPortugues\Tests\Sql\QueryBuilder\Manipulation\Resources\DummyQuery
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $whereClass = '\NilPortugues\Sql\QueryBuilder\Syntax\Where';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Resources\DummyQuery();
+ $this->query->setTable('tablename');
+ }
+
+ /**
+ *
+ */
+ protected function tearDown()
+ {
+ $this->query = null;
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeAbleToSetTableName()
+ {
+ $this->assertSame('tablename', $this->query->getTable()->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetWhere()
+ {
+ $this->assertNull($this->query->getWhere());
+
+ $this->query->where();
+ $this->assertInstanceOf($this->whereClass, $this->query->getWhere());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetWhereOperator()
+ {
+ $this->assertSame('AND', $this->query->getWhereOperator());
+
+ $this->query->where('OR');
+ $this->assertSame('OR', $this->query->getWhereOperator());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/DeleteTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/DeleteTest.php
new file mode 100644
index 0000000..5673c10
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/DeleteTest.php
@@ -0,0 +1,56 @@
+
+ * Date: 6/3/14
+ * Time: 1:37 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Builder\GenericBuilder;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Delete;
+
+/**
+ * Class DeleteTest.
+ */
+class DeleteTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var GenericBuilder
+ */
+ private $writer;
+
+ /**
+ * @var Delete
+ */
+ private $query;
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Delete();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('DELETE', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnLimit1()
+ {
+ $this->query->limit(1);
+
+ $this->assertSame(1, $this->query->getLimitStart());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/InsertTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/InsertTest.php
new file mode 100644
index 0000000..f1c6eba
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/InsertTest.php
@@ -0,0 +1,77 @@
+
+ * Date: 6/3/14
+ * Time: 1:37 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Insert;
+
+/**
+ * Class InsertTest.
+ */
+class InsertTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Insert
+ */
+ private $query;
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Insert();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('INSERT', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetValues()
+ {
+ $values = ['user_id' => 1, 'username' => 'nilportugues'];
+
+ $this->query->setValues($values);
+
+ $this->assertSame($values, $this->query->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetColumns()
+ {
+ $values = ['user_id' => 1, 'username' => 'nilportugues'];
+
+ $this->query->setValues($values);
+
+ $columns = $this->query->getColumns();
+
+ $this->assertInstanceOf('NilPortugues\Sql\QueryBuilder\Syntax\Column', $columns[0]);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetNullableValues()
+ {
+ $values = ['user_id' => 1, 'description' => null, 'isVisible' => false];
+
+ $this->query->setValues($values);
+
+ $this->assertSame($values, $this->query->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/IntersectTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/IntersectTest.php
new file mode 100644
index 0000000..0b01f2e
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/IntersectTest.php
@@ -0,0 +1,89 @@
+
+ * Date: 9/12/14
+ * Time: 7:26 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Intersect;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class IntersectTest.
+ */
+class IntersectTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Intersect
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $exceptionClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Intersect();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('INTERSECT', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetTable()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getTable();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getWhere();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->where();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetIntersectSelects()
+ {
+ $this->assertEquals(array(), $this->query->getIntersects());
+
+ $select1 = new Select('user');
+ $select2 = new Select('user_email');
+
+ $this->query->add($select1);
+ $this->query->add($select2);
+
+ $this->assertEquals(array($select1, $select2), $this->query->getIntersects());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/MinusTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/MinusTest.php
new file mode 100644
index 0000000..0ebe1f9
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/MinusTest.php
@@ -0,0 +1,82 @@
+
+ * Date: 9/12/14
+ * Time: 7:26 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Minus;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class MinusTest.
+ */
+class MinusTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Minus
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $exceptionClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Minus(new Select('user'), new Select('user_email'));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('MINUS', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetTable()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getTable();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getWhere();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->where();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetMinusSelects()
+ {
+ $this->assertEquals(new Select('user'), $this->query->getFirst());
+ $this->assertEquals(new Select('user_email'), $this->query->getSecond());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/QueryFactoryTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/QueryFactoryTest.php
new file mode 100644
index 0000000..0bd6829
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/QueryFactoryTest.php
@@ -0,0 +1,98 @@
+
+ * Date: 6/16/14
+ * Time: 8:50 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\QueryFactory;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class QueryFactoryTest.
+ */
+class QueryFactoryTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @test
+ */
+ public function itShouldCreateSelectObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Select';
+ $this->assertInstanceOf($className, QueryFactory::createSelect());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateInsertObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Insert';
+ $this->assertInstanceOf($className, QueryFactory::createInsert());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUpdateObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Update';
+ $this->assertInstanceOf($className, QueryFactory::createUpdate());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateDeleteObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Delete';
+ $this->assertInstanceOf($className, QueryFactory::createDelete());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateMinusObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Minus';
+ $this->assertInstanceOf($className, QueryFactory::createMinus(new Select('table1'), new Select('table2')));
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUnionObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\Union';
+ $this->assertInstanceOf($className, QueryFactory::createUnion());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateUnionAllObject()
+ {
+ $className = '\NilPortugues\Sql\QueryBuilder\Manipulation\UnionAll';
+ $this->assertInstanceOf($className, QueryFactory::createUnionAll());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldCreateWhereObject()
+ {
+ $mockClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryInterface';
+
+ $query = $this->getMockBuilder($mockClass)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $className = '\NilPortugues\Sql\QueryBuilder\Syntax\Where';
+ $this->assertInstanceOf($className, QueryFactory::createWhere($query));
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/Resources/DummyQuery.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/Resources/DummyQuery.php
new file mode 100644
index 0000000..9b474be
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/Resources/DummyQuery.php
@@ -0,0 +1,27 @@
+
+ * Date: 6/3/14
+ * Time: 12:58 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation\Resources;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\AbstractBaseQuery;
+
+/**
+ * Class DummyQuery.
+ */
+class DummyQuery extends AbstractBaseQuery
+{
+ /**
+ * @return string
+ */
+ public function partName()
+ {
+ return 'DUMMY';
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/SelectTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/SelectTest.php
new file mode 100644
index 0000000..fe445b9
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/SelectTest.php
@@ -0,0 +1,101 @@
+
+ * Date: 6/3/14
+ * Time: 1:36 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy;
+
+/**
+ * Class SelectTest.
+ */
+class SelectTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Select
+ */
+ private $query;
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Select();
+ }
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('SELECT', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetParentOrderByAlso()
+ {
+ $columns = [
+ 'id',
+ 'phase_id',
+ 'league_id',
+ 'date',
+ ];
+ $parentTable = 'events';
+ $this->query->setTable($parentTable);
+ $this->query->setColumns($columns);
+
+ $sorts = [
+ [
+ 'field' => 'league_id',
+ 'direction' => 1,
+ ],
+ [
+ 'field' => 'start_date',
+ 'direction' => 0,
+ 'table' => 'phases',
+ 'joinBy' => 'phase_id',
+ 'joinWith' => 'id',
+ ],
+ [
+ 'field' => 'date',
+ 'direction' => 1,
+ ],
+ ];
+
+ if (is_array($sorts)) {
+ foreach ($sorts as $sort) {
+ $order = (int)$sort['direction'] > 0 ? OrderBy::ASC : OrderBy::DESC;
+ if (count($sort) == 5) {
+ $this->query->leftJoin(
+ $sort['table'],
+ $sort['joinBy'],
+ $sort['joinWith']
+ )->orderBy($sort['field'], $order);
+ } else {
+ $this->query->orderBy($sort['field'], $order);
+ }
+ }
+ }
+
+ $returnedOrders = $this->query->getAllOrderBy();
+ foreach ($returnedOrders as $id => $orderByObject) {
+ $column = $orderByObject->getColumn();
+ $table = $column->getTable();
+ $expectedColumn = $sorts[$id]['field'];
+ $expectedTable = array_key_exists('table', $sorts[$id]) ? $sorts[$id]['table'] : $parentTable;
+ $expectedDirection = (int)$sorts[$id]['direction'] > 0 ? OrderBy::ASC : OrderBy::DESC;
+ $this->assertSame($expectedColumn, $column->getName());
+ $this->assertSame($expectedTable, $table->getName());
+ $this->assertSame($expectedDirection, $orderByObject->getDirection());
+ }
+ $this->assertCount(count($sorts), $returnedOrders);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/UnionAllTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/UnionAllTest.php
new file mode 100644
index 0000000..869eef8
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/UnionAllTest.php
@@ -0,0 +1,89 @@
+
+ * Date: 9/12/14
+ * Time: 7:26 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\UnionAll;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class UnionAllTest.
+ */
+class UnionAllTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var UnionAll
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $exceptionClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new UnionAll();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('UNION ALL', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetTable()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getTable();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getWhere();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->where();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetIntersectSelects()
+ {
+ $this->assertEquals(array(), $this->query->getUnions());
+
+ $select1 = new Select('user');
+ $select2 = new Select('user_email');
+
+ $this->query->add($select1);
+ $this->query->add($select2);
+
+ $this->assertEquals(array($select1, $select2), $this->query->getUnions());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/UnionTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/UnionTest.php
new file mode 100644
index 0000000..f5c394e
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/UnionTest.php
@@ -0,0 +1,89 @@
+
+ * Date: 9/12/14
+ * Time: 7:26 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Union;
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+
+/**
+ * Class UnionTest.
+ */
+class UnionTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Union
+ */
+ private $query;
+
+ /**
+ * @var string
+ */
+ private $exceptionClass = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Union();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('UNION', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetTable()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getTable();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedGetWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->getWhere();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionForUnsupportedWhere()
+ {
+ $this->setExpectedException($this->exceptionClass);
+ $this->query->where();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetIntersectSelects()
+ {
+ $this->assertEquals(array(), $this->query->getUnions());
+
+ $select1 = new Select('user');
+ $select2 = new Select('user_email');
+
+ $this->query->add($select1);
+ $this->query->add($select2);
+
+ $this->assertEquals(array($select1, $select2), $this->query->getUnions());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Manipulation/UpdateTest.php b/vendor/nilportugues/sql-query-builder/tests/Manipulation/UpdateTest.php
new file mode 100644
index 0000000..e417c1c
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Manipulation/UpdateTest.php
@@ -0,0 +1,73 @@
+
+ * Date: 6/3/14
+ * Time: 1:37 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Manipulation;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Update;
+
+/**
+ * Class UpdateTest.
+ */
+class UpdateTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Update
+ */
+ private $query;
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->query = new Update();
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetPartName()
+ {
+ $this->assertSame('UPDATE', $this->query->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnLimit1()
+ {
+ $this->query->limit(1);
+
+ $this->assertSame(1, $this->query->getLimitStart());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnValues()
+ {
+ $values = ['user_id' => 1];
+
+ $this->query->setValues($values);
+
+ $this->assertSame($values, $this->query->getValues());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetNullableValues()
+ {
+ $values = ['user_id' => 1, 'description' => null, 'isVisible' => false];
+
+ $this->query->setValues($values);
+
+ $this->assertSame($values, $this->query->getValues());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Syntax/ColumnTest.php b/vendor/nilportugues/sql-query-builder/tests/Syntax/ColumnTest.php
new file mode 100644
index 0000000..3794ca2
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Syntax/ColumnTest.php
@@ -0,0 +1,96 @@
+
+ * Date: 6/2/14
+ * Time: 11:54 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\Table;
+
+/**
+ * Class ColumnTest.
+ */
+class ColumnTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var string
+ */
+ protected $tableClass = '\NilPortugues\Sql\QueryBuilder\Syntax\Table';
+
+ /**
+ * @var string
+ */
+ protected $queryException = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ * @test
+ */
+ public function itShouldReturnPartName()
+ {
+ $column = new Column('id', 'user');
+
+ $this->assertSame('COLUMN', $column->partName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldConstruct()
+ {
+ $column = new Column('id', 'user');
+
+ $this->assertEquals('id', $column->getName());
+ $this->assertInstanceOf($this->tableClass, $column->getTable());
+ $this->assertEquals('user', $column->getTable()->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetColumnName()
+ {
+ $column = new Column('id', 'user');
+
+ $column->setName('user_id');
+ $this->assertEquals('user_id', $column->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetTableName()
+ {
+ $tableName = 'user';
+
+ $column = new Column('id', $tableName);
+ $column->setTable(new Table($tableName));
+
+ $this->assertInstanceOf($this->tableClass, $column->getTable());
+ $this->assertEquals($tableName, $column->getTable()->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetAliasName()
+ {
+ $column = new Column('user_id', 'user', 'userId');
+ $this->assertEquals('userId', $column->getAlias());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionIfAliasOnAllSelection()
+ {
+ $this->setExpectedException($this->queryException);
+
+ new Column('*', 'user', 'userId');
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Syntax/OrderByTest.php b/vendor/nilportugues/sql-query-builder/tests/Syntax/OrderByTest.php
new file mode 100644
index 0000000..a529359
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Syntax/OrderByTest.php
@@ -0,0 +1,63 @@
+
+ * Date: 6/3/14
+ * Time: 12:07 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Column;
+use NilPortugues\Sql\QueryBuilder\Syntax\OrderBy;
+
+/**
+ * Class OrderByTest.
+ */
+class OrderByTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var string
+ */
+ protected $columnClass = '\NilPortugues\Sql\QueryBuilder\Syntax\Column';
+
+ /**
+ * @test
+ */
+ public function itShouldConstructOrderBy()
+ {
+ $column = new Column('registration_date', 'user');
+ $order = new OrderBy($column, OrderBy::ASC);
+
+ $this->assertInstanceOf($this->columnClass, $order->getColumn());
+ $this->assertEquals(OrderBy::ASC, $order->getDirection());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldGetOrderByDirection()
+ {
+ $column = new Column('registration_date', 'user');
+ $order = new OrderBy($column, OrderBy::ASC);
+
+ $this->assertEquals(OrderBy::ASC, $order->getDirection());
+
+ $order->setDirection(OrderBy::DESC);
+ $this->assertEquals(OrderBy::DESC, $order->getDirection());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionIfDirectionNotValid()
+ {
+ $column = new Column('registration_date', 'user');
+ $order = new OrderBy($column, OrderBy::ASC);
+
+ $this->setExpectedException('\InvalidArgumentException');
+ $order->setDirection('this is not a valid direction');
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Syntax/TableTest.php b/vendor/nilportugues/sql-query-builder/tests/Syntax/TableTest.php
new file mode 100644
index 0000000..6810e97
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Syntax/TableTest.php
@@ -0,0 +1,97 @@
+
+ * Date: 6/2/14
+ * Time: 11:34 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Syntax\Table;
+
+/**
+ * Class TableTest.
+ */
+class TableTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @test
+ */
+ public function testConstruct()
+ {
+ $table = new Table('user');
+ $this->assertEquals('user', $table->getName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnNullIfTableNameHasNoAlias()
+ {
+ $table = new Table('user');
+ $this->assertNull($table->getAlias());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnAliasIfTableNameAliasHasBeenSet()
+ {
+ $table = new Table('user');
+ $table->setAlias('u');
+ $this->assertEquals('u', $table->getAlias());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnNullIfSchemaNotSet()
+ {
+ $table = new Table('user');
+ $this->assertNull($table->getSchema());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnSchemaIfSchemaHasValue()
+ {
+ $table = new Table('user', 'website');
+ $this->assertEquals('website', $table->getSchema());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnTheCompleteName()
+ {
+ $table = new Table('user');
+
+ $table->setAlias('p');
+ $table->setSchema('website');
+
+ $this->assertEquals('website.user AS p', $table->getCompleteName());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnFalseOnIsView()
+ {
+ $table = new Table('user_status');
+ $this->assertFalse($table->isView());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnTrueOnIsView()
+ {
+ $table = new Table('user_status');
+ $table->setView(true);
+ $this->assertTrue($table->isView());
+ }
+}
diff --git a/vendor/nilportugues/sql-query-builder/tests/Syntax/WhereTest.php b/vendor/nilportugues/sql-query-builder/tests/Syntax/WhereTest.php
new file mode 100644
index 0000000..c045875
--- /dev/null
+++ b/vendor/nilportugues/sql-query-builder/tests/Syntax/WhereTest.php
@@ -0,0 +1,419 @@
+
+ * Date: 6/3/14
+ * Time: 12:31 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryBuilder\Syntax;
+
+use NilPortugues\Sql\QueryBuilder\Manipulation\Select;
+use NilPortugues\Sql\QueryBuilder\Syntax\Where;
+use NilPortugues\Tests\Sql\QueryBuilder\Manipulation\Resources\DummyQuery;
+
+/**
+ * Class WhereTest.
+ */
+class WhereTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Where
+ */
+ protected $where;
+
+ /**
+ * @var string
+ */
+ protected $whereClass = '\NilPortugues\Sql\QueryBuilder\Syntax\Where';
+
+ /**
+ * @var string
+ */
+ protected $columnClass = '\NilPortugues\Sql\QueryBuilder\Syntax\Column';
+
+ /**
+ * @var string
+ */
+ protected $queryException = '\NilPortugues\Sql\QueryBuilder\Manipulation\QueryException';
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $query = new DummyQuery();
+ $query->setTable('users');
+
+ $this->where = new Where($query);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeCloneable()
+ {
+ $this->assertEquals($this->where, clone $this->where);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeEmptyOnConstruct()
+ {
+ $this->assertTrue($this->where->isEmpty());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnDefaultConjuctionAnd()
+ {
+ $this->assertSame('AND', $this->where->getConjunction());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnDefaultSubWhere()
+ {
+ $this->assertSame(array(), $this->where->getSubWheres());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnSubFilter()
+ {
+ $filter = $this->where->subWhere();
+
+ $this->assertSame(array(), $filter->getSubWheres());
+ $this->assertInstanceOf($this->whereClass, $filter);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnTheSameEqAndEqual()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $this->assertSame(
+ $this->where->equals($column, $value),
+ $this->where->eq($column, $value)
+ );
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldNotBeEqualTo()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $result = $this->where->notEquals($column, $value)->getComparisons();
+
+ $this->assertSame('<>', $result[0]['conjunction']);
+ $this->assertSame($column, $result[0]['subject']->getName());
+ $this->assertSame($value, $result[0]['target']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeGreaterThan()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $result = $this->where->greaterThan($column, $value)->getComparisons();
+
+ $this->assertSame('>', $result[0]['conjunction']);
+ $this->assertSame($column, $result[0]['subject']->getName());
+ $this->assertSame($value, $result[0]['target']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeGreaterThanOrEqual()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $result = $this->where->greaterThanOrEqual($column, $value)->getComparisons();
+
+ $this->assertSame('>=', $result[0]['conjunction']);
+ $this->assertSame($column, $result[0]['subject']->getName());
+ $this->assertSame($value, $result[0]['target']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeLessThan()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $result = $this->where->lessThan($column, $value)->getComparisons();
+
+ $this->assertSame('<', $result[0]['conjunction']);
+ $this->assertSame($column, $result[0]['subject']->getName());
+ $this->assertSame($value, $result[0]['target']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeLessThanOrEqual()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $result = $this->where->lessThanOrEqual($column, $value)->getComparisons();
+
+ $this->assertSame('<=', $result[0]['conjunction']);
+ $this->assertSame($column, $result[0]['subject']->getName());
+ $this->assertSame($value, $result[0]['target']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeLike()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $result = $this->where->like($column, $value)->getComparisons();
+
+ $this->assertSame('LIKE', $result[0]['conjunction']);
+ $this->assertSame($column, $result[0]['subject']->getName());
+ $this->assertSame($value, $result[0]['target']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldBeNotLike()
+ {
+ $column = 'user_id';
+ $value = 1;
+
+ $result = $this->where->notLike($column, $value)->getComparisons();
+
+ $this->assertSame('NOT LIKE', $result[0]['conjunction']);
+ $this->assertSame($column, $result[0]['subject']->getName());
+ $this->assertSame($value, $result[0]['target']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAccumulateMatchConditions()
+ {
+ $column = array('user_id');
+
+ $result = $this->where
+ ->match($column, array(1, 2, 3))
+ ->getMatches();
+
+ $expected = array(
+ 0 => array(
+ 'columns' => array('user_id'),
+ 'values' => array(1, 2, 3),
+ 'mode' => 'natural',
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAccumulateMatchBooleanConditions()
+ {
+ $column = array('user_id');
+
+ $result = $this->where
+ ->matchBoolean($column, array(1, 2, 3))
+ ->getMatches();
+
+ $expected = array(
+ 0 => array(
+ 'columns' => array('user_id'),
+ 'values' => array(1, 2, 3),
+ 'mode' => 'boolean',
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAccumulateMatchQueryExpansionConditions()
+ {
+ $column = array('user_id');
+
+ $result = $this->where
+ ->matchWithQueryExpansion($column, array(1, 2, 3))
+ ->getMatches();
+
+ $expected = array(
+ 0 => array(
+ 'columns' => array('user_id'),
+ 'values' => array(1, 2, 3),
+ 'mode' => 'query_expansion',
+ ),
+ );
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAccumulateInConditions()
+ {
+ $column = 'user_id';
+
+ $result = $this->where
+ ->in($column, array(1, 2, 3))
+ ->getIns();
+
+ $expected = array($column => array(1, 2, 3));
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldAccumulateNotInConditions()
+ {
+ $column = 'user_id';
+
+ $result = $this->where
+ ->notIn($column, array(1, 2, 3))
+ ->getNotIns();
+
+ $expected = array($column => array(1, 2, 3));
+ $this->assertEquals($expected, $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldWriteBetweenConditions()
+ {
+ $column = 'user_id';
+
+ $result = $this->where
+ ->between($column, 1, 2)
+ ->getBetweens();
+
+ $this->assertInstanceOf($this->columnClass, $result[0]['subject']);
+ $this->assertEquals(1, $result[0]['a']);
+ $this->assertEquals(2, $result[0]['b']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetNullValueCondition()
+ {
+ $column = 'user_id';
+
+ $result = $this->where
+ ->isNull($column)
+ ->getNull();
+
+ $this->assertInstanceOf($this->columnClass, $result[0]['subject']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetIsNotNullValueCondition()
+ {
+ $column = 'user_id';
+
+ $result = $this->where
+ ->isNotNull($column)
+ ->getNotNull();
+
+ $this->assertInstanceOf($this->columnClass, $result[0]['subject']);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetBitClauseValueCondition()
+ {
+ $column = 'user_id';
+
+ $result = $this->where
+ ->addBitClause($column, 1)
+ ->getBooleans();
+
+ $this->assertEquals(1, $result[0]['value']);
+ $this->assertInstanceOf($this->columnClass, $result[0]['subject']);
+ }
+
+ /**
+ * @test
+ */
+ public function ItShouldChangeAndToOrOperator()
+ {
+ $result = $this->where->conjunction('OR');
+ $this->assertEquals('OR', $result->getConjunction());
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldThrowExceptionOnUnknownConjunction()
+ {
+ $this->setExpectedException($this->queryException);
+ $this->where->conjunction('NOT_VALID_CONJUNCTION');
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetExistsCondition()
+ {
+ $select1 = new Select('user');
+ $select1->where()->equals('user_id', 10);
+
+ $result = $this->where->exists($select1)->getExists();
+
+ $this->assertEquals(array($select1), $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldSetNotExistsCondition()
+ {
+ $select1 = new Select('user');
+ $select1->where()->equals('user_id', 10);
+
+ $result = $this->where->notExists($select1)->getNotExists();
+
+ $this->assertEquals(array($select1), $result);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldReturnLiterals()
+ {
+ $result = $this->where->asLiteral('(username is not null and status=:status)')->getComparisons();
+ $this->assertSame('(username is not null and status=:status)', $result[0]);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/.coveralls.yml b/vendor/nilportugues/sql-query-formatter/.coveralls.yml
new file mode 100644
index 0000000..0b342ec
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/.coveralls.yml
@@ -0,0 +1 @@
+repo_token: IBpLC0WCtjsqFy5M7PSyMvz2yMpd81xLD
diff --git a/vendor/nilportugues/sql-query-formatter/.gitignore b/vendor/nilportugues/sql-query-formatter/.gitignore
new file mode 100644
index 0000000..6ca78b2
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/.gitignore
@@ -0,0 +1,5 @@
+.idea/
+bin/
+build/
+vendor/
+composer.lock
diff --git a/vendor/nilportugues/sql-query-formatter/.travis.yml b/vendor/nilportugues/sql-query-formatter/.travis.yml
new file mode 100644
index 0000000..15bffce
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/.travis.yml
@@ -0,0 +1,16 @@
+language: php
+php:
+ - "5.5"
+ - "5.6"
+ - "7.0"
+ - "hhvm"
+
+before_script:
+ - composer install
+
+script:
+ - bin/phpunit --coverage-text
+
+matrix:
+ allow_failures:
+ - php: "hhvm"
\ No newline at end of file
diff --git a/vendor/nilportugues/sql-query-formatter/CONTRIBUTING.md b/vendor/nilportugues/sql-query-formatter/CONTRIBUTING.md
new file mode 100644
index 0000000..3677a2c
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/CONTRIBUTING.md
@@ -0,0 +1,33 @@
+Contributing
+============
+
+First of all, **thank you** for contributing, **you are awesome**!
+
+Here are a few rules to follow in order to ease code reviews, and discussions before
+maintainers accept and merge your work.
+
+You MUST follow the [PSR-1](http://www.php-fig.org/psr/1/) and
+[PSR-2](http://www.php-fig.org/psr/2/). If you don't know about any of them, you
+should really read the recommendations. Can't wait? Use the [PHP-CS-Fixer
+tool](http://cs.sensiolabs.org/).
+
+You MUST run the test suite.
+
+You MUST write (or update) unit tests.
+
+You SHOULD write documentation.
+
+Please, write [commit messages that make
+sense](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
+and [rebase your branch](http://git-scm.com/book/en/Git-Branching-Rebasing)
+before submitting your Pull Request.
+
+One may ask you to [squash your
+commits](http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html)
+too. This is used to "clean" your Pull Request before merging it (we don't want
+commits such as `fix tests`, `fix 2`, `fix 3`, etc.).
+
+Also, while creating your Pull Request on GitHub, you MUST write a description
+which gives the context and/or explains why you are creating it.
+
+Thank you!
diff --git a/vendor/nilportugues/sql-query-formatter/LICENSE.txt b/vendor/nilportugues/sql-query-formatter/LICENSE.txt
new file mode 100644
index 0000000..797681d
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/LICENSE.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Nil Portugués Calderó
+
+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.
diff --git a/vendor/nilportugues/sql-query-formatter/README.md b/vendor/nilportugues/sql-query-formatter/README.md
new file mode 100644
index 0000000..d3963ff
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/README.md
@@ -0,0 +1,143 @@
+SQL Query Formatter
+=================
+
+[](https://travis-ci.org/nilportugues/sql-query-formatter) [](https://coveralls.io/r/nilportugues/sql-query-formatter?branch=master) [](https://scrutinizer-ci.com/g/nilportugues/sql-query-formatter/?branch=master) [](https://insight.sensiolabs.com/projects/a57aa8f3-bbe1-43a5-941e-689d8435ab20) [](https://packagist.org/packages/nilportugues/sql-query-formatter) [](https://packagist.org/packages/nilportugues/sql-query-formatter) [](https://packagist.org/packages/nilportugues/sql-query-formatter)
+
+
+A very lightweight PHP class that re-formats unreadable or computer-generated SQL query statements to human-friendly readable text.
+
+* [1.Installation](#block1)
+* [2. Features](#block2)
+* [3. Usage](#block3)
+* [4. Code Quality](#block5)
+* [5. Author](#block6)
+* [6. Special Thanks](#block6)
+* [7. License](#block7)
+
+
+## 1.Installation
+The recommended way to install the SQL Query Formatter is through [Composer](http://getcomposer.org). Run the following command to install it:
+
+```sh
+php composer.phar require nilportugues/sql-query-formatter
+```
+
+
+## 2. Features
+
+**Human readable SQL formatting**
+
+- Human readable plain text. No colours, no highlighting. Plain text is good enough in most cases.
+
+**Data Binding Awareness**
+
+- SQL Query Formatter takes data binding seriously.
+- Placeholder syntax such as `:variable` or `?` is taken into account and is preserved when formatting.
+
+
+
+## 3. Usage
+
+Sample code:
+```php
+format($query);
+```
+
+Real output:
+```sql
+SELECT
+ user.user_id,
+ user.username,
+ (
+ SELECT
+ role.role_name
+ FROM
+ role
+ WHERE
+ (role.role_id = :v1)
+ LIMIT
+ :v2,
+ :v3
+ ) AS user_role,
+ (
+ SELECT
+ role.role_name
+ FROM
+ role
+ WHERE
+ (role.role_id = :v4)
+ LIMIT
+ :v5,
+ :v6
+ ) AS role
+FROM
+ user
+WHERE
+ (user.user_id = :v7)
+
+```
+
+
+## 4. Fully tested
+Testing has been done using PHPUnit and [Travis-CI](https://travis-ci.org). All code has been tested to be compatible from PHP 5.4 up to PHP 5.6 and [HHVM (nightly release)](http://hhvm.com/).
+
+To run the test suite, you need [Composer](http://getcomposer.org):
+
+```bash
+ php composer.phar install --dev
+ bin/phpunit
+```
+
+
+
+## 5. Author
+Nil Portugués Calderó
+
+ -
+ - [http://nilportugues.com](http://nilportugues.com)
+
+
+
+## 6. Special Thanks
+I would like to thank the following people:
+
+- [Jeremy Dorn](mailto:jeremy@jeremydorn.com) for his [sql-formatter](https://github.com/jdorn/sql-formatter) implementation I used as a basis for building this version.
+
+
+
+## 7. License
+SQL Query Formatter is licensed under the MIT license.
+
+```
+Copyright (c) 2015 Nil Portugués Calderó
+
+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.
+```
diff --git a/vendor/nilportugues/sql-query-formatter/composer.json b/vendor/nilportugues/sql-query-formatter/composer.json
new file mode 100644
index 0000000..ba921a4
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/composer.json
@@ -0,0 +1,42 @@
+{
+ "name":"nilportugues/sql-query-formatter",
+ "description":"A very lightweight PHP class that reformats unreadable and computer-generated SQL query statements to human-friendly, readable text.",
+ "keywords": [ "sql", "mysql", "query", "formatter", "format", "parser", "tokenizer", "reformat", "sql server" ],
+ "type":"library",
+ "license":"MIT",
+ "homepage":"http://nilportugues.com",
+ "authors":
+ [
+ {
+ "name":"Nil Portugués Calderó",
+ "email":"contact@nilportugues.com",
+ "homepage":"http://nilportugues.com",
+ "role":"Lead Developer"
+ }
+ ],
+ "autoload":{
+ "psr-4":{
+ "NilPortugues\\Sql\\QueryFormatter\\":"src/"
+ }
+ },
+ "autoload-dev":{
+ "psr-4":{
+ "NilPortugues\\Tests\\Sql\\QueryFormatter\\":"tests/"
+ }
+ },
+ "require":
+ {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*",
+ "fabpot/php-cs-fixer": "~1.9",
+ "nilportugues/php_backslasher": "~0.2"
+ },
+ "config":
+ {
+ "bin-dir": "bin"
+ },
+ "minimum-stability": "stable"
+}
+
diff --git a/vendor/nilportugues/sql-query-formatter/phpunit.xml.dist b/vendor/nilportugues/sql-query-formatter/phpunit.xml.dist
new file mode 100644
index 0000000..659e6c8
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/phpunit.xml.dist
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ./tests
+
+
+
+
+
+ ./
+
+ ./vendor/
+ ./tests/
+
+
+
+
+
+
+
+
+
+
diff --git a/vendor/nilportugues/sql-query-formatter/src/Formatter.php b/vendor/nilportugues/sql-query-formatter/src/Formatter.php
new file mode 100644
index 0000000..263fb0a
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Formatter.php
@@ -0,0 +1,350 @@
+
+ * Date: 6/26/14
+ * Time: 12:10 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter;
+
+use NilPortugues\Sql\QueryFormatter\Helper\Comment;
+use NilPortugues\Sql\QueryFormatter\Helper\Indent;
+use NilPortugues\Sql\QueryFormatter\Helper\NewLine;
+use NilPortugues\Sql\QueryFormatter\Helper\Parentheses;
+use NilPortugues\Sql\QueryFormatter\Helper\Token;
+use NilPortugues\Sql\QueryFormatter\Helper\WhiteSpace;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Lightweight Formatter heavily based on https://github.com/jdorn/sql-formatter.
+ *
+ * Class Formatter
+ */
+class Formatter
+{
+ /**
+ * @var Tokenizer
+ */
+ protected $tokenizer;
+
+ /**
+ * @var NewLine
+ */
+ protected $newLine;
+
+ /**
+ * @var Parentheses
+ */
+ protected $parentheses;
+
+ /**
+ * @var string
+ */
+ protected $tab = ' ';
+ /**
+ * @var int
+ */
+ protected $inlineCount = 0;
+
+ /**
+ * @var bool
+ */
+ protected $clauseLimit = false;
+ /**
+ * @var string
+ */
+ protected $formattedSql = '';
+ /**
+ * @var Indent
+ */
+ protected $indentation;
+
+ /**
+ * @var Comment
+ */
+ protected $comment;
+
+ /**
+ * Returns a SQL string in a readable human-friendly format.
+ *
+ * @param string $sql
+ *
+ * @return string
+ */
+ public function format($sql)
+ {
+ $this->reset();
+ $tab = "\t";
+
+ $originalTokens = $this->tokenizer->tokenize((string) $sql);
+ $tokens = WhiteSpace::removeTokenWhitespace($originalTokens);
+
+ foreach ($tokens as $i => $token) {
+ $queryValue = $token[Tokenizer::TOKEN_VALUE];
+ $this->indentation->increaseSpecialIndent()->increaseBlockIndent();
+ $addedNewline = $this->newLine->addNewLineBreak($tab);
+
+ if ($this->comment->stringHasCommentToken($token)) {
+ $this->formattedSql = $this->comment->writeCommentBlock($token, $tab, $queryValue);
+ continue;
+ }
+
+ if ($this->parentheses->getInlineParentheses()) {
+ if ($this->parentheses->stringIsClosingParentheses($token)) {
+ $this->parentheses->writeInlineParenthesesBlock($tab, $queryValue);
+ continue;
+ }
+ $this->newLine->writeNewLineForLongCommaInlineValues($token);
+ $this->inlineCount += \strlen($token[Tokenizer::TOKEN_VALUE]);
+ }
+
+ switch ($token) {
+ case $this->parentheses->stringIsOpeningParentheses($token):
+ $tokens = $this->formatOpeningParenthesis($token, $i, $tokens, $originalTokens);
+ break;
+
+ case $this->parentheses->stringIsClosingParentheses($token):
+ $this->indentation->decreaseIndentLevelUntilIndentTypeIsSpecial($this);
+ $this->newLine->addNewLineBeforeToken($addedNewline, $tab);
+ break;
+
+ case $this->stringIsEndOfLimitClause($token):
+ $this->clauseLimit = false;
+ break;
+
+ case $token[Tokenizer::TOKEN_VALUE] === ',' && false === $this->parentheses->getInlineParentheses():
+ $this->newLine->writeNewLineBecauseOfComma();
+ break;
+
+ case Token::isTokenTypeReservedTopLevel($token):
+ $queryValue = $this->formatTokenTypeReservedTopLevel($addedNewline, $tab, $token, $queryValue);
+ break;
+
+ case $this->newLine->isTokenTypeReservedNewLine($token):
+ $this->newLine->addNewLineBeforeToken($addedNewline, $tab);
+
+ if (WhiteSpace::tokenHasExtraWhiteSpaces($token)) {
+ $queryValue = \preg_replace('/\s+/', ' ', $queryValue);
+ }
+ break;
+ }
+
+ $this->formatBoundaryCharacterToken($token, $i, $tokens, $originalTokens);
+ $this->formatWhiteSpaceToken($token, $queryValue);
+ $this->formatDashToken($token, $i, $tokens);
+ }
+
+ return \trim(\str_replace(["\t", " \n"], [$this->tab, "\n"], $this->formattedSql))."\n";
+ }
+
+ /**
+ *
+ */
+ public function reset()
+ {
+ $this->tokenizer = new Tokenizer();
+ $this->indentation = new Indent();
+ $this->parentheses = new Parentheses($this, $this->indentation);
+ $this->newLine = new NewLine($this, $this->indentation, $this->parentheses);
+ $this->comment = new Comment($this, $this->indentation, $this->newLine);
+
+ $this->formattedSql = '';
+ }
+
+ /**
+ * @param $token
+ * @param $i
+ * @param array $tokens
+ * @param array $originalTokens
+ *
+ * @return array
+ */
+ protected function formatOpeningParenthesis($token, $i, array &$tokens, array &$originalTokens)
+ {
+ $length = 0;
+ for ($j = 1; $j <= 250; ++$j) {
+ if (isset($tokens[$i + $j])) {
+ $next = $tokens[$i + $j];
+ if ($this->parentheses->stringIsClosingParentheses($next)) {
+ $this->parentheses->writeNewInlineParentheses();
+ break;
+ }
+
+ if ($this->parentheses->invalidParenthesesTokenValue($next)
+ || $this->parentheses->invalidParenthesesTokenType($next)
+ ) {
+ break;
+ }
+
+ $length += \strlen($next[Tokenizer::TOKEN_VALUE]);
+ }
+ }
+ $this->newLine->writeNewLineForLongInlineValues($length);
+
+ if (WhiteSpace::isPrecedingCurrentTokenOfTokenTypeWhiteSpace($originalTokens, $token)) {
+ $this->formattedSql = \rtrim($this->formattedSql, ' ');
+ }
+
+ $this->newLine->addNewLineAfterOpeningParentheses();
+
+ return $tokens;
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ protected function stringIsEndOfLimitClause($token)
+ {
+ return $this->clauseLimit
+ && $token[Tokenizer::TOKEN_VALUE] !== ','
+ && $token[Tokenizer::TOKEN_TYPE] !== Tokenizer::TOKEN_TYPE_NUMBER
+ && $token[Tokenizer::TOKEN_TYPE] !== Tokenizer::TOKEN_TYPE_WHITESPACE;
+ }
+
+ /**
+ * @param bool $addedNewline
+ * @param string $tab
+ * @param $token
+ * @param $queryValue
+ *
+ * @return mixed
+ */
+ protected function formatTokenTypeReservedTopLevel($addedNewline, $tab, $token, $queryValue)
+ {
+ $this->indentation
+ ->setIncreaseSpecialIndent(true)
+ ->decreaseSpecialIndentIfCurrentIndentTypeIsSpecial();
+
+ $this->newLine->writeNewLineBecauseOfTopLevelReservedWord($addedNewline, $tab);
+
+ if (WhiteSpace::tokenHasExtraWhiteSpaces($token)) {
+ $queryValue = \preg_replace('/\s+/', ' ', $queryValue);
+ }
+ Token::tokenHasLimitClause($token, $this->parentheses, $this);
+
+ return $queryValue;
+ }
+
+ /**
+ * @param $token
+ * @param $i
+ * @param array $tokens
+ * @param array $originalTokens
+ */
+ protected function formatBoundaryCharacterToken($token, $i, array &$tokens, array &$originalTokens)
+ {
+ if (Token::tokenHasMultipleBoundaryCharactersTogether($token, $tokens, $i, $originalTokens)) {
+ $this->formattedSql = \rtrim($this->formattedSql, ' ');
+ }
+ }
+
+ /**
+ * @param $token
+ * @param $queryValue
+ */
+ protected function formatWhiteSpaceToken($token, $queryValue)
+ {
+ if (WhiteSpace::tokenHasExtraWhiteSpaceLeft($token)) {
+ $this->formattedSql = \rtrim($this->formattedSql, ' ');
+ }
+
+ $this->formattedSql .= $queryValue.' ';
+
+ if (WhiteSpace::tokenHasExtraWhiteSpaceRight($token)) {
+ $this->formattedSql = \rtrim($this->formattedSql, ' ');
+ }
+ }
+
+ /**
+ * @param $token
+ * @param $i
+ * @param array $tokens
+ */
+ protected function formatDashToken($token, $i, array &$tokens)
+ {
+ if (Token::tokenIsMinusSign($token, $tokens, $i)) {
+ $previousTokenType = $tokens[$i - 1][Tokenizer::TOKEN_TYPE];
+
+ if (WhiteSpace::tokenIsNumberAndHasExtraWhiteSpaceRight($previousTokenType)) {
+ $this->formattedSql = \rtrim($this->formattedSql, ' ');
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ public function getFormattedSql()
+ {
+ return $this->formattedSql;
+ }
+
+ /**
+ * @param string $formattedSql
+ *
+ * @return $this
+ */
+ public function setFormattedSql($formattedSql)
+ {
+ $this->formattedSql = $formattedSql;
+
+ return $this;
+ }
+
+ /**
+ * @param $string
+ *
+ * @return $this
+ */
+ public function appendToFormattedSql($string)
+ {
+ $this->formattedSql .= $string;
+
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getInlineCount()
+ {
+ return $this->inlineCount;
+ }
+
+ /**
+ * @param int $inlineCount
+ *
+ * @return $this
+ */
+ public function setInlineCount($inlineCount)
+ {
+ $this->inlineCount = $inlineCount;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getClauseLimit()
+ {
+ return $this->clauseLimit;
+ }
+
+ /**
+ * @param bool $clauseLimit
+ *
+ * @return $this
+ */
+ public function setClauseLimit($clauseLimit)
+ {
+ $this->clauseLimit = $clauseLimit;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Helper/Comment.php b/vendor/nilportugues/sql-query-formatter/src/Helper/Comment.php
new file mode 100644
index 0000000..3a109e1
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Helper/Comment.php
@@ -0,0 +1,80 @@
+
+ * Date: 12/22/14
+ * Time: 10:09 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Helper;
+
+use NilPortugues\Sql\QueryFormatter\Formatter;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Comment.
+ */
+class Comment
+{
+ /**
+ * @var \NilPortugues\Sql\QueryFormatter\Formatter
+ */
+ protected $formatter;
+
+ /**
+ * @var Indent
+ */
+ protected $indentation;
+
+ /**
+ * @var NewLine
+ */
+ protected $newLine;
+
+ /**
+ * @param Formatter $formatter
+ * @param Indent $indentation
+ * @param NewLine $newLine
+ */
+ public function __construct(Formatter $formatter, Indent $indentation, NewLine $newLine)
+ {
+ $this->formatter = $formatter;
+ $this->indentation = $indentation;
+ $this->newLine = $newLine;
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public function stringHasCommentToken($token)
+ {
+ return $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_COMMENT
+ || $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_BLOCK_COMMENT;
+ }
+
+ /**
+ * @param $token
+ * @param string $tab
+ * @param $queryValue
+ *
+ * @return string
+ */
+ public function writeCommentBlock($token, $tab, $queryValue)
+ {
+ if ($token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_BLOCK_COMMENT) {
+ $indent = \str_repeat($tab, $this->indentation->getIndentLvl());
+
+ $this->formatter->appendToFormattedSql("\n".$indent);
+ $queryValue = \str_replace("\n", "\n".$indent, $queryValue);
+ }
+
+ $this->formatter->appendToFormattedSql($queryValue);
+ $this->newLine->setNewline(true);
+
+ return $this->formatter->getFormattedSql();
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Helper/Indent.php b/vendor/nilportugues/sql-query-formatter/src/Helper/Indent.php
new file mode 100644
index 0000000..9ba4226
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Helper/Indent.php
@@ -0,0 +1,213 @@
+
+ * Date: 12/22/14
+ * Time: 11:37 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Helper;
+
+use NilPortugues\Sql\QueryFormatter\Formatter;
+
+/**
+ * Class Indent.
+ */
+class Indent
+{
+ /**
+ * @var bool
+ */
+ protected $inlineIndented = false;
+
+ /**
+ * @var bool
+ */
+ protected $increaseSpecialIndent = false;
+
+ /**
+ * @var int
+ */
+ protected $indentLvl = 0;
+
+ /**
+ * @var bool
+ */
+ protected $increaseBlockIndent = false;
+
+ /**
+ * @var array
+ */
+ protected $indentTypes = [];
+
+ /**
+ * Increase the Special Indent if increaseSpecialIndent is true after the current iteration.
+ *
+ * @return $this
+ */
+ public function increaseSpecialIndent()
+ {
+ if ($this->increaseSpecialIndent) {
+ ++$this->indentLvl;
+ $this->increaseSpecialIndent = false;
+ \array_unshift($this->indentTypes, 'special');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Increase the Block Indent if increaseBlockIndent is true after the current iteration.
+ *
+ * @return $this
+ */
+ public function increaseBlockIndent()
+ {
+ if ($this->increaseBlockIndent) {
+ ++$this->indentLvl;
+ $this->increaseBlockIndent = false;
+ \array_unshift($this->indentTypes, 'block');
+ }
+
+ return $this;
+ }
+
+ /**
+ * Closing parentheses decrease the block indent level.
+ *
+ * @param Formatter $formatter
+ *
+ * @return $this
+ */
+ public function decreaseIndentLevelUntilIndentTypeIsSpecial(Formatter $formatter)
+ {
+ $formatter->setFormattedSql(\rtrim($formatter->getFormattedSql(), ' '));
+ --$this->indentLvl;
+
+ while ($j = \array_shift($this->indentTypes)) {
+ if ('special' !== $j) {
+ break;
+ }
+ --$this->indentLvl;
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return $this
+ */
+ public function decreaseSpecialIndentIfCurrentIndentTypeIsSpecial()
+ {
+ \reset($this->indentTypes);
+
+ if (\current($this->indentTypes) === 'special') {
+ --$this->indentLvl;
+ \array_shift($this->indentTypes);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getIncreaseBlockIndent()
+ {
+ return $this->increaseBlockIndent;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getIncreaseSpecialIndent()
+ {
+ return $this->increaseSpecialIndent;
+ }
+
+ /**
+ * @return int
+ */
+ public function getIndentLvl()
+ {
+ return $this->indentLvl;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getIndentTypes()
+ {
+ return $this->indentTypes;
+ }
+
+ /**
+ * @param bool $increaseBlockIndent
+ *
+ * @return $this
+ */
+ public function setIncreaseBlockIndent($increaseBlockIndent)
+ {
+ $this->increaseBlockIndent = $increaseBlockIndent;
+
+ return $this;
+ }
+
+ /**
+ * @param bool $increaseSpecialIndent
+ *
+ * @return $this
+ */
+ public function setIncreaseSpecialIndent($increaseSpecialIndent)
+ {
+ $this->increaseSpecialIndent = $increaseSpecialIndent;
+
+ return $this;
+ }
+
+ /**
+ * @param int $indentLvl
+ *
+ * @return $this
+ */
+ public function setIndentLvl($indentLvl)
+ {
+ $this->indentLvl = $indentLvl;
+
+ return $this;
+ }
+
+ /**
+ * @param array $indentTypes
+ *
+ * @return $this
+ */
+ public function setIndentTypes($indentTypes)
+ {
+ $this->indentTypes = $indentTypes;
+
+ return $this;
+ }
+
+ /**
+ * @param bool $inlineIndented
+ *
+ * @return $this
+ */
+ public function setInlineIndented($inlineIndented)
+ {
+ $this->inlineIndented = $inlineIndented;
+
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getInlineIndented()
+ {
+ return $this->inlineIndented;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Helper/NewLine.php b/vendor/nilportugues/sql-query-formatter/src/Helper/NewLine.php
new file mode 100644
index 0000000..fd03ca9
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Helper/NewLine.php
@@ -0,0 +1,183 @@
+
+ * Date: 12/22/14
+ * Time: 11:37 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Helper;
+
+use NilPortugues\Sql\QueryFormatter\Formatter;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class NewLine.
+ */
+class NewLine
+{
+ /**
+ * @var bool
+ */
+ protected $newline = false;
+
+ /**
+ * @var \NilPortugues\Sql\QueryFormatter\Formatter
+ */
+ protected $formatter;
+
+ /**
+ * @var Indent
+ */
+ protected $indentation;
+
+ /**
+ * @var Parentheses
+ */
+ protected $parentheses;
+
+ /**
+ * @param Formatter $formatter
+ * @param Indent $indentation
+ * @param Parentheses $parentheses
+ */
+ public function __construct(Formatter $formatter, Indent $indentation, Parentheses $parentheses)
+ {
+ $this->formatter = $formatter;
+ $this->indentation = $indentation;
+ $this->parentheses = $parentheses;
+ }
+
+ /**
+ * Adds a new line break if needed.
+ *
+ * @param string $tab
+ *
+ * @return bool
+ */
+ public function addNewLineBreak($tab)
+ {
+ $addedNewline = false;
+
+ if (true === $this->newline) {
+ $this->formatter->appendToFormattedSql("\n".str_repeat($tab, $this->indentation->getIndentLvl()));
+ $this->newline = false;
+ $addedNewline = true;
+ }
+
+ return $addedNewline;
+ }
+
+ /**
+ * @param $token
+ */
+ public function writeNewLineForLongCommaInlineValues($token)
+ {
+ if (',' === $token[Tokenizer::TOKEN_VALUE]) {
+ if ($this->formatter->getInlineCount() >= 30) {
+ $this->formatter->setInlineCount(0);
+ $this->newline = true;
+ }
+ }
+ }
+
+ /**
+ * @param int $length
+ */
+ public function writeNewLineForLongInlineValues($length)
+ {
+ if ($this->parentheses->getInlineParentheses() && $length > 30) {
+ $this->indentation->setIncreaseBlockIndent(true);
+ $this->indentation->setInlineIndented(true);
+ $this->newline = true;
+ }
+ }
+
+ /**
+ * Adds a new line break for an opening parentheses for a non-inline expression.
+ */
+ public function addNewLineAfterOpeningParentheses()
+ {
+ if (false === $this->parentheses->getInlineParentheses()) {
+ $this->indentation->setIncreaseBlockIndent(true);
+ $this->newline = true;
+ }
+ }
+
+ /**
+ * @param bool $addedNewline
+ * @param string $tab
+ */
+ public function addNewLineBeforeToken($addedNewline, $tab)
+ {
+ if (false === $addedNewline) {
+ $this->formatter->appendToFormattedSql(
+ "\n".str_repeat($tab, $this->indentation->getIndentLvl())
+ );
+ }
+ }
+
+ /**
+ * Add a newline before the top level reserved word if necessary and indent.
+ *
+ * @param bool $addedNewline
+ * @param string $tab
+ */
+ public function writeNewLineBecauseOfTopLevelReservedWord($addedNewline, $tab)
+ {
+ if (false === $addedNewline) {
+ $this->formatter->appendToFormattedSql("\n");
+ } else {
+ $this->formatter->setFormattedSql(\rtrim($this->formatter->getFormattedSql(), $tab));
+ }
+ $this->formatter->appendToFormattedSql(\str_repeat($tab, $this->indentation->getIndentLvl()));
+
+ $this->newline = true;
+ }
+
+ /**
+ * Commas start a new line unless they are found within inline parentheses or SQL 'LIMIT' clause.
+ * If the previous TOKEN_VALUE is 'LIMIT', undo new line.
+ */
+ public function writeNewLineBecauseOfComma()
+ {
+ $this->newline = true;
+
+ if (true === $this->formatter->getClauseLimit()) {
+ $this->newline = false;
+ $this->formatter->setClauseLimit(false);
+ }
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public function isTokenTypeReservedNewLine($token)
+ {
+ return $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_RESERVED_NEWLINE;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getNewline()
+ {
+ return $this->newline;
+ }
+
+ /**
+ * @param bool $newline
+ *
+ * @return $this
+ */
+ public function setNewline($newline)
+ {
+ $this->newline = $newline;
+
+ return $this;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Helper/Parentheses.php b/vendor/nilportugues/sql-query-formatter/src/Helper/Parentheses.php
new file mode 100644
index 0000000..f9e903a
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Helper/Parentheses.php
@@ -0,0 +1,139 @@
+
+ * Date: 12/22/14
+ * Time: 11:37 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Helper;
+
+use NilPortugues\Sql\QueryFormatter\Formatter;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Parentheses.
+ */
+class Parentheses
+{
+ /**
+ * @var bool
+ */
+ protected $inlineParentheses = false;
+ /**
+ * @var \NilPortugues\Sql\QueryFormatter\Formatter
+ */
+ protected $formatter;
+
+ /**
+ * @var Indent
+ */
+ protected $indentation;
+
+ /**
+ * @param Formatter $formatter
+ * @param Indent $indentation
+ */
+ public function __construct(Formatter $formatter, Indent $indentation)
+ {
+ $this->formatter = $formatter;
+ $this->indentation = $indentation;
+ }
+
+ /**
+ * @return bool
+ */
+ public function getInlineParentheses()
+ {
+ return $this->inlineParentheses;
+ }
+
+ /**
+ * @param bool $inlineParentheses
+ *
+ * @return $this
+ */
+ public function setInlineParentheses($inlineParentheses)
+ {
+ $this->inlineParentheses = $inlineParentheses;
+
+ return $this;
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public function stringIsOpeningParentheses($token)
+ {
+ return $token[Tokenizer::TOKEN_VALUE] === '(';
+ }
+
+ /**
+ *
+ */
+ public function writeNewInlineParentheses()
+ {
+ $this->inlineParentheses = true;
+ $this->formatter->setInlineCount(0);
+ $this->indentation->setInlineIndented(false);
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public function invalidParenthesesTokenValue($token)
+ {
+ return $token[Tokenizer::TOKEN_VALUE] === ';'
+ || $token[Tokenizer::TOKEN_VALUE] === '(';
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public function invalidParenthesesTokenType($token)
+ {
+ return $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_RESERVED_TOP_LEVEL
+ || $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_RESERVED_NEWLINE
+ || $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_COMMENT
+ || $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_BLOCK_COMMENT;
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public function stringIsClosingParentheses($token)
+ {
+ return $token[Tokenizer::TOKEN_VALUE] === ')';
+ }
+
+ /**
+ * @param string $tab
+ * @param $queryValue
+ */
+ public function writeInlineParenthesesBlock($tab, $queryValue)
+ {
+ $this->formatter->setFormattedSql(\rtrim($this->formatter->getFormattedSql(), ' '));
+
+ if ($this->indentation->getInlineIndented()) {
+ $indentTypes = $this->indentation->getIndentTypes();
+ \array_shift($indentTypes);
+ $this->indentation->setIndentTypes($indentTypes);
+ $this->indentation->setIndentLvl($this->indentation->getIndentLvl() - 1);
+
+ $this->formatter->appendToFormattedSql("\n".str_repeat($tab, $this->indentation->getIndentLvl()));
+ }
+
+ $this->inlineParentheses = false;
+ $this->formatter->appendToFormattedSql($queryValue.' ');
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Helper/Token.php b/vendor/nilportugues/sql-query-formatter/src/Helper/Token.php
new file mode 100644
index 0000000..505cd53
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Helper/Token.php
@@ -0,0 +1,749 @@
+
+ * Date: 12/22/14
+ * Time: 11:38 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Helper;
+
+use NilPortugues\Sql\QueryFormatter\Formatter;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Token.
+ */
+final class Token
+{
+ /**
+ * @var array
+ */
+ public static $reserved = [
+ 'ACCESSIBLE',
+ 'ACTION',
+ 'AGAINST',
+ 'AGGREGATE',
+ 'ALGORITHM',
+ 'ALL',
+ 'ALTER',
+ 'ANALYSE',
+ 'ANALYZE',
+ 'AS',
+ 'ASC',
+ 'AUTOCOMMIT',
+ 'AUTO_INCREMENT',
+ 'BACKUP',
+ 'BEGIN',
+ 'BETWEEN',
+ 'BINLOG',
+ 'BOTH',
+ 'CASCADE',
+ 'CASE',
+ 'CHANGE',
+ 'CHANGED',
+ 'CHARACTER SET',
+ 'CHARSET',
+ 'CHECK',
+ 'CHECKSUM',
+ 'COLLATE',
+ 'COLLATION',
+ 'COLUMN',
+ 'COLUMNS',
+ 'COMMENT',
+ 'COMMIT',
+ 'COMMITTED',
+ 'COMPRESSED',
+ 'CONCURRENT',
+ 'CONSTRAINT',
+ 'CONTAINS',
+ 'CONVERT',
+ 'CREATE',
+ 'CROSS',
+ 'CURRENT_TIMESTAMP',
+ 'DATABASE',
+ 'DATABASES',
+ 'DAY',
+ 'DAY_HOUR',
+ 'DAY_MINUTE',
+ 'DAY_SECOND',
+ 'DEFAULT',
+ 'DEFINER',
+ 'DELAYED',
+ 'DELETE',
+ 'DESC',
+ 'DESCRIBE',
+ 'DETERMINISTIC',
+ 'DISTINCT',
+ 'DISTINCTROW',
+ 'DIV',
+ 'DO',
+ 'DUMPFILE',
+ 'DUPLICATE',
+ 'DYNAMIC',
+ 'ELSE',
+ 'ENCLOSED',
+ 'END',
+ 'ENGINE',
+ 'ENGINE_TYPE',
+ 'ENGINES',
+ 'ESCAPE',
+ 'ESCAPED',
+ 'EVENTS',
+ 'EXEC',
+ 'EXECUTE',
+ 'EXISTS',
+ 'EXPLAIN',
+ 'EXTENDED',
+ 'FAST',
+ 'FIELDS',
+ 'FILE',
+ 'FIRST',
+ 'FIXED',
+ 'FLUSH',
+ 'FOR',
+ 'FORCE',
+ 'FOREIGN',
+ 'FULL',
+ 'FULLTEXT',
+ 'FUNCTION',
+ 'GLOBAL',
+ 'GRANT',
+ 'GRANTS',
+ 'GROUP_CONCAT',
+ 'HEAP',
+ 'HIGH_PRIORITY',
+ 'HOSTS',
+ 'HOUR',
+ 'HOUR_MINUTE',
+ 'HOUR_SECOND',
+ 'IDENTIFIED',
+ 'IF',
+ 'IFNULL',
+ 'IGNORE',
+ 'IN',
+ 'INDEX',
+ 'INDEXES',
+ 'INFILE',
+ 'INSERT',
+ 'INSERT_ID',
+ 'INSERT_METHOD',
+ 'INTERVAL',
+ 'INTO',
+ 'INVOKER',
+ 'IS',
+ 'ISOLATION',
+ 'KEY',
+ 'KEYS',
+ 'KILL',
+ 'LAST_INSERT_ID',
+ 'LEADING',
+ 'LEVEL',
+ 'LIKE',
+ 'LINEAR',
+ 'LINES',
+ 'LOAD',
+ 'LOCAL',
+ 'LOCK',
+ 'LOCKS',
+ 'LOGS',
+ 'LOW_PRIORITY',
+ 'MARIA',
+ 'MASTER',
+ 'MASTER_CONNECT_RETRY',
+ 'MASTER_HOST',
+ 'MASTER_LOG_FILE',
+ 'MATCH',
+ 'MAX_CONNECTIONS_PER_HOUR',
+ 'MAX_QUERIES_PER_HOUR',
+ 'MAX_ROWS',
+ 'MAX_UPDATES_PER_HOUR',
+ 'MAX_USER_CONNECTIONS',
+ 'MEDIUM',
+ 'MERGE',
+ 'MINUTE',
+ 'MINUTE_SECOND',
+ 'MIN_ROWS',
+ 'MODE',
+ 'MODIFY',
+ 'MONTH',
+ 'MRG_MYISAM',
+ 'MYISAM',
+ 'NAMES',
+ 'NATURAL',
+ 'NOT',
+ 'NOW()',
+ 'NULL',
+ 'OFFSET',
+ 'ON',
+ 'OPEN',
+ 'OPTIMIZE',
+ 'OPTION',
+ 'OPTIONALLY',
+ 'ON UPDATE',
+ 'ON DELETE',
+ 'OUTFILE',
+ 'PACK_KEYS',
+ 'PAGE',
+ 'PARTIAL',
+ 'PARTITION',
+ 'PARTITIONS',
+ 'PASSWORD',
+ 'PRIMARY',
+ 'PRIVILEGES',
+ 'PROCEDURE',
+ 'PROCESS',
+ 'PROCESSLIST',
+ 'PURGE',
+ 'QUICK',
+ 'RANGE',
+ 'RAID0',
+ 'RAID_CHUNKS',
+ 'RAID_CHUNKSIZE',
+ 'RAID_TYPE',
+ 'READ',
+ 'READ_ONLY',
+ 'READ_WRITE',
+ 'REFERENCES',
+ 'REGEXP',
+ 'RELOAD',
+ 'RENAME',
+ 'REPAIR',
+ 'REPEATABLE',
+ 'REPLACE',
+ 'REPLICATION',
+ 'RESET',
+ 'RESTORE',
+ 'RESTRICT',
+ 'RETURN',
+ 'RETURNS',
+ 'REVOKE',
+ 'RLIKE',
+ 'ROLLBACK',
+ 'ROW',
+ 'ROWS',
+ 'ROW_FORMAT',
+ 'SECOND',
+ 'SECURITY',
+ 'SEPARATOR',
+ 'SERIALIZABLE',
+ 'SESSION',
+ 'SHARE',
+ 'SHOW',
+ 'SHUTDOWN',
+ 'SLAVE',
+ 'SONAME',
+ 'SOUNDS',
+ 'SQL',
+ 'SQL_AUTO_IS_NULL',
+ 'SQL_BIG_RESULT',
+ 'SQL_BIG_SELECTS',
+ 'SQL_BIG_TABLES',
+ 'SQL_BUFFER_RESULT',
+ 'SQL_CALC_FOUND_ROWS',
+ 'SQL_LOG_BIN',
+ 'SQL_LOG_OFF',
+ 'SQL_LOG_UPDATE',
+ 'SQL_LOW_PRIORITY_UPDATES',
+ 'SQL_MAX_JOIN_SIZE',
+ 'SQL_QUOTE_SHOW_CREATE',
+ 'SQL_SAFE_UPDATES',
+ 'SQL_SELECT_LIMIT',
+ 'SQL_SLAVE_SKIP_COUNTER',
+ 'SQL_SMALL_RESULT',
+ 'SQL_WARNINGS',
+ 'SQL_CACHE',
+ 'SQL_NO_CACHE',
+ 'START',
+ 'STARTING',
+ 'STATUS',
+ 'STOP',
+ 'STORAGE',
+ 'STRAIGHT_JOIN',
+ 'STRING',
+ 'STRIPED',
+ 'SUPER',
+ 'TABLE',
+ 'TABLES',
+ 'TEMPORARY',
+ 'TERMINATED',
+ 'THEN',
+ 'TO',
+ 'TRAILING',
+ 'TRANSACTIONAL',
+ 'TRUE',
+ 'TRUNCATE',
+ 'TYPE',
+ 'TYPES',
+ 'UNCOMMITTED',
+ 'UNIQUE',
+ 'UNLOCK',
+ 'UNSIGNED',
+ 'USAGE',
+ 'USE',
+ 'USING',
+ 'VARIABLES',
+ 'VIEW',
+ 'WHEN',
+ 'WITH',
+ 'WORK',
+ 'WRITE',
+ 'YEAR_MONTH',
+ ];
+
+ /**
+ * @var array
+ */
+ public static $reservedTopLevel = [
+ 'SELECT',
+ 'FROM',
+ 'WHERE',
+ 'SET',
+ 'ORDER BY',
+ 'GROUP BY',
+ 'LIMIT',
+ 'DROP',
+ 'VALUES',
+ 'UPDATE',
+ 'HAVING',
+ 'ADD',
+ 'AFTER',
+ 'ALTER TABLE',
+ 'DELETE FROM',
+ 'UNION ALL',
+ 'UNION',
+ 'EXCEPT',
+ 'INTERSECT',
+ ];
+
+ /**
+ * @var array
+ */
+ public static $reservedNewLine = [
+ 'LEFT OUTER JOIN',
+ 'RIGHT OUTER JOIN',
+ 'LEFT JOIN',
+ 'RIGHT JOIN',
+ 'OUTER JOIN',
+ 'INNER JOIN',
+ 'JOIN',
+ 'XOR',
+ 'OR',
+ 'AND',
+ ];
+
+ /**
+ * @var array
+ */
+ public static $functions = [
+ 'ABS',
+ 'ACOS',
+ 'ADDDATE',
+ 'ADDTIME',
+ 'AES_DECRYPT',
+ 'AES_ENCRYPT',
+ 'AREA',
+ 'ASBINARY',
+ 'ASCII',
+ 'ASIN',
+ 'ASTEXT',
+ 'ATAN',
+ 'ATAN2',
+ 'AVG',
+ 'BDMPOLYFROMTEXT',
+ 'BDMPOLYFROMWKB',
+ 'BDPOLYFROMTEXT',
+ 'BDPOLYFROMWKB',
+ 'BENCHMARK',
+ 'BIN',
+ 'BIT_AND',
+ 'BIT_COUNT',
+ 'BIT_LENGTH',
+ 'BIT_OR',
+ 'BIT_XOR',
+ 'BOUNDARY',
+ 'BUFFER',
+ 'CAST',
+ 'CEIL',
+ 'CEILING',
+ 'CENTROID',
+ 'CHAR',
+ 'CHARACTER_LENGTH',
+ 'CHARSET',
+ 'CHAR_LENGTH',
+ 'COALESCE',
+ 'COERCIBILITY',
+ 'COLLATION',
+ 'COMPRESS',
+ 'CONCAT',
+ 'CONCAT_WS',
+ 'CONNECTION_ID',
+ 'CONTAINS',
+ 'CONV',
+ 'CONVERT',
+ 'CONVERT_TZ',
+ 'CONVEXHULL',
+ 'COS',
+ 'COT',
+ 'COUNT',
+ 'CRC32',
+ 'CROSSES',
+ 'CURDATE',
+ 'CURRENT_DATE',
+ 'CURRENT_TIME',
+ 'CURRENT_TIMESTAMP',
+ 'CURRENT_USER',
+ 'CURTIME',
+ 'DATABASE',
+ 'DATE',
+ 'DATEDIFF',
+ 'DATE_ADD',
+ 'DATE_DIFF',
+ 'DATE_FORMAT',
+ 'DATE_SUB',
+ 'DAY',
+ 'DAYNAME',
+ 'DAYOFMONTH',
+ 'DAYOFWEEK',
+ 'DAYOFYEAR',
+ 'DECODE',
+ 'DEFAULT',
+ 'DEGREES',
+ 'DES_DECRYPT',
+ 'DES_ENCRYPT',
+ 'DIFFERENCE',
+ 'DIMENSION',
+ 'DISJOINT',
+ 'DISTANCE',
+ 'ELT',
+ 'ENCODE',
+ 'ENCRYPT',
+ 'ENDPOINT',
+ 'ENVELOPE',
+ 'EQUALS',
+ 'EXP',
+ 'EXPORT_SET',
+ 'EXTERIORRING',
+ 'EXTRACT',
+ 'EXTRACTVALUE',
+ 'FIELD',
+ 'FIND_IN_SET',
+ 'FLOOR',
+ 'FORMAT',
+ 'FOUND_ROWS',
+ 'FROM_DAYS',
+ 'FROM_UNIXTIME',
+ 'GEOMCOLLFROMTEXT',
+ 'GEOMCOLLFROMWKB',
+ 'GEOMETRYCOLLECTION',
+ 'GEOMETRYCOLLECTIONFROMTEXT',
+ 'GEOMETRYCOLLECTIONFROMWKB',
+ 'GEOMETRYFROMTEXT',
+ 'GEOMETRYFROMWKB',
+ 'GEOMETRYN',
+ 'GEOMETRYTYPE',
+ 'GEOMFROMTEXT',
+ 'GEOMFROMWKB',
+ 'GET_FORMAT',
+ 'GET_LOCK',
+ 'GLENGTH',
+ 'GREATEST',
+ 'GROUP_CONCAT',
+ 'GROUP_UNIQUE_USERS',
+ 'HEX',
+ 'HOUR',
+ 'IF',
+ 'IFNULL',
+ 'INET_ATON',
+ 'INET_NTOA',
+ 'INSERT',
+ 'INSTR',
+ 'INTERIORRINGN',
+ 'INTERSECTION',
+ 'INTERSECTS',
+ 'INTERVAL',
+ 'ISCLOSED',
+ 'ISEMPTY',
+ 'ISNULL',
+ 'ISRING',
+ 'ISSIMPLE',
+ 'IS_FREE_LOCK',
+ 'IS_USED_LOCK',
+ 'LAST_DAY',
+ 'LAST_INSERT_ID',
+ 'LCASE',
+ 'LEAST',
+ 'LEFT',
+ 'LENGTH',
+ 'LINEFROMTEXT',
+ 'LINEFROMWKB',
+ 'LINESTRING',
+ 'LINESTRINGFROMTEXT',
+ 'LINESTRINGFROMWKB',
+ 'LN',
+ 'LOAD_FILE',
+ 'LOCALTIME',
+ 'LOCALTIMESTAMP',
+ 'LOCATE',
+ 'LOG',
+ 'LOG10',
+ 'LOG2',
+ 'LOWER',
+ 'LPAD',
+ 'LTRIM',
+ 'MAKEDATE',
+ 'MAKETIME',
+ 'MAKE_SET',
+ 'MASTER_POS_WAIT',
+ 'MAX',
+ 'MBRCONTAINS',
+ 'MBRDISJOINT',
+ 'MBREQUAL',
+ 'MBRINTERSECTS',
+ 'MBROVERLAPS',
+ 'MBRTOUCHES',
+ 'MBRWITHIN',
+ 'MD5',
+ 'MICROSECOND',
+ 'MID',
+ 'MIN',
+ 'MINUTE',
+ 'MLINEFROMTEXT',
+ 'MLINEFROMWKB',
+ 'MOD',
+ 'MONTH',
+ 'MONTHNAME',
+ 'MPOINTFROMTEXT',
+ 'MPOINTFROMWKB',
+ 'MPOLYFROMTEXT',
+ 'MPOLYFROMWKB',
+ 'MULTILINESTRING',
+ 'MULTILINESTRINGFROMTEXT',
+ 'MULTILINESTRINGFROMWKB',
+ 'MULTIPOINT',
+ 'MULTIPOINTFROMTEXT',
+ 'MULTIPOINTFROMWKB',
+ 'MULTIPOLYGON',
+ 'MULTIPOLYGONFROMTEXT',
+ 'MULTIPOLYGONFROMWKB',
+ 'NAME_CONST',
+ 'NULLIF',
+ 'NUMGEOMETRIES',
+ 'NUMINTERIORRINGS',
+ 'NUMPOINTS',
+ 'OCT',
+ 'OCTET_LENGTH',
+ 'OLD_PASSWORD',
+ 'ORD',
+ 'OVERLAPS',
+ 'PASSWORD',
+ 'PERIOD_ADD',
+ 'PERIOD_DIFF',
+ 'PI',
+ 'POINT',
+ 'POINTFROMTEXT',
+ 'POINTFROMWKB',
+ 'POINTN',
+ 'POINTONSURFACE',
+ 'POLYFROMTEXT',
+ 'POLYFROMWKB',
+ 'POLYGON',
+ 'POLYGONFROMTEXT',
+ 'POLYGONFROMWKB',
+ 'POSITION',
+ 'POW',
+ 'POWER',
+ 'QUARTER',
+ 'QUOTE',
+ 'RADIANS',
+ 'RAND',
+ 'RELATED',
+ 'RELEASE_LOCK',
+ 'REPEAT',
+ 'REPLACE',
+ 'REVERSE',
+ 'RIGHT',
+ 'ROUND',
+ 'ROW_COUNT',
+ 'RPAD',
+ 'RTRIM',
+ 'SCHEMA',
+ 'SECOND',
+ 'SEC_TO_TIME',
+ 'SESSION_USER',
+ 'SHA',
+ 'SHA1',
+ 'SIGN',
+ 'SIN',
+ 'SLEEP',
+ 'SOUNDEX',
+ 'SPACE',
+ 'SQRT',
+ 'SRID',
+ 'STARTPOINT',
+ 'STD',
+ 'STDDEV',
+ 'STDDEV_POP',
+ 'STDDEV_SAMP',
+ 'STRCMP',
+ 'STR_TO_DATE',
+ 'SUBDATE',
+ 'SUBSTR',
+ 'SUBSTRING',
+ 'SUBSTRING_INDEX',
+ 'SUBTIME',
+ 'SUM',
+ 'SYMDIFFERENCE',
+ 'SYSDATE',
+ 'SYSTEM_USER',
+ 'TAN',
+ 'TIME',
+ 'TIMEDIFF',
+ 'TIMESTAMP',
+ 'TIMESTAMPADD',
+ 'TIMESTAMPDIFF',
+ 'TIME_FORMAT',
+ 'TIME_TO_SEC',
+ 'TOUCHES',
+ 'TO_DAYS',
+ 'TRIM',
+ 'TRUNCATE',
+ 'UCASE',
+ 'UNCOMPRESS',
+ 'UNCOMPRESSED_LENGTH',
+ 'UNHEX',
+ 'UNIQUE_USERS',
+ 'UNIX_TIMESTAMP',
+ 'UPDATEXML',
+ 'UPPER',
+ 'USER',
+ 'UTC_DATE',
+ 'UTC_TIME',
+ 'UTC_TIMESTAMP',
+ 'UUID',
+ 'VARIANCE',
+ 'VAR_POP',
+ 'VAR_SAMP',
+ 'VERSION',
+ 'WEEK',
+ 'WEEKDAY',
+ 'WEEKOFYEAR',
+ 'WITHIN',
+ 'X',
+ 'Y',
+ 'YEAR',
+ 'YEARWEEK',
+ ];
+
+ /**
+ * @var array
+ */
+ public static $boundaries = [
+ ',',
+ ';',
+ ')',
+ '(',
+ '.',
+ '=',
+ '<',
+ '>',
+ '+',
+ '-',
+ '*',
+ '/',
+ '!',
+ '^',
+ '%',
+ '|',
+ '&',
+ '#',
+ ];
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public static function isTokenTypeReservedTopLevel($token)
+ {
+ return $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_RESERVED_TOP_LEVEL;
+ }
+
+ /**
+ * @param string $token
+ * @param Parentheses $parentheses
+ * @param Formatter $formatter
+ */
+ public static function tokenHasLimitClause($token, Parentheses $parentheses, Formatter $formatter)
+ {
+ if ('LIMIT' === $token[Tokenizer::TOKEN_VALUE] && false === $parentheses->getInlineParentheses()) {
+ $formatter->setClauseLimit(true);
+ }
+ }
+
+ /**
+ * @param $token
+ * @param $tokens
+ * @param $i
+ * @param $originalTokens
+ *
+ * @return bool
+ */
+ public static function tokenHasMultipleBoundaryCharactersTogether($token, &$tokens, $i, &$originalTokens)
+ {
+ return $token[Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_BOUNDARY
+ && self::tokenPreviousCharacterIsBoundary($tokens, $i)
+ && self::tokenPreviousCharacterIsWhiteSpace($token, $originalTokens);
+ }
+
+ /**
+ * @param $tokens
+ * @param $i
+ *
+ * @return bool
+ */
+ public static function tokenPreviousCharacterIsBoundary(&$tokens, $i)
+ {
+ return (isset($tokens[$i - 1]) && $tokens[$i - 1][Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_BOUNDARY);
+ }
+
+ /**
+ * @param $token
+ * @param $originalTokens
+ *
+ * @return bool
+ */
+ public static function tokenPreviousCharacterIsWhiteSpace($token, &$originalTokens)
+ {
+ return (isset($originalTokens[$token['i'] - 1])
+ && $originalTokens[$token['i'] - 1][Tokenizer::TOKEN_TYPE] !== Tokenizer::TOKEN_TYPE_WHITESPACE);
+ }
+
+ /**
+ * @param $token
+ * @param $tokens
+ * @param $i
+ *
+ * @return bool
+ */
+ public static function tokenIsMinusSign($token, &$tokens, $i)
+ {
+ return '-' === $token[Tokenizer::TOKEN_VALUE]
+ && self::tokenNextCharacterIsNumber($tokens, $i)
+ && isset($tokens[$i - 1]);
+ }
+
+ /**
+ * @param $tokens
+ * @param $i
+ *
+ * @return bool
+ */
+ public static function tokenNextCharacterIsNumber(&$tokens, $i)
+ {
+ return (isset($tokens[$i + 1])
+ && $tokens[$i + 1][Tokenizer::TOKEN_TYPE] === Tokenizer::TOKEN_TYPE_NUMBER);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Helper/WhiteSpace.php b/vendor/nilportugues/sql-query-formatter/src/Helper/WhiteSpace.php
new file mode 100644
index 0000000..6b4cc7a
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Helper/WhiteSpace.php
@@ -0,0 +1,100 @@
+
+ * Date: 12/22/14
+ * Time: 1:19 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Helper;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class WhiteSpace.
+ */
+class WhiteSpace
+{
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public static function tokenHasExtraWhiteSpaceLeft($token)
+ {
+ return
+ $token[Tokenizer::TOKEN_VALUE] === '.'
+ || $token[Tokenizer::TOKEN_VALUE] === ','
+ || $token[Tokenizer::TOKEN_VALUE] === ';';
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public static function tokenHasExtraWhiteSpaceRight($token)
+ {
+ return
+ $token[Tokenizer::TOKEN_VALUE] === '('
+ || $token[Tokenizer::TOKEN_VALUE] === '.';
+ }
+
+ /**
+ * @param $tokenType
+ *
+ * @return bool
+ */
+ public static function tokenIsNumberAndHasExtraWhiteSpaceRight($tokenType)
+ {
+ return
+ $tokenType !== Tokenizer::TOKEN_TYPE_QUOTE
+ && $tokenType !== Tokenizer::TOKEN_TYPE_BACK_TICK_QUOTE
+ && $tokenType !== Tokenizer::TOKEN_TYPE_WORD
+ && $tokenType !== Tokenizer::TOKEN_TYPE_NUMBER;
+ }
+
+ /**
+ * @param $token
+ *
+ * @return bool
+ */
+ public static function tokenHasExtraWhiteSpaces($token)
+ {
+ return \strpos($token[Tokenizer::TOKEN_VALUE], ' ') !== false
+ || \strpos($token[Tokenizer::TOKEN_VALUE], "\n") !== false
+ || \strpos($token[Tokenizer::TOKEN_VALUE], "\t") !== false;
+ }
+
+ /**
+ * @param $originalTokens
+ * @param $token
+ *
+ * @return bool
+ */
+ public static function isPrecedingCurrentTokenOfTokenTypeWhiteSpace($originalTokens, $token)
+ {
+ return isset($originalTokens[$token['i'] - 1])
+ && $originalTokens[$token['i'] - 1][Tokenizer::TOKEN_TYPE] !== Tokenizer::TOKEN_TYPE_WHITESPACE;
+ }
+
+ /**
+ * @param $originalTokens
+ *
+ * @return array
+ */
+ public static function removeTokenWhitespace(array &$originalTokens)
+ {
+ $tokens = [];
+ foreach ($originalTokens as $i => &$token) {
+ if ($token[Tokenizer::TOKEN_TYPE] !== Tokenizer::TOKEN_TYPE_WHITESPACE) {
+ $token['i'] = $i;
+ $tokens[] = $token;
+ }
+ }
+
+ return $tokens;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Boundary.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Boundary.php
new file mode 100644
index 0000000..f077667
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Boundary.php
@@ -0,0 +1,58 @@
+
+ * Date: 12/23/14
+ * Time: 1:34 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Boundary.
+ */
+final class Boundary
+{
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ * @param array $matches
+ */
+ public static function isBoundary(Tokenizer $tokenizer, $string, array &$matches)
+ {
+ if (!$tokenizer->getNextToken() &&
+ self::isBoundaryCharacter($string, $matches, $tokenizer->getRegexBoundaries())
+ ) {
+ $tokenizer->setNextToken(self::getBoundaryCharacter($matches));
+ }
+ }
+
+ /**
+ * @param string $string
+ * @param array $matches
+ * @param string $regexBoundaries
+ *
+ * @return bool
+ */
+ protected static function isBoundaryCharacter($string, array &$matches, $regexBoundaries)
+ {
+ return (1 == \preg_match('/^('.$regexBoundaries.')/', $string, $matches));
+ }
+
+ /**
+ * @param array $matches
+ *
+ * @return array
+ */
+ protected static function getBoundaryCharacter(array &$matches)
+ {
+ return [
+ Tokenizer::TOKEN_VALUE => $matches[1],
+ Tokenizer::TOKEN_TYPE => Tokenizer::TOKEN_TYPE_BOUNDARY,
+ ];
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Comment.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Comment.php
new file mode 100644
index 0000000..63ad383
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Comment.php
@@ -0,0 +1,93 @@
+
+ * Date: 12/23/14
+ * Time: 1:22 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Comment.
+ */
+final class Comment
+{
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ */
+ public static function isComment(Tokenizer $tokenizer, $string)
+ {
+ if (!$tokenizer->getNextToken() && self::isCommentString($string)) {
+ $tokenizer->setNextToken(self::getCommentString($string));
+ }
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return bool
+ */
+ protected static function isCommentString($string)
+ {
+ return !empty($string[0]) && ($string[0] === '#' || self::isTwoCharacterComment($string));
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return bool
+ */
+ protected static function isTwoCharacterComment($string)
+ {
+ return !empty($string[1]) && (isset($string[1]) && (self::startsWithDoubleDash($string) || self::startsAsBlock($string)));
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return bool
+ */
+ protected static function startsWithDoubleDash($string)
+ {
+ return !empty($string[1]) && ($string[0] === '-' && ($string[1] === $string[0]));
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return bool
+ */
+ protected static function startsAsBlock($string)
+ {
+ return !empty($string[1]) && ($string[0] === '/' && $string[1] === '*');
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return array
+ */
+ protected static function getCommentString($string)
+ {
+ $last = \strpos($string, '*/', 2) + 2;
+ $type = Tokenizer::TOKEN_TYPE_BLOCK_COMMENT;
+
+ if (!empty($string[0]) && ($string[0] === '-' || $string[0] === '#')) {
+ $last = \strpos($string, "\n");
+ $type = Tokenizer::TOKEN_TYPE_COMMENT;
+ }
+
+ $last = ($last === false) ? \strlen($string) : $last;
+
+ return [
+ Tokenizer::TOKEN_VALUE => \substr($string, 0, $last),
+ Tokenizer::TOKEN_TYPE => $type,
+ ];
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/LiteralString.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/LiteralString.php
new file mode 100644
index 0000000..45eb4a0
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/LiteralString.php
@@ -0,0 +1,81 @@
+
+ * Date: 12/23/14
+ * Time: 1:36 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class LiteralString.
+ */
+final class LiteralString
+{
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ * @param array $matches
+ */
+ public static function isFunction(Tokenizer $tokenizer, $string, array &$matches)
+ {
+ if (!$tokenizer->getNextToken() && self::isFunctionString($string, $matches, $tokenizer->getRegexFunction())) {
+ $tokenizer->setNextToken(self::getFunctionString($string, $matches));
+ }
+ }
+
+ /**
+ * A function must be succeeded by '('.
+ * This makes it so that a function such as "COUNT(" is considered a function, but "COUNT" alone is not function.
+ *
+ * @param string $string
+ * @param array $matches
+ * @param string $regexFunction
+ *
+ * @return bool
+ */
+ protected static function isFunctionString($string, array &$matches, $regexFunction)
+ {
+ return (1 == \preg_match('/^('.$regexFunction.'[(]|\s|[)])/', \strtoupper($string), $matches));
+ }
+
+ /**
+ * @param string $string
+ * @param array $matches
+ *
+ * @return array
+ */
+ protected static function getFunctionString($string, array &$matches)
+ {
+ return [
+ Tokenizer::TOKEN_TYPE => Tokenizer::TOKEN_TYPE_RESERVED,
+ Tokenizer::TOKEN_VALUE => \substr($string, 0, \strlen($matches[1]) - 1),
+ ];
+ }
+
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ * @param array $matches
+ */
+ public static function getNonReservedString(Tokenizer $tokenizer, $string, array &$matches)
+ {
+ if (!$tokenizer->getNextToken()) {
+ $data = [];
+
+ if (1 == \preg_match('/^(.*?)($|\s|["\'`]|'.$tokenizer->getRegexBoundaries().')/', $string, $matches)) {
+ $data = [
+ Tokenizer::TOKEN_VALUE => $matches[1],
+ Tokenizer::TOKEN_TYPE => Tokenizer::TOKEN_TYPE_WORD,
+ ];
+ }
+
+ $tokenizer->setNextToken($data);
+ }
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Numeral.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Numeral.php
new file mode 100644
index 0000000..70f83fe
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Numeral.php
@@ -0,0 +1,59 @@
+
+ * Date: 12/23/14
+ * Time: 1:32 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Numeral.
+ */
+final class Numeral
+{
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ * @param array $matches
+ *
+ * @return array
+ */
+ public static function isNumeral(Tokenizer $tokenizer, $string, array &$matches)
+ {
+ if (!$tokenizer->getNextToken() && self::isNumeralString($string, $matches, $tokenizer->getRegexBoundaries())) {
+ $tokenizer->setNextToken(self::getNumeralString($matches));
+ }
+ }
+
+ /**
+ * @param string $string
+ * @param array $matches
+ * @param string $regexBoundaries
+ *
+ * @return bool
+ */
+ protected static function isNumeralString($string, array &$matches, $regexBoundaries)
+ {
+ return (1 == \preg_match(
+ '/^([0-9]+(\.[0-9]+)?|0x[0-9a-fA-F]+|0b[01]+)($|\s|"\'`|'.$regexBoundaries.')/',
+ $string,
+ $matches
+ ));
+ }
+
+ /**
+ * @param array $matches
+ *
+ * @return array
+ */
+ protected static function getNumeralString(array &$matches)
+ {
+ return [Tokenizer::TOKEN_VALUE => $matches[1], Tokenizer::TOKEN_TYPE => Tokenizer::TOKEN_TYPE_NUMBER];
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Quoted.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Quoted.php
new file mode 100644
index 0000000..5a209ab
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Quoted.php
@@ -0,0 +1,84 @@
+
+ * Date: 12/23/14
+ * Time: 1:23 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Quoted.
+ */
+final class Quoted
+{
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ */
+ public static function isQuoted(Tokenizer $tokenizer, $string)
+ {
+ if (!$tokenizer->getNextToken() && self::isQuotedString($string)) {
+ $tokenizer->setNextToken(self::getQuotedString($string));
+ }
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return bool
+ */
+ protected static function isQuotedString($string)
+ {
+ return !empty($string[0]) && ($string[0] === '"' || $string[0] === '\'' || $string[0] === '`' || $string[0] === '[');
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return array
+ */
+ protected static function getQuotedString($string)
+ {
+ $tokenType = Tokenizer::TOKEN_TYPE_QUOTE;
+
+ if (!empty($string[0]) && ($string[0] === '`' || $string[0] === '[')) {
+ $tokenType = Tokenizer::TOKEN_TYPE_BACK_TICK_QUOTE;
+ }
+
+ return [
+ Tokenizer::TOKEN_TYPE => $tokenType,
+ Tokenizer::TOKEN_VALUE => self::wrapStringWithQuotes($string),
+ ];
+ }
+
+ /**
+ * This checks for the following patterns:
+ * 1. backtick quoted string using `` to escape
+ * 2. square bracket quoted string (SQL Server) using ]] to escape
+ * 3. double quoted string using "" or \" to escape
+ * 4. single quoted string using '' or \' to escape.
+ *
+ * @param string $string
+ *
+ * @return null
+ */
+ public static function wrapStringWithQuotes($string)
+ {
+ $returnString = null;
+
+ $regex = '/^(((`[^`]*($|`))+)|((\[[^\]]*($|\]))(\][^\]]*($|\]))*)|'.
+ '(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)|((\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*(\'|$))+))/s';
+
+ if (1 == \preg_match($regex, $string, $matches)) {
+ $returnString = $matches[1];
+ }
+
+ return $returnString;
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Reserved.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Reserved.php
new file mode 100644
index 0000000..ec0194d
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/Reserved.php
@@ -0,0 +1,116 @@
+
+ * Date: 12/23/14
+ * Time: 1:18 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class Reserved.
+ */
+final class Reserved
+{
+ /**
+ * @var array
+ */
+ protected static $regex = [
+ Tokenizer::TOKEN_TYPE_RESERVED_TOP_LEVEL => 'getRegexReservedTopLevel',
+ Tokenizer::TOKEN_TYPE_RESERVED_NEWLINE => 'getRegexReservedNewLine',
+ Tokenizer::TOKEN_TYPE_RESERVED => 'getRegexReserved',
+ ];
+
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ * @param array|null $previous
+ *
+ * @return array
+ */
+ public static function isReserved(Tokenizer $tokenizer, $string, $previous)
+ {
+ $tokenData = [];
+
+ if (!$tokenizer->getNextToken() && self::isReservedPrecededByDotCharacter($previous)) {
+ $upperCase = \strtoupper($string);
+
+ self::getReservedString($tokenData, Tokenizer::TOKEN_TYPE_RESERVED_TOP_LEVEL, $string, $tokenizer);
+ self::getReservedString($tokenData, Tokenizer::TOKEN_TYPE_RESERVED_NEWLINE, $upperCase, $tokenizer);
+ self::getReservedString($tokenData, Tokenizer::TOKEN_TYPE_RESERVED, $string, $tokenizer);
+
+ $tokenizer->setNextToken($tokenData);
+ }
+ }
+
+ /**
+ * A reserved word cannot be preceded by a "." in order to differentiate "mytable.from" from the token "from".
+ *
+ * @param $previous
+ *
+ * @return bool
+ */
+ protected static function isReservedPrecededByDotCharacter($previous)
+ {
+ return !$previous || !isset($previous[Tokenizer::TOKEN_VALUE]) || $previous[Tokenizer::TOKEN_VALUE] !== '.';
+ }
+
+ /**
+ * @param array $tokenData
+ * @param $type
+ * @param string $string
+ * @param Tokenizer $tokenizer
+ */
+ protected static function getReservedString(array &$tokenData, $type, $string, Tokenizer $tokenizer)
+ {
+ $matches = [];
+ $method = self::$regex[$type];
+
+ if (empty($tokenData) && self::isReservedString(
+ $string,
+ $matches,
+ $tokenizer->$method(),
+ $tokenizer->getRegexBoundaries()
+ )
+ ) {
+ $tokenData = self::getStringTypeArray($type, $string, $matches);
+ }
+ }
+
+ /**
+ * @param string $upper
+ * @param array $matches
+ * @param string $regexReserved
+ * @param string $regexBoundaries
+ *
+ * @return bool
+ */
+ protected static function isReservedString($upper, array &$matches, $regexReserved, $regexBoundaries)
+ {
+ return 1 == \preg_match(
+ '/^('.$regexReserved.')($|\s|'.$regexBoundaries.')/',
+ \strtoupper($upper),
+ $matches
+ );
+ }
+
+ /**
+ * @param string $type
+ * @param string $string
+ * @param array $matches
+ *
+ * @return array
+ */
+ protected static function getStringTypeArray($type, $string, array &$matches)
+ {
+ return [
+ Tokenizer::TOKEN_TYPE => $type,
+ Tokenizer::TOKEN_VALUE => \substr($string, 0, \strlen($matches[1])),
+ ];
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/UserDefined.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/UserDefined.php
new file mode 100644
index 0000000..18a6b17
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/UserDefined.php
@@ -0,0 +1,88 @@
+
+ * Date: 12/23/14
+ * Time: 1:26 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class UserDefined.
+ */
+final class UserDefined
+{
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ *
+ * @return array
+ */
+ public static function isUserDefinedVariable(Tokenizer $tokenizer, $string)
+ {
+ if (!$tokenizer->getNextToken() && self::isUserDefinedVariableString($string)) {
+ $tokenizer->setNextToken(self::getUserDefinedVariableString($string));
+ }
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return bool
+ */
+ protected static function isUserDefinedVariableString(&$string)
+ {
+ return !empty($string[0]) && !empty($string[1]) && ($string[0] === '@' && isset($string[1]));
+ }
+
+ /**
+ * Gets the user defined variables for in quoted or non-quoted fashion.
+ *
+ * @param string $string
+ *
+ * @return array
+ */
+ protected static function getUserDefinedVariableString(&$string)
+ {
+ $returnData = [
+ Tokenizer::TOKEN_VALUE => null,
+ Tokenizer::TOKEN_TYPE => Tokenizer::TOKEN_TYPE_VARIABLE,
+ ];
+
+ self::setTokenValueStartingWithAtSymbolAndWrapped($returnData, $string);
+ self::setTokenValueStartingWithAtSymbol($returnData, $string);
+
+ return $returnData;
+ }
+
+ /**
+ * @param array $returnData
+ * @param string $string
+ */
+ protected static function setTokenValueStartingWithAtSymbolAndWrapped(array &$returnData, $string)
+ {
+ if (!empty($string[1]) && ($string[1] === '"' || $string[1] === '\'' || $string[1] === '`')) {
+ $returnData[Tokenizer::TOKEN_VALUE] = '@'.Quoted::wrapStringWithQuotes(\substr($string, 1));
+ }
+ }
+
+ /**
+ * @param array $returnData
+ * @param string $string
+ */
+ protected static function setTokenValueStartingWithAtSymbol(array &$returnData, $string)
+ {
+ if (null === $returnData[Tokenizer::TOKEN_VALUE]) {
+ $matches = [];
+ \preg_match('/^(@[a-zA-Z0-9\._\$]+)/', $string, $matches);
+ if ($matches) {
+ $returnData[Tokenizer::TOKEN_VALUE] = $matches[1];
+ }
+ }
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/WhiteSpace.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/WhiteSpace.php
new file mode 100644
index 0000000..50736d8
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Parser/WhiteSpace.php
@@ -0,0 +1,55 @@
+
+ * Date: 12/23/14
+ * Time: 1:19 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer\Parser;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class WhiteSpace.
+ */
+final class WhiteSpace
+{
+ /**
+ * @param Tokenizer $tokenizer
+ * @param string $string
+ * @param array $matches
+ */
+ public static function isWhiteSpace(Tokenizer $tokenizer, $string, array &$matches)
+ {
+ if (self::isWhiteSpaceString($string, $matches)) {
+ $tokenizer->setNextToken(self::getWhiteSpaceString($matches));
+ }
+ }
+
+ /**
+ * @param string $string
+ * @param array $matches
+ *
+ * @return bool
+ */
+ public static function isWhiteSpaceString($string, array &$matches)
+ {
+ return (1 == \preg_match('/^\s+/', $string, $matches));
+ }
+
+ /**
+ * @param array $matches
+ *
+ * @return array
+ */
+ public static function getWhiteSpaceString(array &$matches)
+ {
+ return [
+ Tokenizer::TOKEN_VALUE => $matches[0],
+ Tokenizer::TOKEN_TYPE => Tokenizer::TOKEN_TYPE_WHITESPACE,
+ ];
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Tokenizer.php b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Tokenizer.php
new file mode 100644
index 0000000..664a0d4
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/src/Tokenizer/Tokenizer.php
@@ -0,0 +1,350 @@
+
+ * Date: 6/26/14
+ * Time: 12:10 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Sql\QueryFormatter\Tokenizer;
+
+use NilPortugues\Sql\QueryFormatter\Helper\Token;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\Boundary;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\Comment;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\Numeral;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\Quoted;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\Reserved;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\LiteralString;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\UserDefined;
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Parser\WhiteSpace;
+
+/**
+ * Class Tokenizer.
+ */
+class Tokenizer
+{
+ const TOKEN_TYPE_WHITESPACE = 0;
+ const TOKEN_TYPE_WORD = 1;
+ const TOKEN_TYPE_QUOTE = 2;
+ const TOKEN_TYPE_BACK_TICK_QUOTE = 3;
+ const TOKEN_TYPE_RESERVED = 4;
+ const TOKEN_TYPE_RESERVED_TOP_LEVEL = 5;
+ const TOKEN_TYPE_RESERVED_NEWLINE = 6;
+ const TOKEN_TYPE_BOUNDARY = 7;
+ const TOKEN_TYPE_COMMENT = 8;
+ const TOKEN_TYPE_BLOCK_COMMENT = 9;
+ const TOKEN_TYPE_NUMBER = 10;
+ const TOKEN_TYPE_ERROR = 11;
+ const TOKEN_TYPE_VARIABLE = 12;
+ const TOKEN_TYPE = 0;
+ const TOKEN_VALUE = 1;
+
+ /**
+ * @var string
+ */
+ protected $regexBoundaries;
+
+ /**
+ * @var string
+ */
+ protected $regexReserved;
+
+ /**
+ * @var string
+ */
+ protected $regexReservedNewLine;
+
+ /**
+ * @var string
+ */
+ protected $regexReservedTopLevel;
+
+ /**
+ * @var string
+ */
+ protected $regexFunction;
+
+ /**
+ * @var int
+ */
+ protected $maxCacheKeySize = 15;
+
+ /**
+ * @var array
+ */
+ protected $tokenCache = [];
+
+ /**
+ * @var array
+ */
+ protected $nextToken = [];
+
+ /**
+ * @var int
+ */
+ protected $currentStringLength = 0;
+
+ /**
+ * @var int
+ */
+ protected $oldStringLength = 0;
+
+ /**
+ * @var string
+ */
+ protected $previousToken = '';
+
+ /**
+ * @var int
+ */
+ protected $tokenLength = 0;
+
+ /**
+ * @var array
+ */
+ protected $tokens = [];
+
+ /**
+ * Builds all the regular expressions needed to Tokenize the input.
+ */
+ public function __construct()
+ {
+ $reservedMap = \array_combine(Token::$reserved, \array_map('strlen', Token::$reserved));
+ \arsort($reservedMap);
+ Token::$reserved = \array_keys($reservedMap);
+
+ $this->regexFunction = $this->initRegex(Token::$functions);
+ $this->regexBoundaries = $this->initRegex(Token::$boundaries);
+ $this->regexReserved = $this->initRegex(Token::$reserved);
+ $this->regexReservedTopLevel = \str_replace(' ', '\\s+', $this->initRegex(Token::$reservedTopLevel));
+ $this->regexReservedNewLine = \str_replace(' ', '\\s+', $this->initRegex(Token::$reservedNewLine));
+ }
+
+ /**
+ * @param $variable
+ *
+ * @return string
+ */
+ protected function initRegex($variable)
+ {
+ return '('.implode('|', \array_map(array($this, 'quoteRegex'), $variable)).')';
+ }
+
+ /**
+ * Takes a SQL string and breaks it into tokens.
+ * Each token is an associative array with type and value.
+ *
+ * @param string $string
+ *
+ * @return array
+ */
+ public function tokenize($string)
+ {
+ return (\strlen($string) > 0) ? $this->processTokens($string) : [];
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return array
+ */
+ protected function processTokens($string)
+ {
+ $this->tokens = [];
+ $this->previousToken = '';
+ $this->currentStringLength = \strlen($string);
+ $this->oldStringLength = \strlen($string) + 1;
+
+ while ($this->currentStringLength >= 0) {
+ if ($this->oldStringLength <= $this->currentStringLength) {
+ break;
+ }
+ $string = $this->processOneToken($string);
+ }
+
+ return $this->tokens;
+ }
+
+ /**
+ * @param string $string
+ *
+ * @return string
+ */
+ protected function processOneToken($string)
+ {
+ $token = $this->getToken($string, $this->currentStringLength, $this->previousToken);
+ $this->tokens[] = $token;
+ $this->tokenLength = \strlen($token[self::TOKEN_VALUE]);
+ $this->previousToken = $token;
+
+ $this->oldStringLength = $this->currentStringLength;
+ $this->currentStringLength -= $this->tokenLength;
+
+ return \substr($string, $this->tokenLength);
+ }
+
+ /**
+ * @param string $string
+ * @param int $currentStringLength
+ * @param string string
+ *
+ * @return array|mixed
+ */
+ protected function getToken($string, $currentStringLength, $previousToken)
+ {
+ $cacheKey = $this->useTokenCache($string, $currentStringLength);
+ if (!empty($cacheKey) && isset($this->tokenCache[$cacheKey])) {
+ return $this->getNextTokenFromCache($cacheKey);
+ }
+
+ return $this->getNextTokenFromString($string, $previousToken, $cacheKey);
+ }
+
+ /**
+ * @param string $string
+ * @param int $currentStringLength
+ *
+ * @return string
+ */
+ protected function useTokenCache($string, $currentStringLength)
+ {
+ $cacheKey = '';
+
+ if ($currentStringLength >= $this->maxCacheKeySize) {
+ $cacheKey = \substr($string, 0, $this->maxCacheKeySize);
+ }
+
+ return $cacheKey;
+ }
+
+ /**
+ * @param string $cacheKey
+ *
+ * @return mixed
+ */
+ protected function getNextTokenFromCache($cacheKey)
+ {
+ return $this->tokenCache[$cacheKey];
+ }
+
+ /**
+ * Get the next token and the token type and store it in cache.
+ *
+ * @param string $string
+ * @param string $token
+ * @param string $cacheKey
+ *
+ * @return array
+ */
+ protected function getNextTokenFromString($string, $token, $cacheKey)
+ {
+ $token = $this->parseNextToken($string, $token);
+
+ if ($cacheKey && \strlen($token[self::TOKEN_VALUE]) < $this->maxCacheKeySize) {
+ $this->tokenCache[$cacheKey] = $token;
+ }
+
+ return $token;
+ }
+
+ /**
+ * Return the next token and token type in a SQL string.
+ * Quoted strings, comments, reserved words, whitespace, and punctuation are all their own tokens.
+ *
+ * @param string $string The SQL string
+ * @param array $previous The result of the previous parseNextToken() call
+ *
+ * @return array An associative array containing the type and value of the token.
+ */
+ protected function parseNextToken($string, $previous = null)
+ {
+ $matches = [];
+ $this->nextToken = [];
+
+ WhiteSpace::isWhiteSpace($this, $string, $matches);
+ Comment::isComment($this, $string);
+ Quoted::isQuoted($this, $string);
+ UserDefined::isUserDefinedVariable($this, $string);
+ Numeral::isNumeral($this, $string, $matches);
+ Boundary::isBoundary($this, $string, $matches);
+ Reserved::isReserved($this, $string, $previous);
+ LiteralString::isFunction($this, $string, $matches);
+ LiteralString::getNonReservedString($this, $string, $matches);
+
+ return $this->nextToken;
+ }
+
+ /**
+ * @return array
+ */
+ public function getNextToken()
+ {
+ return $this->nextToken;
+ }
+
+ /**
+ * @param array $nextToken
+ *
+ * @return $this
+ */
+ public function setNextToken($nextToken)
+ {
+ $this->nextToken = $nextToken;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRegexBoundaries()
+ {
+ return $this->regexBoundaries;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRegexFunction()
+ {
+ return $this->regexFunction;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRegexReserved()
+ {
+ return $this->regexReserved;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRegexReservedNewLine()
+ {
+ return $this->regexReservedNewLine;
+ }
+
+ /**
+ * @return string
+ */
+ public function getRegexReservedTopLevel()
+ {
+ return $this->regexReservedTopLevel;
+ }
+
+ /**
+ * Helper function for building regular expressions for reserved words and boundary characters.
+ *
+ * @param string $string
+ *
+ * @return string
+ */
+ protected function quoteRegex($string)
+ {
+ return \preg_quote($string, '/');
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/tests/FormatterTest.php b/vendor/nilportugues/sql-query-formatter/tests/FormatterTest.php
new file mode 100644
index 0000000..75896d6
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/tests/FormatterTest.php
@@ -0,0 +1,73 @@
+
+ * Date: 6/26/14
+ * Time: 9:11 PM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryFormatter;
+
+use NilPortugues\Sql\QueryFormatter\Formatter;
+
+/**
+ * Class FormatterTest.
+ */
+class FormatterTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var string
+ */
+ private $querySeparator = "----------SEPARATOR----------\n";
+
+ /**
+ * @var string
+ */
+ private $expectedResultFilePath = '/Resources/expectedQueries.sql';
+
+ /**
+ * @return array
+ */
+ private function readExpectedQueryFile()
+ {
+ $expectedQueryArray = \explode(
+ $this->querySeparator,
+ \file_get_contents(\realpath(\dirname(__FILE__)).$this->expectedResultFilePath)
+ );
+ $expectedQueryArray = \array_filter($expectedQueryArray);
+
+ return $expectedQueryArray;
+ }
+
+ /**
+ * Data provider reading the test Queries.
+ */
+ public function sqlQueryDataProvider()
+ {
+ $expectedQueryArray = $this->readExpectedQueryFile();
+
+ $queryTestSet = array();
+ foreach ($expectedQueryArray as $expectedQuery) {
+ $queryTestSet[] = array(\preg_replace('/\\s+/', ' ', $expectedQuery), $expectedQuery);
+ }
+
+ return $queryTestSet;
+ }
+
+ /**
+ * @test
+ * @dataProvider sqlQueryDataProvider
+ *
+ * @param $notIndented
+ * @param $indented
+ */
+ public function itShouldReformatNoIndentQueriesToIndentedVersions($notIndented, $indented)
+ {
+ $formatter = new Formatter();
+ $result = $formatter->format($notIndented);
+
+ $this->assertSame($indented, $result);
+ }
+}
diff --git a/vendor/nilportugues/sql-query-formatter/tests/Resources/expectedQueries.sql b/vendor/nilportugues/sql-query-formatter/tests/Resources/expectedQueries.sql
new file mode 100644
index 0000000..052a07f
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/tests/Resources/expectedQueries.sql
@@ -0,0 +1,808 @@
+SELECT
+ customer_id,
+ customer_name,
+ COUNT(order_id) AS total
+FROM
+ customers
+ INNER JOIN orders ON customers.customer_id = orders.customer_id
+GROUP BY
+ customer_id,
+ customer_name
+HAVING
+ COUNT(order_id) > 5
+ORDER BY
+ COUNT(order_id) DESC;
+----------SEPARATOR----------
+UPDATE
+ customers
+SET
+ totalorders = ordersummary.total
+FROM
+ (
+ SELECT
+ customer_id,
+ count(order_id) As total
+ FROM
+ orders
+ GROUP BY
+ customer_id
+ ) As ordersummary
+WHERE
+ customers.customer_id = ordersummary.customer_id
+----------SEPARATOR----------
+SELECT
+ *
+FROM
+ sometable
+UNION ALL
+SELECT
+ *
+FROM
+ someothertable;
+----------SEPARATOR----------
+SET
+ NAMES 'utf8';
+----------SEPARATOR----------
+CREATE TABLE `PREFIX_address` (
+ `id_address` int(10) unsigned NOT NULL auto_increment,
+ `id_country` int(10) unsigned NOT NULL,
+ `id_state` int(10) unsigned default NULL,
+ `id_customer` int(10) unsigned NOT NULL default '0',
+ `id_manufacturer` int(10) unsigned NOT NULL default '0',
+ `id_supplier` int(10) unsigned NOT NULL default '0',
+ `id_warehouse` int(10) unsigned NOT NULL default '0',
+ `alias` varchar(32) NOT NULL,
+ `company` varchar(64) default NULL,
+ `lastname` varchar(32) NOT NULL,
+ `firstname` varchar(32) NOT NULL,
+ `address1` varchar(128) NOT NULL,
+ `address2` varchar(128) default NULL,
+ `postcode` varchar(12) default NULL,
+ `city` varchar(64) NOT NULL,
+ `other` text,
+ `phone` varchar(16) default NULL,
+ `phone_mobile` varchar(16) default NULL,
+ `vat_number` varchar(32) default NULL,
+ `dni` varchar(16) DEFAULT NULL,
+ `date_add` datetime NOT NULL,
+ `date_upd` datetime NOT NULL,
+ `active` tinyint(1) unsigned NOT NULL default '1',
+ `deleted` tinyint(1) unsigned NOT NULL default '0',
+ PRIMARY KEY (`id_address`),
+ KEY `address_customer` (`id_customer`),
+ KEY `id_country` (`id_country`),
+ KEY `id_state` (`id_state`),
+ KEY `id_manufacturer` (`id_manufacturer`),
+ KEY `id_supplier` (`id_supplier`),
+ KEY `id_warehouse` (`id_warehouse`)
+) ENGINE = ENGINE_TYPE DEFAULT CHARSET = utf8
+----------SEPARATOR----------
+CREATE TABLE `PREFIX_alias` (
+ `id_alias` int(10) unsigned NOT NULL auto_increment,
+ `alias` varchar(255) NOT NULL,
+ `search` varchar(255) NOT NULL,
+ `active` tinyint(1) NOT NULL default '1',
+ PRIMARY KEY (`id_alias`),
+ UNIQUE KEY `alias` (`alias`)
+) ENGINE = ENGINE_TYPE DEFAULT CHARSET = utf8
+----------SEPARATOR----------
+CREATE TABLE `PREFIX_carrier` (
+ `id_carrier` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `id_reference` int(10) unsigned NOT NULL,
+ `id_tax_rules_group` int(10) unsigned DEFAULT '0',
+ `name` varchar(64) NOT NULL,
+ `url` varchar(255) DEFAULT NULL,
+ `active` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `shipping_handling` tinyint(1) unsigned NOT NULL DEFAULT '1',
+ `range_behavior` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `is_module` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `is_free` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `shipping_external` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `need_range` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `external_module_name` varchar(64) DEFAULT NULL,
+ `shipping_method` int(2) NOT NULL DEFAULT '0',
+ `position` int(10) unsigned NOT NULL default '0',
+ `max_width` int(10) DEFAULT 0,
+ `max_height` int(10) DEFAULT 0,
+ `max_depth` int(10) DEFAULT 0,
+ `max_weight` int(10) DEFAULT 0,
+ `grade` int(10) DEFAULT 0,
+ PRIMARY KEY (`id_carrier`),
+ KEY `deleted` (`deleted`, `active`),
+ KEY `id_tax_rules_group` (`id_tax_rules_group`)
+) ENGINE = ENGINE_TYPE DEFAULT CHARSET = utf8
+----------SEPARATOR----------
+CREATE TABLE IF NOT EXISTS `PREFIX_specific_price_rule` (
+ `id_specific_price_rule` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` VARCHAR(255) NOT NULL,
+ `id_shop` int(11) unsigned NOT NULL DEFAULT '1',
+ `id_currency` int(10) unsigned NOT NULL,
+ `id_country` int(10) unsigned NOT NULL,
+ `id_group` int(10) unsigned NOT NULL,
+ `from_quantity` mediumint(8) unsigned NOT NULL,
+ `price` DECIMAL(20, 6),
+ `reduction` decimal(20, 6) NOT NULL,
+ `reduction_type` enum('amount', 'percentage') NOT NULL,
+ `from` datetime NOT NULL,
+ `to` datetime NOT NULL,
+ PRIMARY KEY (`id_specific_price_rule`),
+ KEY `id_product` (
+ `id_shop`, `id_currency`, `id_country`,
+ `id_group`, `from_quantity`, `from`,
+ `to`
+ )
+) ENGINE = ENGINE_TYPE DEFAULT CHARSET = utf8
+----------SEPARATOR----------
+UPDATE
+ `PREFIX_configuration`
+SET
+ value = '6'
+WHERE
+ name = 'PS_SEARCH_WEIGHT_PNAME'
+----------SEPARATOR----------
+UPDATE
+ `PREFIX_hook_module`
+SET
+ position = 1
+WHERE
+ id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayPayment'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'cheque'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayPaymentReturn'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'cheque'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayHome'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'homeslider'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionAuthentication'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'statsdata'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionShopDataDuplication'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'homeslider'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayTop'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'blocklanguages'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionCustomerAccountAdd'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'statsdata'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayCustomerAccount'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'favoriteproducts'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayAdminStatsModules'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'statsvisits'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayAdminStatsGraphEngine'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'graphvisifire'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayAdminStatsGridEngine'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'gridhtml'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayLeftColumnProduct'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'blocksharefb'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionSearch'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'statssearch'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionCategoryAdd'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'blockcategories'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionCategoryUpdate'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'blockcategories'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionCategoryDelete'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'blockcategories'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'actionAdminMetaSave'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'blockcategories'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayMyAccountBlock'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'favoriteproducts'
+ )
+ OR id_hook = (
+ SELECT
+ id_hook
+ FROM
+ `PREFIX_hook`
+ WHERE
+ name = 'displayFooter'
+ )
+ AND id_module = (
+ SELECT
+ id_module
+ FROM
+ `PREFIX_module`
+ WHERE
+ name = 'blockreinsurance'
+ )
+----------SEPARATOR----------
+ALTER TABLE
+ `PREFIX_employee`
+ADD
+ `bo_color` varchar(32) default NULL
+AFTER
+ `stats_date_to`
+----------SEPARATOR----------
+INSERT INTO `PREFIX_cms_category_lang`
+VALUES
+ (
+ 1, 3, 'Inicio', '', 'home', NULL, NULL,
+ NULL
+ )
+----------SEPARATOR----------
+INSERT INTO `PREFIX_cms_category`
+VALUES
+ (1, 0, 0, 1, NOW(), NOW(), 0)
+----------SEPARATOR----------
+UPDATE
+ `PREFIX_cms_category`
+SET
+ `position` = 0
+----------SEPARATOR----------
+ALTER TABLE
+ `PREFIX_customer`
+ADD
+ `note` text
+AFTER
+ `secure_key`
+----------SEPARATOR----------
+ALTER TABLE
+ `PREFIX_contact`
+ADD
+ `customer_service` tinyint(1) NOT NULL DEFAULT 0
+AFTER
+ `email`
+----------SEPARATOR----------
+INSERT INTO `PREFIX_specific_price` (
+ `id_product`, `id_shop`, `id_currency`,
+ `id_country`, `id_group`, `priority`,
+ `price`, `from_quantity`, `reduction`,
+ `reduction_type`, `from`, `to`
+) (
+ SELECT
+ dq.`id_product`,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0.00,
+ dq.`quantity`,
+ IF(
+ dq.`id_discount_type` = 2, dq.`value`,
+ dq.`value` / 100
+ ),
+ IF (
+ dq.`id_discount_type` = 2, 'amount',
+ 'percentage'
+ ),
+ '0000-00-00 00:00:00',
+ '0000-00-00 00:00:00'
+ FROM
+ `PREFIX_discount_quantity` dq
+ INNER JOIN `PREFIX_product` p ON (p.`id_product` = dq.`id_product`)
+)
+----------SEPARATOR----------
+DROP
+ TABLE `PREFIX_discount_quantity`
+----------SEPARATOR----------
+INSERT INTO `PREFIX_specific_price` (
+ `id_product`, `id_shop`, `id_currency`,
+ `id_country`, `id_group`, `priority`,
+ `price`, `from_quantity`, `reduction`,
+ `reduction_type`, `from`, `to`
+) (
+ SELECT
+ p.`id_product`,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0.00,
+ 1,
+ IF(
+ p.`reduction_price` > 0, p.`reduction_price`,
+ p.`reduction_percent` / 100
+ ),
+ IF(
+ p.`reduction_price` > 0, 'amount',
+ 'percentage'
+ ),
+ IF (
+ p.`reduction_from` = p.`reduction_to`,
+ '0000-00-00 00:00:00', p.`reduction_from`
+ ),
+ IF (
+ p.`reduction_from` = p.`reduction_to`,
+ '0000-00-00 00:00:00', p.`reduction_to`
+ )
+ FROM
+ `PREFIX_product` p
+ WHERE
+ p.`reduction_price`
+ OR p.`reduction_percent`
+)
+----------SEPARATOR----------
+ALTER TABLE
+ `PREFIX_product`
+DROP
+ `reduction_price`,
+DROP
+ `reduction_percent`,
+DROP
+ `reduction_from`,
+DROP
+ `reduction_to`
+----------SEPARATOR----------
+INSERT INTO `PREFIX_configuration` (
+ `name`, `value`, `date_add`, `date_upd`
+)
+VALUES
+ (
+ 'PS_SPECIFIC_PRICE_PRIORITIES',
+ 'id_shop;id_currency;id_country;id_group',
+ NOW(), NOW()
+ ),
+ ('PS_TAX_DISPLAY', 0, NOW(), NOW()),
+ (
+ 'PS_SMARTY_FORCE_COMPILE', 1, NOW(),
+ NOW()
+ ),
+ (
+ 'PS_DISTANCE_UNIT', 'km', NOW(), NOW()
+ ),
+ (
+ 'PS_STORES_DISPLAY_CMS', 0, NOW(),
+ NOW()
+ ),
+ (
+ 'PS_STORES_DISPLAY_FOOTER', 0, NOW(),
+ NOW()
+ ),
+ (
+ 'PS_STORES_SIMPLIFIED', 0, NOW(),
+ NOW()
+ ),
+ (
+ 'PS_STATSDATA_CUSTOMER_PAGESVIEWS',
+ 1, NOW(), NOW()
+ ),
+ (
+ 'PS_STATSDATA_PAGESVIEWS', 1, NOW(),
+ NOW()
+ ),
+ (
+ 'PS_STATSDATA_PLUGINS', 1, NOW(),
+ NOW()
+ )
+----------SEPARATOR----------
+INSERT INTO `PREFIX_configuration` (
+ `name`, `value`, `date_add`, `date_upd`
+)
+VALUES
+ (
+ 'PS_CONDITIONS_CMS_ID',
+ IFNULL(
+ (
+ SELECT
+ `id_cms`
+ FROM
+ `PREFIX_cms`
+ WHERE
+ `id_cms` = 3
+ ),
+ 0
+ ),
+ NOW(),
+ NOW()
+ )
+----------SEPARATOR----------
+CREATE TEMPORARY TABLE `PREFIX_configuration_tmp` (`value` text)
+----------SEPARATOR----------
+SET
+ @defaultOOS = (
+ SELECT
+ value
+ FROM
+ `PREFIX_configuration`
+ WHERE
+ name = 'PS_ORDER_OUT_OF_STOCK'
+ )
+----------SEPARATOR----------
+UPDATE
+ `PREFIX_product` p
+SET
+ `cache_default_attribute` = 0
+WHERE
+ `id_product` NOT IN (
+ SELECT
+ `id_product`
+ FROM
+ `PREFIX_product_attribute`
+ )
+----------SEPARATOR----------
+INSERT INTO `PREFIX_hook` (
+ `name`, `title`, `description`, `position`
+)
+VALUES
+ (
+ 'processCarrier', 'Carrier Process',
+ NULL, 0
+ )
+----------SEPARATOR----------
+INSERT INTO `PREFIX_stock_mvt_reason_lang` (
+ `id_stock_mvt_reason`, `id_lang`,
+ `name`
+)
+VALUES
+ (1, 1, 'Order'),
+ (1, 2, 'Commande'),
+ (2, 1, 'Missing Stock Movement'),
+ (
+ 2, 2, 'Mouvement de stock manquant'
+ ),
+ (3, 1, 'Restocking'),
+ (3, 2, 'Réssort')
+----------SEPARATOR----------
+INSERT INTO `PREFIX_meta_lang` (
+ `id_lang`, `id_meta`, `title`, `url_rewrite`
+)
+VALUES
+ (
+ 1,
+ (
+ SELECT
+ `id_meta`
+ FROM
+ `PREFIX_meta`
+ WHERE
+ `page` = 'authentication'
+ ),
+ 'Authentication',
+ 'authentication'
+ ),
+ (
+ 2,
+ (
+ SELECT
+ `id_meta`
+ FROM
+ `PREFIX_meta`
+ WHERE
+ `page` = 'authentication'
+ ),
+ 'Authentification',
+ 'authentification'
+ ),
+ (
+ 3,
+ (
+ SELECT
+ `id_meta`
+ FROM
+ `PREFIX_meta`
+ WHERE
+ `page` = 'authentication'
+ ),
+ 'Autenticación',
+ 'autenticacion'
+ )
+----------SEPARATOR----------
+LOCK TABLES `admin_assert` WRITE
+----------SEPARATOR----------
+UNLOCK TABLES
+----------SEPARATOR----------
+DROP
+ TABLE IF EXISTS `admin_role`
+----------SEPARATOR----------
+SELECT
+ -- This is a test
+----------SEPARATOR----------
+SELECT
+ *
+LIMIT
+ 1;
+SELECT
+ a,
+ b,
+ c,
+ d
+FROM
+ e
+LIMIT
+ 1, 2;
+SELECT
+ 1,
+ 2,
+ 3
+WHERE
+ a in (1, 2, 3, 4, 5)
+ AND b = 5;
+----------SEPARATOR----------
+SELECT
+ count - 50
+WHERE
+ a - 50 = b
+WHERE
+ 1
+ AND -50
+WHERE
+ -50 = a
+WHERE
+ a = -50
+WHERE
+ 1
+ /*test*/
+ -50
+WHERE
+ 1
+ AND -50;
+----------SEPARATOR----------
+SELECT
+ @"weird variable name";
+----------SEPARATOR----------
+SELECT
+ "no closing quote
+----------SEPARATOR----------
+SELECT
+ [sqlserver]
+FROM
+ [escap[e]]d style];
+----------SEPARATOR----------
+SELECT
+ count(*) AS all_columns,
+ `Column1`,
+ `Testing`,
+ `Testing Three`
+FROM
+ `Table1`
+WHERE
+ (Column1 = :v1)
+ AND (`Column2` = `Column3`)
+ AND (
+ `Column2` = `Column3`
+ OR Column4 >= NOW()
+ )
+GROUP BY
+ Column1
+ORDER BY
+ Column3 DESC
+LIMIT
+ :v2,
+ :v3
diff --git a/vendor/nilportugues/sql-query-formatter/tests/Tokenizer/TokenizerTest.php b/vendor/nilportugues/sql-query-formatter/tests/Tokenizer/TokenizerTest.php
new file mode 100644
index 0000000..4d6e947
--- /dev/null
+++ b/vendor/nilportugues/sql-query-formatter/tests/Tokenizer/TokenizerTest.php
@@ -0,0 +1,453 @@
+
+ * Date: 6/26/14
+ * Time: 2:19 AM.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace NilPortugues\Tests\Sql\QueryFormatter\Tokenizer;
+
+use NilPortugues\Sql\QueryFormatter\Tokenizer\Tokenizer;
+
+/**
+ * Class TokenizerTest.
+ */
+class TokenizerTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * @var Tokenizer
+ */
+ private $tokenizer;
+
+ /**
+ *
+ */
+ protected function setUp()
+ {
+ $this->tokenizer = new Tokenizer();
+ }
+
+ /**
+ *
+ */
+ protected function tearDown()
+ {
+ $this->tokenizer = null;
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeWhiteSpace()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $whiteSpacesFound = false;
+ foreach ($result as $token) {
+ if (' ' === $token[Tokenizer::TOKEN_VALUE]) {
+ $whiteSpacesFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($whiteSpacesFound);
+ }
+
+ /**
+ * Comment starting with # will be treated as tokens representing the whole comment.
+ *
+ * @test
+ */
+ public function itShouldTokenizeCommentStartingWithSymbolNumber()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $commentFound = false;
+ foreach ($result as $token) {
+ if ('# A comment' === $token[Tokenizer::TOKEN_VALUE]) {
+ $commentFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($commentFound);
+ }
+
+ /**
+ * Comment starting with -- will be treated as tokens representing the whole comment.
+ *
+ * @test
+ */
+ public function itShouldTokenizeCommentStartingWithDash()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $commentFound = false;
+ foreach ($result as $token) {
+ if ('-- This is another comment' === $token[Tokenizer::TOKEN_VALUE]) {
+ $commentFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($commentFound);
+ }
+
+ /**
+ * Comment blocks in SQL Server fashion will be treated as tokens representing the whole comment.
+ *
+ * @test
+ */
+ public function itShouldTokenizeCommentWithBlockComment()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $commentFound = false;
+ foreach ($result as $token) {
+ if ('/* This is a block comment */' === $token[Tokenizer::TOKEN_VALUE]) {
+ $commentFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($commentFound);
+ }
+
+ /**
+ * Unterminated comment block will be processed incorrectly by the tokenizer,
+ * yet we should be able to detect this error in order to handle the resulting situation.
+ *
+ * @test
+ */
+ public function itShouldTokenizeCommentWithUnterminatedBlockComment()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $commentStartFound = false;
+ foreach ($result as $token) {
+ if ('/*' === $token[Tokenizer::TOKEN_VALUE]) {
+ $commentStartFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($commentStartFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeQuoted()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $quotedFound = false;
+ foreach ($result as $token) {
+ if ('`position`' === $token[Tokenizer::TOKEN_VALUE]) {
+ $quotedFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($quotedFound);
+ }
+
+ /**
+ * SQL Server syntax for defining custom variables.
+ *
+ * @test
+ */
+ public function itShouldTokenizeUserDefinedVariableWithQuotations()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $quotedFound = false;
+ foreach ($result as $token) {
+ if ('@find' === $token[Tokenizer::TOKEN_VALUE]) {
+ $quotedFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($quotedFound);
+ }
+
+ /**
+ * This validates Microsoft SQL Server syntax for user variables.
+ *
+ * @test
+ */
+ public function itShouldTokenizeUserDefinedVariableWithAtSymbol()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $this->assertNotEmpty($result);
+ }
+
+ /**
+ * This test is an edge case.
+ *
+ * Given the provided statement, will loop forever if no condition is checking total amount
+ * of the input string processed. This will happen because the tokenizer has no matching case
+ * and string processing will not progress.
+ *
+ * @test
+ */
+ public function itShouldTokenizeUserDefinedVariableNoProgressTokenizer()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $userVariableNotFound = true;
+ foreach ($result as $token) {
+ if ('@' === $token[Tokenizer::TOKEN_VALUE]) {
+ $userVariableNotFound = false;
+ break;
+ }
+ }
+
+ $this->assertTrue($userVariableNotFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeNumeralInteger()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $numeralIntegerFound = false;
+ foreach ($result as $token) {
+ if ('1' == $token[Tokenizer::TOKEN_VALUE]) {
+ $numeralIntegerFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($numeralIntegerFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeNumeralNegativeIntegerAsPositiveInteger()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $numeralIntegerFound = false;
+ foreach ($result as $token) {
+ if ('1' == $token[Tokenizer::TOKEN_VALUE]) {
+ $numeralIntegerFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($numeralIntegerFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeNumeralFloat()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $numeralIntegerFound = false;
+ foreach ($result as $token) {
+ if ('3.14' == $token[Tokenizer::TOKEN_VALUE]) {
+ $numeralIntegerFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($numeralIntegerFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeNumeralNegativeFloatAsPositiveFloat()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $numeralIntegerFound = false;
+ foreach ($result as $token) {
+ if ('3.14' == $token[Tokenizer::TOKEN_VALUE]) {
+ $numeralIntegerFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($numeralIntegerFound);
+ }
+
+ /**
+ * Check if boundary characters are in array. Boundary characters are: ;:)(.=<>+-\/!^%|.
+ *
+ * @test
+ */
+ public function itShouldTokenizeBoundaryCharacter()
+ {
+ $sql = 'SELECT id_user, name FROM users';
+
+ $result = $this->tokenizer->tokenize($sql);
+
+ $boundaryFound = false;
+ foreach ($result as $token) {
+ if (',' === $token[Tokenizer::TOKEN_VALUE]) {
+ $boundaryFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($boundaryFound);
+ }
+
+ /**
+ * Tokenize columns should not be a problem, even if using a reserved word as a column name.
+ * Example: users.user_id
+ * Example of edge cases: users.desc, user.from.
+ *
+ * @test
+ */
+ public function itShouldTokenizeReservedWordPrecededByDotCharacter()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $reservedTokenFound = false;
+ foreach ($result as $token) {
+ if ('desc' == $token[Tokenizer::TOKEN_VALUE]) {
+ $reservedTokenFound = true;
+ break;
+ }
+ }
+
+ $this->assertTrue($reservedTokenFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeReservedTopLevel()
+ {
+ $sql = 'SELECT id_user, name FROM users';
+ $result = $this->tokenizer->tokenize($sql);
+
+ $reservedTopLevelTokenFound = false;
+
+ foreach ($result as $token) {
+ if ('FROM' === $token[Tokenizer::TOKEN_VALUE]) {
+ $reservedTopLevelTokenFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($reservedTopLevelTokenFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeReservedNewLine()
+ {
+ $sql = <<tokenizer->tokenize($sql);
+
+ $reservedNewLineTokenFound = false;
+ foreach ($result as $token) {
+ if ('OR' === $token[Tokenizer::TOKEN_VALUE]) {
+ $reservedNewLineTokenFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($reservedNewLineTokenFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeReserved()
+ {
+ $sql = << 5
+ORDER BY COUNT(order_id) DESC;
+SQL;
+ $result = $this->tokenizer->tokenize($sql);
+
+ $reservedTokenFound = false;
+ foreach ($result as $token) {
+ if ('INNER JOIN' === $token[Tokenizer::TOKEN_VALUE]) {
+ $reservedTokenFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($reservedTokenFound);
+ }
+
+ /**
+ * @test
+ */
+ public function itShouldTokenizeFunction()
+ {
+ $sql = << 5 ORDER BY COUNT(order_id) DESC;
+SQL;
+ $result = $this->tokenizer->tokenize($sql);
+
+ $functionFound = false;
+ foreach ($result as $token) {
+ if ('COUNT' === $token[Tokenizer::TOKEN_VALUE]) {
+ $functionFound = true;
+ break;
+ }
+ }
+ $this->assertTrue($functionFound);
+ }
+}