'realName') * @var array(string=>string) */ private $aliases = null; /** * Counter used to create unique ids in the bind methods. * * @var int */ private $boundCounter = 0; /** * Stores the list of parameters that will be bound with doBind(). * * Format: array( ':name' => &mixed ) * @var array(string=>&mixed) */ private $boundParameters = array(); /** * Stores the list of values that will be bound with doBind(). * * Format: array( ':name' => mixed ) * @var array(string=>mixed) */ private $boundValues = array(); /** * The expression object for this class. * * @var ezcQueryExpression */ public $expr = null; /** * Constructs a new ezcQuery that works on the database $db and with the aliases $aliases. * * The aliases can be used to substitute the column and table names with more * friendly names. E.g PersistentObject uses it to allow using property and class * names instead of column and table names. * * @param PDO $db * @param array(string=>string) $aliases */ public function __construct( PDO $db, array $aliases = array() ) { $this->db = $db; if ( $this->expr == null ) { $this->expr = $db->createExpression(); } if ( !empty( $aliases ) ) { $this->aliases = $aliases; $this->expr->setAliases( $this->aliases ); } } /** * Sets the aliases $aliases for this object. * * The aliases should be in the form array( "aliasName" => "databaseName" ). Table and * column aliases can be mixed in the array. * * The aliases can be used to substitute the column and table names with more * friendly names. The substitution is done when the query is built, not using * AS statements in the database itself. * * Example of a select query with aliases: * * $q->setAliases( array( 'Identifier' => 'id', 'Company' => 'company' ) ); * $this->q->select( 'Company' )->from( 'table' )->where( $q->expr->eq( 'Identifier', 5 ) ); * echo $q->getQuery(); * * * This example will output SQL similar to: * * SELECT company FROM table WHERE id = 5 * * * @param array(string=>string) $aliases * @return void */ public function setAliases( array $aliases ) { $this->aliases = $aliases; $this->expr->setAliases( $aliases ); } /** * Returns true if this object has aliases. * * @return bool */ public function hasAliases() { return $this->aliases !== null ? true : false; } /** * Returns the correct identifier for the alias $alias. * * If the alias does not exists in the list of aliases * it is returned unchanged. * * @return string */ protected function getIdentifier( $alias ) { $aliasParts = explode( '.', $alias ); $identifiers = array(); foreach ( $aliasParts as $singleAliasName ) { if ( $this->aliases !== null && array_key_exists( $singleAliasName, $this->aliases ) ) { $identifiers[]= $this->aliases[$singleAliasName]; } else { $identifiers[]= $singleAliasName; } } $alias = join( '.', $identifiers ); return $alias; } /** * Returns the correct identifiers for the aliases found in $aliases. * * This method is similar to getIdentifier except that it works on an array. * * @param array(string) $alias * @returns array(string) */ protected function getIdentifiers( array $aliasList ) { if ( $this->aliases !== null ) { foreach ( $aliasList as $key => $alias ) { $aliasList[$key] = $this->getIdentifier( $alias ); } } return $aliasList; } /** * Binds the value $value to the specified variable name $placeHolder. * * This method provides a shortcut for PDOStatement::bindValue * when using prepared statements. * * The parameter $value specifies the value that you want to bind. If * $placeholder is not provided bindValue() will automatically create a * placeholder for you. An automatic placeholder will be of the name * 'ezcValue1', 'ezcValue2' etc. * * @see http://no.php.net/manual/en/function.pdostatement-bindparam.php * @see doBind() * * Example: * * $value = 2; * $q->eq( 'id', $q->bindValue( $value ) ); * $stmt = $q->prepare(); // the value 2 is bound to the query. * $value = 4; * $stmt->execute(); // executed with 'id = 2' * * * @param mixed $value * @param string $placeHolder the name to bind with. The string must start with a colon ':'. * @return string the placeholder name used. */ public function bindValue( $value, $placeHolder = null ) { if ( $placeHolder === null ) { $this->boundCounter++; $placeHolder = ":ezcValue{$this->boundCounter}"; } $this->boundValues[$placeHolder] = $value; return $placeHolder; } /** * Binds the parameter $param to the specified variable name $placeHolder.. * * This method provides a shortcut for PDOStatement::bindParam * when using prepared statements. * * The parameter $param specifies the variable that you want to bind. If * $placeholder is not provided bind() will automatically create a * placeholder for you. An automatic placeholder will be of the name * 'ezcValue1', 'ezcValue2' etc. * * @see http://no.php.net/manual/en/function.pdostatement-bindparam.php * @see doBind() * * Example: * * $value = 2; * $q->eq( 'id', $q->bindParam( $value ) ); * $stmt = $q->prepare(); // the parameter $value is bound to the query. * $value = 4; * $stmt->execute(); // executed with 'id = 4' * * * @param &mixed $param * @param string $placeHolder the name to bind with. The string must start with a colon ':'. * @return string the placeholder name used. */ public function bindParam( &$param, $placeHolder = null ) { if ( $placeHolder === null ) { $this->boundCounter++; $placeHolder = ":ezcValue{$this->boundCounter}"; } $this->boundParameters[$placeHolder] =& $param; return $placeHolder; } /** * Resets the bound values and parameters to empty. * * This is useful if your query can be reset and used multiple times. * * @return void */ protected function resetBinds() { $this->boundCounter = 0; $this->boundParameters = array(); $this->boundValues = array(); } /** * Performs binding of variables bound with bindValue and bindParam on the statement $stmt. * * This method must be called if you have used the bind methods * in your query and you build the method yourself using build. * * @param PDOStatement * @return void */ public function doBind( PDOStatement $stmt ) { foreach ( $this->boundValues as $key => $value ) { try { $stmt->bindValue( $key, $value ); } catch ( PDOException $e ) { // see comment below } } foreach ( $this->boundParameters as $key => &$value ) { try { $stmt->bindParam( $key, $value ); } catch ( PDOException $e ) { // we are ignoring this exception since it may only occur when // a bound parameter is not found in the query anymore. // this can happen if either drop an expression with a bound value // created with this query or if you remove a bind in a query by // replacing it with another one. // the only other way to avoid this problem is parse the string for the // bound variables. Note that a simple search will not do since the variable // name may occur in a string. } } } /** * Returns a prepared statement from this query which can be used for execution. * * prepare() automatically calls doBind() on the statement. * @return PDOStatement */ public function prepare() { $stmt = $this->db->prepare( $this->getQuery() ); $this->doBind( $stmt ); return $stmt; } /** * Returns all the elements in $array as one large single dimensional array. * * @todo public? Currently this is needed for QueryExpression. * @return array */ static public function arrayFlatten( array $array ) { $flat = array(); foreach ( $array as $arg ) { switch ( gettype( $arg ) ) { case 'array': $flat = array_merge( $flat, $arg ); break; default: $flat[] = $arg; break; } } return $flat; } /** * Returns the query string for this query object. * * @throws ezcQueryInvalidException if it was not possible to build a valid query. * @return string */ abstract public function getQuery(); } ?>