Made the addFooToTable() methods return true if they did something, false if

they did not. Unwrapped.


git-svn-id: https://samskivert.googlecode.com/svn/trunk@1989 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2006-12-06 02:31:35 +00:00
parent 86767b91be
commit 5e61ec0641
+120 -156
View File
@@ -43,16 +43,16 @@ public class JDBCUtil
public interface BatchProcessor
{
/**
* Called for each row returned during our batch query. Do not advance
* the result set, simply query its values with the get methods.
* Called for each row returned during our batch query. Do not advance the result set,
* simply query its values with the get methods.
*/
public void process (ResultSet row)
throws SQLException;
};
/**
* Closes the supplied JDBC statement and gracefully handles being
* passed null (by doing nothing).
* Closes the supplied JDBC statement and gracefully handles being passed null (by doing
* nothing).
*/
public static void close (Statement stmt)
throws SQLException
@@ -63,8 +63,8 @@ public class JDBCUtil
}
/**
* Closes the supplied JDBC connection and gracefully handles being
* passed null (by doing nothing).
* Closes the supplied JDBC connection and gracefully handles being passed null (by doing
* nothing).
*/
public static void close (Connection conn)
throws SQLException
@@ -75,28 +75,24 @@ public class JDBCUtil
}
/**
* Calls <code>stmt.executeUpdate()</code> on the supplied statement,
* checking to see that it returns the expected update count and
* throwing a persistence exception if it does not.
* Calls <code>stmt.executeUpdate()</code> on the supplied statement, checking to see that it
* returns the expected update count and throwing a persistence exception if it does not.
*/
public static void checkedUpdate (
PreparedStatement stmt, int expectedCount)
public static void checkedUpdate (PreparedStatement stmt, int expectedCount)
throws SQLException, PersistenceException
{
int modified = stmt.executeUpdate();
if (modified != expectedCount) {
String err = "Statement did not modify expected number of rows " +
"[stmt=" + stmt + ", expected=" + expectedCount +
", modified=" + modified + "]";
String err = "Statement did not modify expected number of rows [stmt=" + stmt +
", expected=" + expectedCount + ", modified=" + modified + "]";
throw new PersistenceException(err);
}
}
/**
* Calls <code>stmt.executeUpdate()</code> on the supplied statement
* with the supplied query, checking to see that it returns the
* expected update count and throwing a persistence exception if it
* does not.
* Calls <code>stmt.executeUpdate()</code> on the supplied statement with the supplied query,
* checking to see that it returns the expected update count and throwing a persistence
* exception if it does not.
*/
public static void checkedUpdate (
Statement stmt, String query, int expectedCount)
@@ -104,35 +100,30 @@ public class JDBCUtil
{
int modified = stmt.executeUpdate(query);
if (modified != expectedCount) {
String err = "Statement did not modify expected number of rows " +
"[stmt=" + stmt + ", expected=" + expectedCount +
", modified=" + modified + "]";
String err = "Statement did not modify expected number of rows [stmt=" + stmt +
", expected=" + expectedCount + ", modified=" + modified + "]";
throw new PersistenceException(err);
}
}
/**
* Calls <code>stmt.executeUpdate()</code> on the supplied statement,
* checking to see that it returns the expected update count and
* logging a warning if it does not.
* Calls <code>stmt.executeUpdate()</code> on the supplied statement, checking to see that it
* returns the expected update count and logging a warning if it does not.
*/
public static void warnedUpdate (
PreparedStatement stmt, int expectedCount)
public static void warnedUpdate (PreparedStatement stmt, int expectedCount)
throws SQLException
{
int modified = stmt.executeUpdate();
if (modified != expectedCount) {
Log.warning("Statement did not modify expected number of rows " +
"[stmt=" + stmt + ", expected=" + expectedCount +
", modified=" + modified + "]");
Log.warning("Statement did not modify expected number of rows [stmt=" + stmt +
", expected=" + expectedCount + ", modified=" + modified + "]");
}
}
/**
* Issues a query with a potentially large number of keys in batches.
* For example, you might have 10,000 ids that you wish to use in an "in"
* clause, but don't trust the database to be smart about optimizing that
* many keys, so instead you use batchQuery like so:
* Issues a query with a potentially large number of keys in batches. For example, you might
* have 10,000 ids that you wish to use in an "in" clause, but don't trust the database to be
* smart about optimizing that many keys, so instead you use batchQuery like so:
* <pre>
* Collection<Integer> keys = ...;
* String query = "select NAME from USERS where USER_ID in (#KEYS)";
@@ -145,17 +136,14 @@ public class JDBCUtil
* JDBCUtil.batchQuery(conn, query, keys, false, 500, proc);
* </pre>
*
* @param query the SQL query to run for each batch with the string
* <code>#KEYS#</code> in the place where the batch of keys should be
* substituted.
* @param escapeKeys if true, {@link #escape} will be called on each key to
* escape any dangerous characters and wrap the key in quotes.
* @param batchSize the number of keys at a time to substitute in for
* <code>#KEYS#</code>.
* @param query the SQL query to run for each batch with the string <code>#KEYS#</code> in the
* place where the batch of keys should be substituted.
* @param escapeKeys if true, {@link #escape} will be called on each key to escape any
* dangerous characters and wrap the key in quotes.
* @param batchSize the number of keys at a time to substitute in for <code>#KEYS#</code>.
*/
public static void batchQuery (
Connection conn, String query, Collection<?> keys,
boolean escapeKeys, int batchSize, BatchProcessor processor)
public static void batchQuery (Connection conn, String query, Collection<?> keys,
boolean escapeKeys, int batchSize, BatchProcessor processor)
throws SQLException
{
Statement stmt = conn.createStatement();
@@ -186,9 +174,9 @@ public class JDBCUtil
}
/**
* Calls <code>stmt.executeUpdate()</code> on the supplied statement
* with the supplied query, checking to see that it returns the
* expected update count and logging a warning if it does not.
* Calls <code>stmt.executeUpdate()</code> on the supplied statement with the supplied query,
* checking to see that it returns the expected update count and logging a warning if it does
* not.
*/
public static void warnedUpdate (
Statement stmt, String query, int expectedCount)
@@ -196,15 +184,14 @@ public class JDBCUtil
{
int modified = stmt.executeUpdate(query);
if (modified != expectedCount) {
Log.warning("Statement did not modify expected number of rows " +
"[stmt=" + stmt + ", expected=" + expectedCount +
", modified=" + modified + "]");
Log.warning("Statement did not modify expected number of rows [stmt=" + stmt +
", expected=" + expectedCount + ", modified=" + modified + "]");
}
}
/**
* Escapes any single quotes in the supplied text and wraps it in
* single quotes to make it safe for embedding into a database query.
* Escapes any single quotes in the supplied text and wraps it in single quotes to make it safe
* for embedding into a database query.
*/
public static String escape (String text)
{
@@ -213,8 +200,8 @@ public class JDBCUtil
}
/**
* Escapes a list of values, separating the escaped values by
* commas. See {@link #escape(String)}.
* Escapes a list of values, separating the escaped values by commas. See {@link
* #escape(String)}.
*/
public static String escape (Object[] values)
{
@@ -229,13 +216,11 @@ public class JDBCUtil
}
/**
* Many databases simply fail to handle Unicode text properly and this
* routine provides a common workaround which is to represent a UTF-8
* string as an ISO-8895-1 string. If you don't need to use the
* database's collation routines, this allows you to do pretty much
* exactly what you want at the expense of having to jigger and
* dejigger every goddamned string that might contain multibyte
* characters every time you access the database. Three cheers for
* Many databases simply fail to handle Unicode text properly and this routine provides a
* common workaround which is to represent a UTF-8 string as an ISO-8895-1 string. If you don't
* need to use the database's collation routines, this allows you to do pretty much exactly
* what you want at the expense of having to jigger and dejigger every goddamned string that
* might contain multibyte characters every time you access the database. Three cheers for
* progress!
*/
public static String jigger (String text)
@@ -268,8 +253,8 @@ public class JDBCUtil
}
/**
* Utility method to jigger the specified string so that it's safe
* to use in a regular Statement.
* Utility method to jigger the specified string so that it's safe to use in a regular
* Statement.
*/
public static String safeJigger (String text)
{
@@ -277,32 +262,33 @@ public class JDBCUtil
}
/**
* Used to programatically create a database table. Does nothing if the
* table already exists.
* Used to programatically create a database table. Does nothing if the table already exists.
*
* @return true if the table was created, false if it already existed.
*/
public static void createTableIfMissing (
public static boolean createTableIfMissing (
Connection conn, String table, String[] definition, String postamble)
throws SQLException
{
if (tableExists(conn, table)) {
return;
return true;
}
Statement stmt = conn.createStatement();
try {
stmt.executeUpdate("create table " + table + "(" +
StringUtil.join(definition, ", ") + ") " +
postamble);
stmt.executeUpdate("create table " + table +
"(" + StringUtil.join(definition, ", ") + ") " + postamble);
} finally {
close(stmt);
}
Log.info("Database table '" + table + "' created.");
return true;
}
/**
* Returns true if the table with the specified name exists, false if
* it does not. <em>Note:</em> the table name is case sensitive.
* Returns true if the table with the specified name exists, false if it does
* not. <em>Note:</em> the table name is case sensitive.
*/
public static boolean tableExists (Connection conn, String name)
throws SQLException
@@ -319,13 +305,11 @@ public class JDBCUtil
}
/**
* Returns true if the table with the specified name exists and
* contains a column with the specified name, false if either
* condition does not hold true. <em>Note:</em> the names are case
* sensitive.
* Returns true if the table with the specified name exists and contains a column with the
* specified name, false if either condition does not hold true. <em>Note:</em> the names are
* case sensitive.
*/
public static boolean tableContainsColumn (
Connection conn, String table, String column)
public static boolean tableContainsColumn (Connection conn, String table, String column)
throws SQLException
{
boolean matched = false;
@@ -341,24 +325,21 @@ public class JDBCUtil
}
/**
* Returns true if the index on the specified column exists for the
* specified table, false if it does not. Optionally you can specifiy
* a non null index name, and the table will be checked to see if it
* contains that specifically named index. <em>Note:</em> the names
* are case sensitive.
* Returns true if the index on the specified column exists for the specified table, false if
* it does not. Optionally you can specifiy a non null index name, and the table will be
* checked to see if it contains that specifically named index. <em>Note:</em> the names are
* case sensitive.
*/
public static boolean tableContainsIndex (Connection conn, String table,
String column, String index)
public static boolean tableContainsIndex (
Connection conn, String table, String column, String index)
throws SQLException
{
boolean matched = false;
ResultSet rs = conn.getMetaData().getIndexInfo("", "", table, false,
true);
ResultSet rs = conn.getMetaData().getIndexInfo("", "", table, false, true);
while (rs.next()) {
String tname = rs.getString("TABLE_NAME");
String cname = rs.getString("COLUMN_NAME");
String iname = rs.getString("INDEX_NAME");
if (index == null) {
if (tname.equals(table) && cname.equals(column)) {
matched = true;
@@ -371,11 +352,9 @@ public class JDBCUtil
}
/**
* Returns true if the specified table contains a primary key on the
* specified column.
* Returns true if the specified table contains a primary key on the specified column.
*/
public static boolean tableContainsPrimaryKey (Connection conn,
String table, String column)
public static boolean tableContainsPrimaryKey (Connection conn, String table, String column)
throws SQLException
{
boolean matched = false;
@@ -383,7 +362,6 @@ public class JDBCUtil
while (rs.next()) {
String tname = rs.getString("TABLE_NAME");
String cname = rs.getString("COLUMN_NAME");
if (tname.equals(table) && cname.equals(column)) {
matched = true;
}
@@ -392,16 +370,14 @@ public class JDBCUtil
}
/**
* Returns the name of the index for the specified column in the
* specified table.
* Returns the name of the index for the specified column in the specified table.
*/
public static String getIndexName (Connection conn, String table,
String column)
throws SQLException
{
boolean matched = false;
ResultSet rs = conn.getMetaData().getIndexInfo("", "", table, false,
true);
ResultSet rs = conn.getMetaData().getIndexInfo("", "", table, false, true);
while (rs.next()) {
String tname = rs.getString("TABLE_NAME");
String cname = rs.getString("COLUMN_NAME");
@@ -414,8 +390,8 @@ public class JDBCUtil
}
/**
* Returns the type (as specified in {@link java.sql.Types} for the
* specified column in the specified table.
* Returns the type (as specified in {@link java.sql.Types} for the specified column in the
* specified table.
*/
public static int getColumnType (Connection conn, String table,
String column)
@@ -432,8 +408,8 @@ public class JDBCUtil
/**
* Determines whether or not the specified column accepts null values.
*
* @return true if the column accepts null values, false if it does not
* (or its nullability is unknown)
* @return true if the column accepts null values, false if it does not (or its nullability is
* unknown)
*/
public static boolean isColumnNullable (Connection conn, String table,
String column)
@@ -448,12 +424,11 @@ public class JDBCUtil
}
/**
* Returns the size for the specified column in the specified table. For
* char or date types this is the maximum number of characters, for numeric
* or decimal types this is the precision.
* Returns the size for the specified column in the specified table. For char or date types
* this is the maximum number of characters, for numeric or decimal types this is the
* precision.
*/
public static int getColumnSize (Connection conn, String table,
String column)
public static int getColumnSize (Connection conn, String table, String column)
throws SQLException
{
ResultSet rs = getColumnMetaData(conn, table, column);
@@ -465,28 +440,25 @@ public class JDBCUtil
}
/**
* Adds a column (with name 'cname' and definition 'cdef') to the
* specified table.
* Adds a column (with name 'cname' and definition 'cdef') to the specified table.
*
* @param afterCname (optional) the name of the column after which to
* add the new column.
* @param afterCname (optional) the name of the column after which to add the new column.
*
* @return true if the column was added, false if it already existed.
*/
public static void addColumn (Connection conn, String table,
String cname, String cdef, String afterCname)
public static boolean addColumn (
Connection conn, String table, String cname, String cdef, String afterCname)
throws SQLException
{
if (tableContainsColumn(conn, table, cname)) {
// Log.info("Database table '" + table + "' already has column '" +
// cname + "'.");
return;
// Log.info("Database table '" + table + "' already has column '" + cname + "'.");
return false;
}
String update = "ALTER TABLE " + table + " ADD COLUMN " +
cname + " " + cdef;
String update = "ALTER TABLE " + table + " ADD COLUMN " + cname + " " + cdef;
if (afterCname != null) {
update += " AFTER " + afterCname;
}
PreparedStatement stmt = null;
try {
stmt = conn.prepareStatement(update);
@@ -494,27 +466,21 @@ public class JDBCUtil
} finally {
close(stmt);
}
Log.info("Database column '" + cname + "' added to table '" +
table + "'.");
Log.info("Database column '" + cname + "' added to table '" + table + "'.");
return true;
}
/**
* Changes a column's definition. Takes a full column definition
* 'cdef' (including the name of the column) with which to replace the
* specified column 'cname'.
* Changes a column's definition. Takes a full column definition 'cdef' (including the name of
* the column) with which to replace the specified column 'cname'.
*
* NOTE: A handy thing you can do with this is to rename a column by
* providing a column definition that has a different name, but the
* same column type.
* NOTE: A handy thing you can do with this is to rename a column by providing a column
* definition that has a different name, but the same column type.
*/
public static void changeColumn (Connection conn, String table,
String cname, String cdef)
public static void changeColumn (Connection conn, String table, String cname, String cdef)
throws SQLException
{
String update = "ALTER TABLE " + table + " CHANGE " + cname + " " +
cdef;
String update = "ALTER TABLE " + table + " CHANGE " + cname + " " + cdef;
PreparedStatement stmt = null;
try {
stmt = conn.prepareStatement(update);
@@ -522,19 +488,20 @@ public class JDBCUtil
} finally {
close(stmt);
}
Log.info("Database column '" + cname + "' of table '" + table +
"' modified to have this def '" + cdef + "'.");
}
/**
* Removes a column from the specified table.
*
* @return true if the column was dropped, false if it did not exist in the first place.
*/
public static void dropColumn (Connection conn, String table, String cname)
public static boolean dropColumn (Connection conn, String table, String cname)
throws SQLException
{
if (!tableContainsColumn(conn, table, cname)) {
return;
return false;
}
String update = "ALTER TABLE " + table + " DROP COLUMN " + cname;
@@ -542,23 +509,24 @@ public class JDBCUtil
try {
stmt = conn.prepareStatement(update);
if (stmt.executeUpdate() == 1) {
Log.info("Database index '" + cname + "' removed from " +
"table '" + table + "'.");
Log.info("Database index '" + cname + "' removed from table '" + table + "'.");
}
} finally {
close(stmt);
}
return true;
}
/**
* Removes a named index from the specified table.
*
* @return true if the index was dropped, false if it did not exist in the first place.
*/
public static void dropIndex (Connection conn, String table,
String cname, String iname)
public static boolean dropIndex (Connection conn, String table, String cname, String iname)
throws SQLException
{
if (!tableContainsIndex(conn, table, cname, iname)) {
return;
return false;
}
String update = "ALTER TABLE " + table + " DROP INDEX " + iname;
@@ -566,12 +534,12 @@ public class JDBCUtil
try {
stmt = conn.prepareStatement(update);
if (stmt.executeUpdate() == 1) {
Log.info("Database index '" + iname + "' removed from " +
"table '" + table + "'.");
Log.info("Database index '" + iname + "' removed from table '" + table + "'.");
}
} finally {
close(stmt);
}
return true;
}
/**
@@ -581,7 +549,6 @@ public class JDBCUtil
throws SQLException
{
String update = "ALTER TABLE " + table + " DROP PRIMARY KEY";
PreparedStatement stmt = null;
try {
stmt = conn.prepareStatement(update);
@@ -594,25 +561,24 @@ public class JDBCUtil
}
/**
* Adds an index on the specified column (cname) to the specified
* table. Optionally supply an index name, otherwise the index is
* named after the column.
* Adds an index on the specified column (cname) to the specified table. Optionally supply an
* index name, otherwise the index is named after the column.
*
* @return true if the index was added, false if it already existed.
*/
public static void addIndexToTable (Connection conn, String table,
String cname, String iname)
public static boolean addIndexToTable (
Connection conn, String table, String cname, String iname)
throws SQLException
{
if (tableContainsIndex(conn, table, cname, iname)) {
// Log.info("Database table '" + table + "' already has an index " +
// "on column '" + cname + "'" +
// (iname != null ? " named '" + iname + "'." : "."));
return;
return false;
}
String idx_name = (iname != null ? iname : cname);
String update = "CREATE INDEX " + idx_name + " on " + table + "(" +
cname + ")";
String update = "CREATE INDEX " + idx_name + " on " + table + "(" + cname + ")";
PreparedStatement stmt = null;
try {
stmt = conn.prepareStatement(update);
@@ -620,16 +586,14 @@ public class JDBCUtil
} finally {
close(stmt);
}
Log.info("Database index '" + idx_name + "' added to table '" +
table + "'");
Log.info("Database index '" + idx_name + "' added to table '" + table + "'");
return true;
}
/**
* Helper function for {@link #getColumnType}, etc.
*/
protected static ResultSet getColumnMetaData (
Connection conn, String table, String column)
protected static ResultSet getColumnMetaData (Connection conn, String table, String column)
throws SQLException
{
ResultSet rs = conn.getMetaData().getColumns("", "", table, column);