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

substitutes moved from DibiDriver to Dibi

changed "comments" behavior in DibiParser
This commit is contained in:
David Grudl
2006-09-23 06:34:44 +00:00
parent da70be27a8
commit da608c2db2
14 changed files with 113 additions and 201 deletions

File diff suppressed because one or more lines are too long

View File

@@ -96,12 +96,6 @@ class dibi
*/ */
static private $conn; static private $conn;
/**
* Arguments -> SQL parser
* @var object DibiParser
*/
static private $parser;
/** /**
* Last SQL command @see dibi::query() * Last SQL command @see dibi::query()
* @var string * @var string
@@ -123,6 +117,12 @@ class dibi
static public $debug = false; static public $debug = false;
/**
* Substitutions for identifiers
* @var array
*/
static private $substs = array();
/** /**
@@ -132,11 +132,8 @@ class dibi
* @param string connection name * @param string connection name
* @return bool|object TRUE on success, FALSE or Exception on failure * @return bool|object TRUE on success, FALSE or Exception on failure
*/ */
static public function connect($config, $name = 'def') static public function connect($config, $name = '1')
{ {
// init parser
if (!self::$parser) self::$parser = new DibiParser();
// DSN string // DSN string
if (is_string($config)) if (is_string($config))
parse_str($config, $config); parse_str($config, $config);
@@ -201,21 +198,15 @@ class dibi
/** /**
* Retrieve active connection * Retrieve active connection
* *
* @param string connection registy name or NULL for active connection
* @return object DibiDriver object. * @return object DibiDriver object.
*/ */
static public function getConnection($name = NULL) static public function getConnection()
{ {
if (NULL === $name)
return self::$conn; return self::$conn;
if (isset(self::$registry[$name]))
return self::$registry[$name];
return FALSE;
} }
/** /**
* Change active connection * Change active connection
* *
@@ -252,7 +243,8 @@ class dibi
$args = func_get_args(); $args = func_get_args();
// and generate SQL // and generate SQL
self::$sql = self::$parser->parse(self::$conn, $args); $parser = new DibiParser(self::$conn, self::$substs);
self::$sql = $parser->parse($args);
if (is_error(self::$sql)) return self::$sql; // reraise the exception if (is_error(self::$sql)) return self::$sql; // reraise the exception
// execute SQL // execute SQL
@@ -314,7 +306,8 @@ class dibi
$args = func_get_args(); $args = func_get_args();
// and generate SQL // and generate SQL
$sql = self::$parser->parse(self::$conn, $args); $parser = new DibiParser(self::$conn, self::$substs);
$sql = $parser->parse($args);
$dump = TRUE; // !!! $dump = TRUE; // !!!
if ($dump) { if ($dump) {
if (is_error($sql)) if (is_error($sql))
@@ -350,18 +343,6 @@ class dibi
} }
/**
* Monostate for DibiDriver::addSubst()
* @param string
* @param string
* @return void
*/
static public function addSubst($expr, $subst)
{
return self::$conn ? self::$conn->addSubst($expr, $subst) : FALSE;
}
static private function dumpHighlight($matches) static private function dumpHighlight($matches)
{ {
@@ -398,7 +379,7 @@ class dibi
$sql = wordwrap($sql, 100); $sql = wordwrap($sql, 100);
$sql = htmlSpecialChars($sql); $sql = htmlSpecialChars($sql);
$sql = strtr($sql, array("\n" => '<br />')); $sql = str_replace("\n", '<br />', $sql);
// syntax highlight // syntax highlight
$sql = preg_replace_callback("#(/\*.+?\*/)|(\*\*.+?\*\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#", array('dibi', 'dumpHighlight'), $sql); $sql = preg_replace_callback("#(/\*.+?\*/)|(\*\*.+?\*\*)|\\b($keywords1)\\b|\\b($keywords2)\\b#", array('dibi', 'dumpHighlight'), $sql);
@@ -438,10 +419,29 @@ class dibi
/**
* Create a new substitution pair for indentifiers
* @param string from
* @param string to
* @return void
*/
static public function addSubst($expr, $subst)
{
self::$substs[':'.$expr.':'] = $subst;
}
/**
* Remove substitution pair
* @param string from
* @return void
*/
static public function removeSubst($expr)
{
unset(self::$substs[':'.$expr.':']);
}
} // class dibi } // class dibi
?>

View File

@@ -166,7 +166,7 @@ class DibiMySqlDriver extends DibiDriver {
public function quoteName($value) public function quoteName($value)
{ {
return '`' . strtr( $this->applySubsts($value), array('.' => '`.`')) . '`'; return '`' . str_replace('.', '`.`', $value) . '`';
} }
@@ -334,9 +334,3 @@ class DibiMySqlResult extends DibiResult
} // class DibiMySqlResult } // class DibiMySqlResult
?>

View File

@@ -146,7 +146,7 @@ class DibiMySqliDriver extends DibiDriver {
public function quoteName($value) public function quoteName($value)
{ {
return '`' . strtr( $this->applySubsts($value), array('.' => '`.`')) . '`'; return '`' . str_replace('.', '`.`', $value) . '`';
} }
@@ -284,9 +284,3 @@ class DibiMySqliResult extends DibiResult
} // class DibiMySqliResult } // class DibiMySqliResult
?>

View File

@@ -144,7 +144,7 @@ class DibiOdbcDriver extends DibiDriver {
public function quoteName($value) public function quoteName($value)
{ {
return '[' . strtr( $this->applySubsts($value), array('.' => '].[')) . ']'; return '[' . str_replace('.', '].[', $value) . ']';
} }
@@ -279,6 +279,3 @@ class DibiOdbcResult extends DibiResult
} // class DibiOdbcResult } // class DibiOdbcResult
?>

View File

@@ -136,7 +136,7 @@ class DibiPostgreDriver extends DibiDriver {
public function quoteName($value) public function quoteName($value)
{ {
return $this->applySubsts($value); return $value;
} }
@@ -260,9 +260,3 @@ class DibiPostgreResult extends DibiResult
} // class DibiPostgreResult } // class DibiPostgreResult
?>

View File

@@ -136,7 +136,7 @@ class DibiSqliteDriver extends DibiDriver {
public function quoteName($value) public function quoteName($value)
{ {
return $this->applySubsts($value); return $value;
} }
@@ -236,9 +236,3 @@ class DibiSqliteResult extends DibiResult
} // class DibiSqliteResult } // class DibiSqliteResult
?>

View File

@@ -34,13 +34,6 @@ abstract class DibiDriver
protected protected
$config; $config;
/**
* Substitutions for identifiers
* @var array
*/
protected
$substs = array();
/** /**
* Describes how convert some datatypes to SQL command * Describes how convert some datatypes to SQL command
* @var array * @var array
@@ -159,52 +152,4 @@ abstract class DibiDriver
/**
* Create a new substitution pair for indentifiers
* @param string from
* @param string to
* @return void
*/
public function addSubst($expr, $subst)
{
$this->substs[':'.$expr.':'] = $subst;
}
/**
* Remove substitution pair
* @param string from
* @return void
*/
public function removeSubst($expr)
{
unset($this->substs[':'.$expr.':']);
}
/**
* Apply substitutions to indentifier
* @param string indentifier
* @return string
*/
protected function applySubsts($value)
{
// apply substitutions
if ($this->substs && (strpos($value, ':') !== FALSE))
return strtr($value, $this->substs);
return $value;
}
} // class DibiDriver } // class DibiDriver
?>

View File

@@ -65,6 +65,3 @@ function is_error($var)
{ {
return ($var === FALSE) || ($var instanceof Exception); return ($var === FALSE) || ($var instanceof Exception);
} }
?>

View File

@@ -28,22 +28,30 @@ if (!defined('DIBI')) die();
class DibiParser class DibiParser
{ {
private private
$driver,
$subK, $subV,
$modifier, $modifier,
$hasError, $hasError,
$driver,
$ifLevel, $ifLevel,
$ifLevelStart; $ifLevelStart;
public function __construct($driver, $subst)
{
$this->driver = $driver;
$this->subK = array_keys($subst);
$this->subV = array_values($subst);
}
/** /**
* Generates SQL * Generates SQL
* *
* @param array * @param array
* @return string * @return string
*/ */
public function parse($driver, $args) public function parse($args)
{ {
$this->driver = $driver;
$this->hasError = FALSE; $this->hasError = FALSE;
$command = null; $command = null;
$mod = & $this->modifier; // shortcut $mod = & $this->modifier; // shortcut
@@ -72,7 +80,7 @@ class DibiParser
} }
// simple string means SQL // simple string means SQL
if (is_string($arg) && (!$mod || 'p'==$mod)) { if (is_string($arg) && (!$mod || 'p' == $mod)) {
$mod = FALSE; $mod = FALSE;
// will generate new mod // will generate new mod
$sql[] = $this->formatValue($arg, 'p'); $sql[] = $this->formatValue($arg, 'p');
@@ -88,9 +96,7 @@ class DibiParser
} }
// default processing // default processing
$sql[] = $comment if (!$comment) $sql[] = $this->formatValue($arg, $mod);
? '...'
: $this->formatValue($arg, $mod);
$mod = FALSE; $mod = FALSE;
} // foreach } // foreach
@@ -98,6 +104,9 @@ class DibiParser
$sql = implode(' ', $sql); $sql = implode(' ', $sql);
// remove comments
$sql = preg_replace('#\/\*.*?\*\/#s', '', $sql);
if ($this->hasError) if ($this->hasError)
return new DibiException('Errors during generating SQL', array('sql' => $sql)); return new DibiException('Errors during generating SQL', array('sql' => $sql));
@@ -131,7 +140,7 @@ class DibiParser
} else $mod = FALSE; } else $mod = FALSE;
// generate array // generate array
$vx[] = $this->driver->quoteName($pair[0]) . '=' . $this->formatValue($v, $mod); $vx[] = $this->quoteName($pair[0]) . '=' . $this->formatValue($v, $mod);
} }
return implode(', ', $vx); return implode(', ', $vx);
@@ -151,7 +160,7 @@ class DibiParser
} else $mod = FALSE; } else $mod = FALSE;
// generate arrays // generate arrays
$kx[] = $this->driver->quoteName($pair[0]); $kx[] = $this->quoteName($pair[0]);
$vx[] = $this->formatValue($v, $mod); $vx[] = $this->formatValue($v, $mod);
} }
return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')'; return '(' . implode(', ', $kx) . ') VALUES (' . implode(', ', $vx) . ')';
@@ -197,7 +206,7 @@ class DibiParser
? strtotime($value) ? strtotime($value)
: $value); : $value);
case 'n': // identifier name case 'n': // identifier name
return $this->driver->quoteName($value); return $this->quoteName($value);
case 'p': // preserve as SQL case 'p': // preserve as SQL
$value = (string) $value; $value = (string) $value;
@@ -209,6 +218,7 @@ class DibiParser
// note: only this can change $this->modifier // note: only this can change $this->modifier
return substr($value, 0, $toSkip) return substr($value, 0, $toSkip)
/*
. preg_replace_callback('/ . preg_replace_callback('/
(?=`|\[|\'|"|%) ## speed-up (?=`|\[|\'|"|%) ## speed-up
(?: (?:
@@ -220,7 +230,9 @@ class DibiParser
%([a-zA-Z]{1,2})$| ## 8) right modifier %([a-zA-Z]{1,2})$| ## 8) right modifier
(\'|") ## 9) lone-quote (\'|") ## 9) lone-quote
)/xs', )/xs',
array($this, 'callback'), */
. preg_replace_callback('/(?=`|\[|\'|"|%)(?:`(.+?)`|\[(.+?)\]|(\')((?:\'\'|[^\'])*)\'|(")((?:""|[^"])*)"|%(else|end)|%([a-zA-Z]{1,2})$|(\'|"))/s',
array($this, 'cb'),
substr($value, $toSkip) substr($value, $toSkip)
); );
@@ -264,11 +276,11 @@ class DibiParser
/** /**
* PREG callback for @see self::translate() * PREG callback for @see self::formatValue()
* @param array * @param array
* @return string * @return string
*/ */
private function callback($matches) private function cb($matches)
{ {
// [1] => `ident` // [1] => `ident`
// [2] => [ident] // [2] => [ident]
@@ -280,26 +292,10 @@ class DibiParser
// [8] => right modifier // [8] => right modifier
// [9] => lone-quote // [9] => lone-quote
if ($matches[1]) // SQL identifiers: `ident` if (!empty($matches[7])) { // %end | %else
return $this->driver->quoteName($matches[1]);
if ($matches[2]) // SQL identifiers: [ident]
return $this->driver->quoteName($matches[2]);
if ($matches[3]) // SQL strings: '....'
return $this->comment
? '...'
: $this->driver->escape( strtr($matches[4], array("''" => "'")), TRUE);
if ($matches[5]) // SQL strings: "..."
return $this->comment
? '...'
: $this->driver->escape( strtr($matches[6], array('""' => '"')), TRUE);
if ($matches[7]) { // %end | %else
if (!$this->ifLevel) { if (!$this->ifLevel) {
$this->hasError = TRUE; $this->hasError = TRUE;
return "**Unexpected condition $matches[8]**"; return "**Unexpected condition $matches[7]**";
} }
if ('end' == $matches[7]) { if ('end' == $matches[7]) {
@@ -325,11 +321,26 @@ class DibiParser
} }
} }
if ($matches[8]) { // modifier if (!empty($matches[8])) { // modifier
$this->modifier = $matches[8]; $this->modifier = $matches[8];
return ''; return '';
} }
if ($this->comment) return '';
if ($matches[1]) // SQL identifiers: `ident`
return $this->quoteName($matches[1]);
if ($matches[2]) // SQL identifiers: [ident]
return $this->quoteName($matches[2]);
if ($matches[3]) // SQL strings: '....'
return $this->driver->escape( str_replace("''", "'", $matches[4]), TRUE);
if ($matches[5]) // SQL strings: "..."
return $this->driver->escape( str_replace('""', '"', $matches[6]), TRUE);
if ($matches[9]) { // string quote if ($matches[9]) { // string quote
$this->hasError = TRUE; $this->hasError = TRUE;
@@ -341,14 +352,21 @@ class DibiParser
/**
* Apply substitutions to indentifier and quotes it
* @param string indentifier
* @return string
*/
private function quoteName($value)
{
// apply substitutions
if ($this->subK && (strpos($value, ':') !== FALSE))
return str_replace($this->subK, $this->subV, $value);
return $this->driver->quoteName($value);
}
} // class DibiParser } // class DibiParser
?>

