⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqltokenizer.java

📁 java 数据库 功能强大 效率高 SmallSQL Database is a free DBMS library for the Java(tm) platform. It runs on
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* =============================================================
 * SmallSQL : a free Java DBMS library for the Java(tm) platform
 * =============================================================
 *
 * (C) Copyright 2004-2007, by Volker Berlin.
 *
 * Project Info:  http://www.smallsql.de/
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 *
 * ---------------
 * SQLTokenizer.java
 * ---------------
 * Author: Volker Berlin
 * 
 */
package smallsql.database;

import java.util.*;
import java.sql.Types;

public class SQLTokenizer {

    public static List parseSQL( char[] sql ){
        SearchNode node = searchTree;
        ArrayList tokens = new ArrayList();
        int value = 0;
        int tokenStart = 0;
        boolean wasWhiteSpace = true;
        char quote = 0;
        StringBuffer quoteBuffer = new StringBuffer();

        for(int i=0; i<sql.length; i++){
            char c = sql[i];
            switch(c){
                case '\"':
                case '\'':
                            if(quote == 0){
                                quote = c;
                            }else if(quote == c){
                                // check on escaped quote
                                if(i+1<sql.length && sql[i+1] == quote){
                                    quoteBuffer.append(quote);
                                    i++;
                                }else{
                                    tokens.add( new SQLToken( quoteBuffer.toString(), (quote == '\'') ? STRING : IDENTIFIER,       tokenStart, i+1) );
                                    quoteBuffer.setLength(0);
                                    quote = 0;
                                    tokenStart = i+1;
                                    wasWhiteSpace = true;
                                }
                            }else quoteBuffer.append(c);
                            break;
                case '.':
                            if(quote == 0){
                            	// there are follow cases with a point
                            	// "abc"."abc"	--> identifier --> multiple tokens
                            	// "5"."3"		--> identifier --> multiple tokens
                            	// 5.3			--> number --> one token
                            	// 5.e3			--> number --> one token
                            	// .3			--> number --> one token
                            	// .e3			--> identifier --> multiple tokens
                                int k=tokenStart;
                                if(k == i){ // point is first character
                                	if(sql.length> k+1){
										char cc = sql[k+1];
										if((cc >= '0') && cc <= '9') break; // is a number --> break
                                	}
                                }else{
	                                for(; k<i; k++){
	                                    char cc = sql[k];
	                                    if((cc != '-' && cc != '$' && cc < '0') || cc > '9') break; // is identifier --> break
	                                }
									if(k>=i) break; // preceding tokens are only digits that it is not an identifier else a floating number
                                }
                            }
                            // character before is not a digit that it is an identifier
                            // no break;
				case '-':
							if(quote == 0 && !wasWhiteSpace){
								char c1 = sql[tokenStart];
								char cx = sql[i-1];
								if(((c1 >= '0' && c1 <= '9') || c1 == '.') && (cx == 'e' || cx == 'E'))
									//negative exponential number
									break;
								if(c1 == '$' && tokenStart+1 == i)
									// money number
									break;
							}
                case ' ':
				case '\t':
				case '\n':
				case '\r':
                case ',':
                case '(':
                case ')':
                case '{':
                case '}':
                case '*':
                case '+':
                case '/':
                case '%':
                case '&':
                case '|':
                case '=':
                case '<':
                case '>':
                case '?':
                case '^':
                case '~':
                            if(quote == 0){
                                if(!wasWhiteSpace){
                                   tokens.add( new SQLToken( value, tokenStart, i) );
                                   value = 0;
                                }
                                switch(c){
									case ' ':
                                	case '\t':
                                	case '\n':
                                	case '\r':
                                    	// skip this characters, this are not tokens, this are only source formatter   
                                    	break;
                                    case '<':
                                        if((i+1 < sql.length) && (sql[i+1] == '>')){
                                            tokens.add( new SQLToken( UNEQUALS, i, i+2) );
                                            i++;
                                            break;
                                        }
                                    case '>':
                                        if((i+1 < sql.length) && (sql[i+1] == '=')){
                                            tokens.add( new SQLToken( 100 + c, i, i+2) );
                                            i++;
                                            break;
                                        }
                                    default:
                                        tokens.add( new SQLToken( c, i, i+1) );
                                }
                                wasWhiteSpace = true;
                                tokenStart = i+1;
                            }else{
                                quoteBuffer.append(c);
                            }
                            break;
                default:
                            if(quote == 0){
                                if(wasWhiteSpace){
                                     node = searchTree;
                                }else{
                                    if(node == null){
                                        value = 0;
                                        wasWhiteSpace = false;
                                        break;
                                    }
                                }
								c |= 0x20; // case insensitive
                                while(node != null && node.letter != c) node = node.nextEntry;
                                if(node != null){
                                    value = node.value;
                                    node = node.nextLetter;
                                }else{
                                    value = 0;
                                    node = null;
                                }
                            }else{
                                quoteBuffer.append(c);
                            }
                            wasWhiteSpace = false;
                            break;
            }
        }
        if(!wasWhiteSpace){
           tokens.add( new SQLToken( value, tokenStart, sql.length) );
        }
        return tokens;
    }

