1<?php
2/**
3 * SubpartitionDefinitionProcessor.php
4 *
5 * This file implements the processor for the SUBPARTITION statements
6 * within CREATE TABLE.
7 *
8 * PHP version 5
9 *
10 * LICENSE:
11 * Copyright (c) 2010-2014 Justin Swanhart and André Rothe
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 * 3. The name of the author may not be used to endorse or promote products
23 *    derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 *
36 * @author    André Rothe <andre.rothe@phosco.info>
37 * @copyright 2010-2014 Justin Swanhart and André Rothe
38 * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
39 * @version   SVN: $Id$
40 *
41 */
42
43namespace PHPSQLParser\processors;
44use PHPSQLParser\utils\ExpressionType;
45
46/**
47 * This class processes the SUBPARTITION statements within CREATE TABLE.
48 *
49 * @author  André Rothe <andre.rothe@phosco.info>
50 * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
51 *
52 */
53class SubpartitionDefinitionProcessor extends AbstractProcessor {
54
55    protected function getReservedType($token) {
56        return array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $token);
57    }
58
59    protected function getConstantType($token) {
60        return array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $token);
61    }
62
63    protected function getOperatorType($token) {
64        return array('expr_type' => ExpressionType::OPERATOR, 'base_expr' => $token);
65    }
66
67    protected function getBracketExpressionType($token) {
68        return array('expr_type' => ExpressionType::BRACKET_EXPRESSION, 'base_expr' => $token, 'sub_tree' => false);
69    }
70
71    public function process($tokens) {
72
73        $result = array();
74        $prevCategory = '';
75        $currCategory = '';
76        $parsed = array();
77        $expr = array();
78        $base_expr = '';
79        $skip = 0;
80
81        foreach ($tokens as $tokenKey => $token) {
82            $trim = trim($token);
83            $base_expr .= $token;
84
85            if ($skip > 0) {
86                $skip--;
87                continue;
88            }
89
90            if ($skip < 0) {
91                break;
92            }
93
94            if ($trim === '') {
95                continue;
96            }
97
98            $upper = strtoupper($trim);
99            switch ($upper) {
100
101            case 'SUBPARTITION':
102                if ($currCategory === '') {
103                    $expr[] = $this->getReservedType($trim);
104                    $parsed = array('expr_type' => ExpressionType::SUBPARTITION_DEF, 'base_expr' => trim($base_expr),
105                                    'sub_tree' => false);
106                    $currCategory = $upper;
107                    continue 2;
108                }
109                // else ?
110                break;
111
112            case 'COMMENT':
113                if ($prevCategory === 'SUBPARTITION') {
114                    $expr[] = array('expr_type' => ExpressionType::SUBPARTITION_COMMENT, 'base_expr' => false,
115                                    'sub_tree' => false, 'storage' => substr($base_expr, 0, -strlen($token)));
116
117                    $parsed['sub_tree'] = $expr;
118                    $base_expr = $token;
119                    $expr = array($this->getReservedType($trim));
120
121                    $currCategory = $upper;
122                    continue 2;
123                }
124                // else ?
125                break;
126
127            case 'STORAGE':
128                if ($prevCategory === 'SUBPARTITION') {
129                    // followed by ENGINE
130                    $expr[] = array('expr_type' => ExpressionType::ENGINE, 'base_expr' => false, 'sub_tree' => false,
131                                    'storage' => substr($base_expr, 0, -strlen($token)));
132
133                    $parsed['sub_tree'] = $expr;
134                    $base_expr = $token;
135                    $expr = array($this->getReservedType($trim));
136
137                    $currCategory = $upper;
138                    continue 2;
139                }
140                // else ?
141                break;
142
143            case 'ENGINE':
144                if ($currCategory === 'STORAGE') {
145                    $expr[] = $this->getReservedType($trim);
146                    $currCategory = $upper;
147                    continue 2;
148                }
149                if ($prevCategory === 'SUBPARTITION') {
150                    $expr[] = array('expr_type' => ExpressionType::ENGINE, 'base_expr' => false, 'sub_tree' => false,
151                                    'storage' => substr($base_expr, 0, -strlen($token)));
152
153                    $parsed['sub_tree'] = $expr;
154                    $base_expr = $token;
155                    $expr = array($this->getReservedType($trim));
156
157                    $currCategory = $upper;
158                    continue 2;
159                }
160                // else ?
161                break;
162
163            case '=':
164                if (in_array($currCategory, array('ENGINE', 'COMMENT', 'DIRECTORY', 'MAX_ROWS', 'MIN_ROWS'))) {
165                    $expr[] = $this->getOperatorType($trim);
166                    continue 2;
167                }
168                // else ?
169                break;
170
171            case ',':
172                if ($prevCategory === 'SUBPARTITION' && $currCategory === '') {
173                    // it separates the subpartition-definitions
174                    $result[] = $parsed;
175                    $parsed = array();
176                    $base_expr = '';
177                    $expr = array();
178                }
179                break;
180
181            case 'DATA':
182            case 'INDEX':
183                if ($prevCategory === 'SUBPARTITION') {
184                    // followed by DIRECTORY
185                    $expr[] = array('expr_type' => constant('PHPSQLParser\utils\ExpressionType::SUBPARTITION_' . $upper . '_DIR'),
186                                    'base_expr' => false, 'sub_tree' => false,
187                                    'storage' => substr($base_expr, 0, -strlen($token)));
188
189                    $parsed['sub_tree'] = $expr;
190                    $base_expr = $token;
191                    $expr = array($this->getReservedType($trim));
192
193                    $currCategory = $upper;
194                    continue 2;
195                }
196                // else ?
197                break;
198
199            case 'DIRECTORY':
200                if ($currCategory === 'DATA' || $currCategory === 'INDEX') {
201                    $expr[] = $this->getReservedType($trim);
202                    $currCategory = $upper;
203                    continue 2;
204                }
205                // else ?
206                break;
207
208            case 'MAX_ROWS':
209            case 'MIN_ROWS':
210                if ($prevCategory === 'SUBPARTITION') {
211                    $expr[] = array('expr_type' => constant('PHPSQLParser\utils\ExpressionType::SUBPARTITION_' . $upper),
212                                    'base_expr' => false, 'sub_tree' => false,
213                                    'storage' => substr($base_expr, 0, -strlen($token)));
214
215                    $parsed['sub_tree'] = $expr;
216                    $base_expr = $token;
217                    $expr = array($this->getReservedType($trim));
218
219                    $currCategory = $upper;
220                    continue 2;
221                }
222                // else ?
223                break;
224
225            default:
226                switch ($currCategory) {
227
228                case 'MIN_ROWS':
229                case 'MAX_ROWS':
230                case 'ENGINE':
231                case 'DIRECTORY':
232                case 'COMMENT':
233                    $expr[] = $this->getConstantType($trim);
234
235                    $last = array_pop($parsed['sub_tree']);
236                    $last['sub_tree'] = $expr;
237                    $last['base_expr'] = trim($base_expr);
238                    $base_expr = $last['storage'] . $base_expr;
239                    unset($last['storage']);
240
241                    $parsed['sub_tree'][] = $last;
242                    $parsed['base_expr'] = trim($base_expr);
243                    $expr = $parsed['sub_tree'];
244                    unset($last);
245
246                    $currCategory = $prevCategory;
247                    break;
248
249                case 'SUBPARTITION':
250                // that is the subpartition name
251                    $last = array_pop($expr);
252                    $last['name'] = $trim;
253                    $expr[] = $last;
254                    $expr[] = $this->getConstantType($trim);
255                    $parsed['sub_tree'] = $expr;
256                    $parsed['base_expr'] = trim($base_expr);
257                    break;
258
259                default:
260                    break;
261                }
262                break;
263            }
264
265            $prevCategory = $currCategory;
266            $currCategory = '';
267        }
268
269        $result[] = $parsed;
270        return $result;
271    }
272}
273?>
274