Skip to content

Commit b053076

Browse files
authored
Merge pull request #106 from FOCONIS/feature/change-schema-reset-review
Feature/change schema reset review
2 parents 536d15e + 921b428 commit b053076

File tree

2 files changed

+74
-27
lines changed

2 files changed

+74
-27
lines changed

ebean-datasource/src/main/java/io/ebean/datasource/pool/ConnectionPool.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,9 @@ private Connection initConnection(Connection conn) throws SQLException {
398398
if (readOnly) {
399399
conn.setReadOnly(true);
400400
}
401+
if (catalog != null) {
402+
conn.setCatalog(catalog);
403+
}
401404
if (schema != null) {
402405
conn.setSchema(schema);
403406
}

ebean-datasource/src/main/java/io/ebean/datasource/pool/PooledConnection.java

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ final class PooledConnection extends ConnectionDelegator {
5757

5858
private static final int RO_MYSQL_1290 = 1290;
5959

60+
/**
61+
* Constant for schema/catalog, when we are in SCHEMA_CATALOG_UNKNOWN state
62+
* This is used for correct cache key computation. (We cannot use 'null'
63+
* here, as we might get a collision in edge cases)
64+
*/
65+
private static final String UNKNOWN = "@unknown";
66+
67+
/**
68+
* The schema/catalog is unknown, that means, we have not yet touched the
69+
* value on the underlying connection.
70+
* We do not have to restore it.
71+
*/
72+
private static final int SCHEMA_CATALOG_UNKNOWN = 0;
73+
74+
/**
75+
* The schema/catalog is changed. The original value has to be restored on
76+
* close()
77+
*/
78+
private static final int SCHEMA_CATALOG_CHANGED = 1;
79+
80+
/**
81+
* We know the original value of the underlying connection, but there is no
82+
* demand to restore it.
83+
*/
84+
private static final int SCHEMA_CATALOG_KNOWN = 2;
85+
6086
private final String name;
6187
private final ConnectionPool pool;
6288
private final Connection connection;
@@ -82,12 +108,14 @@ final class PooledConnection extends ConnectionDelegator {
82108
*/
83109
private boolean failoverToReadOnly;
84110
private boolean resetAutoCommit;
85-
private boolean resetSchema;
86-
private boolean resetCatalog;
87-
private boolean initialisedSchema;
88-
private boolean initialisedCatalog;
89-
private String currentSchema;
90-
private String currentCatalog;
111+
private int schemaState = SCHEMA_CATALOG_UNKNOWN;
112+
private int catalogState = SCHEMA_CATALOG_UNKNOWN;
113+
114+
// this is used for cache computation
115+
private String cacheKeySchema = UNKNOWN;
116+
private String cacheKeyCatalog = UNKNOWN;
117+
118+
// original values are lazily initialized and restored on close()
91119
private String originalSchema;
92120
private String originalCatalog;
93121

@@ -122,10 +150,17 @@ final class PooledConnection extends ConnectionDelegator {
122150
this.name = pool.name() + uniqueId;
123151
this.originalSchema = pool.schema();
124152
this.originalCatalog = pool.catalog();
125-
this.initialisedSchema = originalSchema != null;
126-
this.initialisedCatalog = originalCatalog != null;
127-
this.currentSchema = originalSchema != null ? originalSchema : "@default";
128-
this.currentCatalog = originalCatalog != null ? originalCatalog : "@default";
153+
if (originalSchema != null) {
154+
schemaState = SCHEMA_CATALOG_KNOWN;
155+
this.cacheKeySchema = originalSchema;
156+
// if schema & catalog is defined, we can be sure, that connection is initialized properly
157+
assert originalSchema.equals(connection.getSchema()) : "Connection is in the wrong schema: " + connection.getSchema() + ", expected: " + originalSchema;
158+
}
159+
if (originalCatalog != null) {
160+
catalogState = SCHEMA_CATALOG_KNOWN;
161+
this.cacheKeyCatalog = originalCatalog;
162+
assert originalCatalog.equals(connection.getCatalog()) : "Connection is in the wrong catalog: " + connection.getCatalog() + ", expected: " + originalCatalog;
163+
}
129164
this.pstmtCache = new PstmtCache(pool.pstmtCacheSize());
130165
this.maxStackTrace = pool.maxStackTraceSize();
131166
this.creationTime = System.currentTimeMillis();
@@ -287,7 +322,7 @@ void returnPreparedStatement(ExtendedPreparedStatement pstmt) {
287322
*/
288323
@Override
289324
public PreparedStatement prepareStatement(String sql, int returnKeysFlag) throws SQLException {
290-
String key = sql + ':' + currentSchema + ':' + currentCatalog + ':' + returnKeysFlag;
325+
String key = sql + ':' + cacheKeySchema + ':' + cacheKeyCatalog + ':' + returnKeysFlag;
291326
return prepareStatement(sql, true, returnKeysFlag, key);
292327
}
293328

@@ -296,7 +331,7 @@ public PreparedStatement prepareStatement(String sql, int returnKeysFlag) throws
296331
*/
297332
@Override
298333
public PreparedStatement prepareStatement(String sql) throws SQLException {
299-
String key = sql + ':' + currentSchema + ':' + currentCatalog;
334+
String key = sql + ':' + cacheKeySchema + ':' + cacheKeyCatalog;
300335
return prepareStatement(sql, false, 0, key);
301336
}
302337

@@ -350,12 +385,21 @@ public PreparedStatement prepareStatement(String sql, int resultSetType, int res
350385
* Reset the connection for returning to the client. Resets the status,
351386
* startUseTime and hadErrors.
352387
*/
353-
void resetForUse() {
388+
void resetForUse() throws SQLException {
354389
this.status = STATUS_ACTIVE;
355390
this.startUseTime = System.currentTimeMillis();
356391
this.createdByMethod = null;
357392
this.lastStatement = null;
358393
this.hadErrors = false;
394+
// CHECKME: Shoud we keep the asserts here or should we even reset schema/catalog here
395+
assert schemaState != SCHEMA_CATALOG_CHANGED : "connection is in the wrong state (not properly closed)";
396+
if (schemaState == SCHEMA_CATALOG_KNOWN) {
397+
assert originalSchema.equals(getSchema()) : "connection is in the wrong schema: " + getSchema() + ", expected: " + originalSchema;
398+
}
399+
assert catalogState != SCHEMA_CATALOG_CHANGED : "connection is in the wrong state (not properly closed)";
400+
if (catalogState == SCHEMA_CATALOG_KNOWN) {
401+
assert originalCatalog.equals(getCatalog()) : "connection is in the wrong catalog: " + getCatalog() + ", expected: " + originalCatalog;
402+
}
359403
}
360404

361405
/**
@@ -426,16 +470,17 @@ public void close() throws SQLException {
426470
resetIsolationReadOnlyRequired = false;
427471
}
428472

429-
if (resetSchema) {
473+
if (schemaState == SCHEMA_CATALOG_CHANGED) {
430474
connection.setSchema(originalSchema);
431-
currentSchema = null;
432-
resetSchema = false;
475+
// we can use original value for cache computation from now on
476+
cacheKeySchema = originalSchema;
477+
schemaState = SCHEMA_CATALOG_KNOWN;
433478
}
434479

435-
if (resetCatalog) {
480+
if (catalogState == SCHEMA_CATALOG_CHANGED) {
436481
connection.setCatalog(originalCatalog);
437-
currentCatalog = null;
438-
resetCatalog = false;
482+
cacheKeyCatalog = originalCatalog;
483+
catalogState = SCHEMA_CATALOG_KNOWN;
439484
}
440485

441486
// the connection is assumed GOOD so put it back in the pool
@@ -706,13 +751,13 @@ public void setSchema(String schema) throws SQLException {
706751
if (status == STATUS_IDLE) {
707752
throw new SQLException(IDLE_CONNECTION_ACCESSED_ERROR + "setSchema()");
708753
}
709-
if (!initialisedSchema) {
754+
if (schemaState == SCHEMA_CATALOG_UNKNOWN) {
710755
// lazily initialise the originalSchema
711756
originalSchema = getSchema();
712-
initialisedSchema = true;
757+
// state would be KNOWN here
713758
}
714-
currentSchema = schema;
715-
resetSchema = true;
759+
schemaState = SCHEMA_CATALOG_CHANGED;
760+
cacheKeySchema = schema;
716761
connection.setSchema(schema);
717762
}
718763

@@ -721,12 +766,11 @@ public void setCatalog(String catalog) throws SQLException {
721766
if (status == STATUS_IDLE) {
722767
throw new SQLException(IDLE_CONNECTION_ACCESSED_ERROR + "setCatalog()");
723768
}
724-
if (!initialisedCatalog) {
769+
if (schemaState == SCHEMA_CATALOG_UNKNOWN) {
725770
originalCatalog = getCatalog();
726-
initialisedCatalog = true;
727771
}
728-
currentCatalog = catalog;
729-
resetCatalog = true;
772+
catalogState = SCHEMA_CATALOG_CHANGED;
773+
cacheKeyCatalog = catalog;
730774
connection.setCatalog(catalog);
731775
}
732776

0 commit comments

Comments
 (0)