    static private void addKeyWord( String keyword, int value){
        keywords.put( Utils.getInteger( value), keyword );

        char[] letters = keyword.toCharArray();
        if(searchTree == null){
            searchTree = new SearchNode();
            searchTree.letter = (char)(letters[0] | 0x20);
        }
        SearchNode prev = null;
        SearchNode node = searchTree;
        boolean wasNextEntry = true;
        for(int i=0; i<letters.length; i++){
            char c = (char)(letters[i] | 0x20);
            while(node != null && node.letter != c) {
                prev = node;
                node = node.nextEntry;
                wasNextEntry = true;
            }
            if(node == null){
                node = new SearchNode();
                node.letter = c;
                if(wasNextEntry)
                     prev.nextEntry = node;
                else prev.nextLetter = node;
                wasNextEntry = false;
                prev = node;
                node = null;
            }else{
                prev = node;
                node = node.nextLetter;
                wasNextEntry = false;
            }
        }
        prev.value = value;
    }

	static final String getKeyWord(int key){
		return (String)keywords.get( Utils.getInteger(key) );
	}
	
	static final int getSQLDataType(int type){
		// on change of this map the order from getTypeInfo need to be change
		switch(type){
			case SQLTokenizer.BIT:
						return Types.BIT;
			case SQLTokenizer.BOOLEAN:
						return Types.BOOLEAN;
			case SQLTokenizer.BINARY:
						return Types.BINARY;
			case SQLTokenizer.VARBINARY:
						return Types.VARBINARY;
			case SQLTokenizer.LONGVARBINARY:
						return Types.LONGVARBINARY;
			case SQLTokenizer.BLOB:
						return Types.BLOB;
			case SQLTokenizer.TINYINT:
						return Types.TINYINT;
			case SQLTokenizer.SMALLINT:
						return Types.SMALLINT;
			case SQLTokenizer.INT:
						return Types.INTEGER;
			case SQLTokenizer.BIGINT:
						return Types.BIGINT;
			case SQLTokenizer.SMALLMONEY:
			case SQLTokenizer.MONEY:
			case SQLTokenizer.DECIMAL:
						return Types.DECIMAL;
			case SQLTokenizer.NUMERIC:
						return Types.NUMERIC;
			case SQLTokenizer.REAL:
						return Types.REAL;
			case SQLTokenizer.FLOAT:
						return Types.FLOAT;
			case SQLTokenizer.DOUBLE:
						return Types.DOUBLE;
			case SQLTokenizer.DATE:
						return Types.DATE;
			case SQLTokenizer.TIME:
						return Types.TIME;
			case SQLTokenizer.TIMESTAMP:
			case SQLTokenizer.SMALLDATETIME:
						return Types.TIMESTAMP;
			case SQLTokenizer.CHAR:
			case SQLTokenizer.NCHAR:
						return Types.CHAR;
			case SQLTokenizer.VARCHAR:
			case SQLTokenizer.NVARCHAR:
						return Types.VARCHAR;
			case SQLTokenizer.LONGNVARCHAR:
			case SQLTokenizer.LONGVARCHAR:
						return Types.LONGVARCHAR;
			case SQLTokenizer.CLOB:
			case SQLTokenizer.NCLOB:
						return Types.CLOB;
			case SQLTokenizer.JAVA_OBJECT:
						return Types.JAVA_OBJECT;
			case SQLTokenizer.UNIQUEIDENTIFIER:
						return -11;
			case SQLTokenizer.NULL:
						return Types.NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -