Commit 6f0fa012 authored by Taddeus Kroes's avatar Taddeus Kroes

Added 'select' shortcut function to SQL plugin.

parent 41717226
...@@ -328,6 +328,23 @@ class pQuerySql extends pQuery implements pQueryExtension { ...@@ -328,6 +328,23 @@ class pQuerySql extends pQuery implements pQueryExtension {
return mysql_real_escape_string($value, self::$link); return mysql_real_escape_string($value, self::$link);
} }
/**
* Select all records from the given table that match the constraints.
*
* @param string $table The table to select from.
* @param array $constraints Column names pointing to their values.
* @param bool $escape Whether to escape the constraint values. Defaults to TRUE.
* @returns pQuerySql The created query instance.
*/
static function select($table, $columns, $constraints=array(), $escape=true) {
return _sql('SELECT [columns] FROM `[table]` WHERE [constraints];')
->set_unescaped(array(
'columns' => self::parse_columns($columns),
'table' => $table,
'constraints' => self::parse_constraints($constraints, $escape)
));
}
/** /**
* Insert a record in the given table. * Insert a record in the given table.
* *
...@@ -351,8 +368,8 @@ class pQuerySql extends pQuery implements pQueryExtension { ...@@ -351,8 +368,8 @@ class pQuerySql extends pQuery implements pQueryExtension {
/** /**
* Delete all records from the given table that match the constraints. * Delete all records from the given table that match the constraints.
* *
* @param string $table The table to insert into. * @param string $table The table to delete from.
* @param array $constraints Column names pointing to their values * @param array $constraints Column names pointing to their values.
* @param bool $escape Whether to escape the constraint values. Defaults to TRUE. * @param bool $escape Whether to escape the constraint values. Defaults to TRUE.
* @returns pQuerySql The created query instance. * @returns pQuerySql The created query instance.
*/ */
...@@ -364,6 +381,66 @@ class pQuerySql extends pQuery implements pQueryExtension { ...@@ -364,6 +381,66 @@ class pQuerySql extends pQuery implements pQueryExtension {
)); ));
} }
/**
* Parse a list of column names.
*
* @param string|array $columns One of:
* - '*': Returns itself.
* - string: Treated as a column name or aggregate function, and
* escaped as such with backticks.
* - array:
* @returns string The parsed columns.
*/
static function parse_columns($columns) {
if( $columns == '*' )
return '*';
if( is_string($columns) )
return self::escape_column($columns);
if( !is_array($columns) )
return self::error('Unknown columns type.');
$escaped_columns = array();
foreach( $columns as $key => $value ) {
if( is_numeric($key) ) {
// Simple column name
$escaped_columns[] = self::escape_column($value);
} else {
// MySQL 'AS' construction
$escaped_columns[] = self::escape_column($key)." AS `".$value."`";
}
}
return implode(", ", $escaped_columns);
}
/**
* Escape a column name to be safely used (and in a tidy manner) in a column list.
*
* @param string $column The column name to escape.
* @returns string The escaped column.
*/
static function escape_column($column) {
if( preg_match('/^`.*?`$/', $column) ) {
// `column` -> `column`
return $column;
} elseif( preg_match('/^(\w+)\.(\w+)$/', $column, $m) ) {
// table.column -> `table`.`column`
list($table, $column) = array_slice($m, 1);
return "`$table`.`$column`";
} elseif( preg_match('/^(\w+)\(([^)]+)\)$/', $column, $m) ) {
// function(name) -> FUNCTION(`name`)
// function(`name`) -> FUNCTION(`name`)
list($aggregate_function, $column) = array_slice($m, 1);
return strtoupper($aggregate_function)."(".self::escape_column($column).")";
}
// column -> `column`
return "`$column`";
}
/** /**
* Parse a list of constraints. * Parse a list of constraints.
* *
......
...@@ -83,6 +83,41 @@ class pQuerySqlTest extends UnitTestCase { ...@@ -83,6 +83,41 @@ class pQuerySqlTest extends UnitTestCase {
$this->assertEqual($sql->num_rows(), 2); $this->assertEqual($sql->num_rows(), 2);
} }
function test_escape_column_simple() {
$this->assertEqual(__sql::escape_column('foo'), '`foo`');
}
function test_escape_column_escaped() {
$this->assertEqual(__sql::escape_column('`foo`'), '`foo`');
}
function test_escape_column_table() {
$this->assertEqual(__sql::escape_column('foo.bar'), '`foo`.`bar`');
}
function test_escape_column_aggregate() {
$this->assertEqual(__sql::escape_column('count(foo)'), 'COUNT(`foo`)');
}
function test_escape_column_aggregate_escaped() {
$this->assertEqual(__sql::escape_column('count(`foo`)'), 'COUNT(`foo`)');
}
function test_parse_columns_star() {
$sql = __sql::select('foo', '*', '', false);
$this->assertEqual($sql->query, "SELECT * FROM `foo` WHERE 1;");
}
function test_parse_columns_simple() {
$sql = __sql::select('foo', array('id', 'bar'), '', false);
$this->assertEqual($sql->query, "SELECT `id`, `bar` FROM `foo` WHERE 1;");
}
function test_parse_columns_as() {
$sql = __sql::select('foo', array('id' => 'foo_id'), '', false);
$this->assertEqual($sql->query, "SELECT `id` AS `foo_id` FROM `foo` WHERE 1;");
}
function test_parse_constraints_empty() { function test_parse_constraints_empty() {
$this->assertIdentical(__sql::parse_constraints(null, false), "1"); $this->assertIdentical(__sql::parse_constraints(null, false), "1");
} }
...@@ -104,6 +139,11 @@ class pQuerySqlTest extends UnitTestCase { ...@@ -104,6 +139,11 @@ class pQuerySqlTest extends UnitTestCase {
"`id` IN ('1', '2', '3')"); "`id` IN ('1', '2', '3')");
} }
function test_select_query() {
$sql = __sql::select('foo', '*', array('bar' => 'test1'), false);
$this->assertEqual($sql->query, "SELECT * FROM `foo` WHERE `bar` = 'test1';");
}
function test_insert_query() { function test_insert_query() {
$sql = __sql::insert_row('foo', array('bar' => 'test3'), false); $sql = __sql::insert_row('foo', array('bar' => 'test3'), false);
$this->assertEqual($sql->query, "INSERT INTO `foo`(`bar`) VALUES('test3');"); $this->assertEqual($sql->query, "INSERT INTO `foo`(`bar`) VALUES('test3');");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment