summary refs log tree commit diff stats
path: root/lib/impure
diff options
context:
space:
mode:
Diffstat (limited to 'lib/impure')
-rw-r--r--lib/impure/db_odbc.nim150
-rw-r--r--lib/impure/nre.nim17
-rw-r--r--lib/impure/rdstdin.nim9
-rw-r--r--lib/impure/ssl.nim3
4 files changed, 120 insertions, 59 deletions
diff --git a/lib/impure/db_odbc.nim b/lib/impure/db_odbc.nim
index 1b72c6241..d6343acc7 100644
--- a/lib/impure/db_odbc.nim
+++ b/lib/impure/db_odbc.nim
@@ -38,7 +38,7 @@
 ##
 ## .. code-block:: Nim
 ##     import db_odbc
-##     let db = open("localhost", "user", "password", "dbname")
+##     var db = open("localhost", "user", "password", "dbname")
 ##     db.close()
 ##
 ## Creating a table
@@ -64,7 +64,7 @@
 ##
 ##  import db_odbc, math
 ##
-##  let theDb = open("localhost", "nim", "nim", "test")
+##  var theDb = open("localhost", "nim", "nim", "test")
 ##
 ##  theDb.exec(sql"Drop table if exists myTestTbl")
 ##  theDb.exec(sql("create table myTestTbl (" &
@@ -88,9 +88,7 @@
 ##
 ##  theDb.close()
 
-
 import strutils, odbcsql
-
 import db_common
 export db_common
 
@@ -212,7 +210,7 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string {.
       add(result, c)
 
 proc prepareFetch(db: var DbConn, query: SqlQuery,
-                args: varargs[string, `$`]) {.
+                args: varargs[string, `$`]): TSqlSmallInt {.
                 tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].} =
   # Prepare a statement, execute it and fetch the data to the driver
   # ready for retrieval of the data
