Skip to content

Commit

Permalink
Merge pull request #232 from gaelyk/suggestion/datastore-properties-t…
Browse files Browse the repository at this point in the history
…ypes

keeping datastore types to avoid unnecessary reflection
  • Loading branch information
codeconsole committed May 20, 2019
2 parents 7bbcd17 + ab1c9b8 commit c6488a9
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
16 changes: 16 additions & 0 deletions core/src/main/groovyx/gaelyk/datastore/DatastoreEntity.java
Expand Up @@ -100,13 +100,29 @@ public interface DatastoreEntity<K> {
*/
List<String> getDatastoreIndexedProperties();

/**
* Returns list of the types of properties which should be saved in the data store with the index.
* This method should return same values for each instance. It cannot be static because of Java interface restrictions.
*
* @return list of the types of properties which should be saved in the data store with the index
*/
List<Class> getDatastoreIndexedPropertiesTypes();

/**
* Returns list of the names of properties which should be saved in the data store unindexed.
* This method should return same values for each instance. It cannot be static because of Java interface restrictions.
*
* @return list of the names of properties which should be saved in the data store unindexed
*/
List<String> getDatastoreUnindexedProperties();

/**
* Returns list of the types of properties which should be saved in the data store unindexed.
* This method should return same values for each instance. It cannot be static because of Java interface restrictions.
*
* @return list of the types of properties which should be saved in the data store unindexed
*/
List<Class> getDatastoreUnindexedPropertiesTypes();

// taken from GroovyObject, for java compatibility. Groovy classes has these methods
// automagically
Expand Down
53 changes: 53 additions & 0 deletions core/src/main/groovyx/gaelyk/datastore/EntityTransformation.groovy
Expand Up @@ -121,6 +121,10 @@ class EntityTransformation extends AbstractASTTransformation {
GenericsUtils.makeClassSafeWithGenerics(ClassHelper.make(List), new GenericsType(parent))
}

private static ClassNode getClassNodeForClass() {
GenericsUtils.makeClassSafeWithGenerics(ClassHelper.make(List), new GenericsType(ClassHelper.makeWithoutCaching(Class)))
}

private ClassNode handleKey(ClassNode parent, SourceUnit source) {
ClassNode keyAnnoClassNode = ClassHelper.make(groovyx.gaelyk.datastore.Key).plainNodeReference

Expand Down Expand Up @@ -361,7 +365,9 @@ class EntityTransformation extends AbstractASTTransformation {
boolean defaultIndexed = memberHasValue(anno, 'unindexed', false)

List<String> indexed = []
List<ClassNode> indexedTypes = []
List<String> unindexed = []
List<ClassNode> unindexedTypes = []

eachPropertyIncludingSuper(parent) { PropertyNode prop ->
if(Modifier.isStatic(prop.modifiers) || Modifier.isFinal(prop.modifiers)) {
Expand All @@ -382,19 +388,23 @@ class EntityTransformation extends AbstractASTTransformation {
}
if(hasUnindexedAnno){
unindexed << prop.name
unindexedTypes << prop.type
return
}
boolean hasIndexedAnno = annos.any { AnnotationNode a ->
a.classNode == indexedAnnoClassNode
}
if(hasIndexedAnno){
indexed << prop.name
indexedTypes << prop.type
return
}
if(defaultIndexed){
indexed << prop.name
indexedTypes << prop.type
} else {
unindexed << prop.name
unindexedTypes << prop.type
}
}

Expand Down Expand Up @@ -426,6 +436,39 @@ class EntityTransformation extends AbstractASTTransformation {
self.columnNumber = 1
self
}

parent.addField new FieldNode('DATASTORE_INDEXED_PROPERTIES_TYPES', Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, getBoundListNode(classNodeForClass), parent, buildClassList(indexedTypes))

parent.addMethod new MethodNode(
'getDatastoreIndexedPropertiesTypes',
Modifier.PUBLIC,
// cannot use list of classes directly as it causes NPE in TypeResolver
// but thanks to type errasure this also works
GenericsUtils.makeClassSafeWithGenerics(List, ClassHelper.OBJECT_TYPE),
Parameter.EMPTY_ARRAY,
ClassNode.EMPTY_ARRAY,
new ReturnStatement(new VariableExpression('DATASTORE_INDEXED_PROPERTIES_TYPES'))
).with { MethodNode self ->
self.lineNumber = 10013
self.columnNumber = 1
self
}

parent.addField new FieldNode('DATASTORE_UNINDEXED_PROPERTIES_TYPES', Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL, getBoundListNode(classNodeForClass), parent, buildClassList(unindexedTypes))
parent.addMethod new MethodNode(
'getDatastoreUnindexedPropertiesTypes',
Modifier.PUBLIC,
// cannot use list of classes directly as it causes NPE in TypeResolver
// but thanks to type errasure this also works
GenericsUtils.makeClassSafeWithGenerics(List, ClassHelper.OBJECT_TYPE),
Parameter.EMPTY_ARRAY,
ClassNode.EMPTY_ARRAY,
new ReturnStatement(new VariableExpression('DATASTORE_UNINDEXED_PROPERTIES_TYPES'))
).with { MethodNode self ->
self.lineNumber = 10014
self.columnNumber = 1
self
}
}

private void eachPropertyIncludingSuper(ClassNode parent, Closure iterator, List<String> alreadyProcessed = []){
Expand Down Expand Up @@ -457,6 +500,16 @@ class EntityTransformation extends AbstractASTTransformation {
list
}


private Expression buildClassList(List<ClassNode> values) {
ListExpression list = new ListExpression()
for (ClassNode value in values) {
// I'm not sure if ClassExpression is the best one
list.addExpression(new ClassExpression(value))
}
list
}

private MethodNode addDelegatedMethod(String name, ClassNode returnType = ClassHelper.DYNAMIC_TYPE) {
def helper = ClassHelper.make(EntityTransformationHelper).plainNodeReference

Expand Down
Expand Up @@ -315,10 +315,16 @@ class EntityTransformationSpec extends Specification {
obj.getDatastoreKey() == 10
obj.hasDatastoreVersion() == false
obj.getDatastoreIndexedProperties() == ['test1']
obj.getDatastoreIndexedPropertiesTypes() == [String]
obj.getDatastoreUnindexedProperties() == [
'test2',
'test3',
'superProp'
'superProp',
]
obj.getDatastoreUnindexedPropertiesTypes() == [
String,
String,
String,
]
obj.hasDatastoreParent() == false
obj.getDatastoreParent() == null
Expand Down
Expand Up @@ -50,10 +50,18 @@ public class ExampleDatastoreEntity implements DatastoreEntity<Long> {
return Arrays.asList("indexed1", "indexed2", "type");
}

@Override public List<Class> getDatastoreIndexedPropertiesTypes() {
return Arrays.asList(String.class, int.class, EDEType.class);
}

@Override public List<String> getDatastoreUnindexedProperties() {
return Arrays.asList("unindexed1", "unindexed2");
}

@Override public List<Class> getDatastoreUnindexedPropertiesTypes() {
return Arrays.asList(String.class, String.class);
}

public long getId() {
return id;
}
Expand Down

0 comments on commit c6488a9

Please sign in to comment.