StatementManager.java (hsqldb-2.6.0) | : | StatementManager.java (hsqldb-2.6.1) | ||
---|---|---|---|---|
skipping to change at line 71 | skipping to change at line 71 | |||
* it is not in use.<p> | * it is not in use.<p> | |||
* | * | |||
* Modified by fredt@users from the original by campbell-burnet@users to | * Modified by fredt@users from the original by campbell-burnet@users to | |||
* simplify, support multiple identical prepared statements per session, and | * simplify, support multiple identical prepared statements per session, and | |||
* avoid memory leaks. Changed implementation to a session object for optimised | * avoid memory leaks. Changed implementation to a session object for optimised | |||
* access.<p> | * access.<p> | |||
* | * | |||
* @author Campbell Burnet (campbell-burnet@users dot sourceforge.net) | * @author Campbell Burnet (campbell-burnet@users dot sourceforge.net) | |||
* @author Fred Toussi (fredt@users dot sourceforge.net) | * @author Fred Toussi (fredt@users dot sourceforge.net) | |||
* | * | |||
* @version 2.6.0 | * @version 2.6.1 | |||
* @since 1.7.2 | * @since 1.7.2 | |||
*/ | */ | |||
public final class StatementManager { | public final class StatementManager { | |||
/** | /** The Database for which this is managing Statement objects. */ | |||
* The Database for which this object is managing | ||||
* CompiledStatement objects. | ||||
*/ | ||||
private Database database; | private Database database; | |||
/** Set: Compiled statement wrapper for Statement object. */ | /** The Session for which this is managing Statement objects */ | |||
private HashSet<StatementWrapper> statementSet; | private Session session; | |||
/** Set of wrappers for Statement object. */ | ||||
private HashSet<StatementWrapper> statementSet; | ||||
/** Map: Compiled statement id (int) => wrapper for Statement object. */ | /** Map: Statement id (int) => wrapper for Statement object. */ | |||
private LongKeyHashMap csidMap; | private LongKeyHashMap csidMap; | |||
/** | /** | |||
* Monotonically increasing counter used to assign unique ids to compiled | * Monotonically increasing counter used to assign unique ids to | |||
* statements. | * Statement objects. | |||
*/ | */ | |||
private long next_cs_id; | private long next_cs_id; | |||
/** | /** | |||
* Constructs a new instance of <code>CompiledStatementManager</code>. | * Constructs a new instance of <code>StatementManager</code>. | |||
* | * | |||
* @param database the Database instance for which this object is to | * @param session the session instance for which this object is to | |||
* manage compiled statement objects. | * manage Statement objects. | |||
*/ | */ | |||
StatementManager(Database database) { | StatementManager(Session session) { | |||
this.database = database; | this.session = session; | |||
this.database = session.database; | ||||
statementSet = new HashSet(32, new StatementComparator()); | statementSet = new HashSet(32, new StatementComparator()); | |||
csidMap = new LongKeyHashMap(); | csidMap = new LongKeyHashMap(); | |||
next_cs_id = 0; | next_cs_id = 0; | |||
} | } | |||
/** | /** | |||
* Clears all internal data structures, removing any references to compiled statements. | * Clears all internal data structures, removing any references to Statement s. | |||
*/ | */ | |||
synchronized void reset() { | void reset() { | |||
statementSet.clear(); | statementSet.clear(); | |||
csidMap.clear(); | csidMap.clear(); | |||
next_cs_id = 0; | next_cs_id = 0; | |||
} | } | |||
/** | /** | |||
* Retrieves the next compiled statement identifier in the sequence. | * Retrieves the next Statement identifier in the sequence. | |||
* | * | |||
* @return the next compiled statement identifier in the sequence. | * @return the next Statement identifier in the sequence. | |||
*/ | */ | |||
private long nextID() { | private long nextID() { | |||
next_cs_id++; | next_cs_id++; | |||
return next_cs_id; | return next_cs_id; | |||
} | } | |||
/** | /** | |||
* Returns an existing tatement object with the given | * Returns an existing Statement object with the given | |||
* statement identifier. Returns null if the CompiledStatement object | * statement identifier. Returns null if the Statement object | |||
* has expired and cannot be recompiled | * has expired and cannot be recompiled | |||
* | * | |||
* @param session the session | * @param csid the identifier of the requested Statement object | |||
* @param csid the identifier of the requested CompiledStatement object | * @return the requested Statement object | |||
* @return the requested CompiledStatement object | ||||
*/ | */ | |||
public synchronized Statement getStatement(Session session, long csid) { | public Statement getStatement(long csid) { | |||
StatementWrapper sw = (StatementWrapper) csidMap.get(csid); | StatementWrapper sw = (StatementWrapper) csidMap.get(csid); | |||
if (sw == null) { | if (sw == null) { | |||
return null; | return null; | |||
} | } | |||
return getStatement(sw); | ||||
} | ||||
private Statement getStatement(StatementWrapper sw) { | ||||
Statement statement = sw.statement; | Statement statement = sw.statement; | |||
if (statement.getCompileTimestamp() | if (statement.getCompileTimestamp() | |||
< database.schemaManager.getSchemaChangeTimestamp()) { | < database.schemaManager.getSchemaChangeTimestamp()) { | |||
Statement newStatement = recompileStatement(session, statement); | Statement newStatement = recompileStatement(statement); | |||
if (newStatement == null) { | if (newStatement == null) { | |||
removeStatement(csid); | removeStatement(statement.getID()); | |||
return null; | return null; | |||
} | } | |||
newStatement.setCompileTimestamp( | newStatement.setCompileTimestamp( | |||
database.txManager.getGlobalChangeTimestamp()); | database.txManager.getGlobalChangeTimestamp()); | |||
sw.statement = newStatement; | sw.statement = newStatement; | |||
return newStatement; | return newStatement; | |||
} | } | |||
return sw.statement; | return sw.statement; | |||
} | } | |||
/** | /** | |||
* Recompiles an existing statement. | * Recompiles an existing statement. | |||
* | * | |||
* Used by transaction manager for all statements, prepared or not prepred. | * Used by transaction manager for all statements, prepared or not prepred. | |||
* | * | |||
* @param session the session | ||||
* @param statement the old expired statement | * @param statement the old expired statement | |||
* @return the requested CompiledStatement object | * @return the requested Statement object | |||
*/ | */ | |||
public synchronized Statement getStatement(Session session, | public Statement getStatement(Statement statement) { | |||
Statement statement) { | ||||
long csid = statement.getID(); | long csid = statement.getID(); | |||
StatementWrapper sw = (StatementWrapper) csidMap.get(csid); | ||||
if (sw != null) { | if (csid != 0) { | |||
return getStatement(session, csid); | StatementWrapper sw = (StatementWrapper) csidMap.get(csid); | |||
if (sw != null) { | ||||
return getStatement(sw); | ||||
} | ||||
} | } | |||
return recompileStatement(session, statement); | return recompileStatement(statement); | |||
} | } | |||
/** | /** | |||
* Returns an up-to-date compiled statement using the SQL and settings of | * Returns an up-to-date Statement using the SQL and settings of | |||
* the original. Returns null if the new statement is invalid. | * the original. Returns null if the SQL cannot be compiled. | |||
* | * | |||
* @param session the session | ||||
* @param cs the old expired statement | * @param cs the old expired statement | |||
* @return the new Statement object | * @return the new Statement object | |||
*/ | */ | |||
private Statement recompileStatement(Session session, Statement cs) { | private Statement recompileStatement(Statement cs) { | |||
HsqlName oldSchema = session.getCurrentSchemaHsqlName(); | HsqlName oldSchema = session.getCurrentSchemaHsqlName(); | |||
Statement newStatement; | Statement newStatement; | |||
// revalidate with the original schema | // revalidate with the original schema | |||
try { | try { | |||
HsqlName schema = cs.getSchemaName(); | HsqlName schema = cs.getSchemaName(); | |||
int props = cs.getCursorPropertiesRequest(); | int props = cs.getCursorPropertiesRequest(); | |||
if (schema != null) { | if (schema != null) { | |||
skipping to change at line 252 | skipping to change at line 257 | |||
} catch (Throwable t) { | } catch (Throwable t) { | |||
return null; | return null; | |||
} finally { | } finally { | |||
session.setCurrentSchemaHsqlName(oldSchema); | session.setCurrentSchemaHsqlName(oldSchema); | |||
} | } | |||
return newStatement; | return newStatement; | |||
} | } | |||
/** | /** | |||
* Registers a compiled statement to be managed. | * Registers a Statement to be managed. | |||
* | * | |||
* @param wrapper the wrapper for the Statement to add | * @param wrapper the wrapper for the Statement to add | |||
* @return The statement id assigned to the Statement object | * @return The statement id assigned to the Statement object | |||
*/ | */ | |||
private long registerStatement(StatementWrapper wrapper) { | private long registerStatement(StatementWrapper wrapper) { | |||
Statement cs = wrapper.statement; | Statement cs = wrapper.statement; | |||
cs.setCompileTimestamp(database.txManager.getGlobalChangeTimestamp()); | cs.setCompileTimestamp(database.txManager.getGlobalChangeTimestamp()); | |||
skipping to change at line 277 | skipping to change at line 282 | |||
csidMap.put(csid, wrapper); | csidMap.put(csid, wrapper); | |||
return csid; | return csid; | |||
} | } | |||
/** | /** | |||
* Removes a link between a PreparedStatement and a Statement. If the | * Removes a link between a PreparedStatement and a Statement. If the | |||
* statement is not linked with any other PreparedStatement, it is | * statement is not linked with any other PreparedStatement, it is | |||
* removed from management. | * removed from management. | |||
* | * | |||
* @param csid the compiled statement identifier | * @param csid the Statement identifier | |||
*/ | */ | |||
synchronized void freeStatement(long csid) { | void freeStatement(long csid) { | |||
StatementWrapper sw = (StatementWrapper) csidMap.get(csid); | StatementWrapper sw = (StatementWrapper) csidMap.get(csid); | |||
if (sw == null) { | if (sw == null) { | |||
return; | return; | |||
} | } | |||
sw.usageCount--; | sw.usageCount--; | |||
if (sw.usageCount == 0) { | if (sw.usageCount == 0) { | |||
removeStatement(csid); | removeStatement(csid); | |||
} | } | |||
} | } | |||
/** | /** | |||
* Removes an invalidated Statement. | * Removes an invalidated Statement. | |||
* | * | |||
* @param csid the compiled statement identifier | * @param csid the Statement identifier | |||
*/ | */ | |||
synchronized void removeStatement(long csid) { | private void removeStatement(long csid) { | |||
if (csid <= 0) { | if (csid <= 0) { | |||
// statement was never added | // statement was never added | |||
return; | return; | |||
} | } | |||
StatementWrapper sw = (StatementWrapper) csidMap.remove(csid); | StatementWrapper sw = (StatementWrapper) csidMap.remove(csid); | |||
if (sw != null) { | if (sw != null) { | |||
statementSet.remove(sw); | statementSet.remove(sw); | |||
} | } | |||
} | } | |||
/** | /** | |||
* Compiles an SQL statement and returns a Statement Object | * Compiles an SQL statement and returns a Statement Object | |||
* | * | |||
* @param session the session | ||||
* @param cmd the Result holding the SQL | * @param cmd the Result holding the SQL | |||
* @return CompiledStatement | * @return Statement | |||
*/ | */ | |||
synchronized Statement compile(Session session, Result cmd) { | Statement compile(Result cmd) { | |||
StatementWrapper newWrapper = new StatementWrapper(); | StatementWrapper newWrapper = new StatementWrapper(); | |||
newWrapper.sql = cmd.getMainString(); | newWrapper.sql = cmd.getMainString(); | |||
newWrapper.cursorProps = cmd.getExecuteProperties(); | newWrapper.cursorProps = cmd.getExecuteProperties(); | |||
newWrapper.generatedType = cmd.getGeneratedResultType(); | newWrapper.generatedType = cmd.getGeneratedResultType(); | |||
newWrapper.generatedMetaData = cmd.getGeneratedResultMetaData(); | newWrapper.generatedMetaData = cmd.getGeneratedResultMetaData(); | |||
newWrapper.schemaName = session.currentSchema; | newWrapper.schemaName = session.currentSchema; | |||
StatementWrapper wrapper = statementSet.get(newWrapper); | StatementWrapper wrapper = statementSet.get(newWrapper); | |||
End of changes. 36 change blocks. | ||||
48 lines changed or deleted | 52 lines changed or added |