Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3.x quoter #132

Merged
merged 5 commits into from
Mar 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/AbstractQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
namespace Aura\SqlQuery;

use Aura\SqlQuery\Common\SubselectInterface;
use Aura\SqlQuery\Common\QuoterInterface;

/**
*
Expand Down Expand Up @@ -84,7 +85,7 @@ abstract class AbstractQuery
* placeholders (@see getSeqPlaceholder()).
*
*/
public function __construct(Quoter $quoter, $builder, $seq_bind_prefix = '')
public function __construct(QuoterInterface $quoter, $builder, $seq_bind_prefix = '')
{
$this->quoter = $quoter;
$this->builder = $builder;
Expand Down
21 changes: 2 additions & 19 deletions src/Quoter.php → src/Common/Quoter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* @license http://opensource.org/licenses/bsd-license.php BSD
*
*/
namespace Aura\SqlQuery;
namespace Aura\SqlQuery\Common;

/**
*
Expand All @@ -15,7 +15,7 @@
* @package Aura.SqlQuery
*
*/
class Quoter
class Quoter implements QuoterInterface
{
/**
*
Expand All @@ -35,23 +35,6 @@ class Quoter
*/
protected $quote_name_suffix = '"';

/**
*
* Constructor.
*
* @param string $quote_name_prefix The prefix to use when quoting
* identifier names.
*
* @param string $quote_name_suffix The suffix to use when quoting
* identifier names.
*
*/
public function __construct($quote_name_prefix, $quote_name_suffix)
{
$this->quote_name_prefix = $quote_name_prefix;
$this->quote_name_suffix = $quote_name_suffix;
}

/**
*
* Returns the prefix to use when quoting identifier names.
Expand Down
76 changes: 76 additions & 0 deletions src/Common/QuoterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
/**
*
* This file is part of Aura for PHP.
*
* @license http://opensource.org/licenses/bsd-license.php BSD
*
*/
namespace Aura\SqlQuery\Common;

/**
*
* A quoting mechanism for identifier names (not values).
*
* @package Aura.SqlQuery
*
*/
interface QuoterInterface
{
/**
*
* Returns the prefix to use when quoting identifier names.
*
* @return string
*
*/
public function getQuoteNamePrefix();

/**
*
* Returns the suffix to use when quoting identifier names.
*
* @return string
*
*/
public function getQuoteNameSuffix();

/**
*
* Quotes a single identifier name (table, table alias, table column,
* index, sequence).
*
* If the name contains `' AS '`, this method will separately quote the
* parts before and after the `' AS '`.
*
* If the name contains a space, this method will separately quote the
* parts before and after the space.
*
* If the name contains a dot, this method will separately quote the
* parts before and after the dot.
*
* @param string $spec The identifier name to quote.
*
* @return string The quoted identifier name.
*
*/
public function quoteName($spec);

/**
*
* Quotes all fully-qualified identifier names ("table.col") in a string,
* typically an SQL snippet for a SELECT clause.
*
* Does not quote identifier names that are string literals (i.e., inside
* single or double quotes).
*
* Looks for a trailing ' AS alias' and quotes the alias as well.
*
* @param string $text The string in which to quote fully-qualified
* identifier names to quote.
*
* @return string|array The string with names quoted in it.
*
*/
public function quoteNamesIn($text);
}
25 changes: 25 additions & 0 deletions src/Mysql/Quoter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
namespace Aura\SqlQuery\Mysql;

use Aura\SqlQuery\Common;

class Quoter extends Common\Quoter
{
/**
*
* The prefix to use when quoting identifier names.
*
* @var string
*
*/
protected $quote_name_prefix = '`';

/**
*
* The suffix to use when quoting identifier names.
*
* @var string
*
*/
protected $quote_name_suffix = '`';
}
69 changes: 23 additions & 46 deletions src/QueryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,6 @@ class QueryFactory
*/
protected $common = false;

/**
*
* The quote prefix/suffix to use for each type.
*
* @param array
*
*/
protected $quotes = array(
'Common' => array('"', '"'),
'Mysql' => array('`', '`'),
'Pgsql' => array('"', '"'),
'Sqlite' => array('"', '"'),
'Sqlsrv' => array('[', ']'),
);

/**
*
* The quote name prefix extracted from `$quotes`.
*
* @var string
*
*/
protected $quote_name_prefix;

/**
*
* The quote name suffix extracted from `$quotes`.
*
* @var string
*
*/
protected $quote_name_suffix;

/**
*
* A map of `table.col` names to last-insert-id names.
Expand All @@ -83,7 +50,7 @@ class QueryFactory
*
* A Quoter for identifiers.
*
* @param Quoter
* @param QuoterInterface
*
*/
protected $quoter;
Expand All @@ -107,14 +74,10 @@ class QueryFactory
* query objects instead of db-specific ones.
*
*/
public function __construct(
$db,
$common = null
) {
public function __construct($db, $common = null)
{
$this->db = ucfirst(strtolower($db));
$this->common = ($common === self::COMMON);
$this->quote_name_prefix = $this->quotes[$this->db][0];
$this->quote_name_suffix = $this->quotes[$this->db][1];
}

/**
Expand Down Expand Up @@ -205,11 +168,20 @@ protected function newInstance($query)

return new $queryClass(
$this->getQuoter(),
new $builderClass(),
$this->newBuilder($query),
$this->newSeqBindPrefix()
);
}

protected function newBuilder($query)
{
$builderClass = "Aura\SqlQuery\\{$this->db}\\{$query}Builder";
if ($this->common || ! class_exists($builderClass)) {
$builderClass = "Aura\SqlQuery\Common\\{$query}Builder";
}
return new $builderClass();
}

/**
*
* Returns the Quoter object for queries; creates one if needed.
Expand All @@ -220,15 +192,20 @@ protected function newInstance($query)
protected function getQuoter()
{
if (! $this->quoter) {
$this->quoter = new Quoter(
$this->quote_name_prefix,
$this->quote_name_suffix
);
$this->quoter = $this->newQuoter();
}

return $this->quoter;
}

protected function newQuoter()
{
$quoterClass = "Aura\SqlQuery\\{$this->db}\Quoter";
if ($this->common || ! class_exists($quoterClass)) {
$quoterClass = "Aura\SqlQuery\Common\Quoter";
}
return new $quoterClass();
}

/**
*
* Returns a new sequential-placeholder prefix for a query object.
Expand Down
25 changes: 25 additions & 0 deletions src/Sqlsrv/Quoter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
namespace Aura\SqlQuery\Sqlsrv;

use Aura\SqlQuery\Common;

class Quoter extends Common\Quoter
{
/**
*
* The prefix to use when quoting identifier names.
*
* @var string
*
*/
protected $quote_name_prefix = '[';

/**
*
* The suffix to use when quoting identifier names.
*
* @var string
*
*/
protected $quote_name_suffix = ']';
}
17 changes: 8 additions & 9 deletions tests/QuoterTest.php → tests/Common/QuoterTest.php
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
<?php
namespace Aura\SqlQuery;
namespace Aura\SqlQuery\Common;

class QuoterTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
// use double-quotes for identifier quoting
$this->quoter = new Quoter('`', '`');
$this->quoter = new Quoter();
}

public function testQuoteName()
{
// table AS alias
$actual = $this->quoter->quoteName('table AS alias');
$this->assertSame('`table` AS `alias`', $actual);
$this->assertSame('"table" AS "alias"', $actual);

// table.col AS alias
$actual = $this->quoter->quoteName('table.col AS alias');
$this->assertSame('`table`.`col` AS `alias`', $actual);
$this->assertSame('"table"."col" AS "alias"', $actual);

// table alias
$actual = $this->quoter->quoteName('table alias');
$this->assertSame('`table` `alias`', $actual);
$this->assertSame('"table" "alias"', $actual);

// table.col alias
$actual = $this->quoter->quoteName('table.col alias');
$this->assertSame('`table`.`col` `alias`', $actual);
$this->assertSame('"table"."col" "alias"', $actual);

// plain old identifier
$actual = $this->quoter->quoteName('table');
$this->assertSame('`table`', $actual);
$this->assertSame('"table"', $actual);

// star
$actual = $this->quoter->quoteName('*');
Expand All @@ -44,7 +43,7 @@ public function testQuoteNamesIn()
{
$sql = "*, *.*, f.bar, foo.bar, CONCAT('foo.bar', \"baz.dib\") AS zim";
$actual = $this->quoter->quoteNamesIn($sql);
$expect = "*, *.*, `f`.`bar`, `foo`.`bar`, CONCAT('foo.bar', \"baz.dib\") AS `zim`";
$expect = "*, *.*, \"f\".\"bar\", \"foo\".\"bar\", CONCAT('foo.bar', \"baz.dib\") AS \"zim\"";
$this->assertSame($expect, $actual);
}
}