001: /*
002: * Copyright 2006-2007 The Scriptella Project Team.
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: */
016: package scriptella.jdbc;
017:
018: import scriptella.AbstractTestCase;
019:
020: import java.io.IOException;
021: import java.io.StringReader;
022: import java.util.Arrays;
023:
024: /**
025: * Tests for {@link SqlReaderTokenizer}.
026: *
027: * @author Fyodor Kupolov
028: * @version 1.0
029: */
030: public class SqlTokenizerTest extends AbstractTestCase {
031: public void test() throws IOException {
032: String s = "insert into table values 1,?v,\"?text\";st2";
033: SqlTokenizer tok = new SqlReaderTokenizer(new StringReader(s));
034: String actual = tok.nextStatement();
035: assertEquals("insert into table values 1,?v,\"?text\"", actual);
036: assertTrue(Arrays.equals(new int[] { 27 }, tok.getInjections()));
037: actual = tok.nextStatement();
038: assertEquals("st2", actual);
039: assertTrue(tok.getInjections().length == 0);
040:
041: s = "DROP TABLE Test;";
042: tok = new SqlReaderTokenizer(new StringReader(s));
043: actual = tok.nextStatement();
044: assertEquals("DROP TABLE Test", actual);
045: actual = tok.nextStatement();
046: assertNull(actual);
047:
048: s = "UPDATE test set value='Updated1' where ID=1;";
049: tok = new SqlReaderTokenizer(new StringReader(s));
050: actual = tok.nextStatement();
051: assertEquals("UPDATE test set value='Updated1' where ID=1",
052: actual);
053: actual = tok.nextStatement();
054: assertNull(actual);
055: }
056:
057: public void testComments() throws IOException {
058: String s = "insert into table values 1,?v--$comment\n;"
059: + "-notacomment$v/**fdfdfd$comment\n$comment.v$$???\n;;;*/;stmt${var};\n"
060: + "//$comment";
061: SqlReaderTokenizer tok = new SqlReaderTokenizer(
062: new StringReader(s));
063: tok.setKeepFormat(true);
064: assertEquals("insert into table values 1,?v--$comment\n", tok
065: .nextStatement());
066: assertTrue(Arrays.equals(new int[] { 27 }, tok.getInjections()));
067: assertEquals(
068: "-notacomment$v/**fdfdfd$comment\n$comment.v$$???\n;;;*/",
069: tok.nextStatement());
070: assertTrue(Arrays.equals(new int[] { 12 }, tok.getInjections()));
071: assertEquals("stmt${var}", tok.nextStatement());
072: assertTrue(Arrays.equals(new int[] { 4 }, tok.getInjections()));
073: tok.nextStatement();
074: assertTrue(tok.getInjections().length == 0);
075: }
076:
077: public void testQuotes() throws IOException {
078: String data = "INSERT INTO \"$TBL\" VALUES (\"?V\")";
079: SqlTokenizer tok = new SqlReaderTokenizer(
080: new StringReader(data));
081: tok.nextStatement();
082: assertTrue(Arrays.equals(new int[] { 13 }, tok.getInjections()));
083: }
084:
085: /**
086: * Test correct handling of empty files.
087: */
088: public void testEmpty() throws IOException {
089: SqlTokenizer tok = new SqlReaderTokenizer(new StringReader(""));
090: assertNull(tok.nextStatement());
091: }
092:
093: public void testSeparator() throws IOException {
094: String data = "st;1;;st 2";
095: SqlReaderTokenizer tok = new SqlReaderTokenizer(
096: new StringReader(data));
097: tok.setSeparator(";;");
098: assertEquals("st;1", tok.nextStatement());
099: assertEquals("st 2", tok.nextStatement());
100: assertNull(tok.nextStatement());
101: tok = new SqlReaderTokenizer(new StringReader(data));
102: tok.setSeparator(";;");
103: tok.setSeparatorOnSingleLine(true);
104: assertEquals("st;1;;st 2", tok.nextStatement());
105: assertNull(tok.nextStatement());
106: data = "st;1 \n;;\nst 2";
107: tok = new SqlReaderTokenizer(new StringReader(data));
108: tok.setSeparator(";;");
109: tok.setSeparatorOnSingleLine(true);
110: assertEquals("st;1 \n", tok.nextStatement());
111: assertEquals("st 2", tok.nextStatement());
112: assertNull(tok.nextStatement());
113: data = "st;$v1\n / /*?comment*/ ?v2 2";
114: tok = new SqlReaderTokenizer(new StringReader(data));
115: tok.setSeparator("/");
116: tok.setSeparatorOnSingleLine(true);
117: tok.setKeepFormat(true);
118: assertEquals(data, tok.nextStatement());
119: assertTrue(Arrays.equals(new int[] { 3, 23 }, tok
120: .getInjections()));
121: assertNull(tok.nextStatement());
122: ///
123: data = "st;$v1\r/\n/*?comment*/ ?v2 2";
124: tok = new SqlReaderTokenizer(new StringReader(data));
125: tok.setSeparator("/");
126: tok.setSeparatorOnSingleLine(true);
127: tok.setKeepFormat(true);
128: assertEquals("st;$v1\r", tok.nextStatement());
129: assertTrue(Arrays.equals(new int[] { 3 }, tok.getInjections()));
130: assertEquals("/*?comment*/ ?v2 2", tok.nextStatement());
131: assertTrue(Arrays.equals(new int[] { 13 }, tok.getInjections()));
132: assertNull(tok.nextStatement());
133: ///
134: data = "STATEMENT1 / \n\r"
135: + " / \r\nSTATEMENT2\n/**fdfdfd**//";
136: tok = new SqlReaderTokenizer(new StringReader(data));
137: tok.setSeparator("/");
138: tok.setSeparatorOnSingleLine(true);
139: assertEquals("STATEMENT1 / \n", tok.nextStatement());
140: assertEquals("\nSTATEMENT2\n" + "/", tok.nextStatement());
141: ///
142: data = "/\nscript\n/\n";
143: tok = new SqlReaderTokenizer(new StringReader(data));
144: tok.setSeparator("/");
145: tok.setSeparatorOnSingleLine(true);
146: assertEquals("", tok.nextStatement());
147: assertEquals("script\n", tok.nextStatement());
148: assertNull(tok.nextStatement());
149: ///
150: data = "/\nscript\n/";
151: tok = new SqlReaderTokenizer(new StringReader(data));
152: tok.setSeparator("/");
153: tok.setSeparatorOnSingleLine(true);
154: assertEquals("", tok.nextStatement());
155: assertEquals("script\n", tok.nextStatement());
156: assertNull(tok.nextStatement());
157: ///
158: data = "statement;--comment\n/\nscrip$t\n/";
159: tok = new SqlReaderTokenizer(new StringReader(data));
160: tok.setSeparator("/");
161: tok.setSeparatorOnSingleLine(true);
162: assertEquals("statement;\n", tok.nextStatement());
163: assertEquals("scrip$t\n", tok.nextStatement());
164: assertTrue(Arrays.equals(new int[] { 5 }, tok.getInjections()));
165: assertNull(tok.nextStatement());
166: }
167:
168: /**
169: * Tests if oracle hints are preserved.
170: */
171: public void testOracleHint() throws IOException {
172: String original = "SQL /*+ HINT */ --NOTAHINT \n\r /* +NOTAHINT*/";
173: SqlReaderTokenizer tok = new SqlReaderTokenizer(
174: new StringReader(original));
175: assertEquals("SQL /*+ HINT */ \n", tok.nextStatement());
176: assertNull(tok.nextStatement());
177: tok = new SqlReaderTokenizer(new StringReader(original));
178: tok.setKeepFormat(true);
179: assertEquals(original, tok.nextStatement());
180: assertNull(tok.nextStatement());
181: //Now test with / separator - result should be the same
182: tok = new SqlReaderTokenizer(new StringReader(original));
183: tok.setKeepFormat(true);
184: tok.setSeparator("/");
185: tok.setSeparatorOnSingleLine(true);
186: assertEquals(original, tok.nextStatement());
187: assertNull(tok.nextStatement());
188: //Now test the ?,$ handling
189: original = "SQL $v1 ?v2 /*+ HINT */ --?NOT$AHINT \n\r'$v3'/* +$NOTAHINT*/ ?v4";
190: tok = new SqlReaderTokenizer(new StringReader(original));
191: assertEquals("SQL $v1 ?v2 /*+ HINT */ \n'$v3' ?v4", tok
192: .nextStatement());
193: assertTrue(Arrays.equals(new int[] { 4, 8, 26, 31 }, tok
194: .getInjections()));
195: //The same check but with keep format
196: tok = new SqlReaderTokenizer(new StringReader(original));
197: tok.setKeepFormat(true);
198: assertEquals(original, tok.nextStatement());
199: assertTrue(Arrays.equals(new int[] { 4, 8, 40, 60 }, tok
200: .getInjections()));
201: assertNull(tok.nextStatement());
202: }
203:
204: /**
205: * Tests if extra whitespaces are removed in keepformat=false mode.
206: * Single whitespace trimming is not performed, because performance is more important.
207: */
208: public void testWhitespaceTrim() throws IOException {
209: String sql = " --Comment\n\n\n SQL--text\n; SQL2";
210: SqlTokenizer tok = new SqlReaderTokenizer(new StringReader(sql));
211: assertEquals(" \nSQL\n", tok.nextStatement());
212: assertEquals(" SQL2", tok.nextStatement());
213: assertNull(tok.nextStatement());
214: }
215:
216: }
|