| <?php |
| /** |
| * File containing the ezcQueryOracle class. |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| * @package Database |
| * @version //autogentag// |
| * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
| */ |
| |
| /** |
| * Oracle specific implementation of ezcQuery. |
| * |
| * This class reimplements methods where Oracle differs from |
| * the standard implementation in ezcQuery.Most notably LIMIT |
| * which is not supported directly in oracle. |
| * |
| * @see ezcQuery |
| * @package Database |
| * @version //autogentag// |
| */ |
| class ezcQuerySelectOracle extends ezcQuerySelect |
| { |
| /** |
| * If a limit and/or offset has been set for this query. |
| */ |
| private $hasLimit = false; |
| |
| /** |
| * The limit set. |
| * |
| * @var int |
| */ |
| private $limit = 0; |
| |
| /** |
| * The offset set. |
| * |
| * @var int |
| */ |
| private $offset = 0; |
| |
| /** |
| * Constructs a new ezcQueryOracle object working on the database $db. |
| * |
| * @param PDO $db |
| */ |
| public function __construct( PDO $db ) |
| { |
| parent::__construct( $db ); |
| } |
| |
| /** |
| * Resets the query object for reuse. |
| * |
| * @return void |
| */ |
| public function reset() |
| { |
| $this->hasLimit = false; |
| $this->limit = 0; |
| $this->offset = 0; |
| parent::reset(); |
| } |
| |
| /** |
| * Returns SQL to create an alias. |
| * |
| * This method can be used to create an alias for either a |
| * table or a column. |
| * Example: |
| * <code> |
| * // this will make the table users have the alias employees |
| * // and the column user_id the alias employee_id |
| * $q->select( $q->aliAs( 'user_id', 'employee_id' ) |
| * ->from( $q->aliAs( 'users', 'employees' ) ); |
| * </code> |
| * |
| * @param string $name Old name |
| * @param string $alias Alias |
| * @return string the query string "columnname as targetname |
| */ |
| public function alias( $name, $alias ) |
| { |
| $name = $this->getIdentifier( $name ); |
| return "{$name} {$alias}"; |
| } |
| |
| /** |
| * Returns SQL that limits the result set. |
| * |
| * $limit controls the maximum number of rows that will be returned. |
| * $offset controls which row that will be the first in the result |
| * set from the total amount of matching rows. |
| * |
| * Example: |
| * <code> |
| * $q->select( '*' )->from( 'table' ) |
| * ->limit( 10, 0 ); |
| * </code> |
| * |
| * Oracle does not support the LIMIT keyword. A complete rewrite of the |
| * query is neccessary. Queries will be rewritten like this: |
| * <code> |
| * Original query in MySQL syntax: |
| * SELECT * FROM table LIMIT 10, 5 |
| * The corresponding Oracle query: |
| * SELECT * FROM (SELECT a.*, ROWNUM rn FROM (SELECT * FROM table) a WHERE rownum <= 15) WHERE rn >= 6; |
| * </code> |
| * Even though the Oracle query is three times as long it performs about the same |
| * as mysql on small result sets and a bit better on large result sets. |
| * |
| * Note that you will not get a result if you call buildLimit() when using the oracle database. |
| * |
| * @param string $limit integer expression |
| * @param string $offset integer expression |
| * @return ezcQuerySelect |
| */ |
| public function limit( $limit, $offset = 0 ) |
| { |
| $this->hasLimit = true; |
| $this->limit = $limit; |
| $this->offset = $offset; |
| return $this; |
| } |
| |
| |
| /** |
| * Returns dummy table name 'dual'. |
| * |
| * @return string |
| */ |
| static public function getDummyTableName() |
| { |
| return 'dual'; |
| } |
| |
| /** |
| * Transforms the query from the parent to provide LIMIT functionality. |
| */ |
| public function getQuery() |
| { |
| $query = parent::getQuery(); |
| if ( $this->hasLimit ) |
| { |
| $max = $this->offset + $this->limit; |
| if ( $this->offset > 0 ) |
| { |
| $min = $this->offset + 1; |
| $query = "SELECT * FROM (SELECT a.*, ROWNUM rn FROM ( {$query} ) a WHERE rownum <= {$max} ) WHERE rn >= {$min}"; |
| } |
| else |
| { |
| $query = "SELECT a.* FROM ( {$query} ) a WHERE ROWNUM <= {$max}"; |
| } |
| } |
| return $query; |
| } |
| |
| /** |
| * Handles preparing query. |
| * |
| * Overrides ezcQuery->prepare() |
| * |
| * Adds "FROM dual" to the select if no FROM clause specified |
| * i.e. fixes queries like "SELECT 1+1" to work in Oracle. |
| * |
| * @return PDOStatement |
| */ |
| public function prepare() |
| { |
| if ( $this->fromString == null || $this->fromString == '' ) |
| { |
| $this->from( $this->getDummyTableName() ); |
| } |
| return parent::prepare(); |
| } |
| |
| } |
| |
| ?> |