mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 10:22:15 +00:00
fix a sqlite bug (#18669)
This commit is contained in:
@@ -171,7 +171,7 @@ import sqlite3, macros
|
||||
import db_common
|
||||
export db_common
|
||||
|
||||
import std/private/since
|
||||
import std/private/[since, dbutils]
|
||||
|
||||
type
|
||||
DbConn* = PSqlite3 ## Encapsulates a database connection.
|
||||
@@ -211,14 +211,7 @@ proc dbQuote*(s: string): string =
|
||||
add(result, '\'')
|
||||
|
||||
proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string =
|
||||
result = ""
|
||||
var a = 0
|
||||
for c in items(string(formatstr)):
|
||||
if c == '?':
|
||||
add(result, dbQuote(args[a]))
|
||||
inc(a)
|
||||
else:
|
||||
add(result, c)
|
||||
dbFormatImpl(formatstr, dbQuote, args)
|
||||
|
||||
proc prepare*(db: DbConn; q: string): SqlPrepared {.since: (1, 3).} =
|
||||
## Creates a new `SqlPrepared` statement.
|
||||
@@ -642,7 +635,7 @@ proc getValue*(db: DbConn, stmtName: SqlPrepared): string
|
||||
|
||||
proc tryInsertID*(db: DbConn, query: SqlQuery,
|
||||
args: varargs[string, `$`]): int64
|
||||
{.tags: [WriteDbEffect], raises: [].} =
|
||||
{.tags: [WriteDbEffect], raises: [DbError].} =
|
||||
## Executes the query (typically "INSERT") and returns the
|
||||
## generated ID for the row or -1 in case of an error.
|
||||
##
|
||||
@@ -699,7 +692,7 @@ proc insertID*(db: DbConn, query: SqlQuery,
|
||||
|
||||
proc tryInsert*(db: DbConn, query: SqlQuery, pkName: string,
|
||||
args: varargs[string, `$`]): int64
|
||||
{.tags: [WriteDbEffect], raises: [], since: (1, 3).} =
|
||||
{.tags: [WriteDbEffect], raises: [DbError], since: (1, 3).} =
|
||||
## same as tryInsertID
|
||||
tryInsertID(db, query, args)
|
||||
|
||||
|
||||
15
lib/std/private/dbutils.nim
Normal file
15
lib/std/private/dbutils.nim
Normal file
@@ -0,0 +1,15 @@
|
||||
import db_common
|
||||
|
||||
|
||||
template dbFormatImpl*(formatstr: SqlQuery, dbQuote: proc (s: string): string, args: varargs[string]): string =
|
||||
var res = ""
|
||||
var a = 0
|
||||
for c in items(string(formatstr)):
|
||||
if c == '?':
|
||||
if a == args.len:
|
||||
dbError("""The number of "?" given exceeds the number of parameters present in the query.""")
|
||||
add(res, dbQuote(args[a]))
|
||||
inc(a)
|
||||
else:
|
||||
add(res, c)
|
||||
res
|
||||
@@ -48,3 +48,31 @@ block tsqlitebindatas: ## db_sqlite binary data
|
||||
|
||||
db.close()
|
||||
doAssert tryRemoveFile(dbName)
|
||||
|
||||
|
||||
block:
|
||||
block:
|
||||
const dbName = buildDir / "db.sqlite3"
|
||||
var db = db_sqlite.open(dbName, "", "", "")
|
||||
var witness = false
|
||||
try:
|
||||
db.exec(sql("CREATE TABLE table1 (url TEXT, other_field INT);"))
|
||||
db.exec(sql("REPLACE INTO table (url, another_field) VALUES (?, '123');"))
|
||||
except DbError as e:
|
||||
witness = true
|
||||
doAssert e.msg == "The number of \"?\" given exceeds the number of parameters present in the query."
|
||||
finally:
|
||||
db.close()
|
||||
removeFile(dbName)
|
||||
|
||||
doAssert witness
|
||||
|
||||
block:
|
||||
const dbName = buildDir / "db.sqlite3"
|
||||
var db = db_sqlite.open(dbName, "", "", "")
|
||||
try:
|
||||
db.exec(sql("CREATE TABLE table1 (url TEXT, other_field INT);"))
|
||||
db.exec(sql("INSERT INTO table1 (url, other_field) VALUES (?, ?);"), "http://domain.com/test?param=1", 123)
|
||||
finally:
|
||||
db.close()
|
||||
removeFile(dbName)
|
||||
|
||||
Reference in New Issue
Block a user