diff options
Diffstat (limited to 'lib/impure')
-rw-r--r-- | lib/impure/db_postgres.nim | 45 | ||||
-rw-r--r-- | lib/impure/db_sqlite.nim | 2 | ||||
-rw-r--r-- | lib/impure/nre.nim | 36 | ||||
-rw-r--r-- | lib/impure/re.nim | 33 |
4 files changed, 62 insertions, 54 deletions
diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index a42950557..1459f0d7e 100644 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -74,7 +74,7 @@ type ## converted to nil. InstantRow* = object ## a handle that can be res: PPGresult ## used to get a row's - line: int ## column text on demand + line: int ## column text on demand SqlPrepared* = distinct string ## a identifier for the prepared queries {.deprecated: [TRow: Row, TDbConn: DbConn, TSqlPrepared: SqlPrepared].} @@ -98,15 +98,18 @@ proc dbFormat(formatstr: SqlQuery, args: varargs[string]): string = var a = 0 if args.len > 0 and not string(formatstr).contains("?"): dbError("""parameter substitution expects "?" """) - for c in items(string(formatstr)): - if c == '?': - if args[a] == nil: - add(result, "NULL") + if args.len == 0: + return string(formatstr) + else: + for c in items(string(formatstr)): + if c == '?': + if args[a] == nil: + add(result, "NULL") + else: + add(result, dbQuote(args[a])) + inc(a) else: - add(result, dbQuote(args[a])) - inc(a) - else: - add(result, c) + add(result, c) proc tryExec*(db: DbConn, query: SqlQuery, args: varargs[string, `$`]): bool {.tags: [ReadDbEffect, WriteDbEffect].} = @@ -172,7 +175,7 @@ proc prepare*(db: DbConn; stmtName: string, query: SqlQuery; return SqlPrepared(stmtName) proc setRow(res: PPGresult, r: var Row, line, cols: int32) = - for col in 0..cols-1: + for col in 0'i32..cols-1: setLen(r[col], 0) let x = pqgetvalue(res, line, col) if x.isNil: @@ -188,7 +191,7 @@ iterator fastRows*(db: DbConn, query: SqlQuery, var res = setupQuery(db, query, args) var L = pqnfields(res) var result = newRow(L) - for i in 0..pqntuples(res)-1: + for i in 0'i32..pqntuples(res)-1: setRow(res, result, i, L) yield result pqclear(res) @@ -199,7 +202,7 @@ iterator fastRows*(db: DbConn, stmtName: SqlPrepared, var res = setupQuery(db, stmtName, args) var L = pqNfields(res) var result = newRow(L) - for i in 0..pqNtuples(res)-1: + for i in 0'i32..pqNtuples(res)-1: setRow(res, result, i, L) yield result pqClear(res) @@ -210,7 +213,7 @@ iterator instantRows*(db: DbConn, query: SqlQuery, ## same as fastRows but returns a handle that can be used to get column text ## on demand using []. Returned handle is valid only within iterator body. var res = setupQuery(db, query, args) - for i in 0..pqNtuples(res)-1: + for i in 0'i32..pqNtuples(res)-1: yield InstantRow(res: res, line: i) pqClear(res) @@ -220,7 +223,7 @@ iterator instantRows*(db: DbConn, stmtName: SqlPrepared, ## same as fastRows but returns a handle that can be used to get column text ## on demand using []. Returned handle is valid only within iterator body. var res = setupQuery(db, stmtName, args) - for i in 0..pqNtuples(res)-1: + for i in 0'i32..pqNtuples(res)-1: yield InstantRow(res: res, line: i) pqClear(res) @@ -237,7 +240,7 @@ proc getColumnType(res: PPGresult, col: int) : DbType = of 21: return DbType(kind: DbTypeKind.dbInt, name: "int2", size: 2) of 23: return DbType(kind: DbTypeKind.dbInt, name: "int4", size: 4) of 20: return DbType(kind: DbTypeKind.dbInt, name: "int8", size: 8) - of 1560: return DbType(kind: DbTypeKind.dbBit, name: "bit") + of 1560: return DbType(kind: DbTypeKind.dbBit, name: "bit") of 1562: return DbType(kind: DbTypeKind.dbInt, name: "varbit") of 18: return DbType(kind: DbTypeKind.dbFixedChar, name: "char") @@ -251,7 +254,7 @@ proc getColumnType(res: PPGresult, col: int) : DbType = of 700: return DbType(kind: DbTypeKind.dbFloat, name: "float4") of 701: return DbType(kind: DbTypeKind.dbFloat, name: "float8") - of 790: return DbType(kind: DbTypeKind.dbDecimal, name: "money") + of 790: return DbType(kind: DbTypeKind.dbDecimal, name: "money") of 1700: return DbType(kind: DbTypeKind.dbDecimal, name: "numeric") of 704: return DbType(kind: DbTypeKind.dbTimeInterval, name: "tinterval") @@ -274,12 +277,12 @@ proc getColumnType(res: PPGresult, col: int) : DbType = of 603: return DbType(kind: DbTypeKind.dbBox, name: "box") of 604: return DbType(kind: DbTypeKind.dbPolygon, name: "polygon") of 628: return DbType(kind: DbTypeKind.dbLine, name: "line") - of 718: return DbType(kind: DbTypeKind.dbCircle, name: "circle") + of 718: return DbType(kind: DbTypeKind.dbCircle, name: "circle") of 650: return DbType(kind: DbTypeKind.dbInet, name: "cidr") of 829: return DbType(kind: DbTypeKind.dbMacAddress, name: "macaddr") of 869: return DbType(kind: DbTypeKind.dbInet, name: "inet") - + of 2950: return DbType(kind: DbTypeKind.dbVarchar, name: "uuid") of 3614: return DbType(kind: DbTypeKind.dbVarchar, name: "tsvector") of 3615: return DbType(kind: DbTypeKind.dbVarchar, name: "tsquery") @@ -361,11 +364,11 @@ proc getColumnType(res: PPGresult, col: int) : DbType = proc setColumnInfo(columns: var DbColumns; res: PPGresult; L: int32) = setLen(columns, L) - for i in 0..<L: + for i in 0'i32..<L: columns[i].name = $pqfname(res, i) columns[i].typ = getColumnType(res, i) columns[i].tableName = $(pqftable(res, i)) ## Returns the OID of the table from which the given column was fetched. - ## Query the system table pg_class to determine exactly which table is referenced. + ## Query the system table pg_class to determine exactly which table is referenced. #columns[i].primaryKey = libpq does not have a function for that #columns[i].foreignKey = libpq does not have a function for that @@ -374,7 +377,7 @@ iterator instantRows*(db: DbConn; columns: var DbColumns; query: SqlQuery; {.tags: [ReadDbEffect].} = var res = setupQuery(db, query, args) setColumnInfo(columns, res, pqnfields(res)) - for i in 0..<pqntuples(res): + for i in 0'i32..<pqntuples(res): yield InstantRow(res: res, line: i) pqClear(res) diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 53dafdda7..21049571f 100644 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -148,7 +148,7 @@ proc setupQuery(db: DbConn, query: SqlQuery, if prepare_v2(db, q, q.len.cint, result, nil) != SQLITE_OK: dbError(db) proc setRow(stmt: Pstmt, r: var Row, cols: cint) = - for col in 0..cols-1: + for col in 0'i32..cols-1: setLen(r[col], column_bytes(stmt, col)) # set capacity setLen(r[col], 0) let x = column_text(stmt, col) diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim index 4013182af..3d4afc0ae 100644 --- a/lib/impure/nre.nim +++ b/lib/impure/nre.nim @@ -155,7 +155,7 @@ type ## - ``"abc".match(re"(?<letter>\w)").captures["letter"] == "a"`` ## - ``"abc".match(re"(\w)\w").captures[-1] == "ab"`` ## - ## ``captureBounds[]: Option[Slice[int]]`` + ## ``captureBounds[]: Option[HSlice[int, int]]`` ## gets the bounds of the given capture according to the same rules as ## the above. If the capture is not filled, then ``None`` is returned. ## The bounds are both inclusive. @@ -167,7 +167,7 @@ type ## ``match: string`` ## the full text of the match. ## - ## ``matchBounds: Slice[int]`` + ## ``matchBounds: HSlice[int, int]`` ## the bounds of the match, as in ``captureBounds[]`` ## ## ``(captureBounds|captures).toTable`` @@ -182,9 +182,9 @@ type ## Not nil. str*: string ## The string that was matched against. ## Not nil. - pcreMatchBounds: seq[Slice[cint]] ## First item is the bounds of the match - ## Other items are the captures - ## `a` is inclusive start, `b` is exclusive end + pcreMatchBounds: seq[HSlice[cint, cint]] ## First item is the bounds of the match + ## Other items are the captures + ## `a` is inclusive start, `b` is exclusive end Captures* = distinct RegexMatch CaptureBounds* = distinct RegexMatch @@ -251,13 +251,13 @@ proc captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(p proc captures*(pattern: RegexMatch): Captures = return Captures(pattern) -proc `[]`*(pattern: CaptureBounds, i: int): Option[Slice[int]] = +proc `[]`*(pattern: CaptureBounds, i: int): Option[HSlice[int, int]] = let pattern = RegexMatch(pattern) if pattern.pcreMatchBounds[i + 1].a != -1: let bounds = pattern.pcreMatchBounds[i + 1] return some(int(bounds.a) .. int(bounds.b-1)) else: - return none(Slice[int]) + return none(HSlice[int, int]) proc `[]`*(pattern: Captures, i: int): string = let pattern = RegexMatch(pattern) @@ -272,10 +272,10 @@ proc `[]`*(pattern: Captures, i: int): string = proc match*(pattern: RegexMatch): string = return pattern.captures[-1] -proc matchBounds*(pattern: RegexMatch): Slice[int] = +proc matchBounds*(pattern: RegexMatch): HSlice[int, int] = return pattern.captureBounds[-1].get -proc `[]`*(pattern: CaptureBounds, name: string): Option[Slice[int]] = +proc `[]`*(pattern: CaptureBounds, name: string): Option[HSlice[int, int]] = let pattern = RegexMatch(pattern) return pattern.captureBounds[pattern.pattern.captureNameToId.fget(name)] @@ -295,13 +295,13 @@ proc toTable*(pattern: Captures, default: string = nil): Table[string, string] = result = initTable[string, string]() toTableImpl(nextVal == nil) -proc toTable*(pattern: CaptureBounds, default = none(Slice[int])): - Table[string, Option[Slice[int]]] = - result = initTable[string, Option[Slice[int]]]() +proc toTable*(pattern: CaptureBounds, default = none(HSlice[int, int])): + Table[string, Option[HSlice[int, int]]] = + result = initTable[string, Option[HSlice[int, int]]]() toTableImpl(nextVal.isNone) template itemsImpl(cond: untyped) {.dirty.} = - for i in 0 .. <RegexMatch(pattern).pattern.captureCount: + for i in 0 ..< RegexMatch(pattern).pattern.captureCount: let nextVal = pattern[i] # done in this roundabout way to avoid multiple yields (potential code # bloat) @@ -309,13 +309,13 @@ template itemsImpl(cond: untyped) {.dirty.} = yield nextYieldVal -iterator items*(pattern: CaptureBounds, default = none(Slice[int])): Option[Slice[int]] = +iterator items*(pattern: CaptureBounds, default = none(HSlice[int, int])): Option[HSlice[int, int]] = itemsImpl(nextVal.isNone) iterator items*(pattern: Captures, default: string = nil): string = itemsImpl(nextVal == nil) -proc toSeq*(pattern: CaptureBounds, default = none(Slice[int])): seq[Option[Slice[int]]] = +proc toSeq*(pattern: CaptureBounds, default = none(HSlice[int, int])): seq[Option[HSlice[int, int]]] = accumulateResult(pattern.items(default)) proc toSeq*(pattern: Captures, default: string = nil): seq[string] = @@ -396,8 +396,6 @@ proc extractOptions(pattern: string): tuple[pattern: string, flags: int, study: # }}} -type UncheckedArray {.unchecked.}[T] = array[0 .. 0, T] - proc destroyRegex(pattern: Regex) = pcre.free_substring(cast[cstring](pattern.pcreObj)) pattern.pcreObj = nil @@ -412,7 +410,7 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] = result = initTable[string, int]() - for i in 0 .. <entryCount: + for i in 0 ..< entryCount: let pos = i * entrySize let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1 var name = "" @@ -464,7 +462,7 @@ proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Opt # 1x capture count as slack space for PCRE let vecsize = (pattern.captureCount() + 1) * 3 # div 2 because each element is 2 cints long - myResult.pcreMatchBounds = newSeq[Slice[cint]](ceil(vecsize / 2).int) + myResult.pcreMatchBounds = newSeq[HSlice[cint, cint]](ceil(vecsize / 2).int) myResult.pcreMatchBounds.setLen(vecsize div 3) let strlen = if endpos == int.high: str.len else: endpos+1 diff --git a/lib/impure/re.nim b/lib/impure/re.nim index e00f91de1..c7f8f336b 100644 --- a/lib/impure/re.nim +++ b/lib/impure/re.nim @@ -13,10 +13,6 @@ ## We had to de-deprecate this module since too much code relies on it ## and many people prefer its API over ``nre``'s. ## -## **Note:** The 're' proc defaults to the **extended regular expression -## syntax** which lets you use whitespace freely to make your regexes readable. -## However, this means matching whitespace requires ``\s`` or something similar. -## ## This module is implemented by providing a wrapper around the ## `PRCE (Perl-Compatible Regular Expressions) <http://www.pcre.org>`_ ## C library. This means that your application will depend on the PRCE @@ -53,9 +49,6 @@ type RegexError* = object of ValueError ## is raised if the pattern is no valid regular expression. -{.deprecated: [TRegexFlag: RegexFlag, TRegexDesc: RegexDesc, TRegex: Regex, - EInvalidRegEx: RegexError].} - proc raiseInvalidRegex(msg: string) {.noinline, noreturn.} = var e: ref RegexError new(e) @@ -78,7 +71,7 @@ proc finalizeRegEx(x: Regex) = if not isNil(x.e): pcre.free_substring(cast[cstring](x.e)) -proc re*(s: string, flags = {reExtended, reStudy}): Regex = +proc re*(s: string, flags = {reStudy}): Regex = ## Constructor of regular expressions. ## ## Note that Nim's @@ -96,6 +89,13 @@ proc re*(s: string, flags = {reExtended, reStudy}): Regex = result.e = pcre.study(result.h, options, addr msg) if not isNil(msg): raiseInvalidRegex($msg) +proc rex*(s: string, flags = {reStudy, reExtended}): Regex = + ## Constructor for extended regular expressions. + ## + ## The extended means that comments starting with `#` and + ## whitespace are ignored. + result = re(s, flags) + proc bufSubstr(b: cstring, sPos, ePos: int): string {.inline.} = ## Return a Nim string built from a slice of a cstring buffer. ## Don't assume cstring is '\0' terminated @@ -467,8 +467,8 @@ proc replacef*(s: string, sub: Regex, by: string): string = prev = match.last + 1 add(result, substr(s, prev)) -proc parallelReplace*(s: string, subs: openArray[ - tuple[pattern: Regex, repl: string]]): string = +proc multiReplace*(s: string, subs: openArray[ + tuple[pattern: Regex, repl: string]]): string = ## Returns a modified copy of ``s`` with the substitutions in ``subs`` ## applied in parallel. result = "" @@ -487,13 +487,20 @@ proc parallelReplace*(s: string, subs: openArray[ # copy the rest: add(result, substr(s, i)) +proc parallelReplace*(s: string, subs: openArray[ + tuple[pattern: Regex, repl: string]]): string {.deprecated.} = + ## Returns a modified copy of ``s`` with the substitutions in ``subs`` + ## applied in parallel. + ## **Deprecated since version 0.18.0**: Use ``multiReplace`` instead. + result = multiReplace(s, subs) + proc transformFile*(infile, outfile: string, subs: openArray[tuple[pattern: Regex, repl: string]]) = ## reads in the file ``infile``, performs a parallel replacement (calls ## ``parallelReplace``) and writes back to ``outfile``. Raises ``IOError`` if an ## error occurs. This is supposed to be used for quick scripting. var x = readFile(infile).string - writeFile(outfile, x.parallelReplace(subs)) + writeFile(outfile, x.multiReplace(subs)) iterator split*(s: string, sep: Regex): string = ## Splits the string ``s`` into substrings. @@ -576,12 +583,12 @@ const ## common regular expressions ## describes an URL when isMainModule: - doAssert match("(a b c)", re"\( .* \)") + doAssert match("(a b c)", rex"\( .* \)") doAssert match("WHiLe", re("while", {reIgnoreCase})) doAssert "0158787".match(re"\d+") doAssert "ABC 0232".match(re"\w+\s+\d+") - doAssert "ABC".match(re"\d+ | \w+") + doAssert "ABC".match(rex"\d+ | \w+") {.push warnings:off.} doAssert matchLen("key", re(reIdentifier)) == 3 |