|
From: <bir...@us...> - 2009-05-20 15:23:25
|
Revision: 117
http://mptstore.svn.sourceforge.net/mptstore/?rev=117&view=rev
Author: birkland
Date: 2009-05-20 15:23:10 +0000 (Wed, 20 May 2009)
Log Message:
-----------
No longer cache the non-existence of tables
Modified Paths:
--------------
trunk/src/java/org/nsdl/mptstore/core/BasicTableManager.java
Modified: trunk/src/java/org/nsdl/mptstore/core/BasicTableManager.java
===================================================================
--- trunk/src/java/org/nsdl/mptstore/core/BasicTableManager.java 2008-03-31 19:05:54 UTC (rev 116)
+++ trunk/src/java/org/nsdl/mptstore/core/BasicTableManager.java 2009-05-20 15:23:10 UTC (rev 117)
@@ -1,3 +1,4 @@
+
package org.nsdl.mptstore.core;
import java.sql.Connection;
@@ -3,6 +4,6 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
+import java.sql.SQLException;
import java.sql.Statement;
-import java.sql.SQLException;
import java.text.ParseException;
@@ -22,15 +23,15 @@
import org.nsdl.mptstore.util.NTriplesUtil;
/**
- * A <code>TableManager</code> designed to perform DDL operations
- * on separate connections from those used for DML.
+ * A <code>TableManager</code> designed to perform DDL operations on separate
+ * connections from those used for DML. The DDL-in-a-separate-connection
+ * strategy employed by this implementation should work with a wide variety of
+ * databases.
*
- * The DDL-in-a-separate-connection strategy employed by this
- * implementation should work with a wide variety of databases.
- *
* @author cw...@cs...
*/
-public class BasicTableManager implements TableManager {
+public class BasicTableManager
+ implements TableManager {
/**
* The Logger for this class.
@@ -39,26 +40,26 @@
Logger.getLogger(BasicTableManager.class.getName());
/**
- * The <code>DataSource</code> from which to obtain connections
- * for DDL operations.
+ * The <code>DataSource</code> from which to obtain connections for DDL
+ * operations.
*/
- private DataSource _dataSource;
+ private final DataSource _dataSource;
/**
* The <code>DDLGenerator</code> for this instance.
*/
- private DDLGenerator _ddlGenerator;
+ private final DDLGenerator _ddlGenerator;
/**
* The name of the table in which the table-to-predicate mappings are
* persisted.
*/
- private String _mapTable;
+ private final String _mapTable;
/**
* The prefix for all predicate table names.
*/
- private String _soTablePrefix;
+ private final String _soTablePrefix;
/**
* The in-memory predicate-to-table mapping.
@@ -71,23 +72,27 @@
private Map<String, PredicateNode> _reverseMap;
/**
- * Initialize the table manager.
+ * Initialize the table manager. This will create the map table if it
+ * doesn't yet exist, and will read the current mappings into memory.
*
- * This will create the map table if it doesn't yet exist,
- * and will read the current mappings into memory.
- *
- * @param dataSource The DataSource from which to obtain
- * connections for DDL operations.
- * @param ddlGenerator The DDLGenerator to use when DDL is needed.
- * @param mapTable The name of the table in which the table-to-predicate
- * mappings are persisted.
- * @param soTablePrefix The prefix for all predicate table names.
- * @throws SQLException if any kind of database error occurs.
+ * @param dataSource
+ * The DataSource from which to obtain connections for DDL
+ * operations.
+ * @param ddlGenerator
+ * The DDLGenerator to use when DDL is needed.
+ * @param mapTable
+ * The name of the table in which the table-to-predicate mappings are
+ * persisted.
+ * @param soTablePrefix
+ * The prefix for all predicate table names.
+ * @throws SQLException
+ * if any kind of database error occurs.
*/
public BasicTableManager(final DataSource dataSource,
final DDLGenerator ddlGenerator,
final String mapTable,
- final String soTablePrefix) throws SQLException {
+ final String soTablePrefix)
+ throws SQLException {
_dataSource = dataSource;
_ddlGenerator = ddlGenerator;
@@ -98,9 +103,8 @@
try {
if (!mapTableExists(conn)) {
LOG.info("Creating map table");
- executeDDL(conn,
- _ddlGenerator.getCreateMapTableDDL(
- _mapTable).iterator());
+ executeDDL(conn, _ddlGenerator.getCreateMapTableDDL(_mapTable)
+ .iterator());
}
loadMapTable(conn);
} finally {
@@ -136,6 +140,9 @@
/** {@inheritDoc} */
public String getTableFor(final PredicateNode predicate) {
synchronized (_map) {
+ if (!_map.containsKey(predicate)) {
+ loadMapTable();
+ }
return _map.get(predicate);
}
}
@@ -150,6 +157,7 @@
/** {@inheritDoc} */
public Set<String> getTables() {
synchronized (_map) {
+ loadMapTable();
return new HashSet<String>(_reverseMap.keySet());
}
}
@@ -157,6 +165,7 @@
/** {@inheritDoc} */
public Set<PredicateNode> getPredicates() {
synchronized (_map) {
+ loadMapTable();
return new HashSet<PredicateNode>(_map.keySet());
}
}
@@ -170,14 +179,16 @@
/**
* Check whether the map table exists.
*
- * @param conn The connection to use for determining the table's existence.
+ * @param conn
+ * The connection to use for determining the table's existence.
* @return true if so, false if not.
- * @throws SQLException if a database error occurs.
+ * @throws SQLException
+ * if a database error occurs.
*/
private boolean mapTableExists(final Connection conn) throws SQLException {
- ResultSet results = conn.getMetaData().getTables(null, null,
- _mapTable, null);
+ ResultSet results =
+ conn.getMetaData().getTables(null, null, _mapTable, null);
try {
if (results.next()) {
LOG.info("Found pre-existing map table");
@@ -227,16 +238,41 @@
}
}
+ private void loadMapTable() {
+ Connection conn = null;
+ try {
+ conn = _dataSource.getConnection();
+ loadMapTable(conn);
+ } catch (SQLException e) {
+ LOG.warn("Could not re-load map table", e);
+ } finally {
+ if (conn != null) {
+ try {
+ conn.close();
+ } catch (SQLException e) {
+ LOG.warn("Error closing connection", e);
+ }
+ }
+ }
+ }
+
/**
* Read the content of the map table into memory.
*
- * @param conn The connection to use for reading.
- * @throws SQLException if a database error occurs.
+ * @param conn
+ * The connection to use for reading.
+ * @throws SQLException
+ * if a database error occurs.
*/
private void loadMapTable(final Connection conn) throws SQLException {
LOG.info("Loading map table");
- _map = new HashMap<PredicateNode, String>();
- _reverseMap = new HashMap<String, PredicateNode>();
+ if (_map == null || _reverseMap == null) {
+ _map = new HashMap<PredicateNode, String>();
+ _reverseMap = new HashMap<String, PredicateNode>();
+ } else {
+ _map.clear();
+ _reverseMap.clear();
+ }
Statement st = conn.createStatement();
ResultSet results = null;
String pString = null;
@@ -250,8 +286,8 @@
_reverseMap.put(table, predicate);
}
} catch (ParseException e) {
- throw new SQLException("Unable to parse predicate ("
- + pString + ") from map table. " + e.getMessage());
+ throw new SQLException("Unable to parse predicate (" + pString
+ + ") from map table. " + e.getMessage());
} finally {
if (results != null) {
try {
@@ -271,20 +307,21 @@
/**
* Add a new table, mapping it to the given predicate.
* <p>
- * The new mapping will be persisted to the database
- * and stored in memory.
+ * The new mapping will be persisted to the database and stored in memory.
* </p>
* <p>
- * If a table is already mapped to the given predicate,
- * no action will be taken; the table name will just be
- * returned.
+ * If a table is already mapped to the given predicate, no action will be
+ * taken; the table name will just be returned.
* </p>
*
- * @param predicate The predicate.
- * @param conn The connection on which to create the table and
- * persist the mapping.
+ * @param predicate
+ * The predicate.
+ * @param conn
+ * The connection on which to create the table and persist the
+ * mapping.
* @return the table name.
- * @throws SQLException if a database error occurs.
+ * @throws SQLException
+ * if a database error occurs.
*/
private synchronized String mapTableFor(final PredicateNode predicate,
final Connection conn)
@@ -296,14 +333,14 @@
if (table != null) {
return table;
} else {
- LOG.info("Mapping new table for predicate: "
- + predicate.toString());
+ LOG
+ .info("Mapping new table for predicate: "
+ + predicate.toString());
int id = addPredicateToMapTable(predicate, conn);
try {
table = _soTablePrefix + id;
- executeDDL(conn,
- _ddlGenerator.getCreateSOTableDDL(table)
- .iterator());
+ executeDDL(conn, _ddlGenerator.getCreateSOTableDDL(table)
+ .iterator());
} catch (SQLException e) {
try {
// since we're not on a transaction, we must manually
@@ -326,11 +363,14 @@
/**
* Add a new predicate to the map table.
*
- * @param predicate The predicate to add.
- * @param conn The connection to use.
- * @return the auto-generated id for the predicate, used to formulate
- * the name for the new predicate table.
- * @throws SQLException if a database error occurs.
+ * @param predicate
+ * The predicate to add.
+ * @param conn
+ * The connection to use.
+ * @return the auto-generated id for the predicate, used to formulate the
+ * name for the new predicate table.
+ * @throws SQLException
+ * if a database error occurs.
*/
private int addPredicateToMapTable(final PredicateNode predicate,
final Connection conn)
@@ -339,8 +379,9 @@
String pString = predicate.toString();
// add to map table
- PreparedStatement ps = conn.prepareStatement(
- "INSERT INTO " + _mapTable + " (p) VALUES (?)");
+ PreparedStatement ps =
+ conn.prepareStatement("INSERT INTO " + _mapTable
+ + " (p) VALUES (?)");
try {
ps.setString(1, pString);
ps.execute();
@@ -353,8 +394,9 @@
}
// select db-generated id
- ps = conn.prepareStatement(
- "SELECT pKey from " + _mapTable + " WHERE p = ?");
+ ps =
+ conn.prepareStatement("SELECT pKey from " + _mapTable
+ + " WHERE p = ?");
try {
ps.setString(1, pString);
ResultSet rs = ps.executeQuery();
@@ -381,15 +423,19 @@
/**
* Remove the persistent mapping of the given predicate.
*
- * @param predicate The predicate whose mapping should be removed.
- * @param conn The connection on which to perform the operation.
- * @throws SQLException if a database error occurrs.
+ * @param predicate
+ * The predicate whose mapping should be removed.
+ * @param conn
+ * The connection on which to perform the operation.
+ * @throws SQLException
+ * if a database error occurrs.
*/
private void deletePredicateFromMapTable(final PredicateNode predicate,
final Connection conn)
throws SQLException {
- PreparedStatement ps = conn.prepareStatement(
- "DELETE FROM " + _mapTable + " WHERE p = ?");
+ PreparedStatement ps =
+ conn.prepareStatement("DELETE FROM " + _mapTable
+ + " WHERE p = ?");
try {
ps.setString(1, predicate.toString());
ps.execute();
@@ -402,13 +448,15 @@
}
}
-
/**
* Execute the given DDL statements.
*
- * @param conn The connection to use.
- * @param ddlIter The DDL to execute.
- * @throws SQLException if a database error occurs.
+ * @param conn
+ * The connection to use.
+ * @param ddlIter
+ * The DDL to execute.
+ * @throws SQLException
+ * if a database error occurs.
*/
private void executeDDL(final Connection conn,
final Iterator<String> ddlIter)
@@ -430,15 +478,16 @@
}
/**
- * Drop and unmap the indicated predicate tables.
+ * Drop and unmap the indicated predicate tables. The
+ * <code>DataSource</code> given in the constructor will be used for the
+ * connection.
*
- * The <code>DataSource</code> given in the constructor
- * will be used for the connection.
- *
- * @param all Boolean indicating whether to drop all of them,
- * or just the ones that are empty.
+ * @param all
+ * Boolean indicating whether to drop all of them, or just the ones
+ * that are empty.
* @return the number of dropped predicate tables.
- * @throws SQLException if a database error occurs.
+ * @throws SQLException
+ * if a database error occurs.
*/
private synchronized int dropPredicateTables(final boolean all)
throws SQLException {
@@ -474,10 +523,13 @@
/**
* Determine whether the given predicate table is empty.
*
- * @param table The name of the table.
- * @param conn The connection on which to make the determination.
+ * @param table
+ * The name of the table.
+ * @param conn
+ * The connection on which to make the determination.
* @return true if empty, false otherwise.
- * @throws SQLException if a database error occurs.
+ * @throws SQLException
+ * if a database error occurs.
*/
private boolean isPredicateTableEmpty(final String table,
final Connection conn)
@@ -504,29 +556,33 @@
}
/**
- * Remove the predicate from the memory and database maps,
- * then drop the associated table.
+ * Remove the predicate from the memory and database maps, then drop the
+ * associated table.
*
- * @param predicate The predicate to unmap.
- * @param table The associated predicate table.
- * @param conn The connection to use.
- * @throws SQLException if a database error occurs.
+ * @param predicate
+ * The predicate to unmap.
+ * @param table
+ * The associated predicate table.
+ * @param conn
+ * The connection to use.
+ * @throws SQLException
+ * if a database error occurs.
*/
private void unmapPredicate(final PredicateNode predicate,
final String table,
- final Connection conn)
- throws SQLException {
+ final Connection conn) throws SQLException {
String pString = predicate.toString();
- LOG.info("Unmapping " + pString
- + " and dropping associated table: " + table);
+ LOG.info("Unmapping " + pString + " and dropping associated table: "
+ + table);
_map.remove(predicate);
_reverseMap.remove(table);
- PreparedStatement ps = conn.prepareStatement(
- "DELETE FROM " + _mapTable + " WHERE p = ?");
+ PreparedStatement ps =
+ conn.prepareStatement("DELETE FROM " + _mapTable
+ + " WHERE p = ?");
try {
ps.setString(1, pString);
ps.execute();
@@ -538,8 +594,7 @@
}
}
- executeDDL(conn,
- _ddlGenerator.getDropSOTableDDL(table).iterator());
+ executeDDL(conn, _ddlGenerator.getDropSOTableDDL(table).iterator());
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|