View File

@@ -373,7 +373,3 @@ class DibiResultIterator implements Iterator
} // class DibiResultIterator } // class DibiResultIterator
?>

View File

@@ -9,7 +9,7 @@ require_once '../dibi/dibi.php';
// mysql // mysql
dibi::connect(array( dibi::connect(array(
'driver' => 'mysqli', 'driver' => 'mysql',
'host' => 'localhost', 'host' => 'localhost',
'username' => 'root', 'username' => 'root',
'password' => 'xxx', // change to real password! 'password' => 'xxx', // change to real password!

View File

@@ -9,7 +9,7 @@ require_once '../dibi/dibi.php';
// mysql // mysql
dibi::connect(array( dibi::connect(array(
'driver' => 'mysqli', 'driver' => 'mysql',
'host' => 'localhost', 'host' => 'localhost',
'username' => 'root', 'username' => 'root',
'password' => 'xxx', // change to real password! 'password' => 'xxx', // change to real password!

View File

@@ -5,7 +5,7 @@ require_once '../dibi/dibi.php';
// connects to mysqli // connects to mysqli
dibi::connect(array( dibi::connect(array(
'driver' => 'mysqli', 'driver' => 'mysql',
'host' => 'localhost', 'host' => 'localhost',
'username' => 'root', 'username' => 'root',
'password' => 'xxx', // change to real password! 'password' => 'xxx', // change to real password!
@@ -14,7 +14,7 @@ dibi::connect(array(
// create new substitution :blog: ==> wp_items_ // create new substitution :blog: ==> wp_items_
dibi::addSubst('blog', 'wp_items_'); dibi::addSubst('blog', 'wp_');
// generate and dump SQL // generate and dump SQL