op, boolean retryOnTransientFailure, boolean readOnly)
throws PersistenceException
{
Connection conn = null;
@@ -153,16 +142,16 @@ public class SimpleRepository extends Repository
// check our pre-condition
if (_precond != null && !_precond.validate(_dbident, op)) {
- Log.warning("Repository operation failed pre-condition check! " +
- "[dbident=" + _dbident + ", op=" + op + "].");
+ Log.warning("Repository operation failed pre-condition check! [dbident=" + _dbident +
+ ", op=" + op + "].");
Thread.dumpStack();
}
// obtain our database connection and associated goodies
conn = _provider.getConnection(_dbident, readOnly);
- // make sure that no one else performs a database operation using the
- // same connection until we're done
+ // make sure that no one else performs a database operation using the same connection until
+ // we're done
synchronized (conn) {
try {
liaison = LiaisonRegistry.getLiaison(conn);
@@ -193,15 +182,15 @@ public class SimpleRepository extends Repository
} catch (SQLException sqe) {
if (attemptedOperation) {
- // back out our changes if something got hosed (but not if
- // the hosage was a result of losing our connection)
+ // back out our changes if something got hosed (but not if the hosage was a
+ // result of losing our connection)
try {
if (supportsTransactions && !conn.isClosed()) {
conn.rollback();
}
} catch (SQLException rbe) {
- Log.warning("Unable to roll back operation " +
- "[err=" + sqe + ", rberr=" + rbe + "].");
+ Log.warning("Unable to roll back operation [err=" + sqe +
+ ", rberr=" + rbe + "].");
}
}
@@ -218,13 +207,11 @@ public class SimpleRepository extends Repository
throw new PersistenceException(err, sqe);
}
- // the MySQL JDBC driver has the annoying habit of including
- // the embedded exception stack trace in the message of their
- // outer exception; if I want a fucking stack trace, I'll call
- // printStackTrace() thanksverymuch
+ // the MySQL JDBC driver has the annoying habit of including the embedded exception
+ // stack trace in the message of their outer exception; if I want a fucking stack
+ // trace, I'll call printStackTrace() thanksverymuch
String msg = StringUtil.split("" + sqe, "\n")[0];
- Log.info("Transient failure executing operation, " +
- "retrying [error=" + msg + "].");
+ Log.info("Transient failure executing operation, retrying [error=" + msg + "].");
} catch (PersistenceException pe) {
// back out our changes if something got hosed
@@ -233,8 +220,8 @@ public class SimpleRepository extends Repository
conn.rollback();
}
} catch (SQLException rbe) {
- Log.warning("Unable to roll back operation " +
- "[origerr=" + pe + ", rberr=" + rbe + "].");
+ Log.warning("Unable to roll back operation [origerr=" + pe +
+ ", rberr=" + rbe + "].");
}
throw pe;
@@ -246,8 +233,8 @@ public class SimpleRepository extends Repository
conn.rollback();
}
} catch (SQLException rbe) {
- Log.warning("Unable to roll back operation " +
- "[origerr=" + rte + ", rberr=" + rbe + "].");
+ Log.warning("Unable to roll back operation [origerr=" + rte +
+ ", rberr=" + rbe + "].");
}
throw rte;
@@ -259,15 +246,15 @@ public class SimpleRepository extends Repository
}
}
- // we'll only fall through here if the above code failed due to a
- // transient exception (the connection was closed for being idle, for
- // example) and we've been asked to retry; so let's do so
+ // we'll only fall through here if the above code failed due to a transient exception (the
+ // connection was closed for being idle, for example) and we've been asked to retry; so
+ // let's do so
return execute(op, false, readOnly);
}
/**
- * Executes the supplied update query in this repository, returning
- * the number of rows modified.
+ * Executes the supplied update query in this repository, returning the number of rows
+ * modified.
*/
protected int update (final String query)
throws PersistenceException
@@ -288,9 +275,8 @@ public class SimpleRepository extends Repository
}
/**
- * Executes the supplied update query in this repository, throwing an
- * exception if the modification count is not equal to the specified
- * count.
+ * Executes the supplied update query in this repository, throwing an exception if the
+ * modification count is not equal to the specified count.
*/
protected void checkedUpdate (final String query, final int count)
throws PersistenceException
@@ -312,8 +298,8 @@ public class SimpleRepository extends Repository
}
/**
- * Executes the supplied update query in this repository, logging a warning
- * if the modification count is not equal to the specified count.
+ * Executes the supplied update query in this repository, logging a warning if the modification
+ * count is not equal to the specified count.
*/
protected void warnedUpdate (final String query, final int count)
throws PersistenceException
@@ -335,15 +321,12 @@ public class SimpleRepository extends Repository
}
/**
- * Instructs MySQL to perform table maintenance on the specified
- * table.
+ * Instructs MySQL to perform table maintenance on the specified table.
*
- * @param action analyze recomputes the distribution of
- * the keys for the specified table. This can help certain joins to be
- * performed more efficiently. optimize instructs MySQL
- * to coalesce fragmented records and reclaim space left by deleted
- * records. This can improve a tables efficiency but can take a long
- * time to run on large tables.
+ * @param action analyze recomputes the distribution of the keys for the specified
+ * table. This can help certain joins to be performed more efficiently. optimize
+ * instructs MySQL to coalesce fragmented records and reclaim space left by deleted records.
+ * This can improve a tables efficiency but can take a long time to run on large tables.
*/
protected void maintenance (final String action, final String table)
throws PersistenceException
@@ -355,15 +338,12 @@ public class SimpleRepository extends Repository
Statement stmt = null;
try {
stmt = conn.createStatement();
- ResultSet rs = stmt.executeQuery(
- action + " table " + table);
+ ResultSet rs = stmt.executeQuery(action + " table " + table);
while (rs.next()) {
String result = rs.getString("Msg_text");
if (result == null ||
- result.indexOf("up to date") == -1 &&
- !result.equals("OK")) {
- Log.info("Table maintenance [" +
- SimpleRepository.toString(rs) + "].");
+ (result.indexOf("up to date") == -1 && !result.equals("OK"))) {
+ Log.info("Table maintenance [" + SimpleRepository.toString(rs) + "].");
}
}
@@ -376,12 +356,10 @@ public class SimpleRepository extends Repository
}
/**
- * Derived classes can override this method and perform any schema
- * migration they might need (using the idempotent {@link JDBCUtil} schema
- * migration methods). This is called during the repository's constructor
- * and will thus take place before derived classes (like the {@link
- * JORARepository} introspect on the schema to match it up to associated
- * Java classes).
+ * Derived classes can override this method and perform any schema migration they might need
+ * (using the idempotent {@link JDBCUtil} schema migration methods). This is called during the
+ * repository's constructor and will thus take place before derived classes (like the {@link
+ * JORARepository} introspect on the schema to match it up to associated Java classes).
*/
protected void migrateSchema (Connection conn, DatabaseLiaison liaison)
throws SQLException, PersistenceException
@@ -389,17 +367,17 @@ public class SimpleRepository extends Repository
}
/**
- * Called when we fetch a connection from the provider. This gives
- * derived classes an opportunity to configure whatever internals they
- * might be using with the connection that was fetched.
+ * Called when we fetch a connection from the provider. This gives derived classes an
+ * opportunity to configure whatever internals they might be using with the connection that was
+ * fetched.
*/
protected void gotConnection (Connection conn)
{
}
/**
- * Converts a row of a result set to a string, prepending each column
- * with the column name from the result set metadata.
+ * Converts a row of a result set to a string, prepending each column with the column name from
+ * the result set metadata.
*/
protected static String toString (ResultSet rs)
throws SQLException
@@ -418,5 +396,6 @@ public class SimpleRepository extends Repository
}
protected String _dbident;
+
protected static PreCondition _precond;
}
diff --git a/src/java/com/samskivert/jdbc/StaticConnectionProvider.java b/src/java/com/samskivert/jdbc/StaticConnectionProvider.java
index 1ac9dcd9..4d77d967 100644
--- a/src/java/com/samskivert/jdbc/StaticConnectionProvider.java
+++ b/src/java/com/samskivert/jdbc/StaticConnectionProvider.java
@@ -3,7 +3,7 @@
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001-2007 Michael Bayne
-//
+//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
@@ -31,15 +31,12 @@ import com.samskivert.util.PropertiesUtil;
import com.samskivert.util.StringUtil;
/**
- * The static connection provider generates JDBC connections based on
- * configuration information provided via a properties file. It does no
- * connection pooling and always returns the same connection for a
- * particular identifier (unless that connection need be closed because of
- * a connection failure, in which case it opens a new one the next time
- * the connection is requested).
+ * The static connection provider generates JDBC connections based on configuration information
+ * provided via a properties file. It does no connection pooling and always returns the same
+ * connection for a particular identifier (unless that connection need be closed because of a
+ * connection failure, in which case it opens a new one the next time the connection is requested).
*
- * The configuration properties file should contain the following
- * information:
+ *
The configuration properties file should contain the following information:
*
*
* IDENT.driver=[jdbc driver class]
@@ -50,14 +47,13 @@ import com.samskivert.util.StringUtil;
* [...]
*
*
- * Where IDENT is the database identifier for a particular
- * database connection. When a particular database identifier is
- * requested, the configuration information will be fetched from the
- * properties.
+ * Where IDENT is the database identifier for a particular database connection. When a
+ * particular database identifier is requested, the configuration information will be fetched from
+ * the properties.
*
- * Additionally, a default set of properties can be provided using the
- * identifier default. Values not provided for a specific
- * identifier will be sought from the defaults. For example:
+ *
Additionally, a default set of properties can be provided using the identifier
+ * default. Values not provided for a specific identifier will be sought from the
+ * defaults. For example:
*
*
* default.driver=[jdbc driver class]
@@ -75,15 +71,15 @@ import com.samskivert.util.StringUtil;
public class StaticConnectionProvider implements ConnectionProvider
{
/**
- * Constructs a static connection provider which will load its
- * configuration from a properties file accessible via the classpath
- * of the running application and identified by the specified path.
+ * Constructs a static connection provider which will load its configuration from a properties
+ * file accessible via the classpath of the running application and identified by the specified
+ * path.
*
- * @param propPath the path (relative to the classpath) to the
- * properties file that will be used for configuration information.
+ * @param propPath the path (relative to the classpath) to the properties file that will be
+ * used for configuration information.
*
- * @exception IOException thrown if an error occurs locating or
- * loading the specified properties file.
+ * @exception IOException thrown if an error occurs locating or loading the specified
+ * properties file.
*/
public StaticConnectionProvider (String propPath)
throws IOException
@@ -92,8 +88,8 @@ public class StaticConnectionProvider implements ConnectionProvider
}
/**
- * Constructs a static connection provider which will fetch its
- * configuration information from the specified properties object.
+ * Constructs a static connection provider which will fetch its configuration information from
+ * the specified properties object.
*
* @param props the configuration for this connection provider.
*/
@@ -103,8 +99,7 @@ public class StaticConnectionProvider implements ConnectionProvider
}
/**
- * Closes all of the open database connections in preparation for
- * shutting down.
+ * Closes all of the open database connections in preparation for shutting down.
*/
public void shutdown ()
{
@@ -112,12 +107,11 @@ public class StaticConnectionProvider implements ConnectionProvider
Iterator iter = _keys.keySet().iterator();
while (iter.hasNext()) {
String key = (String)iter.next();
- Mapping conmap = (Mapping)_keys.get(key);
+ Mapping conmap = _keys.get(key);
try {
conmap.connection.close();
} catch (SQLException sqe) {
- Log.warning("Error shutting down connection " +
- "[key=" + key + ", err=" + sqe + "].");
+ Log.warning("Error shutting down connection [key=" + key + ", err=" + sqe + "].");
}
}
@@ -126,6 +120,13 @@ public class StaticConnectionProvider implements ConnectionProvider
_idents.clear();
}
+ // from ConnectionProvider
+ public String getURL (String ident)
+ {
+ Properties props = PropertiesUtil.getSubProperties(_props, ident, DEFAULTS_KEY);
+ return props.getProperty("url");
+ }
+
// documentation inherited
public Connection getConnection (String ident, boolean readOnly)
throws PersistenceException
@@ -135,9 +136,7 @@ public class StaticConnectionProvider implements ConnectionProvider
// open the connection if we haven't already
if (conmap == null) {
- String[] defaults;
- Properties props =
- PropertiesUtil.getSubProperties(_props, ident, DEFAULTS_KEY);
+ Properties props = PropertiesUtil.getSubProperties(_props, ident, DEFAULTS_KEY);
// get the JDBC configuration info
String err = "No driver class specified [ident=" + ident + "].";
@@ -149,33 +148,30 @@ public class StaticConnectionProvider implements ConnectionProvider
err = "No driver password specified [ident=" + ident + "].";
String password = requireProp(props, "password", err);
- // if this is a read-only connection,
-
- // we cache connections by username+url+readOnly to avoid making
- // more that one connection to a particular database server
+ // if this is a read-only connection, we cache connections by username+url+readOnly to
+ // avoid making more that one connection to a particular database server
String key = username + "@" + url + ":" + readOnly;
conmap = _keys.get(key);
if (conmap == null) {
Log.debug("Creating " + key + " for " + ident + ".");
conmap = new Mapping();
conmap.key = key;
- conmap.connection =
- openConnection(driver, url, username, password);
+ conmap.connection = openConnection(driver, url, username, password);
- // make the connection read-only to let the JDBC driver know
- // that it can and should use the read-only mirror(s)
+ // make the connection read-only to let the JDBC driver know that it can and should
+ // use the read-only mirror(s)
if (readOnly) {
try {
conmap.connection.setReadOnly(true);
} catch (SQLException sqe) {
closeConnection(ident, conmap.connection);
- err = "Failed to make connection read-only " +
- "[key=" + key + ", ident=" + ident + "].";
+ err = "Failed to make connection read-only [key=" + key +
+ ", ident=" + ident + "].";
throw new PersistenceException(err, sqe);
}
}
-
_keys.put(key, conmap);
+
} else {
Log.debug("Reusing " + key + " for " + ident + ".");
}
@@ -185,19 +181,25 @@ public class StaticConnectionProvider implements ConnectionProvider
_idents.put(mapkey, conmap);
}
+ // in case the previous user turned off auto-commit we have to make sure here it's on
+ try {
+ conmap.connection.setAutoCommit(true);
+ } catch (SQLException e) {
+ throw new PersistenceException("Failed to turn on connection auto-commit", e);
+ }
+
return conmap.connection;
}
// documentation inherited
- public void releaseConnection (String ident, boolean readOnly,
- Connection conn)
+ public void releaseConnection (String ident, boolean readOnly, Connection conn)
{
// nothing to do here, all is well
}
// documentation inherited
- public void connectionFailed (String ident, boolean readOnly,
- Connection conn, SQLException error)
+ public void connectionFailed (
+ String ident, boolean readOnly, Connection conn, SQLException error)
{
String mapkey = ident + ":" + readOnly;
Mapping conmap = _idents.get(mapkey);
@@ -216,8 +218,7 @@ public class StaticConnectionProvider implements ConnectionProvider
_keys.remove(conmap.key);
}
- protected Connection openConnection (
- String driver, String url, String username, String password)
+ protected Connection openConnection (String driver, String url, String username, String passwd)
throws PersistenceException
{
// create an instance of the driver
@@ -233,11 +234,11 @@ public class StaticConnectionProvider implements ConnectionProvider
try {
Properties props = new Properties();
props.put("user", username);
- props.put("password", password);
+ props.put("password", passwd);
return jdriver.connect(url, props);
+
} catch (SQLException sqe) {
- String err = "Error creating database connection " +
- "[driver=" + driver + ", url=" + url +
+ String err = "Error creating database connection [driver=" + driver + ", url=" + url +
", username=" + username + "].";
throw new PersistenceException(err, sqe);
}
@@ -253,25 +254,23 @@ public class StaticConnectionProvider implements ConnectionProvider
}
}
- protected static String requireProp (
- Properties props, String name, String errmsg)
+ protected static String requireProp (Properties props, String name, String errmsg)
throws PersistenceException
{
String value = props.getProperty(name);
if (StringUtil.isBlank(value)) {
- // augment the error message
- errmsg = "Unable to get connection. " + errmsg;
+ errmsg = "Unable to get connection. " + errmsg; // augment the error message
throw new PersistenceException(errmsg);
}
return value;
}
- /** Contains information on a particular connection to which any
- * number of database identifiers can be mapped. */
+ /** Contains information on a particular connection to which any number of database identifiers
+ * can be mapped. */
protected static class Mapping
{
- /** The combination of username and JDBC url that uniquely
- * identifies our database connection. */
+ /** The combination of username and JDBC url that uniquely identifies our database
+ * connection. */
public String key;
/** The connection itself. */
diff --git a/src/java/com/samskivert/jdbc/TransitionRepository.java b/src/java/com/samskivert/jdbc/TransitionRepository.java
index 55b99592..b8ac406d 100644
--- a/src/java/com/samskivert/jdbc/TransitionRepository.java
+++ b/src/java/com/samskivert/jdbc/TransitionRepository.java
@@ -3,7 +3,7 @@
//
// samskivert library - useful routines for java programs
// Copyright (C) 2001-2007 Michael Bayne
-//
+//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
@@ -28,9 +28,8 @@ import java.sql.SQLException;
import com.samskivert.io.PersistenceException;
/**
- * Used to note that transitionary code has been run to migrate persistent
- * data. The TransitionRepository is especially useful for data that
- * one cannot examine to determine if it's been transitioned.
+ * Used to note that transitionary code has been run to migrate persistent data. This is especially
+ * useful for data that one cannot examine to determine if it's been transitioned.
*/
public class TransitionRepository extends SimpleRepository
{
@@ -81,18 +80,20 @@ public class TransitionRepository extends SimpleRepository
public Boolean invoke (Connection conn, DatabaseLiaison liaison)
throws SQLException, PersistenceException
{
- Object found = null;
PreparedStatement stmt = null;
try {
- stmt = conn.prepareStatement("select NAME " +
- "from TRANSITIONS where CLASS=? and NAME=?");
+ stmt = conn.prepareStatement(
+ " select " + liaison.columnSQL("NAME") +
+ " from " + liaison.tableSQL("TRANSITIONS") +
+ " where " + liaison.columnSQL("CLASS") + "=?" +
+ " and " + liaison.columnSQL("NAME") + "=?");
stmt.setString(1, cname);
stmt.setString(2, name);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
- while (rs.next()); // is this really necessary?
return true;
}
+
} finally {
JDBCUtil.close(stmt);
}
@@ -114,12 +115,14 @@ public class TransitionRepository extends SimpleRepository
{
PreparedStatement stmt = null;
try {
- stmt = conn.prepareStatement("insert into TRANSITIONS " +
- "(CLASS, NAME) values (?, ?)");
+ stmt = conn.prepareStatement(
+ "insert into " + liaison.tableSQL("TRANSITIONS") + " (" +
+ liaison.columnSQL("CLASS") + ", " + liaison.columnSQL("NAME") +
+ ") values (?, ?)");
stmt.setString(1, cname);
stmt.setString(2, name);
-
JDBCUtil.checkedUpdate(stmt, 1);
+
} finally {
JDBCUtil.close(stmt);
}
@@ -141,8 +144,10 @@ public class TransitionRepository extends SimpleRepository
{
PreparedStatement stmt = null;
try {
- stmt = conn.prepareStatement("delete from TRANSITIONS " +
- "where CLASS=? and NAME=?");
+ stmt = conn.prepareStatement(
+ " delete from " + liaison.tableSQL("TRANSITIONS") +
+ " where " + liaison.columnSQL("CLASS") + "=? " +
+ " and " + liaison.columnSQL("NAME") + "=?");
stmt.setString(1, cname);
stmt.setString(2, name);
@@ -160,10 +165,12 @@ public class TransitionRepository extends SimpleRepository
protected void migrateSchema (Connection conn, DatabaseLiaison liaison)
throws SQLException, PersistenceException
{
- JDBCUtil.createTableIfMissing(conn, "TRANSITIONS", new String[] {
- "CLASS varchar(200) not null",
- "NAME varchar(50) not null",
- "APPLIED timestamp not null",
- "primary key (CLASS, NAME)" }, "");
+ liaison.createTableIfMissing(
+ conn,
+ "TRANSITIONS",
+ new String[] { "CLASS", "NAME", "APPLIED" },
+ new String[] { "VARCHAR(200)", "VARCHAR(50)", "TIMESTAMP NOT NULL" },
+ null,
+ new String[] { "CLASS", "NAME" });
}
}