From c50ef25fd777e2f078252df061115667d6b3d114 Mon Sep 17 00:00:00 2001 From: Senketsu Date: Sat, 12 Sep 2015 12:14:17 +0200 Subject: [PATCH 1/5] convience procs for db_mysql [#3217] --- lib/impure/db_mysql.nim | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 7f75112646710..67d2868b0c0cc 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -47,6 +47,7 @@ type DbConn* = PMySQL ## encapsulates a database connection Row* = seq[string] ## a row of a dataset. NULL database values will be ## transformed always to the empty string. + RowNew* = tuple[hasData: bool,data: seq[string]] InstantRow* = tuple[row: cstringArray, len: int] ## a handle that can be ## used to get a row's ## column text on demand @@ -189,6 +190,69 @@ proc len*(row: InstantRow): int {.inline.} = ## returns number of columns in the row row.len +proc hasData*(rows: seq[Row]): bool = + result = false + for row in rows: + for item in row: + if item != "": + result = true + +proc hasData*(row: Row): bool = + result = false + for item in row: + if item != "": + result = true + +proc hasData*(value: string): bool = + result = false + if value != "": + result = true + +proc getRowNew*(db: DbConn, query: SqlQuery, + args: varargs[string, `$`]): RowNew {.tags: [FReadDB].} = + result.hasData = false + rawExec(db, query, args) + var sqlres = mysql.useResult(db) + if sqlres != nil: + var L = int(mysql.numFields(sqlres)) + result.data = newRow(L) + var row = mysql.fetchRow(sqlres) + if row != nil: + for i in 0..L-1: + setLen(result.data[i], 0) + if row[i] == nil: + result.data[i] = nil + else: + add(result.data[i], row[i]) + result.hasData = true + properFreeResult(sqlres, row) + +proc getAllRowsNew*(db: DbConn, query: SqlQuery, + args: varargs[string, `$`]): seq[RowNew] {.tags: [FReadDB].} = + ## executes the query and returns the whole result dataset. + result = @[] + rawExec(db, query, args) + var sqlres = mysql.useResult(db) + if sqlres != nil: + var L = int(mysql.numFields(sqlres)) + var row: cstringArray + var j = 0 + while true: + row = mysql.fetchRow(sqlres) + if row == nil: break + setLen(result, j+1) + result[j].data = @[] + result[j].hasData = false + newSeq(result[j].data, L) + for i in 0..L-1: + if row[i] == nil: + result[j].data[i] = nil + else: + result[j].data[i] = $row[i] + result[j].hasData = true + inc(j) + mysql.freeResult(sqlres) + proc getRow*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): Row {.tags: [FReadDB].} = ## retrieves a single row. If the query doesn't return any rows, this proc From fecb99e1f53466a5b7950ad8521ac576f96f60fa Mon Sep 17 00:00:00 2001 From: Senketsu Date: Tue, 15 Sep 2015 10:56:24 +0200 Subject: [PATCH 2/5] separated RowNew type and its functions to db_mysql_ex --- lib/impure/db_mysql.nim | 52 ++--------------------------------- lib/impure/db_mysql_ex.nim | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 49 deletions(-) create mode 100644 lib/impure/db_mysql_ex.nim diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 67d2868b0c0cc..7e14f55e7b379 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -47,7 +47,6 @@ type DbConn* = PMySQL ## encapsulates a database connection Row* = seq[string] ## a row of a dataset. NULL database values will be ## transformed always to the empty string. - RowNew* = tuple[hasData: bool,data: seq[string]] InstantRow* = tuple[row: cstringArray, len: int] ## a handle that can be ## used to get a row's ## column text on demand @@ -120,7 +119,7 @@ proc tryExec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): bool {. var q = dbFormat(query, args) return mysql.realQuery(db, q, q.len) == 0'i32 -proc rawExec(db: DbConn, query: SqlQuery, args: varargs[string, `$`]) = +proc rawExec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]) = var q = dbFormat(query, args) if mysql.realQuery(db, q, q.len) != 0'i32: dbError(db) @@ -130,11 +129,11 @@ proc exec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]) {. var q = dbFormat(query, args) if mysql.realQuery(db, q, q.len) != 0'i32: dbError(db) -proc newRow(L: int): Row = +proc newRow*(L: int): Row = newSeq(result, L) for i in 0..L-1: result[i] = "" -proc properFreeResult(sqlres: mysql.PRES, row: cstringArray) = +proc properFreeResult*(sqlres: mysql.PRES, row: cstringArray) = if row != nil: while mysql.fetchRow(sqlres) != nil: discard mysql.freeResult(sqlres) @@ -208,51 +207,6 @@ proc hasData*(value: string): bool = if value != "": result = true -proc getRowNew*(db: DbConn, query: SqlQuery, - args: varargs[string, `$`]): RowNew {.tags: [FReadDB].} = - result.hasData = false - rawExec(db, query, args) - var sqlres = mysql.useResult(db) - if sqlres != nil: - var L = int(mysql.numFields(sqlres)) - result.data = newRow(L) - var row = mysql.fetchRow(sqlres) - if row != nil: - for i in 0..L-1: - setLen(result.data[i], 0) - if row[i] == nil: - result.data[i] = nil - else: - add(result.data[i], row[i]) - result.hasData = true - properFreeResult(sqlres, row) - -proc getAllRowsNew*(db: DbConn, query: SqlQuery, - args: varargs[string, `$`]): seq[RowNew] {.tags: [FReadDB].} = - ## executes the query and returns the whole result dataset. - result = @[] - rawExec(db, query, args) - var sqlres = mysql.useResult(db) - if sqlres != nil: - var L = int(mysql.numFields(sqlres)) - var row: cstringArray - var j = 0 - while true: - row = mysql.fetchRow(sqlres) - if row == nil: break - setLen(result, j+1) - result[j].data = @[] - result[j].hasData = false - newSeq(result[j].data, L) - for i in 0..L-1: - if row[i] == nil: - result[j].data[i] = nil - else: - result[j].data[i] = $row[i] - result[j].hasData = true - inc(j) - mysql.freeResult(sqlres) - proc getRow*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): Row {.tags: [FReadDB].} = ## retrieves a single row. If the query doesn't return any rows, this proc diff --git a/lib/impure/db_mysql_ex.nim b/lib/impure/db_mysql_ex.nim new file mode 100644 index 0000000000000..fce5acd37f94d --- /dev/null +++ b/lib/impure/db_mysql_ex.nim @@ -0,0 +1,56 @@ +import strutils, mysql +import db_mysql + +type + RowNew* = tuple[hasData: bool,data: seq[string]] ## new Row type with a boolean + ## indicating if any data were + ## retrieved + +proc getRowNew*(db: DbConn, query: SqlQuery, + args: varargs[string, `$`]): RowNew {.tags: [FReadDB].} = + ## executes the query and returns RowNew with hasData indicating if any data + ## were retrieved + result.hasData = false + rawExec(db, query, args) + var sqlres = mysql.useResult(db) + if sqlres != nil: + var L = int(mysql.numFields(sqlres)) + result.data = newRow(L) + var row = mysql.fetchRow(sqlres) + if row != nil: + for i in 0..L-1: + setLen(result.data[i], 0) + if row[i] == nil: + result.data[i] = nil + else: + add(result.data[i], row[i]) + result.hasData = true + properFreeResult(sqlres, row) + +proc getAllRowsNew*(db: DbConn, query: SqlQuery, + args: varargs[string, `$`]): seq[RowNew] {.tags: [FReadDB].} = + ## executes the query and returns the whole result dataset with a boolean for + ## each row indicating whether row has any data + result = @[] + rawExec(db, query, args) + var sqlres = mysql.useResult(db) + if sqlres != nil: + var L = int(mysql.numFields(sqlres)) + var row: cstringArray + var j = 0 + while true: + row = mysql.fetchRow(sqlres) + if row == nil: break + setLen(result, j+1) + result[j].data = @[] + result[j].hasData = false + newSeq(result[j].data, L) + for i in 0..L-1: + if row[i] == nil: + result[j].data[i] = nil + else: + result[j].data[i] = $row[i] + result[j].hasData = true + inc(j) + mysql.freeResult(sqlres) + From 651c9de7c651dc4fc7200ee42d1b451920f328bf Mon Sep 17 00:00:00 2001 From: Senketsu Date: Wed, 16 Sep 2015 14:50:24 +0200 Subject: [PATCH 3/5] removed db_mysql_ex from stdlib --- lib/impure/db_mysql_ex.nim | 56 -------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 lib/impure/db_mysql_ex.nim diff --git a/lib/impure/db_mysql_ex.nim b/lib/impure/db_mysql_ex.nim deleted file mode 100644 index fce5acd37f94d..0000000000000 --- a/lib/impure/db_mysql_ex.nim +++ /dev/null @@ -1,56 +0,0 @@ -import strutils, mysql -import db_mysql - -type - RowNew* = tuple[hasData: bool,data: seq[string]] ## new Row type with a boolean - ## indicating if any data were - ## retrieved - -proc getRowNew*(db: DbConn, query: SqlQuery, - args: varargs[string, `$`]): RowNew {.tags: [FReadDB].} = - ## executes the query and returns RowNew with hasData indicating if any data - ## were retrieved - result.hasData = false - rawExec(db, query, args) - var sqlres = mysql.useResult(db) - if sqlres != nil: - var L = int(mysql.numFields(sqlres)) - result.data = newRow(L) - var row = mysql.fetchRow(sqlres) - if row != nil: - for i in 0..L-1: - setLen(result.data[i], 0) - if row[i] == nil: - result.data[i] = nil - else: - add(result.data[i], row[i]) - result.hasData = true - properFreeResult(sqlres, row) - -proc getAllRowsNew*(db: DbConn, query: SqlQuery, - args: varargs[string, `$`]): seq[RowNew] {.tags: [FReadDB].} = - ## executes the query and returns the whole result dataset with a boolean for - ## each row indicating whether row has any data - result = @[] - rawExec(db, query, args) - var sqlres = mysql.useResult(db) - if sqlres != nil: - var L = int(mysql.numFields(sqlres)) - var row: cstringArray - var j = 0 - while true: - row = mysql.fetchRow(sqlres) - if row == nil: break - setLen(result, j+1) - result[j].data = @[] - result[j].hasData = false - newSeq(result[j].data, L) - for i in 0..L-1: - if row[i] == nil: - result[j].data[i] = nil - else: - result[j].data[i] = $row[i] - result[j].hasData = true - inc(j) - mysql.freeResult(sqlres) - From dc5e74e4032d161cabe59c33bba7abddf5716dc6 Mon Sep 17 00:00:00 2001 From: Senketsu Date: Wed, 16 Sep 2015 17:26:29 +0200 Subject: [PATCH 4/5] add proc hasData() to db_[sqlite/postgres], extension ready --- lib/impure/db_mysql.nim | 4 +++- lib/impure/db_postgres.nim | 24 ++++++++++++++++++++++-- lib/impure/db_sqlite.nim | 24 ++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 5 deletions(-) diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 7e14f55e7b379..f57f5ef105143 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -129,7 +129,7 @@ proc exec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]) {. var q = dbFormat(query, args) if mysql.realQuery(db, q, q.len) != 0'i32: dbError(db) -proc newRow*(L: int): Row = +proc newRow(L: int): Row = newSeq(result, L) for i in 0..L-1: result[i] = "" @@ -195,12 +195,14 @@ proc hasData*(rows: seq[Row]): bool = for item in row: if item != "": result = true + break proc hasData*(row: Row): bool = result = false for item in row: if item != "": result = true + break proc hasData*(value: string): bool = result = false diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index b75915a7239bf..bd03d3f0a5063 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -107,7 +107,7 @@ proc newRow(L: int): Row = newSeq(result, L) for i in 0..L-1: result[i] = "" -proc setupQuery(db: DbConn, query: SqlQuery, +proc setupQuery*(db: DbConn, query: SqlQuery, args: varargs[string]): PPGresult = var arr = allocCStringArray(args) result = pqexecParams(db, query.string, int32(args.len), nil, arr, @@ -115,7 +115,7 @@ proc setupQuery(db: DbConn, query: SqlQuery, deallocCStringArray(arr) if pqResultStatus(result) != PGRES_TUPLES_OK: dbError(db) -proc setupQuery(db: DbConn, stmtName: SqlPrepared, +proc setupQuery*(db: DbConn, stmtName: SqlPrepared, args: varargs[string]): PPGresult = var arr = allocCStringArray(args) result = pqexecPrepared(db, stmtName.string, int32(args.len), arr, @@ -180,6 +180,26 @@ proc len*(row: InstantRow): int32 {.inline.} = ## returns number of columns in the row pqNfields(row.res) +proc hasData*(rows: seq[Row]): bool = + result = false + for row in rows: + for item in row: + if item != "": + result = true + break + +proc hasData*(row: Row): bool = + result = false + for item in row: + if item != "": + result = true + break + +proc hasData*(value: string): bool = + result = false + if value != "": + result = true + proc getRow*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): Row {.tags: [FReadDB].} = ## retrieves a single row. If the query doesn't return any rows, this proc diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 8366fdadce965..67b934a55fe94 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -66,7 +66,7 @@ proc sql*(query: string): SqlQuery {.noSideEffect, inline.} = ## on, later versions will check the string for valid syntax. result = SqlQuery(query) -proc dbError(db: DbConn) {.noreturn.} = +proc dbError*(db: DbConn) {.noreturn.} = ## raises an EDb exception. var e: ref EDb new(e) @@ -116,7 +116,7 @@ proc newRow(L: int): Row = newSeq(result, L) for i in 0..L-1: result[i] = "" -proc setupQuery(db: DbConn, query: SqlQuery, +proc setupQuery*(db: DbConn, query: SqlQuery, args: varargs[string]): Pstmt = var q = dbFormat(query, args) if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db) @@ -163,6 +163,26 @@ proc len*(row: InstantRow): int32 {.inline.} = ## returns number of columns in the row column_count(row) +proc hasData*(rows: seq[Row]): bool = + result = false + for row in rows: + for item in row: + if item != "": + result = true + break + +proc hasData*(row: Row): bool = + result = false + for item in row: + if item != "": + result = true + break + +proc hasData*(value: string): bool = + result = false + if value != "": + result = true + proc getRow*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): Row {.tags: [FReadDb].} = ## retrieves a single row. If the query doesn't return any rows, this proc From 07bb8beffcd0bf6fbdda2b16a33e312b9ecdfca7 Mon Sep 17 00:00:00 2001 From: Senketsu Date: Thu, 17 Sep 2015 14:19:20 +0200 Subject: [PATCH 5/5] fix hasData to check for nil --- lib/impure/db_mysql.nim | 6 +++--- lib/impure/db_postgres.nim | 6 +++--- lib/impure/db_sqlite.nim | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index f57f5ef105143..bea099bf56a23 100644 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -193,20 +193,20 @@ proc hasData*(rows: seq[Row]): bool = result = false for row in rows: for item in row: - if item != "": + if item != "" and item != nil: result = true break proc hasData*(row: Row): bool = result = false for item in row: - if item != "": + if item != "" and item != nil: result = true break proc hasData*(value: string): bool = result = false - if value != "": + if value != "" and value != nil: result = true proc getRow*(db: DbConn, query: SqlQuery, diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index bd03d3f0a5063..58d57c2d1683d 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -184,20 +184,20 @@ proc hasData*(rows: seq[Row]): bool = result = false for row in rows: for item in row: - if item != "": + if item != "" and item != nil: result = true break proc hasData*(row: Row): bool = result = false for item in row: - if item != "": + if item != "" and item != nil: result = true break proc hasData*(value: string): bool = result = false - if value != "": + if value != "" and value != nil: result = true proc getRow*(db: DbConn, query: SqlQuery, diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 67b934a55fe94..a0edd57052985 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -167,20 +167,20 @@ proc hasData*(rows: seq[Row]): bool = result = false for row in rows: for item in row: - if item != "": + if item != "" and item != nil: result = true break proc hasData*(row: Row): bool = result = false for item in row: - if item != "": + if item != "" and item != nil: result = true break proc hasData*(value: string): bool = result = false - if value != "": + if value != "" and value != nil: result = true proc getRow*(db: DbConn, query: SqlQuery,