-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: define AST tree for the query model INTELLIJ-18 (#13)
- Loading branch information
Showing
22 changed files
with
609 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
dependencies { | ||
implementation(project(":packages:mongodb-mql-model")) | ||
implementation(libs.mongodb.driver) | ||
implementation(libs.gson) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dependencies { | ||
implementation(libs.owasp.encoder) | ||
} |
126 changes: 126 additions & 0 deletions
126
packages/mongodb-mql-model/src/main/kotlin/com/mongodb/jbplugin/mql/BsonType.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
/** | ||
* Represents all supported Bson types. We are not using the ones defined in the driver as we need more information, | ||
* like nullability and composability (for example, a value that can be either int or bool). | ||
*/ | ||
|
||
package com.mongodb.jbplugin.mql | ||
|
||
import java.math.BigDecimal | ||
import java.math.BigInteger | ||
import java.time.Instant | ||
import java.time.LocalDate | ||
import java.time.LocalDateTime | ||
import java.util.* | ||
|
||
/** | ||
* Represents any of the valid BSON types. | ||
*/ | ||
interface BsonType | ||
|
||
/** | ||
* A double (64 bit floating point) | ||
*/ | ||
data object BsonDouble : BsonType | ||
|
||
/** | ||
* BSON String | ||
*/ | ||
data object BsonString : BsonType | ||
|
||
/** | ||
* Represents a map of key -> type. | ||
* | ||
* @property schema | ||
*/ | ||
data class BsonObject( | ||
val schema: Map<String, BsonType>, | ||
) : BsonType | ||
|
||
/** | ||
* Represents the possible types that can be included in an array. | ||
* | ||
* @property schema | ||
*/ | ||
data class BsonArray( | ||
val schema: BsonType, | ||
) : BsonType | ||
|
||
/** | ||
* Boolean | ||
*/ | ||
data object BsonBoolean : BsonType | ||
|
||
/** | ||
* Date | ||
*/ | ||
data object BsonDate : BsonType | ||
|
||
/** | ||
* null / non existing field | ||
*/ | ||
|
||
data object BsonNull : BsonType | ||
|
||
/** | ||
* 32-bit integer | ||
*/ | ||
|
||
data object BsonInt32 : BsonType | ||
|
||
/** | ||
* 64-bit integer | ||
*/ | ||
data object BsonInt64 : BsonType | ||
|
||
/** | ||
* Decimal128 (128 bit floating point) | ||
*/ | ||
data object BsonDecimal128 : BsonType | ||
|
||
/** | ||
* This is not a BSON type per se, but need a value for an unknown | ||
* bson type. | ||
*/ | ||
data object BsonAny : BsonType | ||
|
||
/** | ||
* This is not a BSON type per se, but a schema is dynamic and for a single | ||
* field we can have multiple types of values, so we will map this scenario | ||
* with the AnyOf type. | ||
* | ||
* @property types | ||
*/ | ||
data class BsonAnyOf( | ||
val types: List<BsonType>, | ||
) : BsonType { | ||
constructor(vararg types: BsonType) : this(types.toList()) | ||
} | ||
|
||
/** | ||
* Returns the inferred BSON type of the current Java class, considering it's nullability. | ||
*/ | ||
fun Class<*>.toBsonType(): BsonType { | ||
return when (this) { | ||
Double::class.javaPrimitiveType -> BsonDouble | ||
Double::class.javaObjectType -> BsonAnyOf(BsonNull, BsonDouble) | ||
Boolean::class.javaPrimitiveType -> BsonBoolean | ||
Boolean::class.javaObjectType -> BsonAnyOf(BsonNull, BsonBoolean) | ||
Int::class.javaPrimitiveType -> BsonInt32 | ||
Int::class.javaObjectType -> BsonAnyOf(BsonNull, BsonInt32) | ||
CharSequence::class.java, String::class.java -> BsonAnyOf(BsonNull, BsonString) | ||
Date::class.java, Instant::class.java, LocalDate::class.java, LocalDateTime::class.java -> | ||
BsonAnyOf(BsonNull, BsonDate) | ||
BigInteger::class.java -> BsonAnyOf(BsonNull, BsonInt64) | ||
BigDecimal::class.java -> BsonAnyOf(BsonNull, BsonDecimal128) | ||
else -> if (Collection::class.java.isAssignableFrom(this)) { | ||
return BsonAnyOf(BsonNull, BsonArray(BsonAny)) // types are lost at runtime | ||
} else { | ||
val fields = | ||
this.declaredFields.associate { | ||
it.name to it.type.toBsonType() | ||
} | ||
|
||
return BsonAnyOf(BsonNull, BsonObject(fields)) | ||
} | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
packages/mongodb-mql-model/src/main/kotlin/com/mongodb/jbplugin/mql/CollectionSchema.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package com.mongodb.jbplugin.mql | ||
|
||
import org.intellij.lang.annotations.Language | ||
import java.lang.Integer.parseInt | ||
|
||
/** | ||
* @property namespace | ||
* @property schema | ||
*/ | ||
class CollectionSchema( | ||
val namespace: Namespace, | ||
val schema: BsonObject, | ||
) { | ||
fun typeOf( | ||
@Language("JSONPath") jsonPath: String, | ||
): BsonType { | ||
val splitJsonPath = jsonPath.split('.').toList() | ||
return recursivelyGetType(splitJsonPath, schema) | ||
} | ||
|
||
private fun recursivelyGetType( | ||
jsonPath: List<String>, | ||
root: BsonType, | ||
): BsonType { | ||
if (jsonPath.isEmpty()) { | ||
return root | ||
} | ||
|
||
val current = jsonPath.first() | ||
val isCurrentNumber = kotlin.runCatching { parseInt(current) }.isSuccess | ||
|
||
val listOfOptions = mutableListOf<BsonType>() | ||
|
||
when (root) { | ||
is BsonArray -> if (isCurrentNumber) { | ||
val childType = recursivelyGetType(jsonPath.subList(1, jsonPath.size), root.schema) | ||
listOfOptions.add(childType) | ||
} else { | ||
listOfOptions.add(BsonNull) | ||
} | ||
is BsonObject -> { | ||
val objectType = root.schema[jsonPath[0]] | ||
listOfOptions.add( | ||
objectType?.let { | ||
recursivelyGetType(jsonPath.subList(1, jsonPath.size), objectType) | ||
} ?: BsonNull, | ||
) | ||
} | ||
is BsonAnyOf -> listOfOptions.addAll( | ||
root.types.map { recursivelyGetType(jsonPath, it) }, | ||
) | ||
else -> listOfOptions.add(BsonNull) | ||
} | ||
|
||
return if (listOfOptions.size == 1) { | ||
listOfOptions.first() | ||
} else { | ||
BsonAnyOf(listOfOptions) | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
packages/mongodb-mql-model/src/main/kotlin/com/mongodb/jbplugin/mql/Namespace.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.mongodb.jbplugin.mql | ||
|
||
import java.util.* | ||
|
||
/** | ||
* Represents a MongoDB Namespace (db/coll) | ||
* | ||
* @property database | ||
* @property collection | ||
*/ | ||
class Namespace private constructor( | ||
val database: String, | ||
val collection: String, | ||
) { | ||
override fun toString(): String = "$database.$collection" | ||
|
||
override fun equals(other: Any?): Boolean = other is Namespace && hashCode() == other.hashCode() | ||
|
||
override fun hashCode(): Int = Objects.hash(database, collection) | ||
|
||
companion object { | ||
operator fun invoke( | ||
database: String, | ||
collection: String, | ||
): Namespace = | ||
Namespace( | ||
database, | ||
collection, | ||
) | ||
} | ||
} |
Oops, something went wrong.