-
Notifications
You must be signed in to change notification settings - Fork 496
/
SqliteTypeResolver.kt
61 lines (56 loc) · 2.63 KB
/
SqliteTypeResolver.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package app.cash.sqldelight.dialects.sqlite_3_18
import app.cash.sqldelight.dialect.api.IntermediateType
import app.cash.sqldelight.dialect.api.PrimitiveType
import app.cash.sqldelight.dialect.api.PrimitiveType.BLOB
import app.cash.sqldelight.dialect.api.PrimitiveType.INTEGER
import app.cash.sqldelight.dialect.api.PrimitiveType.REAL
import app.cash.sqldelight.dialect.api.PrimitiveType.TEXT
import app.cash.sqldelight.dialect.api.TypeResolver
import app.cash.sqldelight.dialects.sqlite_3_18.grammar.psi.SqliteTypeName
import com.alecstrong.sql.psi.core.psi.SqlFunctionExpr
import com.alecstrong.sql.psi.core.psi.SqlTypeName
import com.squareup.kotlinpoet.BOOLEAN
open class SqliteTypeResolver(private val parentResolver: TypeResolver) : TypeResolver by parentResolver {
override fun functionType(functionExpr: SqlFunctionExpr): IntermediateType? {
return functionExpr.sqliteFunctionType() ?: parentResolver.functionType(functionExpr)
}
override fun definitionType(typeName: SqlTypeName): IntermediateType = with(typeName) {
check(this is SqliteTypeName) { "Get $this" }
return when {
textDataType != null -> IntermediateType(TEXT)
blobDataType != null -> IntermediateType(BLOB)
intDataType != null -> IntermediateType(INTEGER)
realDataType != null -> IntermediateType(REAL)
else -> throw IllegalArgumentException("Unknown sql type $text")
}
}
private fun SqlFunctionExpr.sqliteFunctionType() = when (functionName.text.lowercase()) {
"printf" -> IntermediateType(TEXT).nullableIf(resolvedType(exprList[0]).javaType.isNullable)
"datetime", "julianday", "strftime", "sqlite_compileoption_get", "sqlite_source_id", "sqlite_version" -> {
IntermediateType(TEXT)
}
"changes", "last_insert_rowid", "sqlite_compileoption_used", "total_changes" -> {
IntermediateType(INTEGER)
}
"unicode" -> {
IntermediateType(INTEGER).nullableIf(exprList.any { resolvedType(it).javaType.isNullable })
}
"randomblob", "zeroblob" -> IntermediateType(BLOB)
"total", "bm25" -> IntermediateType(REAL)
"likelihood", "likely", "unlikely" -> resolvedType(exprList[0])
"highlight", "snippet" -> IntermediateType(TEXT).asNullable()
"offsets" -> IntermediateType(TEXT).asNullable()
else -> null
}
override fun simplifyType(intermediateType: IntermediateType): IntermediateType {
if (intermediateType.dialectType == INTEGER &&
intermediateType.javaType.copy(nullable = false) == BOOLEAN
) {
return intermediateType.copy(
dialectType = PrimitiveType.BOOLEAN,
simplified = true,
)
}
return parentResolver.simplifyType(intermediateType)
}
}