1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-04 05:07:36 +02:00

- BC change: DibiResult::fetchAll() returns always multidimensional arrays (for single columns use fetchPairs() instead)

- added DibiTable::insertOrUpdate()
- new modifier %by
This commit is contained in:
David Grudl
2008-10-01 16:04:16 +00:00
parent 9b84459f09
commit 9eddba204f
9 changed files with 102 additions and 44 deletions

View File

@@ -249,6 +249,7 @@ class DibiPostgreDriver extends DibiObject implements IDibiDriver
}
case dibi::IDENTIFIER:
// @see http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
$a = strrpos($value, '.');
if ($a === FALSE) {
return '"' . str_replace('"', '""', $value) . '"';

View File

@@ -92,7 +92,7 @@ class DibiConnection extends DibiObject
$driver = preg_replace('#[^a-z0-9_]#', '_', $config['driver']);
$class = "Dibi" . $driver . "Driver";
if (!class_exists($class, FALSE)) {
include_once __FILE__ . "/../../drivers/$driver.php";
include_once dirname(__FILE__) . "/../drivers/$driver.php";
if (!class_exists($class, FALSE)) {
throw new DibiException("Unable to create instance of dibi driver class '$class'.");

View File

@@ -259,12 +259,11 @@ class DibiFluent extends DibiObject
* Fetches all records from table.
* @param int offset
* @param int limit
* @param bool simplify one-column result set?
* @return array
*/
public function fetchAll($offset = NULL, $limit = NULL, $simplify = TRUE)
public function fetchAll($offset = NULL, $limit = NULL)
{
return $this->execute()->fetchAll($offset, $limit, $simplify);
return $this->execute()->fetchAll($offset, $limit);
}

View File

@@ -312,10 +312,9 @@ class DibiResult extends DibiObject implements IDataSource
*
* @param int offset
* @param int limit
* @param bool simplify one-column result set?
* @return array
*/
final public function fetchAll($offset = NULL, $limit = NULL, $simplify = TRUE)
final public function fetchAll($offset = NULL, $limit = NULL)
{
$limit = $limit === NULL ? -1 : (int) $limit;
$this->seek((int) $offset);
@@ -323,22 +322,11 @@ class DibiResult extends DibiObject implements IDataSource
if (!$row) return array(); // empty result set
$data = array();
if ($simplify && !$this->objects && count($row) === 1) {
// special case: one-column result set
$key = key($row);
do {
if ($limit === 0) break;
$limit--;
$data[] = $row[$key];
} while ($row = $this->fetch());
} else {
do {
if ($limit === 0) break;
$limit--;
$data[] = $row;
} while ($row = $this->fetch());
}
do {
if ($limit === 0) break;
$limit--;
$data[] = $row;
} while ($row = $this->fetch());
return $data;
}
@@ -456,13 +444,16 @@ class DibiResult extends DibiObject implements IDataSource
throw new InvalidArgumentException("Either none or both columns must be specified.");
}
if (count($row) < 2) {
throw new UnexpectedValueException("Result must have at least two columns.");
}
// autodetect
$tmp = array_keys($row);
$key = $tmp[0];
if (count($row) < 2) { // indexed-array
do {
$data[] = $row[$key];
} while ($row = $this->fetch(FALSE));
return $data;
}
$value = $tmp[1];
} else {
@@ -633,7 +624,7 @@ class DibiResult extends DibiObject implements IDataSource
*/
final public function getIterator($offset = NULL, $limit = NULL)
{
return new ArrayIterator($this->fetchAll($offset, $limit, FALSE));
return new ArrayIterator($this->fetchAll($offset, $limit));
}

View File

@@ -162,9 +162,15 @@ abstract class DibiTable extends DibiObject
*/
public function update($where, $data)
{
$data = $this->prepare($data);
if ($where === NULL && isset($data[$this->primary])) {;
$where = $data[$this->primary];
unset($data[$this->primary]);
}
$this->connection->query(
'UPDATE %n', $this->name,
'SET %a', $this->prepare($data),
'SET %a', $data,
'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $where, ')'
);
return $this->connection->affectedRows();
@@ -172,6 +178,36 @@ abstract class DibiTable extends DibiObject
/**
* Inserts or updates rows in a table.
* @param array|object
* @return int (new) primary key
*/
public function insertOrUpdate($data)
{
$data = $this->prepare($data);
if (!isset($data[$this->primary])) {
throw new InvalidArgumentException("Missing primary key '$this->primary' in dataset.");
}
try {
$this->connection->query(
'INSERT INTO %n', $this->name, '%v', $data
);
} catch (DibiDriverException $e) {
$where = $data[$this->primary];
unset($data[$this->primary]);
$this->connection->query(
'UPDATE %n', $this->name,
'SET %a', $data,
'WHERE %n', $this->primary, 'IN (' . $this->primaryModifier, $where, ')'
);
}
}
/**
* Deletes rows from a table by primary key.
* @param mixed primary key value(s)

View File

@@ -198,11 +198,11 @@ final class DibiTranslator extends DibiObject
if (is_array($value)) {
$vx = $kx = array();
$separator = ', ';
$operator = ', ';
switch ($modifier) {
case 'and':
case 'or': // key=val AND key IS NULL AND ...
$separator = ' ' . strtoupper($modifier) . ' ';
$operator = ' ' . strtoupper($modifier) . ' ';
if (empty($value)) {
return '1';
@@ -215,21 +215,12 @@ final class DibiTranslator extends DibiObject
foreach ($value as $k => $v) {
$pair = explode('%', $k, 2); // split into identifier & modifier
$k = $this->delimite($pair[0]);
if (isset($pair[1])) {
$pair = explode(' ', $pair[1], 2); // split into modifier & operator
$op = isset($pair[1]) ? $pair[1] : '=';
$v = $this->formatValue($v, $pair[0]);
} else {
$op = '=';
$v = $this->formatValue($v, FALSE);
}
if ($v === 'NULL') {
$op = 'IS';
}
$v = $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
$op = isset($pair[1]) && $pair[1] === 'l' ? 'IN' : ($v === 'NULL' ? 'IS' : '=');
$vx[] = $k . ' ' . $op . ' ' . $v;
}
}
return implode($separator, $vx);
return implode($operator, $vx);
case 'a': // key=val, key=val, ...
foreach ($value as $k => $v) {
@@ -237,7 +228,7 @@ final class DibiTranslator extends DibiObject
$vx[] = $this->delimite($pair[0]) . '='
. $this->formatValue($v, isset($pair[1]) ? $pair[1] : FALSE);
}
return implode($separator, $vx);
return implode($operator, $vx);
case 'l': // (val, val, ...)
@@ -256,6 +247,13 @@ final class DibiTranslator extends DibiObject
}
return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
case 'by': // key ASC, key DESC
foreach ($value as $k => $v) {
$v = (is_string($v) && strcasecmp($v, 'desc')) || $v > 0 ? 'ASC' : 'DESC';
$vx[] = $this->delimite($k) . ' ' . $v;
}
return implode(', ', $vx);
default: // value, value, value - all with the same modifier
foreach ($value as $v) {
$vx[] = $this->formatValue($v, $modifier);

View File

@@ -31,7 +31,7 @@ class Products extends DibiTable
// create table object
$products = new Products();
$products = new Products;
echo "Table name: $products->name\n";
echo "Primary key: $products->primary\n";
@@ -83,6 +83,13 @@ $id = $products->insert($data);
var_dump($id); // generated id
// inserts or updates row into a table
$data = array();
$data['title'] = 'New product';
$data[$products->primary] = 5;
$products->insertOrUpdate($data);
// is absolutely SQL injection safe
$key = '3 OR 1=1';
$products->delete($key);

View File

@@ -64,3 +64,15 @@ SELECT *
FROM [people]
WHERE [id] IN (", $array, ")
");
// ORDER BY array
$order = array(
'field1' => 'asc',
'field2' => 'desc',
);
dibi::test("
SELECT *
FROM [people]
ORDER BY %by", $order, "
");

View File

@@ -1,2 +1,16 @@
<style>
h1 {
font-family: Trebuchet MS,"Geneva CE", lucida, sans-serif;
color: #1e5eb6;
}
img {
border: none;
}
</style>
<h1>Icon for your website</h1>
<a href="http://dibiphp.com" title="dibi - tiny 'n' smart database abstraction layer"
><img src="dibi-powered.gif" width="80" height="15" alt="dibi powered" /></a>