001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.tests.lang.PrepareExecuteDDL
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.tests.lang;
023:
024: import org.apache.derbyTesting.junit.BaseJDBCTestCase;
025: import org.apache.derbyTesting.junit.JDBC;
026:
027: import java.sql.*;
028:
029: import junit.framework.Test;
030: import junit.framework.TestSuite;
031:
032: /**
033: * Test the dependency system for active statements when
034: * a DDL is executed in a separate connection after the
035: * prepare but before the execute.
036: *
037: */
038: public class PrepareExecuteDDL extends BaseJDBCTestCase {
039:
040: /**
041: * Connection to execute the DDL on. Needs
042: * to be different to the single connection
043: * provided by the super-class. This connection
044: * is used to execute DDL while the other connection
045: * has open objcts dependent on the objct changed by the DDL.
046: */
047: private Connection connDDL;
048:
049: /**
050: * List of statements that are prepared and then executed.
051: * The testPrepareExecute method prepares each statement
052: * in this list, executes one DDL, executes each prepared
053: * statement and then checks the result.
054: * <BR>
055: * The result checking is driven off the initial text
056: * of the statement.
057: */
058: private static final String[] STMTS = { "SELECT * FROM PED001",
059: "SELECT A, B FROM PED001",
060: "GRANT SELECT ON PED001 TO U_PED_001",
061: "GRANT SELECT(A,B) ON PED001 TO U_PED_001",
062: "REVOKE SELECT(A,B) ON PED001 FROM U_PED_001",
063: "REVOKE SELECT ON PED001 FROM U_PED_001", };
064:
065: /**
066: * All the DDL commands that will be executed, one per
067: * fixture, as the mutation between the prepare and execute.
068: */
069: private static final String[] DDL = {
070: "ALTER TABLE PED001 ADD COLUMN D BIGINT",
071: "ALTER TABLE PED001 ADD CONSTRAINT PED001_PK PRIMARY KEY (A)",
072: "ALTER TABLE PED001 LOCKSIZE ROW",
073: "ALTER TABLE PED001 LOCKSIZE TABLE", "DROP TABLE PED001", };
074:
075: /**
076: * Create a suite of tests, one per statement in DDL.
077: */
078: public static Test suite() {
079: TestSuite suite = new TestSuite();
080: for (int i = 0; i < DDL.length; i++)
081: suite.addTest(new PrepareExecuteDDL("testPrepareExcute",
082: DDL[i]));
083: return suite;
084: }
085:
086: private final String ddl;
087:
088: private PrepareExecuteDDL(String name, String ddl) {
089: super (name);
090: this .ddl = ddl;
091: }
092:
093: private boolean tableDropped() {
094: return ddl.startsWith("DROP TABLE ");
095: }
096:
097: public void testPrepareExcute() throws SQLException {
098: Connection conn = getConnection();
099:
100: PreparedStatement[] psa = new PreparedStatement[STMTS.length];
101: for (int i = 0; i < STMTS.length; i++) {
102: String sql = STMTS[i];
103: psa[i] = conn.prepareStatement(sql);
104: }
105:
106: connDDL.createStatement().execute(ddl);
107:
108: for (int i = 0; i < STMTS.length; i++) {
109: String sql = STMTS[i];
110: if (sql.startsWith("SELECT "))
111: checkSelect(psa[i], sql);
112: else if (sql.startsWith("GRANT ")
113: || sql.startsWith("REVOKE "))
114: checkGrantRevoke(psa[i], sql);
115: else
116: fail("unknown SQL" + sql);
117:
118: psa[i].close();
119: }
120: }
121:
122: private void checkSelect(PreparedStatement ps, String sql)
123: throws SQLException {
124: assertEquals(true, sql.startsWith("SELECT "));
125:
126: boolean result;
127: try {
128: result = ps.execute();
129: } catch (SQLException e) {
130:
131: //TODO: Use DMD to see if table exists or not.
132: assertSQLState("42X05", e);
133: assertTrue(tableDropped());
134:
135: return;
136: }
137: assertTrue(result);
138:
139: ResultSet rs = ps.getResultSet();
140:
141: DatabaseMetaData dmd = connDDL.getMetaData();
142: JDBC.assertMetaDataMatch(dmd, rs.getMetaData());
143:
144: boolean isSelectStar = sql.startsWith("SELECT * ");
145:
146: if (isSelectStar)
147: ;
148:
149: JDBC.assertDrainResults(rs);
150: }
151:
152: private void checkGrantRevoke(PreparedStatement ps, String sql)
153: throws SQLException {
154: assertEquals(true, sql.startsWith("GRANT ")
155: || sql.startsWith("REVOKE "));
156:
157: try {
158: assertFalse(ps.execute());
159: } catch (SQLException e) {
160:
161: assertSQLState("42X05", e);
162: assertTrue(tableDropped());
163:
164: return;
165: }
166: }
167:
168: /**
169: * Set the fixture up with a clean, standard table PED001.
170: */
171: protected void setUp() throws SQLException {
172:
173: connDDL = openDefaultConnection();
174: Statement s = connDDL.createStatement();
175:
176: s
177: .execute("CREATE TABLE PED001 (A INT NOT NULL, B DECIMAL(6,4), C VARCHAR(20))");
178:
179: s.close();
180: }
181:
182: /**
183: * Tear-down the fixture by removing the table (if it still
184: * exists).
185: */
186: protected void tearDown() throws Exception {
187: Statement s = connDDL.createStatement();
188: try {
189: s.execute("DROP TABLE PED001");
190: } catch (SQLException e) {
191: assertSQLState("42Y55", e);
192: }
193: s.close();
194: JDBC.cleanup(connDDL);
195: super.tearDown();
196:
197: }
198: }
|