/*
* Copyright (c) 2004-2013 Tada AB and other contributors, as listed below.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the The BSD 3-Clause License
* which accompanies this distribution, and is available at
* http://opensource.org/licenses/BSD-3-Clause
*
* Contributors:
* Tada AB
*/
package org.postgresql.pljava.example;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Time;
import java.util.logging.Logger;
import org.postgresql.pljava.SavepointListener;
import org.postgresql.pljava.Session;
import org.postgresql.pljava.SessionManager;
/**
* Some methods used for testing the SPI JDBC driver.
*
* @author Thomas Hallgren
*/
public class SPIActions {
private static final String SP_CHECKSTATE = "sp.checkState";
private static final SavepointListener spListener = new SavepointListener() {
@Override
public void onAbort(Session session, Savepoint savepoint,
Savepoint parent) throws SQLException {
log("Abort of savepoint " + savepoint.getSavepointId());
nextState(session, 3, 4);
}
@Override
public void onCommit(Session session, Savepoint savepoint,
Savepoint parent) throws SQLException {
log("Commit of savepoint " + savepoint.getSavepointId());
nextState(session, 3, 4);
}
@Override
public void onStart(Session session, Savepoint savepoint,
Savepoint parent) throws SQLException {
log("Start of savepoint " + savepoint.getSavepointId());
nextState(session, 0, 1);
}
};
public static String getDateAsString() throws SQLException {
ResultSet rs = null;
Statement stmt = null;
Connection conn = DriverManager
.getConnection("jdbc:default:connection");
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT CURRENT_DATE");
if (rs.next())
return rs.getDate(1).toString();
return "Date could not be retrieved";
} finally {
if (rs != null)
rs.close();
if (stmt != null)
stmt.close();
conn.close();
}
}
public static String getTimeAsString() throws SQLException {
ResultSet rs = null;
Statement stmt = null;
Connection conn = DriverManager
.getConnection("jdbc:default:connection");
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT CURRENT_TIME");
if (rs.next())
return rs.getTime(1).toString();
return "Time could not be retrieved";
} finally {
if (rs != null)
rs.close();
if (stmt != null)
stmt.close();
conn.close();
}
}
static void log(String msg) {
// GCJ has a somewhat serious bug (reported)
//
if ("GNU libgcj".equals(System.getProperty("java.vm.name"))) {
System.out.print("INFO: ");
System.out.println(msg);
} else
Logger.getAnonymousLogger().info(msg);
}
public static int maxFromSetReturnExample(int base, int increment)
throws SQLException {
int max = Integer.MIN_VALUE;
Connection conn = DriverManager
.getConnection("jdbc:default:connection");
PreparedStatement stmt = null;
ResultSet rs = null;
try {
stmt = conn
.prepareStatement("SELECT base FROM setReturnExample(?, ?)");
stmt.setInt(1, base);
stmt.setInt(2, increment);
rs = stmt.executeQuery();
while (rs.next()) {
base = rs.getInt(1);
if (base > max)
max = base;
}
return base;
} finally {
if (rs != null)
rs.close();
if (stmt != null)
stmt.close();
conn.close();
}
}
/**
* Test of bug #1556
*
*/
public static void nestedStatements(int innerCount) throws SQLException {
Connection connection = DriverManager
.getConnection("jdbc:default:connection");
Statement statement = connection.createStatement();
// Create a set of ID's so that we can do somthing semi-useful during
// the long loop.
//
statement.execute("DELETE FROM javatest.employees1");
statement.execute("INSERT INTO javatest.employees1 VALUES("
+ "1, 'Calvin Forrester', 10000)");
statement.execute("INSERT INTO javatest.employees1 VALUES("
+ "2, 'Edwin Archer', 20000)");
statement.execute("INSERT INTO javatest.employees1 VALUES("
+ "3, 'Rebecka Shawn', 30000)");
statement.execute("INSERT INTO javatest.employees1 VALUES("
+ "4, 'Priscilla Johnson', 25000)");
int idx = 1;
ResultSet results = statement
.executeQuery("SELECT * FROM javatest.hugeResult(" + innerCount
+ ")");
while (results.next()) {
Statement innerStatement = connection.createStatement();
innerStatement
.executeUpdate("UPDATE javatest.employees1 SET salary = salary + 1 WHERE id="
+ idx);
innerStatement.close();
if (++idx == 5)
idx = 0;
}
results.close();
statement.close();
connection.close();
}
private static void nextState(Session session, int expected, int next)
throws SQLException {
Integer state = (Integer) session.getAttribute(SP_CHECKSTATE);
if (state == null || state.intValue() != expected)
throw new SQLException(SP_CHECKSTATE + ": Expected " + expected
+ ", got " + state);
session.setAttribute(SP_CHECKSTATE, new Integer(next));
}
public static int testSavepointSanity() throws SQLException {
Connection conn = DriverManager
.getConnection("jdbc:default:connection");
// Create an anonymous savepoint.
//
log("Attempting to set an anonymous savepoint");
Session currentSession = SessionManager.current();
currentSession.setAttribute(SP_CHECKSTATE, new Integer(0));
currentSession.addSavepointListener(spListener);
Savepoint sp = conn.setSavepoint();
nextState(currentSession, 1, 2);
try {
Statement stmt = conn.createStatement();
log("Attempting to set a SAVEPOINT using SQL (should fail)");
stmt.execute("SAVEPOINT foo");
} catch (SQLException e) {
log("It failed allright. Everything OK then");
log("Rolling back to anonymous savepoint");
nextState(currentSession, 2, 3);
conn.rollback(sp);
nextState(currentSession, 4, 5);
return 1;
} finally {
currentSession.removeSavepointListener(spListener);
}
throw new SQLException(
"SAVEPOINT through SQL succeeded. That's bad news!");
}
public static int testTransactionRecovery() throws SQLException {
Connection conn = DriverManager
.getConnection("jdbc:default:connection");
// Create an anonymous savepoint.
//
log("Attempting to set an anonymous savepoint");
Session currentSession = SessionManager.current();
currentSession.setAttribute(SP_CHECKSTATE, new Integer(0));
currentSession.addSavepointListener(spListener);
Statement stmt = conn.createStatement();
Savepoint sp = conn.setSavepoint();
nextState(currentSession, 1, 2);
try {
log("Attempting to execute a statement with a syntax error");
stmt.execute("THIS MUST BE A SYNTAX ERROR");
} catch (SQLException e) {
log("It failed. Let's try to recover "
+ "by rolling back to anonymous savepoint");
nextState(currentSession, 2, 3);
conn.rollback(sp);
nextState(currentSession, 4, 5);
log("Rolled back.");
log("Now let's try to execute a correct statement.");
currentSession.setAttribute(SP_CHECKSTATE, new Integer(0));
sp = conn.setSavepoint();
nextState(currentSession, 1, 2);
ResultSet rs = stmt.executeQuery("SELECT 'OK'");
while (rs.next()) {
log("Expected: OK; Retrieved: " + rs.getString(1));
}
rs.close();
stmt.close();
nextState(currentSession, 2, 3);
conn.releaseSavepoint(sp);
nextState(currentSession, 4, 5);
return 1;
} finally {
currentSession.removeSavepointListener(spListener);
}
// Should never get here
return -1;
}
public static int transferPeopleWithSalary(int salary) throws SQLException {
Connection conn = DriverManager
.getConnection("jdbc:default:connection");
PreparedStatement select = null;
PreparedStatement insert = null;
PreparedStatement delete = null;
ResultSet rs = null;
String stmt;
try {
stmt = "SELECT id, name, salary FROM employees1 WHERE salary > ?";
log(stmt);
select = conn.prepareStatement(stmt);
stmt = "INSERT INTO employees2(id, name, salary, transferDay, transferTime) VALUES (?, ?, ?, ?, ?)";
log(stmt);
insert = conn.prepareStatement(stmt);
stmt = "DELETE FROM employees1 WHERE id = ?";
log(stmt);
delete = conn.prepareStatement(stmt);
log("assigning parameter value " + salary);
select.setInt(1, salary);
log("Executing query");
rs = select.executeQuery();
int rowNo = 0;
log("Doing next");
while (rs.next()) {
log("Processing row " + ++rowNo);
int id = rs.getInt(1);
String name = rs.getString(2);
int empSal = rs.getInt(3);
insert.setInt(1, id);
insert.setString(2, name);
insert.setInt(3, empSal);
long now = System.currentTimeMillis();
insert.setDate(4, new Date(now));
insert.setTime(5, new Time(now));
int nRows = insert.executeUpdate();
log("Insert processed " + nRows + " rows");
delete.setInt(1, id);
nRows = delete.executeUpdate();
log("Delete processed " + nRows + " rows");
log("Doing next");
}
if (rowNo == 0)
log("No row found");
return rowNo;
} finally {
if (select != null)
select.close();
if (insert != null)
insert.close();
if (delete != null)
delete.close();
conn.close();
}
}
}