CAY-1966 SQLTemplate/SQLSelect positional parameter binding * positional parameters must be included in cache key
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/e2069efe Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/e2069efe Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/e2069efe Branch: refs/heads/master Commit: e2069efeb92b1684c548af50aefa508942b5d3b8 Parents: 60f3f15 Author: aadamchik <[email protected]> Authored: Fri Jan 16 09:19:09 2015 +0300 Committer: aadamchik <[email protected]> Committed: Fri Jan 16 09:36:29 2015 +0300 ---------------------------------------------------------------------- .../cayenne/query/SQLTemplateMetadata.java | 117 +++++++++---------- .../org/apache/cayenne/query/SQLSelectTest.java | 19 +++ 2 files changed, 77 insertions(+), 59 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/e2069efe/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplateMetadata.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplateMetadata.java b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplateMetadata.java index 61a3a68..de106d5 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplateMetadata.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/query/SQLTemplateMetadata.java @@ -31,63 +31,62 @@ import org.apache.cayenne.map.ObjEntity; */ class SQLTemplateMetadata extends BaseQueryMetadata { - boolean resolve(Object root, EntityResolver resolver, SQLTemplate query) { - - if (super.resolve(root, resolver, null)) { - - resultSetMapping = query.getResult() != null ? query - .getResult() - .getResolvedComponents(resolver) : null; - - // generate unique cache key... - if (QueryCacheStrategy.NO_CACHE == getCacheStrategy()) { - - } - else { - - // create a unique key based on entity, SQL, and parameters - - StringBuilder key = new StringBuilder(); - ObjEntity entity = getObjEntity(); - if (entity != null) { - key.append(entity.getName()); - } - else if (dbEntity != null) { - key.append("db:").append(dbEntity.getName()); - } - - if (query.getDefaultTemplate() != null) { - key.append('/').append(query.getDefaultTemplate()); - } - - Map<String, ?> parameters = query.getParams(); - if (!parameters.isEmpty()) { - - List<String> keys = new ArrayList<String>(parameters.keySet()); - Collections.sort(keys); - - for (String parameterKey : keys) { - key.append('/').append(parameterKey).append('=').append( - parameters.get(parameterKey)); - } - } - - if (query.getFetchOffset() > 0 || query.getFetchLimit() > 0) { - key.append('/'); - if (query.getFetchOffset() > 0) { - key.append('o').append(query.getFetchOffset()); - } - if (query.getFetchLimit() > 0) { - key.append('l').append(query.getFetchLimit()); - } - } - - this.cacheKey = key.toString(); - } - - return true; - } - - return false; - } + boolean resolve(Object root, EntityResolver resolver, SQLTemplate query) { + + if (super.resolve(root, resolver, null)) { + + resultSetMapping = query.getResult() != null ? query.getResult().getResolvedComponents(resolver) : null; + + // generate unique cache key... + if (QueryCacheStrategy.NO_CACHE == getCacheStrategy()) { + + } else { + + // create a unique key based on entity, SQL, and parameters + + StringBuilder key = new StringBuilder(); + ObjEntity entity = getObjEntity(); + if (entity != null) { + key.append(entity.getName()); + } else if (dbEntity != null) { + key.append("db:").append(dbEntity.getName()); + } + + if (query.getDefaultTemplate() != null) { + key.append('/').append(query.getDefaultTemplate()); + } + + Map<String, ?> parameters = query.getParams(); + if (!parameters.isEmpty()) { + + List<String> keys = new ArrayList<String>(parameters.keySet()); + Collections.sort(keys); + + for (String parameterKey : keys) { + key.append('/').append(parameterKey).append('=').append(parameters.get(parameterKey)); + } + } + + for (Object parameter : query.getPositionalParams()) { + key.append("/p:").append(parameter); + } + + if (query.getFetchOffset() > 0 || query.getFetchLimit() > 0) { + key.append('/'); + if (query.getFetchOffset() > 0) { + key.append('o').append(query.getFetchOffset()); + } + if (query.getFetchLimit() > 0) { + key.append('l').append(query.getFetchLimit()); + } + } + + this.cacheKey = key.toString(); + } + + return true; + } + + return false; + } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/e2069efe/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectTest.java ---------------------------------------------------------------------- diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectTest.java b/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectTest.java index 439ff44..303d9e4 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/query/SQLSelectTest.java @@ -20,6 +20,8 @@ package org.apache.cayenne.query; import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertThat; @@ -116,4 +118,21 @@ public class SQLSelectTest { SQLTemplate replacement = (SQLTemplate) q.createReplacementQuery(mock(EntityResolver.class)); assertArrayEquals(new Object[] { "a", "b" }, replacement.getPositionalParams().toArray()); } + + @Test + public void testGetMetadata_ParamsArray_Multiple_Cache() { + + EntityResolver resolver = mock(EntityResolver.class); + QueryMetadata md0 = SQLSelect.dataRowQuery("bla").localCache().getMetaData(resolver); + QueryMetadata md1 = SQLSelect.dataRowQuery("bla").localCache().paramsArray("a").getMetaData(resolver); + QueryMetadata md2 = SQLSelect.dataRowQuery("bla").localCache().paramsArray("a", "b").getMetaData(resolver); + + assertNotNull(md0.getCacheKey()); + assertNotNull(md1.getCacheKey()); + assertNotNull(md2.getCacheKey()); + + assertNotEquals(md0.getCacheKey(), md1.getCacheKey()); + assertNotEquals(md0.getCacheKey(), md2.getCacheKey()); + assertNotEquals(md1.getCacheKey(), md2.getCacheKey()); + } }