@@ -224,7 +222,8 @@ proc prepareFetch(db: var DbConn, query: SqlQuery,
   var q = dbFormat(query, args)
   db.sqlCheck(SQLPrepare(db.stmt, q.PSQLCHAR, q.len.TSqlSmallInt))
   db.sqlCheck(SQLExecute(db.stmt))
-  db.sqlCheck(SQLFetch(db.stmt))
+  result = SQLFetch(db.stmt)
+  db.sqlCheck(result)
 
 proc prepareFetchDirect(db: var DbConn, query: SqlQuery,
                 args: varargs[string, `$`]) {.
@@ -250,8 +249,8 @@ proc tryExec*(db: var DbConn, query: SqlQuery, args: varargs[string, `$`]): bool
     var
       rCnt = -1
     res = SQLRowCount(db.stmt, rCnt)
-    if res != SQL_SUCCESS: dbError(db)
     properFreeResult(SQL_HANDLE_STMT, db.stmt)
+    if res != SQL_SUCCESS: dbError(db)
   except: discard
   return res == SQL_SUCCESS
 
@@ -286,19 +285,30 @@ iterator fastRows*(db: var DbConn, query: SqlQuery,
     sz: TSqlSmallInt = 0
     cCnt: TSqlSmallInt = 0.TSqlSmallInt
     res: TSqlSmallInt = 0.TSqlSmallInt
-  db.prepareFetch(query, args)
-  res = SQLNumResultCols(db.stmt, cCnt)
-  rowRes.setLen(cCnt)
-  while res == SQL_SUCCESS:
-    for colId in 1..cCnt:
-      buf[0] = '\0'
-      db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
-                               cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
-      rowRes[colId-1] = $buf.cstring
-    yield rowRes
-    res = SQLFetch(db.stmt)
-  db.sqlCheck(res)
+    tempcCnt: TSqlSmallInt # temporary cCnt,Fix the field values to be null when the release schema is compiled.
+    # tempcCnt,A field to store the number of temporary variables, for unknown reasons,
+    # after performing a sqlgetdata function and circulating variables cCnt value will be changed to 0,
+    # so the values of the temporary variable to store the cCnt.
+    # After every cycle and specified to cCnt. To ensure the traversal of all fields.
+  res = db.prepareFetch(query, args)
+  if res == SQL_NO_DATA:
+    discard
+  elif res == SQL_SUCCESS:
+    res = SQLNumResultCols(db.stmt, cCnt)
+    rowRes = newRow(cCnt)
+    rowRes.setLen(max(cCnt,0))
+    tempcCnt = cCnt
+    while res == SQL_SUCCESS:
+      for colId in 1..cCnt:
+        buf[0] = '\0'
+        db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
+                                 cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
+        rowRes[colId-1] = $buf.cstring
+        cCnt = tempcCnt
+      yield rowRes
+      res = SQLFetch(db.stmt)
   properFreeResult(SQL_HANDLE_STMT, db.stmt)
+  db.sqlCheck(res)
 
 iterator instantRows*(db: var DbConn, query: SqlQuery,
                       args: varargs[string, `$`]): InstantRow
@@ -310,19 +320,30 @@ iterator instantRows*(db: var DbConn, query: SqlQuery,
     sz: TSqlSmallInt = 0
     cCnt: TSqlSmallInt = 0.TSqlSmallInt
     res: TSqlSmallInt = 0.TSqlSmallInt
-  db.prepareFetch(query, args)
-  res = SQLNumResultCols(db.stmt, cCnt)
-  rowRes.setLen(cCnt)
-  while res == SQL_SUCCESS:
-    for colId in 1..cCnt:
-      buf[0] = '\0'
-      db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
-                               cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
-      rowRes[colId-1] = $buf.cstring
-    yield (row: rowRes, len: cCnt.int)
-    res = SQLFetch(db.stmt)
-  db.sqlCheck(res)
+    tempcCnt: TSqlSmallInt # temporary cCnt,Fix the field values to be null when the release schema is compiled.
+    # tempcCnt,A field to store the number of temporary variables, for unknown reasons,
+    # after performing a sqlgetdata function and circulating variables cCnt value will be changed to 0,
+    # so the values of the temporary variable to store the cCnt.
+    # After every cycle and specified to cCnt. To ensure the traversal of all fields.
+  res = db.prepareFetch(query, args)
+  if res == SQL_NO_DATA:
+    discard
+  elif res == SQL_SUCCESS:
+    res = SQLNumResultCols(db.stmt, cCnt)
+    rowRes = newRow(cCnt)
+    rowRes.setLen(max(cCnt,0))
+    tempcCnt = cCnt
+    while res == SQL_SUCCESS:
+      for colId in 1..cCnt:
+        buf[0] = '\0'
+        db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
+                                 cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
+        rowRes[colId-1] = $buf.cstring
+        cCnt = tempcCnt
+      yield (row: rowRes, len: cCnt.int)
+      res = SQLFetch(db.stmt)
   properFreeResult(SQL_HANDLE_STMT, db.stmt)
+  db.sqlCheck(res)
 
 proc `[]`*(row: InstantRow, col: int): string {.inline.} =
   ## Returns text for given column of the row
@@ -338,44 +359,69 @@ proc getRow*(db: var DbConn, query: SqlQuery,
   ## Retrieves a single row. If the query doesn't return any rows, this proc
   ## will return a Row with empty strings for each column.
   var
+    rowRes: Row
     sz: TSqlSmallInt = 0.TSqlSmallInt
     cCnt: TSqlSmallInt = 0.TSqlSmallInt
     res: TSqlSmallInt = 0.TSqlSmallInt
-  db.prepareFetch(query, args)
-  res = SQLNumResultCols(db.stmt, cCnt)
-  result.setLen(max(cCnt,0))
-  if res == SQL_SUCCESS:
+    tempcCnt: TSqlSmallInt # temporary cCnt,Fix the field values to be null when the release schema is compiled.
+    ## tempcCnt,A field to store the number of temporary variables, for unknown reasons,
+    ## after performing a sqlgetdata function and circulating variables cCnt value will be changed to 0,
+    ## so the values of the temporary variable to store the cCnt.
+    ## After every cycle and specified to cCnt. To ensure the traversal of all fields.
+  res = db.prepareFetch(query, args)
+  if res == SQL_NO_DATA:
+    result = @[]
+  elif res == SQL_SUCCESS:
+    res = SQLNumResultCols(db.stmt, cCnt)
+    rowRes = newRow(cCnt)
+    rowRes.setLen(max(cCnt,0))
+    tempcCnt = cCnt
     for colId in 1..cCnt:
+      buf[0] = '\0'
       db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
                                cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
-      result[colId-1] = $buf.cstring
+      rowRes[colId-1] = $buf.cstring
+      cCnt = tempcCnt
     res = SQLFetch(db.stmt)
-  db.sqlCheck(res)
+    result = rowRes
   properFreeResult(SQL_HANDLE_STMT, db.stmt)
+  db.sqlCheck(res)
 
 proc getAllRows*(db: var DbConn, query: SqlQuery,
                  args: varargs[string, `$`]): seq[Row] {.
-           tags: [ReadDbEffect, WriteDbEffect], raises: [DbError].} =
+           tags: [ReadDbEffect, WriteDbEffect], raises: [DbError] .} =
   ## Executes the query and returns the whole result dataset.
   var
+    rows: seq[Row] = @[]
     rowRes: Row
     sz: TSqlSmallInt = 0
     cCnt: TSqlSmallInt = 0.TSqlSmallInt
     res: TSqlSmallInt = 0.TSqlSmallInt
-  db.prepareFetch(query, args)
-  res = SQLNumResultCols(db.stmt, cCnt)
-  result = @[]
-  rowRes.setLen(max(cCnt,0))
-  while res == SQL_SUCCESS:
-    buf[0] = '\0'
-    for colId in 1..cCnt:
-      db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
-                               cast[SqlPointer](buf.addr), 4095.TSqlSmallInt, sz.addr))
-      rowRes[colId-1] = $buf.cstring
-    result.add(rowRes)
-    res = SQLFetch(db.stmt)
-  db.sqlCheck(res)
+    tempcCnt: TSqlSmallInt # temporary cCnt,Fix the field values to be null when the release schema is compiled.
+    ## tempcCnt,A field to store the number of temporary variables, for unknown reasons,
+    ## after performing a sqlgetdata function and circulating variables cCnt value will be changed to 0,
+    ## so the values of the temporary variable to store the cCnt.
+    ## After every cycle and specified to cCnt. To ensure the traversal of all fields.
+  res = db.prepareFetch(query, args)
+  if res == SQL_NO_DATA:
+    result = @[]
+  elif res == SQL_SUCCESS:
+    res = SQLNumResultCols(db.stmt, cCnt)
+    rowRes = newRow(cCnt)
+    rowRes.setLen(max(cCnt,0))
+    tempcCnt = cCnt
+    while res == SQL_SUCCESS:
+      for colId in 1..cCnt:
+        buf[0] = '\0'
+        db.sqlCheck(SQLGetData(db.stmt, colId.SqlUSmallInt, SQL_C_CHAR,
+                                 cast[cstring](buf.addr), 4095.TSqlSmallInt, sz.addr))
+        rowRes[colId-1] = $buf.cstring
+        cCnt = tempcCnt
+      rows.add(rowRes)
+      res = SQLFetch(db.stmt)
+    result = rows
   properFreeResult(SQL_HANDLE_STMT, db.stmt)
+  db.sqlCheck(res)
 
 iterator rows*(db: var DbConn, query: SqlQuery,
                args: varargs[string, `$`]): Row {.
@@ -496,5 +542,5 @@ proc setEncoding*(connection: DbConn, encoding: string): bool {.
   ##
   ## Sets the encoding of a database connection, returns true for
   ## success, false for failure.
-  #result = set_character_set(connection, encoding) == 0
+  ##result = set_character_set(connection, encoding) == 0
   dbError("setEncoding() is currently not implemented by the db_odbc module")
diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim
index 973f1f2ee..b739e9eff 100644
--- a/lib/impure/nre.nim
+++ b/lib/impure/nre.nim
@@ -1,6 +1,6 @@
 #
 #            Nim's Runtime Library
-#        (c) Copyright 2015 Nim Contributers
+#        (c) Copyright 2015 Nim Contributors
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -10,12 +10,13 @@
 from pcre import nil
 import nre.private.util
 import tables
-import unsigned
 from strutils import toLower, `%`
 from math import ceil
 import options
 from unicode import runeLenAt
 
+export options
+
 
 ## What is NRE?
 ## ============
@@ -509,7 +510,7 @@ iterator findIter*(str: string, pattern: Regex, start = 0, endpos = int.high): R
   ## Variants:
   ##
   ## -  ``proc findAll(...)`` returns a ``seq[string]``
-  # see pcredemo for explaination
+  # see pcredemo for explanation
   let matchesCrLf = pattern.matchesCrLf()
   let unicode = uint32(getinfo[culong](pattern, pcre.INFO_OPTIONS) and
     pcre.UTF8) > 0u32
@@ -567,6 +568,16 @@ proc findAll*(str: string, pattern: Regex, start = 0, endpos = int.high): seq[st
   for match in str.findIter(pattern, start, endpos):
     result.add(match.match)
 
+proc contains*(str: string, pattern: Regex, start = 0, endpos = int.high): bool =
+  ## Determine if the string contains the given pattern between the end and
+  ## start positions:
+  ## -  "abc".contains(re"bc") == true
+  ## -  "abc".contains(re"cd") == false
+  ## -  "abc".contains(re"a", start = 1) == false
+  ##
+  ## Same as ``isSome(str.find(pattern, start, endpos))``.
+  return isSome(str.find(pattern, start, endpos))
+
 proc split*(str: string, pattern: Regex, maxSplit = -1, start = 0): seq[string] =
   ## Splits the string with the given regex. This works according to the
   ## rules that Perl and Javascript use:
diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim
index 15137b436..f722a6b39 100644
--- a/lib/impure/rdstdin.nim
+++ b/lib/impure/rdstdin.nim
@@ -55,7 +55,7 @@ when defined(Windows):
       event*: KEY_EVENT_RECORD
       safetyBuffer: array[0..5, DWORD]
 
-  proc readConsoleInputW*(hConsoleInput: THANDLE, lpBuffer: var INPUTRECORD,
+  proc readConsoleInputW*(hConsoleInput: HANDLE, lpBuffer: var INPUTRECORD,
                           nLength: uint32,
                           lpNumberOfEventsRead: var uint32): WINBOOL{.
       stdcall, dynlib: "kernel32", importc: "ReadConsoleInputW".}
@@ -105,7 +105,8 @@ else:
   proc readLineFromStdin*(prompt: string): TaintedString {.
                           tags: [ReadIOEffect, WriteIOEffect].} =
     var buffer = linenoise.readLine(prompt)
-    if isNil(buffer): quit(0)
+    if isNil(buffer):
+      raise newException(IOError, "Linenoise returned nil")
     result = TaintedString($buffer)
     if result.string.len > 0:
       historyAdd(buffer)
@@ -114,12 +115,12 @@ else:
   proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {.
                           tags: [ReadIOEffect, WriteIOEffect].} =
     var buffer = linenoise.readLine(prompt)
-    if isNil(buffer): quit(0)
+    if isNil(buffer):
+      raise newException(IOError, "Linenoise returned nil")
     line = TaintedString($buffer)
     if line.string.len > 0:
       historyAdd(buffer)
     linenoise.free(buffer)
-    # XXX how to determine CTRL+D?
     result = true
 
   proc readPasswordFromStdin*(prompt: string, password: var TaintedString):
diff --git a/lib/impure/ssl.nim b/lib/impure/ssl.nim
index 721e5ce51..e3312d792 100644
--- a/lib/impure/ssl.nim
+++ b/lib/impure/ssl.nim
@@ -9,6 +9,9 @@
 
 ## This module provides an easy to use sockets-style
 ## nim interface to the OpenSSL library.
+##
+## **Warning:** This module is deprecated, use the SSL procedures defined in
+## the ``net`` module instead.
 
 {.deprecated.}