001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.common.text; 017 018import java.util.LinkedList; 019import java.util.List; 020import org.modeshape.common.annotation.Immutable; 021 022public class SampleSqlParser { 023 024 public List<Statement> parse( String ddl ) { 025 TokenStream tokens = new TokenStream(ddl, TokenStream.basicTokenizer(false), false); 026 List<Statement> statements = new LinkedList<Statement>(); 027 tokens.start(); 028 029 while (tokens.hasNext()) { 030 if (tokens.matches("SELECT")) { 031 statements.add(parseSelect(tokens)); 032 } else { 033 statements.add(parseDelete(tokens)); 034 } 035 } 036 return statements; 037 } 038 039 protected Select parseSelect( TokenStream tokens ) throws ParsingException { 040 tokens.consume("SELECT"); 041 List<Column> columns = parseColumns(tokens); 042 tokens.consume("FROM"); 043 String tableName = tokens.consume(); 044 return new Select(tableName, columns); 045 } 046 047 protected List<Column> parseColumns( TokenStream tokens ) throws ParsingException { 048 List<Column> columns = new LinkedList<Column>(); 049 if (tokens.matches('*')) { 050 tokens.consume(); // leave the columns empty to signal wildcard 051 } else { 052 // Read names until we see a ',' 053 do { 054 String columnName = tokens.consume(); 055 if (tokens.canConsume("AS")) { 056 String columnAlias = tokens.consume(); 057 columns.add(new Column(columnName, columnAlias)); 058 } else { 059 columns.add(new Column(columnName, null)); 060 } 061 } while (tokens.canConsume(',')); 062 } 063 return columns; 064 } 065 066 protected Delete parseDelete( TokenStream tokens ) throws ParsingException { 067 tokens.consume("DELETE", "FROM"); 068 String tableName = tokens.consume(); 069 tokens.consume("WHERE"); 070 String lhs = tokens.consume(); 071 tokens.consume('='); 072 String rhs = tokens.consume(); 073 return new Delete(tableName, new Criteria(lhs, rhs)); 074 } 075 076 @Immutable 077 public abstract static class Statement { 078 } 079 080 @Immutable 081 public static class Select extends Statement { 082 private final String from; 083 private final List<Column> columns; 084 085 public Select( String from, 086 List<Column> columns ) { 087 this.from = from; 088 this.columns = columns; 089 } 090 091 public String getFrom() { 092 return from; 093 } 094 095 public List<Column> getColumns() { 096 return columns; 097 } 098 } 099 100 @Immutable 101 public static class Delete extends Statement { 102 private final String from; 103 private final Criteria criteria; 104 105 public Delete( String from, 106 Criteria criteria ) { 107 this.from = from; 108 this.criteria = criteria; 109 } 110 111 public String getFrom() { 112 return from; 113 } 114 115 public Criteria getCriteria() { 116 return criteria; 117 } 118 } 119 120 @Immutable 121 public static class Column { 122 private final String name; 123 private final String alias; 124 125 public Column( String name, 126 String alias ) { 127 this.name = name; 128 this.alias = alias; 129 } 130 131 public String getName() { 132 return name; 133 } 134 135 public String getAlias() { 136 return alias; 137 } 138 } 139 140 @Immutable 141 public static class Criteria { 142 private final String lhs; 143 private final String rhs; 144 145 public Criteria( String lhs, 146 String rhs ) { 147 this.lhs = lhs; 148 this.rhs = rhs; 149 } 150 151 public String getLhs() { 152 return lhs; 153 } 154 155 public String getRhs() { 156 return rhs; 157 } 158 } 159 160 @Immutable 161 public static class Query { 162 private final String from; 163 private final List<Column> columns; 164 165 public Query( String from, 166 List<Column> columns ) { 167 this.from = from; 168 this.columns = columns; 169 } 170 171 public String getFrom() { 172 return from; 173 } 174 175 public List<Column> getColumns() { 176 return columns; 177 } 178 } 179 180}