Ensure that field names are treated consistently and in a case-insensitive way.
Project: http://git-wip-us.apache.org/repos/asf/usergrid/repo
Commit: http://git-wip-us.apache.org/repos/asf/usergrid/commit/5452d68c
Tree: http://git-wip-us.apache.org/repos/asf/usergrid/tree/5452d68c
Diff: http://git-wip-us.apache.org/repos/asf/usergrid/diff/5452d68c
Branch: refs/heads/release-2.1.1
Commit: 5452d68c29bb59ec8794639cdc8d6d819792e8bb
Parents: 151abf7
Author: Dave Johnson <snoopdave@apache.org>
Authored: Wed Jun 1 09:56:01 2016 -0400
Committer: Dave Johnson <snoopdave@apache.org>
Committed: Wed Jun 1 09:56:01 2016 -0400
----------------------------------------------------------------------
.../read/search/CandidateEntityFilter.java | 13 +++
.../model/field/value/EntityObject.java | 15 ++-
.../queries/SelectMappingsQueryTest.java | 105 +++++++++++++++++++
3 files changed, 128 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/usergrid/blob/5452d68c/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
----------------------------------------------------------------------
diff --git a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
index 4aa6c8d..7770436 100644
--- a/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
+++ b/stack/core/src/main/java/org/apache/usergrid/corepersistence/pipeline/read/search/CandidateEntityFilter.java
@@ -161,6 +161,13 @@ public class CandidateEntityFilter extends AbstractFilter<FilterResult<Candidate
}
+ /**
+ * Sets field in result map with support for nested fields via recursion.
+ *
+ * @param result The result map of filtered fields
+ * @param parts The parts of the field name (more than one if field is nested)
+ * @param fieldMap Map of fields of the object
+ */
private void nestedFieldSet( Map<String, Field> result, String[] parts, Map<String,
Field> fieldMap) {
if ( parts.length > 0 ) {
@@ -184,6 +191,12 @@ public class CandidateEntityFilter extends AbstractFilter<FilterResult<Candidate
}
+ /**
+ * Check to see if field should be included in filtered result with support for nested
fields via recursion.
+ *
+ * @param parts The parts of the field name (more than one if field is nested)
+ * @param fieldMap Map of fields of the object
+ */
private boolean nestedFieldCheck( String[] parts, Map<String, Field> fieldMap)
{
if ( parts.length > 0 ) {
http://git-wip-us.apache.org/repos/asf/usergrid/blob/5452d68c/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/value/EntityObject.java
----------------------------------------------------------------------
diff --git a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/value/EntityObject.java
b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/value/EntityObject.java
index db44e87..a157029 100644
--- a/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/value/EntityObject.java
+++ b/stack/corepersistence/model/src/main/java/org/apache/usergrid/persistence/model/field/value/EntityObject.java
@@ -19,10 +19,7 @@
package org.apache.usergrid.persistence.model.field.value;
import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
import org.apache.usergrid.persistence.model.field.Field;
@@ -41,11 +38,19 @@ public class EntityObject implements Serializable {
@JsonIgnore
private long size;
+ // field names are treated in case-insensitive way by design
+ static class CaseInsensitiveComparator implements Comparator<String> {
+ public int compare(String o1, String o2) {
+ return o1.compareToIgnoreCase(o2);
+ }
+ }
+ public static final CaseInsensitiveComparator INSTANCE = new CaseInsensitiveComparator();
+
/**
* Fields the users can set
*/
@JsonTypeInfo( use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class"
)
- private final Map<String, Field> fields = new HashMap<String, Field>();
+ private Map<String, Field> fields = new TreeMap<String, Field>(INSTANCE);
/**
* Add the field, return the old one if it existed
http://git-wip-us.apache.org/repos/asf/usergrid/blob/5452d68c/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/SelectMappingsQueryTest.java
----------------------------------------------------------------------
diff --git a/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/SelectMappingsQueryTest.java
b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/SelectMappingsQueryTest.java
new file mode 100644
index 0000000..eb6aeee
--- /dev/null
+++ b/stack/rest/src/test/java/org/apache/usergrid/rest/applications/queries/SelectMappingsQueryTest.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.usergrid.rest.applications.queries;
+
+import org.apache.usergrid.rest.test.resource.model.Collection;
+import org.apache.usergrid.rest.test.resource.model.Entity;
+import org.apache.usergrid.rest.test.resource.model.QueryParameters;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+
+public class SelectMappingsQueryTest extends QueryTestBase {
+ private static final Logger logger = LoggerFactory.getLogger(OrderByTest.class);
+
+
+ @Test
+ public void testNestedSelectFieldNames() throws Exception {
+
+ generateTestEntities(20, "things");
+
+ QueryParameters params = new QueryParameters()
+ .setQuery("select actor.displayName,sometestprop where sometestprop = 'testprop'");
+ Collection things = this.app().collection("things").get(params);
+ assertEquals( 10, things.getNumOfEntities() );
+
+ Iterator<Entity> iter = things.iterator();
+ while ( iter.hasNext() ) {
+
+ Entity entity = iter.next();
+ assertEquals( 5, entity.getDynamicProperties().size() );
+
+ assertNotNull( entity.getDynamicProperties().get("uuid") );
+ assertNotNull( entity.getDynamicProperties().get("type") );
+ assertNotNull( entity.getDynamicProperties().get("metadata") );
+ assertNotNull( entity.getDynamicProperties().get("sometestprop") );
+
+ Map<String, Object> actor = (Map<String, Object>)entity.getDynamicProperties().get("actor");
+ assertNotNull( actor );
+ assertNotNull( actor.get("displayName") );
+
+ }
+ }
+
+
+ /**
+ * Shows that field names are case-insensitive.
+ * If you define two fields with same name but different cases, behavior is undefined.
+ */
+ @Test
+ public void testFieldNameCaseSensitivity() throws Exception {
+
+ int numberOfEntities = 10;
+ String collectionName = "things";
+
+ Entity[] entities = new Entity[numberOfEntities];
+ Entity props = new Entity();
+
+ for (int i = 0; i < numberOfEntities; i++) {
+ props.put("testProp", "a");
+ props.put("testprop", "b");
+ entities[i] = app().collection(collectionName).post(props);
+ }
+ refreshIndex();
+
+ {
+ QueryParameters params = new QueryParameters()
+ .setQuery( "select * where testProp = 'b'" );
+ Collection things = this.app().collection( "things" ).get( params );
+
+ // if field names were case sensitive, this would fail
+ assertEquals( numberOfEntities, things.getNumOfEntities() );
+ }
+
+ {
+ QueryParameters params = new QueryParameters()
+ .setQuery( "select * where testprop='b'" );
+ Collection things = this.app().collection( "things" ).get( params );
+
+ assertEquals( numberOfEntities, things.getNumOfEntities() );
+ }
+
+ }
+
+}
|