@@ -21,6 +21,8 @@ export SqlQuery, mapIt
2121type
2222 OzarkModelDefect * = object of CatchableError
2323
24+ const preparedQueryStatements = CacheTable " preparedQueryStatements"
25+
2426randomize () # initialize random seed for generating unique statement names in `tryInsertID`
2527
2628template 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
480489macro 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+
549567macro 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