Minahito
minah****@users*****
2006年 10月 19日 (木) 19:20:59 JST
Index: xoops2jp/html/modules/legacy/lib/EasyLex/EasyLex_SQLScanner.class.php diff -u /dev/null xoops2jp/html/modules/legacy/lib/EasyLex/EasyLex_SQLScanner.class.php:1.1.2.1 --- /dev/null Thu Oct 19 19:20:59 2006 +++ xoops2jp/html/modules/legacy/lib/EasyLex/EasyLex_SQLScanner.class.php Thu Oct 19 19:20:58 2006 @@ -0,0 +1,415 @@ +<?php +/** + * @package EasyLexSQL + * @varsion $Id: EasyLex_SQLScanner.class.php,v 1.1.2.1 2006/10/19 10:20:58 minahito Exp $ + * + * In the original BSD license, both occurrences of the phrase "COPYRIGHT + * HOLDERS AND CONTRIBUTORS" in the disclaimer read "REGENTS AND CONTRIBUTORS". + * + * Copyright (c) 2006, XOOPS Cube Project team/minahito (minah****@users*****) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * a) Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * b) Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * c) Neither the name of the XOOPS Cube Project team nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +define('EASYLEX_SQL_UNKNOWN', 0); +define('EASYLEX_SQL_DIGIT', 1); +define('EASYLEX_SQL_LETTER', 2); +define('EASYLEX_SQL_STRING_LITERAL', 3); +define('EASYLEX_SQL_STRING_LITERAL_ESCAPE', 10); +define('EASYLEX_SQL_OPEN_PARENTHESIS', 4); +define('EASYLEX_SQL_CLOSE_PARENTHESIS', 5); +define('EASYLEX_SQL_SEPARATER', 6); +define('EASYLEX_SQL_SEMICOLON', 7); +define('EASYLEX_SQL_MARK', 8); +define('EASYLEX_SQL_COMMA', 9); + +/** + * This is BSD easy lexcal scanner for SQL. + * + * @version 1.00 + */ +class EasyLex_SQLScanner +{ + var $mTokens; + var $mStatus = EASYLEX_SQL_UNKNOWN; + + /** + * @var Array of char + */ + var $mBuffer = array(); + + var $mIndex = 0; + + var $mActiveToken = ''; + + var $mActiveQuoteMark = null; + + function setBuffer($buffer) + { + $this->mBuffer = array(); + for ($i = 0; $i < strlen($buffer); $i++) { + $this->mBuffer[$i] = $buffer{$i}; + } + + $this->mIndex = 0; + } + + function parse() + { + while ($this->mIndex <= count($this->mBuffer)) { + if ($this->mIndex == count($this->mBuffer)) { + $ch = ''; + $type = EASYLEX_SQL_UNKNOWN; + } + else { + $ch = $this->mBuffer[$this->mIndex]; + $type = $this->_getChrType($ch); + } + + switch ($this->mStatus) { + case EASYLEX_SQL_UNKNOWN: + $this->_parseUnknown($ch, $type); + break; + + case EASYLEX_SQL_DIGIT: + $this->_parseDigit($ch, $type); + break; + + case EASYLEX_SQL_LETTER: + $this->_parseLetter($ch, $type); + break; + + case EASYLEX_SQL_STRING_LITERAL: + $this->_parseStringLiteral($ch, $type); + break; + + case EASYLEX_SQL_STRING_LITERAL_ESCAPE: + $this->_parseStringLiteralEscape($ch, $type); + break; + + case EASYLEX_SQL_OPEN_PARENTHESIS: + $this->_parseOpenParenthesis($ch, $type); + break; + + case EASYLEX_SQL_CLOSE_PARENTHESIS: + $this->_parseCloseParenthesis($ch, $type); + break; + + case EASYLEX_SQL_SEPARATER: + $this->_parseSeparater($ch, $type); + break; + + case EASYLEX_SQL_MARK: + $this->_parseMark($ch, $type); + break; + + case EASYLEX_SQL_SEMICOLON: + $this->_parseSemicolon($ch, $type); + break; + + case EASYLEX_SQL_COMMA: + $this->_parseComma($ch, $type); + break; + } + } + } + + /** + * Load file and set buffer. If $preprocess is true, scan commetns and + * remove these. + * + * @param string $path file path + * @param bool $preprocess + * @return bool + */ + function loadFile($path, $preprocess = true) + { + if (!file_exists($path)) { + return false; + } + + $fp = fopen($path, "rb"); + if (!$fp) { + return false; + } + + $t_buff = ""; + while ($str = fgets($fp)) { + if ($preprocess) { + $str = preg_replace("/^\s*\#.*/", "", $str); + } + $t_buff .= $str; + } + + $this->setBuffer($t_buff); + + fclose($fp); + return true; + } + + function _getChrType($ch) + { + if (preg_match("/\s/", $ch)) { + return EASYLEX_SQL_SEPARATER; + } + + if ($ch == '(') { + return EASYLEX_SQL_OPEN_PARENTHESIS; + } + + if ($ch == ')') { + return EASYLEX_SQL_CLOSE_PARENTHESIS; + } + + if ($ch == ';') { + return EASYLEX_SQL_SEMICOLON; + } + + if ($ch == ',') { + return EASYLEX_SQL_COMMA; + } + + if (preg_match("/[0-9]/", $ch)) { + return EASYLEX_SQL_DIGIT; + } + + if (preg_match("/[!=<>%\*]/", $ch)) { + return EASYLEX_SQL_MARK; + } + + return EASYLEX_SQL_LETTER; + } + + function _parseUnknown($ch, $type) + { + $this->mStatus = $type; + $this->mActiveToken .= $ch; + $this->mIndex++; + + if ($ch == "'" || $ch == '"' || $ch == '`') { + $this->mStatus = EASYLEX_SQL_STRING_LITERAL; + $this->mActiveQuoteMark = $ch; + } + + } + + function _parseDigit($ch, $type) + { + if ($type == EASYLEX_SQL_DIGIT) { + $this->mActiveToken .= $ch; + $this->mIndex++; + } + elseif ($type == EASYLEX_SQL_LETTER) { + $this->mStatus = EASYLEX_SQL_LETTER; + $this->mActiveToken .= $ch; + $this->mIndex++; + } + else { + $this->_createToken(); + } + } + + function _parseLetter($ch, $type) + { + if ($type == EASYLEX_SQL_LETTER || $type == EASYLEX_SQL_DIGIT) { + $this->mActiveToken .= $ch; + $this->mIndex++; + } + else { + $this->_createToken(); + } + } + + function _parseStringLiteral($ch, $type) + { + $this->mActiveToken .= $ch; + $this->mIndex++; + + if ($ch == "\\") { + $this->mStatus = EASYLEX_SQL_STRING_LITERAL_ESCAPE; + } + elseif ($ch == $this->mActiveQuoteMark) { + $this->_createToken(); + } + } + + function _parseStringLiteralEscape($ch, $type) + { + $this->mStatus = EASYLEX_SQL_STRING_LITERAL; + } + + function _parseOpenParenthesis($ch, $type) + { + $this->_createToken(); + } + + function _parseCloseParenthesis($ch, $type) + { + $this->_createToken(); + } + + function _parseSeparater($ch, $type) + { + if ($type == EASYLEX_SQL_SEPARATER) { + $this->mActiveToken .= $ch; + $this->mIndex++; + } + else { + // $this->_createToken(); + $this->mStatus = EASYLEX_SQL_UNKNOWN; + $this->mActiveToken = ""; + } + } + + function _parseSemicolon($ch, $type) + { + $this->_createToken(); + } + + function _parseMark($ch, $type) + { + if ($type == EASYLEX_SQL_MARK) { + $this->mActiveToken .= $ch; + $this->mIndex++; + } + else { + $this->_createToken(); + } + } + + function _parseComma($ch, $type) + { + $this->_createToken(); + } + + function _createToken($type = null, $value = null) + { + if ($type === null) { + $type = $this->mStatus; + } + + if ($value === null) { + $value = $this->mActiveToken; + } + + $token =& new EasyLex_SQLToken($type, $value); + $this->mTokens[] =& $token; + + $this->mStatus = EASYLEX_SQL_UNKNOWN; + $this->mActiveToken = ""; + + return $token; + } + + /** + * Return Array of operations. + * + * @return Array $ret[Index] = Array of tokens. + */ + function &getOperations() + { + $ret = array(); + $t_tokens = array(); + $depth = 0; + + foreach (array_keys($this->mTokens) as $key) { + if ($this->mTokens[$key]->mType == EASYLEX_SQL_OPEN_PARENTHESIS) { + $depth++; + } + elseif ($this->mTokens[$key]->mType == EASYLEX_SQL_CLOSE_PARENTHESIS) { + $depth--; + } + + $t_tokens[] =& $this->mTokens[$key]; + + if ($this->mTokens[$key]->mType == EASYLEX_SQL_SEMICOLON && $depth == 0) { + $ret[] =& $t_tokens; + unset($t_tokens); + $t_tokens = array(); + } + } + + if (count($t_tokens) > 0) { + $ret[] =& $t_tokens; + unset($t_tokens); + } + + return $ret; + } + + function getSQL() + { + $sqls = array(); + $lines =& $this->getOperations(); + + foreach ($lines as $line) { + $t_arr = array(); + foreach ($line as $token) { + $t_arr[] = $token->getOutputValue(); + } + $sqls[] = join(" ", $t_arr); + } + + return $sqls; + } +} + +class EasyLex_SQLToken +{ + var $mType = EASYLEX_SQL_UNKNOWN; + var $mValue = ""; + + function EasyLex_SQLToken($type, $value) + { + $this->mType = $type; + $this->mValue = $value; + } + + function getOutputValue() + { + if ($this->mType == EASYLEX_SQL_SEPARATER) { + return ""; + } + else { + return $this->mValue; + } + } + + function getValue() + { + if ($this->mType == EASYLEX_SQL_SEPARATER) { + return ""; + } + + if ($this->mType == EASYLEX_SQL_STRING_LITERAL) { + return substr($this->mValue, 1, strlen($this->mValue) - 2); + } + + return $this->mValue; + } +} + +?> \ No newline at end of file