1<?php 2/** 3 * ReferenceDefinitionProcessor.php 4 * 5 * This file implements the processor reference definition part of the CREATE TABLE statements. 6 * 7 * Copyright (c) 2010-2012, Justin Swanhart 8 * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de> 9 * 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without modification, 13 * are permitted provided that the following conditions are met: 14 * 15 * * Redistributions of source code must retain the above copyright notice, 16 * this list of conditions and the following disclaimer. 17 * * Redistributions in binary form must reproduce the above copyright notice, 18 * this list of conditions and the following disclaimer in the documentation 19 * and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24 * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 26 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 27 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 30 * DAMAGE. 31 */ 32 33namespace PHPSQLParser\processors; 34use PHPSQLParser\utils\ExpressionType; 35 36/** 37 * 38 * This class processes the reference definition part of the CREATE TABLE statements. 39 * 40 * @author arothe 41 */ 42class ReferenceDefinitionProcessor extends AbstractProcessor { 43 44 protected function buildReferenceDef($expr, $base_expr, $key) { 45 $expr['till'] = $key; 46 $expr['base_expr'] = $base_expr; 47 return $expr; 48 } 49 50 public function process($tokens) { 51 52 $expr = array('expr_type' => ExpressionType::REFERENCE, 'base_expr' => false, 'sub_tree' => array()); 53 $base_expr = ''; 54 55 foreach ($tokens as $key => $token) { 56 57 $trim = trim($token); 58 $base_expr .= $token; 59 60 if ($trim === '') { 61 continue; 62 } 63 64 $upper = strtoupper($trim); 65 66 switch ($upper) { 67 68 case ',': 69 # we stop on a single comma 70 # or at the end of the array $tokens 71 $expr = $this->buildReferenceDef($expr, trim(substr($base_expr, 0, -strlen($token))), $key - 1); 72 break 2; 73 74 case 'REFERENCES': 75 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 76 $currCategory = $upper; 77 break; 78 79 case 'MATCH': 80 if ($currCategory === 'REF_COL_LIST') { 81 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 82 $currCategory = 'REF_MATCH'; 83 continue 2; 84 } 85 # else? 86 break; 87 88 case 'FULL': 89 case 'PARTIAL': 90 case 'SIMPLE': 91 if ($currCategory === 'REF_MATCH') { 92 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 93 $expr['match'] = $upper; 94 $currCategory = 'REF_COL_LIST'; 95 continue 2; 96 } 97 # else? 98 break; 99 100 case 'ON': 101 if ($currCategory === 'REF_COL_LIST') { 102 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 103 $currCategory = 'REF_ACTION'; 104 continue 2; 105 } 106 # else ? 107 break; 108 109 case 'UPDATE': 110 case 'DELETE': 111 if ($currCategory === 'REF_ACTION') { 112 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 113 $currCategory = 'REF_OPTION_' . $upper; 114 continue 2; 115 } 116 # else ? 117 break; 118 119 case 'RESTRICT': 120 case 'CASCADE': 121 if (strpos($currCategory, 'REF_OPTION_') === 0) { 122 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 123 $expr['on_' . strtolower(substr($currCategory, -6))] = $upper; 124 continue 2; 125 } 126 # else ? 127 break; 128 129 case 'SET': 130 case 'NO': 131 if (strpos($currCategory, 'REF_OPTION_') === 0) { 132 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 133 $expr['on_' . strtolower(substr($currCategory, -6))] = $upper; 134 $currCategory = 'SEC_' . $currCategory; 135 continue 2; 136 } 137 # else ? 138 break; 139 140 case 'NULL': 141 case 'ACTION': 142 if (strpos($currCategory, 'SEC_REF_OPTION_') === 0) { 143 $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim); 144 $expr['on_' . strtolower(substr($currCategory, -6))] .= ' ' . $upper; 145 $currCategory = 'REF_COL_LIST'; 146 continue 2; 147 } 148 # else ? 149 break; 150 151 default: 152 switch ($currCategory) { 153 154 case 'REFERENCES': 155 if ($upper[0] === '(' && substr($upper, -1) === ')') { 156 # index_col_name list 157 $processor = new IndexColumnListProcessor($this->options); 158 $cols = $processor->process($this->removeParenthesisFromStart($trim)); 159 $expr['sub_tree'][] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim, 160 'sub_tree' => $cols); 161 $currCategory = 'REF_COL_LIST'; 162 continue 3; 163 } 164 # foreign key reference table name 165 $expr['sub_tree'][] = array('expr_type' => ExpressionType::TABLE, 'table' => $trim, 166 'base_expr' => $trim, 'no_quotes' => $this->revokeQuotation($trim)); 167 continue 3; 168 169 default: 170 # else ? 171 break; 172 } 173 break; 174 } 175 } 176 177 if (!isset($expr['till'])) { 178 $expr = $this->buildReferenceDef($expr, trim($base_expr), -1); 179 } 180 return $expr; 181 } 182} 183?>