Expand typed SQL DSL

This commit is contained in:
pavel 2026-08-28 00:02:32 +02:00
commit 314c8fb207
17 changed files with 1082 additions and 498 deletions

View file

@ -47,10 +47,10 @@ const expectedTokens = [
"throw", "enum", "match", "package", "import", "jsonNaming", "embed", "table", "column", "id",
"generated", "Int", "Long", "String", "Boolean", "Unit", "Double", "Float", "Any",
"ByteSlice", "Error", "Result", "List", "MutableList", "Map", "MutableMap", "Channel", "GotlinSQLQuery",
"GotlinSQLIterator", "from", "where", "orderBy", "orderByDescending", "limit",
"GotlinSQLIterator", "from", "alias", "join", "leftJoin", "rightJoin", "where", "groupBy", "having", "orderBy", "orderByDescending", "limit", "offset",
"runBlocking", "coroutineScope", "launch", "async", "await", "delay", "withTimeout", "isActive",
"forUpdate", "skipLocked", "insert", "update", "delete", "onConflict", "doNothing",
"doUpdate", "returning", "build", "fetch", "single", "iterator", "set", "now", "mapTo"
"forUpdate", "skipLocked", "insert", "insertAll", "update", "delete", "onConflict", "doNothing",
"doUpdate", "returning", "build", "fetch", "single", "iterator", "count", "sum", "avg", "min", "max", "now", "mapTo"
];
for (const token of expectedTokens) {
assert(grammarSource.includes(token), `grammar is missing ${token}`);
@ -63,9 +63,9 @@ for (const annotation of ["jsonNaming", "embed", "table", "column", "id", "gener
const sqlSource = JSON.stringify(grammar.repository.sql);
for (const method of [
"from", "where", "select", "orderBy", "orderByDescending", "limit", "forUpdate",
"skipLocked", "insert", "update", "delete", "onConflict", "doNothing", "doUpdate",
"returning", "build", "fetch", "single", "iterator", "set", "now"
"from", "alias", "join", "leftJoin", "rightJoin", "where", "select", "groupBy", "having", "orderBy", "orderByDescending", "limit", "offset", "forUpdate",
"skipLocked", "insert", "insertAll", "update", "delete", "onConflict", "doNothing", "doUpdate",
"returning", "build", "fetch", "single", "iterator", "count", "sum", "avg", "min", "max", "now"
]) {
assert(sqlSource.includes(method), `SQL grammar is missing ${method}`);
}
@ -83,7 +83,7 @@ for (const declaration of [
const prefixes = new Set(Object.values(snippets).map((snippet) => snippet.prefix));
for (const prefix of [
"dataclass", "exprfun", "withcontext", "genericfun", "genericclass", "tablerow", "embed", "coroutinescope", "launch", "async", "enum", "match", "matchvalue", "mapto", "safe", "nonnull", "resultfun", "resultmatch", "defer", "foreach", "sqlfetch",
"sqlsingle", "sqliterator", "sqlinsertnothing", "sqlinsertupdate", "sqlupdatereturning"
"sqlsingle", "sqliterator", "sqlinsertnothing", "sqlinsertupdate", "sqlupdatereturning", "sqlbulk", "sqljoin"
]) {
assert(prefixes.has(prefix), `snippets are missing prefix ${prefix}`);
}

View file

@ -224,7 +224,7 @@
"sql.insert<${1:Row}>(${2:row})",
" .onConflict { ${3:it.id} }",
" .doUpdate { ${4:excluded} ->",
" set(${1:Row}.${5:value}, ${4:excluded}.${5:value})",
" ${1:Row}.${5:value} = ${4:excluded}.${5:value}",
" }",
" .build()"
],
@ -233,9 +233,9 @@
"SQL Update Returning": {
"prefix": "sqlupdatereturning",
"body": [
"val ${1:updated}: *${2:Row} = sql.update<${2:Row}>()",
"val ${1:updated}: ${2:Row} = sql.update<${2:Row}>()",
" .set { ${3:row} ->",
" set(${3:row}.${4:value}, ${5:newValue})",
" ${3:row}.${4:value} = ${5:newValue}",
" }",
" .where { ${6:it.id == id} }",
" .returning { it }",
@ -243,6 +243,22 @@
],
"description": "Update and return a typed SQL row"
},
"SQL Bulk Insert": {
"prefix": "sqlbulk",
"body": ["val ${1:query} = sql.insertAll<${2:Row}>(${3:rows}).build()"],
"description": "Build a typed bulk insert"
},
"SQL Join And Aggregate": {
"prefix": "sqljoin",
"body": [
"val ${1:query} = sql.from<${2:LeftRow}>()",
" .alias(\"${3:left}\")",
" .leftJoin<${4:RightRow}>(\"${5:right}\") { ${3:left}, ${5:right} -> ${3:left}.${6:id} == ${5:right}.${7:leftId} }",
" .groupBy { ${3:left}, ${5:right} -> ${3:left}.${6:id} }",
" .build()"
],
"description": "Build a typed joined and grouped query"
},
"If": {
"prefix": "if",
"body": [

View file

@ -202,11 +202,11 @@
},
{
"name": "support.function.sql.query.gotlin",
"match": "(?<=\\.)\\b(from|where|select|orderBy|orderByDescending|limit|forUpdate|skipLocked)\\b"
"match": "(?<=\\.)\\b(from|alias|join|leftJoin|rightJoin|where|select|groupBy|having|orderBy|orderByDescending|limit|offset|forUpdate|skipLocked)\\b"
},
{
"name": "support.function.sql.mutation.gotlin",
"match": "(?<=\\.)\\b(insert|update|delete|onConflict|doNothing|doUpdate|returning)\\b"
"match": "(?<=\\.)\\b(insert|insertAll|update|delete|onConflict|doNothing|doUpdate|returning)\\b"
},
{
"name": "support.function.sql.execution.gotlin",
@ -214,7 +214,7 @@
},
{
"name": "support.function.sql.helper.gotlin",
"match": "\\b(set|now)\\b(?=\\s*\\()"
"match": "\\b(count|countDistinct|sum|avg|min|max|now)\\b(?=\\s*\\()"
},
{
"name": "support.function.mapping.gotlin",