1<?php 2/** 3 * OrderByProcessor.php 4 * 5 * This file implements the processor for the ORDER-BY statements. 6 * 7 * PHP version 5 8 * 9 * LICENSE: 10 * Copyright (c) 2010-2014 Justin Swanhart and André Rothe 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * @author André Rothe <andre.rothe@phosco.info> 36 * @copyright 2010-2014 Justin Swanhart and André Rothe 37 * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) 38 * @version SVN: $Id$ 39 * 40 */ 41 42namespace PHPSQLParser\processors; 43use PHPSQLParser\utils\ExpressionType; 44 45/** 46 * This class processes the ORDER-BY statements. 47 * 48 * @author André Rothe <andre.rothe@phosco.info> 49 * @license http://www.debian.org/misc/bsd.license BSD License (3 Clause) 50 * 51 */ 52class OrderByProcessor extends AbstractProcessor { 53 54 protected function processSelectExpression($unparsed) { 55 $processor = new SelectExpressionProcessor($this->options); 56 return $processor->process($unparsed); 57 } 58 59 protected function initParseInfo() { 60 return array('base_expr' => "", 'dir' => "ASC", 'expr_type' => ExpressionType::EXPRESSION); 61 } 62 63 protected function processOrderExpression(&$parseInfo, $select) { 64 $parseInfo['base_expr'] = trim($parseInfo['base_expr']); 65 66 if ($parseInfo['base_expr'] === "") { 67 return false; 68 } 69 70 if (is_numeric($parseInfo['base_expr'])) { 71 $parseInfo['expr_type'] = ExpressionType::POSITION; 72 } else { 73 $parseInfo['no_quotes'] = $this->revokeQuotation($parseInfo['base_expr']); 74 // search to see if the expression matches an alias 75 foreach ($select as $clause) { 76 if (empty($clause['alias'])) { 77 continue; 78 } 79 80 if ($clause['alias']['no_quotes'] === $parseInfo['no_quotes']) { 81 $parseInfo['expr_type'] = ExpressionType::ALIAS; 82 break; 83 } 84 } 85 } 86 87 if ($parseInfo['expr_type'] === ExpressionType::EXPRESSION) { 88 $expr = $this->processSelectExpression($parseInfo['base_expr']); 89 $expr['direction'] = $parseInfo['dir']; 90 unset($expr['alias']); 91 return $expr; 92 } 93 94 $result = array(); 95 $result['expr_type'] = $parseInfo['expr_type']; 96 $result['base_expr'] = $parseInfo['base_expr']; 97 if (isset($parseInfo['no_quotes'])) { 98 $result['no_quotes'] = $parseInfo['no_quotes']; 99 } 100 $result['direction'] = $parseInfo['dir']; 101 return $result; 102 } 103 104 public function process($tokens, $select = array()) { 105 $out = array(); 106 $parseInfo = $this->initParseInfo(); 107 108 if (!$tokens) { 109 return false; 110 } 111 112 foreach ($tokens as $token) { 113 $upper = strtoupper(trim($token)); 114 switch ($upper) { 115 case ',': 116 $out[] = $this->processOrderExpression($parseInfo, $select); 117 $parseInfo = $this->initParseInfo(); 118 break; 119 120 case 'DESC': 121 $parseInfo['dir'] = "DESC"; 122 break; 123 124 case 'ASC': 125 $parseInfo['dir'] = "ASC"; 126 break; 127 128 default: 129 if ($this->isCommentToken($token)) { 130 $out[] = parent::processComment($token); 131 break; 132 } 133 134 $parseInfo['base_expr'] .= $token; 135 } 136 } 137 138 $out[] = $this->processOrderExpression($parseInfo, $select); 139 return $out; 140 } 141} 142?> 143