Skip to content

Commit df081b5

Browse files
authored
feat(spring-criteria): add support for not operator INTELLIJ-61 (#76)
1 parent 91765ca commit df081b5

File tree

4 files changed

+77
-6
lines changed

4 files changed

+77
-6
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ MongoDB plugin for IntelliJ IDEA.
55
## [Unreleased]
66

77
### Added
8+
* [INTELLIJ-61](https://jira.mongodb.org/browse/INTELLIJ-61) Add support for Spring Criteria
9+
not operator, like in `where(field).not().is(value)`
810
* [INTELLIJ-49](https://jira.mongodb.org/browse/INTELLIJ-49) Add support for Spring Criteria
911
update operators.
1012
* [INTELLIJ-44](https://jira.mongodb.org/browse/INTELLIJ-44) Ability to load the Spring configuration from

packages/mongodb-dialects/mongosh/src/main/kotlin/com/mongodb/jbplugin/dialects/mongosh/MongoshDialectFormatter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ private fun <S> MongoshBackend.resolveValueReference(
256256
) = when (val ref = valueRef.reference) {
257257
is HasValueReference.Constant -> registerConstant(ref.value)
258258
is HasValueReference.Runtime -> registerVariable(
259-
(fieldRef?.reference as? HasFieldReference.Known)?.fieldName ?: "<value>",
259+
(fieldRef?.reference as? HasFieldReference.Known)?.fieldName ?: "value",
260260
ref.type
261261
)
262262

packages/mongodb-dialects/spring-criteria/src/main/kotlin/com/mongodb/jbplugin/dialects/springcriteria/SpringCriteriaDialectParser.kt

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.mongodb.jbplugin.dialects.springcriteria
22

3+
import com.intellij.database.dialects.base.introspector.listOf
34
import com.intellij.psi.*
45
import com.intellij.psi.util.elementType
56
import com.intellij.psi.util.findParentOfType
@@ -319,13 +320,22 @@ object SpringCriteriaDialectParser : DialectParser<PsiElement> {
319320
}
320321

321322
// v----------------------- field filter (it can be a where, an and...)
322-
// v------------- valueMethodCall
323-
// v----- the value itself
324-
// 2st scenario: $fieldRef$.$filter$("abc")
325-
val fieldMethodCall =
323+
// v--------------------- optional negation
324+
// v------------- valueMethodCall
325+
// v----- the value itself
326+
// 2st scenario: $fieldRef$.$not$?.$filter$("abc")
327+
var negate = false
328+
var fieldMethodCall =
326329
valueMethodCall.firstChild.firstChild.meaningfulExpression() as? PsiMethodCallExpression
327330
?: return emptyList()
328331

332+
val fieldMethod = fieldMethodCall.fuzzyResolveMethod() ?: return emptyList()
333+
if (fieldMethod.name == "not") {
334+
negate = true
335+
fieldMethodCall = fieldMethodCall.firstChild?.firstChild?.meaningfulExpression()
336+
as? PsiMethodCallExpression ?: return emptyList()
337+
}
338+
329339
val fieldReference = inferFieldReference(fieldMethodCall)
330340
val valueReference = inferValueReference(valueMethodCall)
331341

@@ -337,7 +347,7 @@ object SpringCriteriaDialectParser : DialectParser<PsiElement> {
337347
// v------- fieldMethodCall is here
338348
// $nextFieldRef$.$nextValueRef$.$fieldRef$.$filter$("abc")
339349
val nextQueryExpression = fieldMethodCall.firstChild?.firstChild
340-
val thisQueryNode = listOf(
350+
var thisQueryNode = listOf(
341351
Node(
342352
valueFilterExpression,
343353
listOf(
@@ -347,6 +357,17 @@ object SpringCriteriaDialectParser : DialectParser<PsiElement> {
347357
)
348358
)
349359
)
360+
if (negate) {
361+
thisQueryNode = listOf(
362+
Node(
363+
valueFilterExpression,
364+
listOf(
365+
Named(Name.NOT),
366+
HasFilter(thisQueryNode)
367+
)
368+
)
369+
)
370+
}
350371

351372
if (nextQueryExpression != null && nextQueryExpression is PsiMethodCallExpression) {
352373
return thisQueryNode + parseFilterRecursively(nextQueryExpression)

packages/mongodb-dialects/spring-criteria/src/test/kotlin/com/mongodb/jbplugin/dialects/springcriteria/SpringCriteriaDialectParserTest.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,4 +739,52 @@ class Repository {
739739
}
740740
}
741741
}
742+
743+
@ParsingTest(
744+
fileName = "Book.java",
745+
"""
746+
import org.springframework.data.mongodb.core.MongoTemplate;
747+
import org.springframework.data.mongodb.core.mapping.Document;
748+
import org.springframework.data.mongodb.core.query.Criteria;
749+
import static org.springframework.data.mongodb.core.query.Criteria.where;
750+
import static org.springframework.data.mongodb.core.query.Query.query;
751+
import static org.springframework.data.mongodb.core.query.Update.update;
752+
753+
import java.util.List;
754+
755+
import static org.springframework.data.mongodb.core.query.Criteria.where;
756+
757+
@Document
758+
record Book() {}
759+
760+
class Repository {
761+
private final MongoTemplate template;
762+
763+
public Repository(MongoTemplate template) {
764+
this.template = template;
765+
}
766+
767+
public Book randomBook() {
768+
return template.find(query(where("field").not().is("123456")), Book.class);
769+
}
770+
}
771+
"""
772+
)
773+
fun `supports not queries when prefixing the operation with not`(
774+
psiFile: PsiFile
775+
) {
776+
val query = psiFile.getQueryAtMethod("Repository", "randomBook")
777+
SpringCriteriaDialectParser.parse(query).assert(IsCommand.CommandType.FIND_MANY) {
778+
collection<HasCollectionReference.OnlyCollection<PsiElement>> {
779+
assertEquals("book", collection)
780+
}
781+
782+
filterN(0, Name.NOT) {
783+
filterN(0, Name.EQ) {
784+
field<HasFieldReference.Known<PsiElement>> { assertEquals("field", fieldName) }
785+
value<HasValueReference.Constant<PsiElement>> { assertEquals("123456", value) }
786+
}
787+
}
788+
}
789+
}
742790
}

0 commit comments

Comments
 (0)