package net.sourceforge.mayfly.acceptance;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
public class StatementTest extends SqlTestCase {
public void testReturnValueFromExecuteUpdate() throws Exception {
Statement statement = connection.createStatement();
assertEquals(0, statement.executeUpdate("CREATE Table foo (b integer)"));
assertEquals(1, statement.executeUpdate("inSERT into foo (b) values (77)"));
statement.close();
PreparedStatement prepared = connection.prepareStatement("insert into foo (b) values (88)");
assertEquals(1, prepared.executeUpdate());
prepared.close();
}
public void testSyntaxErrorDetectedEarly() throws Exception {
String sql = "insert into some place or another";
if (dialect.detectsSyntaxErrorsInPrepareStatement()) {
try {
connection.prepareStatement(sql);
fail();
} catch (SQLException e) {
assertMessage("expected VALUES or SELECT but got place", e);
}
}
else {
PreparedStatement prepared = connection.prepareStatement(sql);
try {
prepared.executeUpdate();
fail();
}
catch (SQLException e) {
assertMessage("expected VALUES but got place", e);
}
prepared.close();
}
}
public void testQuestionMarkInPreparedStatement() throws Exception {
execute("create table foo (B Integer, a integer)");
PreparedStatement prepared = connection.prepareStatement("insert into foo (a, b) values (?, ?)");
prepared.setInt(1, 70);
prepared.setInt(2, 90);
assertEquals(1, prepared.executeUpdate());
prepared.close();
assertResultSet(new String[] { "90, 70" }, query("select b, a from foo"));
}
public void testStringJdbcParameter() throws Exception {
execute("create table foo (s VARCHAR(80))");
PreparedStatement prepared = connection.prepareStatement("insert into foo (s) values (?)");
prepared.setString(1, "can't");
assertEquals(1, prepared.executeUpdate());
prepared.close();
ResultSet results = query("select s from foo");
assertTrue(results.next());
assertEquals("can't", results.getString(1));
assertFalse(results.next());
results.close();
}
public void testStringInSelect() throws Exception {
execute("create table foo (s VARCHAR(80))");
execute("insert into foo (s) values ('can''t')");
PreparedStatement prepared = connection.prepareStatement("select s from foo where s = ?");
prepared.setString(1, "can't");
ResultSet results = prepared.executeQuery();
assertTrue(results.next());
assertEquals("can't", results.getString(1));
assertFalse(results.next());
results.close();
prepared.close();
}
public void testParameterInNonPreparedStatement() throws Exception {
execute("create table foo (x integer)");
expectExecuteFailure("insert into foo(x) values (?)", "Attempt to specify '?' outside a prepared statement");
}
public void testBadSetIntCalls() throws Exception {
execute("create table Foo (B Integer, a integer)");
PreparedStatement prepared = connection.prepareStatement("insert into foo (a, b) values (?, ?)");
try {
prepared.setInt(0, 70);
fail();
} catch (SQLException e) {
assertMessage("Parameter index 0 is out of bounds", e);
}
try {
prepared.setInt(3, 70);
fail();
} catch (SQLException e) {
assertMessage("Parameter index 3 is out of bounds", e);
}
prepared.close();
}
public void testSetToNull() throws Exception {
execute("create table foo (a varchar(80))");
PreparedStatement prepared = connection.prepareStatement("insert into foo (a) values (?)");
// That passing null should mean the same as setNull sems to be the consensus
// of databases tested.
prepared.setString(1, null);
prepared.executeUpdate();
prepared.close();
assertResultSet(new String[] { " null " }, query("select a from foo"));
}
public void testSetNull() throws Exception {
execute("create table foo (x integer)");
PreparedStatement prepared = connection.prepareStatement(
"insert into foo (x) values (?)");
prepared.setNull(1, Types.INTEGER);
prepared.executeUpdate();
prepared.close();
assertResultSet(new String[] { " null " }, query("select x from foo"));
}
public void testSetObjectNull() throws Exception {
execute("create table foo (x integer)");
PreparedStatement prepared = connection.prepareStatement(
"insert into foo (x) values (?)");
if (dialect.canSetObjectNull()) {
prepared.setObject(1, null);
prepared.executeUpdate();
prepared.close();
assertResultSet(
new String[] { " null " },
query("select x from foo"));
}
else {
try {
prepared.setObject(1, null);
fail();
}
catch (SQLException expected) {
assertMessage("expected data type integer but got null",
expected);
}
}
}
public void testSetObjectNullWithType() throws Exception {
execute("create table foo (x integer)");
PreparedStatement prepared = connection.prepareStatement(
"insert into foo (x) values (?)");
prepared.setObject(1, null, Types.INTEGER);
prepared.executeUpdate();
prepared.close();
assertResultSet(
new String[] { " null " },
query("select x from foo"));
}
public void testSetObjectInteger() throws Exception {
execute("create table foo (x integer)");
PreparedStatement prepared = connection.prepareStatement(
"insert into foo (x) values (?)");
prepared.setObject(1, new Integer(55));
prepared.executeUpdate();
assertResultSet(
new String[] { " 55 " },
query("select x from foo"));
}
public void testSetObjectMismatchedTypes() throws Exception {
execute("create table foo (x integer)");
PreparedStatement prepared = connection.prepareStatement(
"insert into foo (x) values (?)");
if (dialect.canSetStringOnDecimalColumn()) {
prepared.setObject(1, "66");
prepared.executeUpdate();
assertResultSet(
new String[] { " 66 " },
query("select x from foo"));
}
else {
try {
prepared.setObject(1, "66");
prepared.executeUpdate();
fail();
}
catch (SQLException e) {
assertMessage(
"attempt to store string '66' into integer column x", e);
}
}
}
public void testMissingSetCall() throws Exception {
execute("create table foo (a Integer, b integer)");
PreparedStatement prepared = connection.prepareStatement(
"insert into foo (a, b) values (?, ?)");
prepared.setInt(2, 90);
if (dialect.requiresAllParameters()) {
try {
prepared.executeUpdate();
fail();
} catch (SQLException e) {
assertMessage("Parameter 1 missing", e);
}
prepared.close();
} else {
// Hypersonic behavior. Defaulting to null seems too forgiving, especially given
// the way that JDBC, used straightforwardly, tends to turn null into 0.
assertEquals(1, prepared.executeUpdate());
prepared.close();
assertResultSet(new String[] { " null , 90 " }, query("select a, b from foo"));
}
}
public void testSelect() throws Exception {
execute("create table foo (a integer, b integer, c integer)");
execute("insert into foo (a, b, c) values (4, 5, 6)");
execute("insert into foo (a, b, c) values (7, 8, 9)");
PreparedStatement prepared = connection.prepareStatement(
"select a from foo where (? = c and b = ?) or a = ?");
prepared.setInt(1, 9);
prepared.setInt(2, 8);
prepared.setInt(3, 3);
ResultSet results = prepared.executeQuery();
assertResultSet(new String[] { " 7 " }, results);
prepared.close();
}
}