001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.util;
007:
008: import java.io.IOException;
009: import java.io.Reader;
010: import java.sql.SQLException;
011:
012: import org.h2.message.Message;
013:
014: /**
015: * This class can split SQL scripts to single SQL statements.
016: * Each SQL statement ends with the character ';', however it is ignored
017: * in comments and quotes.
018: */
019: public class ScriptReader {
020: private Reader reader;
021: private boolean end;
022: private boolean insideRemark;
023: private boolean blockRemark;
024: private boolean skipRemarks;
025:
026: public ScriptReader(Reader reader) {
027: this .reader = reader;
028: }
029:
030: public void close() throws SQLException {
031: try {
032: reader.close();
033: } catch (IOException e) {
034: throw Message.convertIOException(e, null);
035: }
036: }
037:
038: private int read() throws SQLException {
039: try {
040: return reader.read();
041: } catch (IOException e) {
042: throw Message.convertIOException(e, null);
043: }
044: }
045:
046: public String readStatement() throws SQLException {
047: if (end) {
048: return null;
049: }
050: StringBuffer buff = new StringBuffer(200);
051: int c = read();
052: while (true) {
053: if (c < 0) {
054: end = true;
055: return buff.length() == 0 ? null : buff.toString();
056: } else if (c == ';') {
057: break;
058: }
059: switch (c) {
060: case '\'':
061: buff.append((char) c);
062: while (true) {
063: c = read();
064: if (c < 0) {
065: break;
066: }
067: buff.append((char) c);
068: if (c == '\'') {
069: break;
070: }
071: }
072: c = read();
073: break;
074: case '"':
075: buff.append((char) c);
076: while (true) {
077: c = read();
078: if (c < 0) {
079: break;
080: }
081: buff.append((char) c);
082: if (c == '\"') {
083: break;
084: }
085: }
086: c = read();
087: break;
088: case '/': {
089: int last = c;
090: c = read();
091: if (c == '*') {
092: // block comment
093: insideRemark = true;
094: blockRemark = true;
095: if (!skipRemarks) {
096: buff.append((char) last);
097: buff.append((char) c);
098: }
099: while (true) {
100: c = read();
101: if (c < 0) {
102: break;
103: }
104: if (!skipRemarks) {
105: buff.append((char) c);
106: }
107: if (c == '*') {
108: c = read();
109: if (c < 0) {
110: break;
111: }
112: if (!skipRemarks) {
113: buff.append((char) c);
114: }
115: if (c == '/') {
116: insideRemark = false;
117: break;
118: }
119: }
120: }
121: c = read();
122: } else if (c == '/') {
123: // single line comment
124: insideRemark = true;
125: blockRemark = false;
126: if (!skipRemarks) {
127: buff.append((char) last);
128: buff.append((char) c);
129: }
130: while (true) {
131: c = read();
132: if (c < 0) {
133: break;
134: }
135: if (!skipRemarks) {
136: buff.append((char) c);
137: }
138: if (c == '\r' || c == '\n') {
139: insideRemark = false;
140: break;
141: }
142: }
143: c = read();
144: } else {
145: buff.append((char) last);
146: }
147: break;
148: }
149: case '-': {
150: int last = c;
151: c = read();
152: if (c == '-') {
153: // single line comment
154: insideRemark = true;
155: blockRemark = false;
156: if (!skipRemarks) {
157: buff.append((char) last);
158: buff.append((char) c);
159: }
160: while (true) {
161: c = read();
162: if (c < 0) {
163: break;
164: }
165: if (!skipRemarks) {
166: buff.append((char) c);
167: }
168: if (c == '\r' || c == '\n') {
169: insideRemark = false;
170: break;
171: }
172: }
173: c = read();
174: } else {
175: buff.append((char) last);
176: }
177: break;
178: }
179: default:
180: buff.append((char) c);
181: c = read();
182: }
183: }
184: return buff.toString();
185: }
186:
187: public boolean isInsideRemark() {
188: return insideRemark;
189: }
190:
191: public boolean isBlockRemark() {
192: return blockRemark;
193: }
194:
195: public void setSkipRemarks(boolean skipRemarks) {
196: this.skipRemarks = skipRemarks;
197: }
198: }
|