Skip to content

Commit 06f980d

Browse files
committed
common statements
Signed-off-by: George Lemon <georgelemon@protonmail.com>
1 parent 7783567 commit 06f980d

File tree

6 files changed

+42
-16
lines changed

6 files changed

+42
-16
lines changed

src/ozark/model.nim

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,21 +238,19 @@ proc parseObjectField(tableName: string, field, fieldIdent: NimNode) =
238238

239239
for p in pragmas:
240240
colDefNode.add(newNode(nkIdent, pragmaToConstraint(p)))
241-
242241
if defaultSql.isSome:
243242
colDefNode.add(newNode(nkIdent, "DEFAULT " & defaultSql.get))
244-
245243
SqlSchemas[tableName][$fieldName] = colDefNode
246244

247-
248245
macro newModel*(id, fields: untyped) =
249246
## Macro for defining a new model at compile time.
250247
## This macro will create a Nim object that represents
251248
## the model and also register it in the StaticSchemas table.
252249
result = newNimNode(nnkStmtList)
253250
let tableName = getTableName($id)
254251
if StaticSchemas.hasKey(tableName):
255-
raise newException(ValueError, "Model with id '" & $id & "' already exists.")
252+
result = StaticSchemas[tableName]
253+
return # Model already defined, skip redefinition (allows for multiple imports without conflicts)
256254
var modelFields = newNimNode(nnkRecList)
257255
# var modelSchema = newTable[string, SqlNode]()
258256
SqlSchemas[tableName] = newTable[string, SqlNode]()
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
block:
2-
let sqlPrepared = prepare(dbcon, "ozark_instant_$3", SqlQuery("$1"), $4)
2+
let sqlPrepared = ensurePrepared(dbcon, "ozark_instant_$3", SqlQuery("$1"), $4)
33
dbcon.exec(sqlPrepared$2)

src/ozark/private/stubs/iteratorGetRow.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
block:
2-
let sqlPrepared = prepare(dbcon, "ozark_instant_$7", SqlQuery("$1"), $6)
2+
let sqlPrepared = ensurePrepared(dbcon, "ozark_instant_$7", SqlQuery("$1"), $6)
33
var
44
row = getRow(dbcon, sqlPrepared$5)
55
isEmpty = true

src/ozark/private/stubs/iteratorInstantRows.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ block:
55
cols: DBColumns = @[]
66
colKeys: seq[string]
77
let colNames = [$3]
8-
let sqlPrepared = prepare(dbcon, "ozark_instant_$7", SqlQuery("$1"), $6)
8+
let sqlPrepared = ensurePrepared(dbcon, "ozark_instant_$7", SqlQuery("$1"), $6)
99
for row in instantRows(dbcon, cols, sqlPrepared $5):
1010
isEmpty = isEmpty and row.len == 0
1111
if isEmpty: continue # skip empty rows
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
11
block:
2-
let sqlPrepared =
3-
prepare(dbcon, "ozark_insert_$3",
4-
SqlQuery("$1 RETURNING id"), $4)
2+
let sqlPrepared = ensurePrepared(dbcon, "ozark_insert_$3", SqlQuery("$1 RETURNING id"), $4)
53
tryInsertID(dbcon, sqlPrepared, $2)

src/ozark/query.nim

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export SqlQuery, mapIt
2121
type
2222
OzarkModelDefect* = object of CatchableError
2323

24+
const preparedQueryStatements = CacheTable"preparedQueryStatements"
25+
2426
randomize() # initialize random seed for generating unique statement names in `tryInsertID`
2527

2628
template table*(models: ptr ModelsTable, name): untyped =
@@ -472,10 +474,17 @@ macro getAll*(sql: untyped): untyped =
472474
## Finalize and get all results of the SQL statement.
473475
## This macro produce the final SQL string and wraps it in a runtime call
474476
## to execute it and return all rows via `instantRows`
475-
if sql.kind != nnkBlockExpr or sql[1][^1][0].strVal notin ["ozarkWhereResult", "ozarkRawSQLResult", "ozarkLimitResult"]:
477+
if sql.kind != nnkBlockExpr or sql[1][^1][0].strVal notin [
478+
"ozarkWhereResult", "ozarkRawSQLResult",
479+
"ozarkLimitResult", "ozarkOrderByResult",
480+
"ozarkSelectResult"
481+
]:
476482
error("The argument to `getAll` must be the result of a `where` macro.")
477-
let v = sql[1][^1][2] # extract the additional arguments (e.g. for WHERE IN) from the macro arguments for later use in code generation
478-
sql.parseSqlQuery("instantRows", @[v])
483+
if sql[1][^1][0].strVal == "ozarkSelectResult":
484+
result = sql.parseSqlQuery("instantRows")
485+
else:
486+
let v = sql[1][^1][2] # extract the additional arguments (e.g. for WHERE IN) from the macro arguments for later use in code generation
487+
result = sql.parseSqlQuery("instantRows", @[v])
479488

480489
macro get*(sql: untyped): untyped =
481490
## Finalize SQL statement. This macro produces the final SQL
@@ -546,6 +555,15 @@ macro rawSQL*(models: ptr ModelsTable, sql: static string, values: varargs[untyp
546555
except SqlParseError as e:
547556
raise newException(OzarkModelDefect, "SQL Parsing Error: " & e.msg)
548557

558+
type PreparedKey = tuple[conn: pointer, name: string]
559+
var preparedRtCache {.threadvar.}: Table[PreparedKey, SqlPrepared]
560+
561+
proc ensurePrepared*(db: DbConn, name: string, sql: SqlQuery, nParams: int): SqlPrepared =
562+
let key: PreparedKey = (cast[pointer](db), name)
563+
if key notin preparedRtCache:
564+
preparedRtCache[key] = prepare(db, name, sql, nParams)
565+
result = preparedRtCache[key]
566+
549567
macro exec*(sql: untyped) =
550568
## Finalize and execute an SQL statement that doesn't
551569
## return results (e.g. INSERT, UPDATE, DELETE).
@@ -561,7 +579,7 @@ macro exec*(sql: untyped) =
561579
try:
562580
let sqlNode = parseSQL($sql[1])
563581
case sqlNode.sons[0].kind
564-
of nkInsert:
582+
of nkInsert, nkDelete:
565583
let randId = genSym(nskVar, "id")
566584
let stub = staticRead("private" / "stubs" / "execSql.nim")
567585
result = macros.parseStmt(stub % [
@@ -575,6 +593,20 @@ macro exec*(sql: untyped) =
575593
randId.repr,
576594
$(sql[2][1]).len
577595
])
596+
of nkUpdate:
597+
let randId = genSym(nskVar, "id")
598+
let stub = staticRead("private" / "stubs" / "execSql.nim")
599+
result = macros.parseStmt(stub % [
600+
$sql[1],
601+
(
602+
if sql[2][1][1].len > 0:
603+
", " &
604+
$sql[2][1][1].mapIt(it.repr).join(",")
605+
else: ""
606+
),
607+
randId.repr,
608+
$(sql[2][1][1]).len # bracket len
609+
])
578610
of nkCreateTable, nkCreateTableIfNotExists:
579611
let randId = genSym(nskVar, "id")
580612
let stub = staticRead("private" / "stubs" / "execSql.nim")
@@ -593,8 +625,6 @@ macro exec*(sql: untyped) =
593625
randId.repr,
594626
"0"
595627
])
596-
of nkDelete:
597-
discard # todo
598628
else: discard
599629
except SqlParseError as e:
600630
raise newException(OzarkModelDefect, "SQL Parsing Error: " & e.msg)

0 commit comments

Comments
 (0)