+ public static final int MAX_CACHED_INSTANCES = 3;
+
+ private static class StatementDescriptor {
+
+ String query;
+
+ boolean scrollable;
+
+ int instance;
+
+ PreparedStatement target;
+
+ public StatementDescriptor(String query, boolean scrollable) {
+ this.query = query;
+ this.scrollable = scrollable;
+ this.instance = 0;
+ }
+
+ public synchronized void instanciate(Connection c) throws SQLException {
+ if (scrollable) {
+ target = c.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
+ } else {
+ target = c.prepareStatement(query, query.startsWith("SELECT ") ? Statement.NO_GENERATED_KEYS : Statement.RETURN_GENERATED_KEYS);
+ }
+
+ }
+
+ public synchronized PreparedStatement getTarget() {
+ return target;
+ }
+
+ public synchronized void increase() {
+ if (target != null) {
+ throw new IllegalStateException();
+ }
+ instance++;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + instance;
+ result = prime * result + ((query == null) ? 0 : query.hashCode());
+ result = prime * result + (scrollable ? 1231 : 1237);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ StatementDescriptor other = (StatementDescriptor) obj;
+ if (instance != other.instance) {
+ return false;
+ }
+ if (query == null) {
+ if (other.query != null) {
+ return false;
+ }
+ } else if ( !query.equals(other.query)) {
+ return false;
+ }
+ if (scrollable != other.scrollable) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ public static final int CURRENT_SCHEMA_VERSION = 9;
+