1/* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18package libcore.sqlite; 19 20import SQLite.Database; 21import SQLite.Function; 22import SQLite.FunctionContext; 23import SQLite.JDBC2z.JDBCConnection; 24import java.sql.Connection; 25import java.sql.PreparedStatement; 26import java.sql.ResultSet; 27import java.sql.SQLException; 28import java.sql.Statement; 29import junit.framework.TestCase; 30import tests.support.Support_SQL; 31 32 33/** 34 * Test that statements honor their timeout. 35 */ 36public final class QueryTimeoutTest extends TestCase { 37 38 private static final String EXEC_QUERY 39 = "insert into t_copy select a from t_orig where DELAY(2,1)=1"; 40 41 private static final String FETCH_QUERY = "select a from t_orig where DELAY(2,1)=1"; 42 43 private Connection connection; 44 45 @Override public void setUp() throws Exception { 46 Support_SQL.loadDriver(); 47 connection = Support_SQL.getConnection(); 48 49 exec("drop table if exists t_orig;"); 50 exec("drop table if exists t_copy;"); 51 exec("create table t_orig (a int)"); 52 exec("create table t_copy (a int)"); 53 54 for (int i = 0; i < 7; i++) { 55 exec("insert into t_orig values (" + i + ");"); 56 } 57 58 Database database = ((JDBCConnection) connection).getSQLiteDatabase(); 59 database.create_function("DELAY", 2, new Function() { 60 @Override public void function(FunctionContext functionContext, String[] args) { 61 try { 62 int seconds = Integer.parseInt(args[0]); 63 Thread.sleep(seconds * 1000); 64 } catch (InterruptedException ignored) { 65 } 66 functionContext.set_result(Integer.parseInt(args[1])); 67 } 68 @Override public void last_step(FunctionContext functionContext) { 69 } 70 @Override public void step(FunctionContext functionContext, String[] args) { 71 } 72 }); 73 74 connection.setAutoCommit(true); 75 } 76 77 @Override public void tearDown() throws Exception { 78 connection.close(); 79 } 80 81 private void exec(String queryString) throws Exception { 82 System.out.println("Executing " + queryString); 83 Statement statement = null; 84 try { 85 statement = connection.createStatement(); 86 statement.execute(queryString); 87 } finally { 88 if (statement != null) { 89 statement.close(); 90 } 91 } 92 } 93 94 public void testPreparedStatementFetch() throws Exception { 95 PreparedStatement statement = connection.prepareStatement(FETCH_QUERY); 96 statement.setQueryTimeout(1); 97 ResultSet resultSet = null; 98 try { 99 resultSet = statement.executeQuery(); 100 while (resultSet.next()) { 101 } 102 fail(); 103 } catch (SQLException expected) { 104 } finally { 105 statement.close(); 106 if (resultSet != null) { 107 resultSet.close(); 108 } 109 } 110 } 111 112 public void testPreparedStatementUpdate() throws Exception { 113 PreparedStatement statement = connection.prepareStatement(EXEC_QUERY); 114 try { 115 statement.setQueryTimeout(1); 116 statement.execute(); 117 fail(); 118 } catch (SQLException expected) { 119 } finally { 120 statement.close(); 121 } 122 } 123 124 public void testInvalidTimeout() throws Exception { 125 connection.setAutoCommit(true); 126 PreparedStatement statement = connection.prepareStatement("select 'hello'"); 127 128 try { 129 statement.setQueryTimeout(-1); 130 fail(); 131 } catch (SQLException expected) { 132 } 133 134 ResultSet resultSet = statement.executeQuery(); 135 resultSet.close(); 136 statement.close(); 137 } 138 139 public void testExecuteUpdate() throws Exception { 140 Statement statement = connection.createStatement(); 141 try { 142 statement.setQueryTimeout(1); 143 statement.executeUpdate(EXEC_QUERY); 144 fail(); 145 } catch (SQLException expected) { 146 } finally { 147 statement.close(); 148 } 149 } 150 151 public void testTimeoutAndStatementReuse() throws Exception { 152 Statement statement = connection.createStatement(); 153 statement.setQueryTimeout(1); 154 for (int i = 0; i < 3; i++) { 155 try { 156 ResultSet resultSet = statement.executeQuery(FETCH_QUERY); 157 while (resultSet.next()) { 158 } 159 fail(); 160 } catch (SQLException expected) { 161 } 162 } 163 statement.close(); 164 } 165} 166