/** * @param stream * @return String */ public String getToken(StringStream stream) { int c = 0; StringBuilder buffer = new StringBuilder(); this.skipWhitespace(stream); while ((c = stream.read()) != -1) { if (c <= ' ' || c == '(' || c == ')' || c == ',') { stream.back(); break; } else { buffer.append((char) c); } } String token = buffer.toString(); if (token.equals("--")) { while ((c = stream.read()) != -1) { if (c == '\n') { break; } } return this.getToken(stream); } return token; }
/** * skip whitespace * * @param stream */ public void skipWhitespace(StringStream stream) { int i = 0; while ((i = stream.read()) != -1) { if (i > ' ') { stream.back(); break; } } }
/** * @param stream * @return String */ public String getString(StringStream stream) { this.skipWhitespace(stream); if (stream.read() != '\'') { throw new RuntimeException("except keyword '\\''!"); } int i = 0; StringBuilder buffer = new StringBuilder(); while ((i = stream.read()) != -1) { if (i == '\\') { this.unescape(stream, buffer); } else if (i == '\'') { break; } else { buffer.append((char) i); } } return buffer.toString(); }
/** * @param stream * @return String */ public String getWord(StringStream stream) { int c = 0; char quoto = '\0'; StringBuilder buffer = new StringBuilder(); this.skipWhitespace(stream); c = stream.read(); if (c == '`' || c == '\'' || c == '"' || c == '[') { quoto = (char) c; this.skipWhitespace(stream); } else { stream.back(); } while ((c = stream.read()) != -1) { if (this.isSqlIdentifierPart(c)) { buffer.append((char) c); } else { stream.back(); break; } } String word = buffer.toString(); this.skipWhitespace(stream); if (quoto != '\0') { c = stream.read(); if (quoto == '[' && c != ']') { throw new RuntimeException(word + ": except ']'!"); } else if (quoto != c) { throw new RuntimeException( "column '" + word + "', except '" + quoto + "': found '" + (char) c); } } return word; }
/** * CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name * * @param stream * @return Table */ public Table parse(StringStream stream) { String token = null; while (true) { token = this.getToken(stream); if (token.length() < 1) { return null; } if (token.equalsIgnoreCase("create")) { break; } String line = null; while ((line = stream.readLine()) != null) { line = line.trim(); if (line.endsWith(";")) { break; } } } token = this.getToken(stream); if (token.equalsIgnoreCase("TEMPORARY")) { token = this.getToken(stream); } if (token.equalsIgnoreCase("TABLE") == false) { throw new RuntimeException("except keyword 'TABLE'!"); } String tableName = this.getTableName(stream); if (tableName.equalsIgnoreCase("IF")) { token = this.getToken(stream); if (token.equalsIgnoreCase("NOT") == false) { throw new RuntimeException("except keyword 'NOT'!"); } token = this.getToken(stream); if (token.equalsIgnoreCase("EXISTS") == false) { throw new RuntimeException("except keyword 'EXISTS'!"); } tableName = this.getTableName(stream); } String className = this.toCamel(tableName); String variableName = Character.toLowerCase(className.charAt(0)) + className.substring(1); Table table = new Table(tableName); table.setTableCode(tableName); table.setTableName(tableName); table.setTableType("TABLE"); table.setRemarks(""); table.setQueryName(tableName); table.setClassName(className); table.setVariableName(variableName); this.skipWhitespace(stream); int i = stream.read(); if (i != '(') { throw new RuntimeException("tableName: " + tableName + ", except '('"); } while (true) { this.skipWhitespace(stream); i = stream.peek(); if (i == -1 || i == ')') { break; } String columnName = this.getColumnName(stream); /** @TODO: keyword check */ if (columnName.equalsIgnoreCase("PRIMARY") || columnName.equalsIgnoreCase("UNIQUE") || columnName.equalsIgnoreCase("KEY")) { while ((i = stream.read()) != -1) { if (i == '\n') { break; } } continue; } Column column = new Column(columnName); column.setColumnCode(columnName); String variable = java.beans.Introspector.decapitalize(this.toCamel(columnName)); if ("ID".equals(variable) == false) { variable = Character.toLowerCase(variable.charAt(0)) + variable.substring(1); } this.skipWhitespace(stream); String typeName = this.getToken(stream); column.setTypeName(typeName); column.setJavaTypeName(this.dialect.convert(column)); column.setVariableName(variable); column.setMethodSetter("set" + this.toCamel(columnName)); column.setMethodGetter("get" + this.toCamel(columnName)); this.skipWhitespace(stream); i = stream.read(); if (i == '(') { Integer precision = this.getInteger(stream); if (precision == null) { throw new RuntimeException(column.getColumnName() + ", except number!"); } column.setColumnSize(precision.intValue()); column.setPrecision(0); this.skipWhitespace(stream); if (stream.read() != ')') { throw new RuntimeException("except ')'!"); } } else { stream.back(); } while (true) { this.skipWhitespace(stream); i = stream.peek(); if (i == -1 || i == ',') { stream.read(); break; } if (i == ')') { break; } token = this.getToken(stream); if (token.equalsIgnoreCase("NOT")) { this.skipWhitespace(stream); token = this.getToken(stream); if (token.equalsIgnoreCase("NULL") == false) { throw new RuntimeException("except keyword 'NULL'!"); } column.setNullable(0); } else if (token.equalsIgnoreCase("AUTO_INCREMENT")) { column.setAutoIncrement(1); } else if (token.equalsIgnoreCase("DEFAULT")) { this.skipWhitespace(stream); i = stream.peek(); if (i == '\'') { this.getString(stream); } else { String defaultValue = this.getToken(stream); if (defaultValue.length() < 1) { throw new RuntimeException( column.getColumnName() + " - default value except default value!"); } /* Integer value = this.getInteger(stream); if(value == null) { throw new RuntimeException(column.getColumnName() + " - default value except number!"); } */ } } else if (token.equalsIgnoreCase("COMMENT")) { String remarks = this.getString(stream); column.setRemarks(remarks); } else if (token.equalsIgnoreCase("unsigned")) { } else { throw new RuntimeException("unknown keyword '" + token + "'!"); } } table.addColumn(column); } while ((i = stream.read()) != -1) { if (i == ';') { break; } } return table; }
/** * @param stream * @param buffer */ public void unescape(StringStream stream, StringBuilder buffer) { int c = stream.read(); if (c < 0) { return; } switch (c) { case 'n': { buffer.append("\n"); break; } case 't': { buffer.append("\t"); break; } case 'b': { buffer.append("\b"); break; } case 'r': { buffer.append("\r"); break; } case 'f': { buffer.append("\f"); break; } case '\'': { buffer.append("\'"); break; } case '\"': { buffer.append("\""); break; } case '\\': { buffer.append("\\"); break; } case 'u': { char[] cbuf = {'0', '0', '0', '0'}; int i = stream.read(cbuf); if (i == 4) { String hex = new String(cbuf); try { int value = Integer.parseInt(hex, 16); buffer.append((char) value); } catch (NumberFormatException e) { } } break; } default: { stream.back(); char[] cbuf = {'0', '0', '0'}; int i = stream.read(cbuf); if (i == 3) { String hex = new String(cbuf); try { int value = Integer.parseInt(hex, 16); buffer.append((char) value); } catch (NumberFormatException e) { } } break; } } }