diff options
Diffstat (limited to 'lib/impure')
-rw-r--r-- | lib/impure/db_mongo.nim | 38 | ||||
-rwxr-xr-x | lib/impure/db_mysql.nim | 46 | ||||
-rwxr-xr-x | lib/impure/db_postgres.nim | 38 | ||||
-rwxr-xr-x | lib/impure/db_sqlite.nim | 42 | ||||
-rwxr-xr-x | lib/impure/rdstdin.nim | 12 | ||||
-rwxr-xr-x | lib/impure/web.nim | 2 |
6 files changed, 113 insertions, 65 deletions
diff --git a/lib/impure/db_mongo.nim b/lib/impure/db_mongo.nim index 5195e2a09..b7fb325f9 100644 --- a/lib/impure/db_mongo.nim +++ b/lib/impure/db_mongo.nim @@ -33,6 +33,10 @@ type EDb* = object of EIO ## exception that is raised if a database error occurs TDbConn* = TMongo ## a database connection; alias for ``TMongo`` + FDb* = object of FIO ## effect that denotes a database operation + FReadDb* = object of FReadIO ## effect that denotes a read operation + FWriteDb* = object of FWriteIO ## effect that denotes a write operation + proc dbError*(db: TDbConn, msg: string) {.noreturn.} = ## raises an EDb exception with message `msg`. var e: ref EDb @@ -43,12 +47,13 @@ proc dbError*(db: TDbConn, msg: string) {.noreturn.} = e.msg = $db.err & " " & msg raise e -proc Close*(db: var TDbConn) = +proc Close*(db: var TDbConn) {.tags: [FDB].} = ## closes the database connection. disconnect(db) destroy(db) -proc Open*(host: string = defaultHost, port: int = defaultPort): TDbConn = +proc Open*(host: string = defaultHost, port: int = defaultPort): TDbConn {. + tags: [FDB].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. init(result) @@ -108,7 +113,8 @@ proc getId*(obj: var TBSon): TOid = else: raise newException(EInvalidIndex, "_id not in object") -proc insertID*(db: var TDbConn, namespace: string, data: PJsonNode): TOid = +proc insertID*(db: var TDbConn, namespace: string, data: PJsonNode): TOid {. + tags: [FWriteDb].} = ## converts `data` to BSON format and inserts it in `namespace`. Returns ## the generated OID for the ``_id`` field. result = genOid() @@ -116,11 +122,13 @@ proc insertID*(db: var TDbConn, namespace: string, data: PJsonNode): TOid = insert(db, namespace, x) destroy(x) -proc insert*(db: var TDbConn, namespace: string, data: PJsonNode) = +proc insert*(db: var TDbConn, namespace: string, data: PJsonNode) {. + tags: [FWriteDb].} = ## converts `data` to BSON format and inserts it in `namespace`. discard InsertID(db, namespace, data) -proc update*(db: var TDbConn, namespace: string, obj: var TBSon) = +proc update*(db: var TDbConn, namespace: string, obj: var TBSon) {. + tags: [FReadDB, FWriteDb].} = ## updates `obj` in `namespace`. var cond: TBson init(cond) @@ -129,13 +137,15 @@ proc update*(db: var TDbConn, namespace: string, obj: var TBSon) = update(db, namespace, cond, obj, ord(UPDATE_UPSERT)) destroy(cond) -proc update*(db: var TDbConn, namespace: string, oid: TOid, obj: PJsonNode) = +proc update*(db: var TDbConn, namespace: string, oid: TOid, obj: PJsonNode) {. + tags: [FReadDB, FWriteDb].} = ## updates the data with `oid` to have the new data `obj`. var a = jsonToBSon(obj, oid) Update(db, namespace, a) destroy(a) -proc delete*(db: var TDbConn, namespace: string, oid: TOid) = +proc delete*(db: var TDbConn, namespace: string, oid: TOid) {. + tags: [FWriteDb].} = ## Deletes the object belonging to `oid`. var cond: TBson init(cond) @@ -144,11 +154,13 @@ proc delete*(db: var TDbConn, namespace: string, oid: TOid) = discard remove(db, namespace, cond) destroy(cond) -proc delete*(db: var TDbConn, namespace: string, obj: var TBSon) = +proc delete*(db: var TDbConn, namespace: string, obj: var TBSon) {. + tags: [FWriteDb].} = ## Deletes the object `obj`. delete(db, namespace, getId(obj)) -iterator find*(db: var TDbConn, namespace: string): var TBSon = +iterator find*(db: var TDbConn, namespace: string): var TBSon {. + tags: [FReadDB].} = ## iterates over any object in `namespace`. var cursor: TCursor init(cursor, db, namespace) @@ -157,7 +169,7 @@ iterator find*(db: var TDbConn, namespace: string): var TBSon = destroy(cursor) iterator find*(db: var TDbConn, namespace: string, - query, fields: var TBSon): var TBSon = + query, fields: var TBSon): var TBSon {.tags: [FReadDB].} = ## yields the `fields` of any document that suffices `query`. var cursor = find(db, namespace, query, fields, 0'i32, 0'i32, 0'i32) if cursor != nil: @@ -171,7 +183,8 @@ proc setupFieldnames(fields: varargs[string]): TBSon = finish(result) iterator find*(db: var TDbConn, namespace: string, - query: var TBSon, fields: varargs[string]): var TBSon = + query: var TBSon, fields: varargs[string]): var TBSon {. + tags: [FReadDB].} = ## yields the `fields` of any document that suffices `query`. If `fields` ## is ``[]`` the whole document is yielded. var f = setupFieldnames(fields) @@ -188,7 +201,8 @@ proc setupQuery(query: string): TBSon = finish(result) iterator find*(db: var TDbConn, namespace: string, - query: string, fields: varargs[string]): var TBSon = + query: string, fields: varargs[string]): var TBSon {. + tags: [FReadDB].} = ## yields the `fields` of any document that suffices `query`. If `fields` ## is ``[]`` the whole document is yielded. var f = setupFieldnames(fields) diff --git a/lib/impure/db_mysql.nim b/lib/impure/db_mysql.nim index 6284b7995..118ed39bb 100755 --- a/lib/impure/db_mysql.nim +++ b/lib/impure/db_mysql.nim @@ -18,7 +18,11 @@ type EDb* = object of EIO ## exception that is raised if a database error occurs TSqlQuery* = distinct string ## an SQL query string - + + FDb* = object of FIO ## effect that denotes a database operation + FReadDb* = object of FReadIO ## effect that denotes a read operation + FWriteDb* = object of FWriteIO ## effect that denotes a write operation + proc dbError(db: TDbConn) {.noreturn.} = ## raises an EDb exception. var e: ref EDb @@ -60,12 +64,18 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = else: add(result, c) -proc TryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool = +proc TryExec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]): bool {. + tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) return mysql.RealQuery(db, q, q.len) == 0'i32 -proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) = +proc rawExec(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) = + var q = dbFormat(query, args) + if mysql.RealQuery(db, q, q.len) != 0'i32: dbError(db) + +proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. + tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var q = dbFormat(query, args) if mysql.RealQuery(db, q, q.len) != 0'i32: dbError(db) @@ -80,11 +90,11 @@ proc properFreeResult(sqlres: mysql.PRES, row: cstringArray) = mysql.FreeResult(sqlres) iterator FastRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For MySQL this is the case!. - Exec(db, query, args) + rawExec(db, query, args) var sqlres = mysql.UseResult(db) if sqlres != nil: var L = int(mysql.NumFields(sqlres)) @@ -100,9 +110,9 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery, properFreeResult(sqlres, row) proc getRow*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## retrieves a single row. - Exec(db, query, args) + rawExec(db, query, args) var sqlres = mysql.UseResult(db) if sqlres != nil: var L = int(mysql.NumFields(sqlres)) @@ -115,10 +125,10 @@ proc getRow*(db: TDbConn, query: TSqlQuery, properFreeResult(sqlres, row) proc GetAllRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): seq[TRow] = + args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] - Exec(db, query, args) + rawExec(db, query, args) var sqlres = mysql.UseResult(db) if sqlres != nil: var L = int(mysql.NumFields(sqlres)) @@ -134,12 +144,12 @@ proc GetAllRows*(db: TDbConn, query: TSqlQuery, mysql.FreeResult(sqlres) iterator Rows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## same as `FastRows`, but slower and safe. for r in items(GetAllRows(db, query, args)): yield r proc GetValue*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): string = + args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the result dataset's the first column ## of the first row. Returns "" if the dataset contains no rows. This uses ## `FastRows`, so it inherits its fragile behaviour. @@ -149,7 +159,7 @@ proc GetValue*(db: TDbConn, query: TSqlQuery, break proc TryInsertID*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. var q = dbFormat(query, args) @@ -159,24 +169,26 @@ proc TryInsertID*(db: TDbConn, query: TSqlQuery, result = mysql.InsertId(db) proc InsertID*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row. result = TryInsertID(db, query, args) if result < 0: dbError(db) proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {. + tags: [FReadDB, FWriteDb].} = ## runs the query (typically "UPDATE") and returns the ## number of affected rows - Exec(db, query, args) + rawExec(db, query, args) result = mysql.AffectedRows(db) -proc Close*(db: TDbConn) = +proc Close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. if db != nil: mysql.Close(db) -proc Open*(connection, user, password, database: string): TDbConn = +proc Open*(connection, user, password, database: string): TDbConn {. + tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. result = mysql.Init(nil) diff --git a/lib/impure/db_postgres.nim b/lib/impure/db_postgres.nim index cb8da75b8..2e2b09bc2 100755 --- a/lib/impure/db_postgres.nim +++ b/lib/impure/db_postgres.nim @@ -18,6 +18,10 @@ type EDb* = object of EIO ## exception that is raised if a database error occurs TSqlQuery* = distinct string ## an SQL query string + + FDb* = object of FIO ## effect that denotes a database operation + FReadDb* = object of FReadIO ## effect that denotes a read operation + FWriteDb* = object of FWriteIO ## effect that denotes a write operation proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} = ## constructs a TSqlQuery from the string `query`. This is supposed to be @@ -60,14 +64,15 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = add(result, c) proc TryExec*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): bool = + args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) var res = PQExec(db, q) result = PQresultStatus(res) == PGRES_COMMAND_OK PQclear(res) -proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) = +proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. + tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. var q = dbFormat(query, args) var res = PQExec(db, q) @@ -91,7 +96,7 @@ proc setRow(res: PPGresult, r: var TRow, line, cols: int32) = add(r[col], x) iterator FastRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For Postgres it is safe though. @@ -104,7 +109,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery, PQclear(res) proc getRow*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## retrieves a single row. var res = setupQuery(db, query, args) var L = PQnfields(res) @@ -113,38 +118,39 @@ proc getRow*(db: TDbConn, query: TSqlQuery, PQclear(res) proc GetAllRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): seq[TRow] = + args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] for r in FastRows(db, query, args): result.add(r) iterator Rows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## same as `FastRows`, but slower and safe. for r in items(GetAllRows(db, query, args)): yield r proc GetValue*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): string = + args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the result dataset's the first column ## of the first row. Returns "" if the dataset contains no rows. var x = PQgetvalue(setupQuery(db, query, args), 0, 0) result = if isNil(x): "" else: $x proc TryInsertID*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {.tags: [FWriteDb].}= ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. For Postgre this adds ## ``RETURNING id`` to the query, so it only works if your primary key is ## named ``id``. - var val = GetValue(db, TSqlQuery(string(query) & " RETURNING id"), args) - if val.len > 0: - result = ParseBiggestInt(val) + var x = PQgetvalue(setupQuery(db, TSqlQuery(string(query) & " RETURNING id"), + args), 0, 0) + if not isNil(x): + result = ParseBiggestInt($x) else: result = -1 proc InsertID*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row. For Postgre this adds ## ``RETURNING id`` to the query, so it only works if your primary key is @@ -153,7 +159,8 @@ proc InsertID*(db: TDbConn, query: TSqlQuery, if result < 0: dbError(db) proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {.tags: [ + FReadDB, FWriteDb].} = ## executes the query (typically "UPDATE") and returns the ## number of affected rows. var q = dbFormat(query, args) @@ -162,11 +169,12 @@ proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, result = parseBiggestInt($PQcmdTuples(res)) PQclear(res) -proc Close*(db: TDbConn) = +proc Close*(db: TDbConn) {.tags: [FDb].} = ## closes the database connection. if db != nil: PQfinish(db) -proc Open*(connection, user, password, database: string): TDbConn = +proc Open*(connection, user, password, database: string): TDbConn {. + tags: [FDb].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. result = PQsetdbLogin(nil, nil, nil, nil, database, user, password) diff --git a/lib/impure/db_sqlite.nim b/lib/impure/db_sqlite.nim index 4abc2ca97..e9864c599 100755 --- a/lib/impure/db_sqlite.nim +++ b/lib/impure/db_sqlite.nim @@ -19,6 +19,10 @@ type TSqlQuery* = distinct string ## an SQL query string + FDb* = object of FIO ## effect that denotes a database operation + FReadDb* = object of FReadIO ## effect that denotes a read operation + FWriteDb* = object of FWriteIO ## effect that denotes a write operation + proc sql*(query: string): TSqlQuery {.noSideEffect, inline.} = ## constructs a TSqlQuery from the string `query`. This is supposed to be ## used as a raw-string-literal modifier: @@ -60,7 +64,7 @@ proc dbFormat(formatstr: TSqlQuery, args: varargs[string]): string = add(result, c) proc TryExec*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): bool = + args: varargs[string, `$`]): bool {.tags: [FReadDB, FWriteDb].} = ## tries to execute the query and returns true if successful, false otherwise. var q = dbFormat(query, args) var stmt: sqlite3.PStmt @@ -68,7 +72,8 @@ proc TryExec*(db: TDbConn, query: TSqlQuery, if step(stmt) == SQLITE_DONE: result = finalize(stmt) == SQLITE_OK -proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) = +proc Exec*(db: TDbConn, query: TSqlQuery, args: varargs[string, `$`]) {. + tags: [FReadDB, FWriteDb].} = ## executes the query and raises EDB if not successful. if not TryExec(db, query, args): dbError(db) @@ -89,7 +94,7 @@ proc setRow(stmt: PStmt, r: var TRow, cols: cint) = if not isNil(x): add(r[col], x) iterator FastRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## executes the query and iterates over the result dataset. This is very ## fast, but potenially dangerous: If the for-loop-body executes another ## query, the results can be undefined. For Sqlite it is safe though. @@ -102,7 +107,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery, if finalize(stmt) != SQLITE_OK: dbError(db) proc getRow*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## retrieves a single row. var stmt = setupQuery(db, query, args) var L = (columnCount(stmt)) @@ -112,19 +117,19 @@ proc getRow*(db: TDbConn, query: TSqlQuery, if finalize(stmt) != SQLITE_OK: dbError(db) proc GetAllRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): seq[TRow] = + args: varargs[string, `$`]): seq[TRow] {.tags: [FReadDB].} = ## executes the query and returns the whole result dataset. result = @[] for r in FastRows(db, query, args): result.add(r) iterator Rows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): TRow = + args: varargs[string, `$`]): TRow {.tags: [FReadDB].} = ## same as `FastRows`, but slower and safe. for r in FastRows(db, query, args): yield r proc GetValue*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): string = + args: varargs[string, `$`]): string {.tags: [FReadDB].} = ## executes the query and returns the result dataset's the first column ## of the first row. Returns "" if the dataset contains no rows. var stmt = setupQuery(db, query, args) @@ -140,16 +145,19 @@ proc GetValue*(db: TDbConn, query: TSqlQuery, result = "" proc TryInsertID*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row or -1 in case of an error. - if tryExec(db, query, args): - result = last_insert_rowid(db) - else: - result = -1 + var q = dbFormat(query, args) + var stmt: sqlite3.PStmt + if prepare_v2(db, q, q.len.cint, stmt, nil) == SQLITE_OK: + if step(stmt) == SQLITE_DONE: + if finalize(stmt) == SQLITE_OK: + return last_insert_rowid(db) + result = -1 proc InsertID*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {.tags: [FWriteDb].} = ## executes the query (typically "INSERT") and returns the ## generated ID for the row. For Postgre this adds ## ``RETURNING id`` to the query, so it only works if your primary key is @@ -158,17 +166,19 @@ proc InsertID*(db: TDbConn, query: TSqlQuery, if result < 0: dbError(db) proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery, - args: varargs[string, `$`]): int64 = + args: varargs[string, `$`]): int64 {. + tags: [FReadDB, FWriteDb].} = ## executes the query (typically "UPDATE") and returns the ## number of affected rows. Exec(db, query, args) result = changes(db) -proc Close*(db: TDbConn) = +proc Close*(db: TDbConn) {.tags: [FDB].} = ## closes the database connection. if sqlite3.close(db) != SQLITE_OK: dbError(db) -proc Open*(connection, user, password, database: string): TDbConn = +proc Open*(connection, user, password, database: string): TDbConn {. + tags: [FDB].} = ## opens a database connection. Raises `EDb` if the connection could not ## be established. Only the ``connection`` parameter is used for ``sqlite``. var db: TDbConn diff --git a/lib/impure/rdstdin.nim b/lib/impure/rdstdin.nim index cd614fa98..cf076e929 100755 --- a/lib/impure/rdstdin.nim +++ b/lib/impure/rdstdin.nim @@ -14,12 +14,14 @@ ## wanted functionality. when defined(Windows): - proc ReadLineFromStdin*(prompt: string): TaintedString = + proc ReadLineFromStdin*(prompt: string): TaintedString {. + tags: [FReadIO, FWriteIO].} = ## Reads a line from stdin. stdout.write(prompt) result = readLine(stdin) - proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool = + proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool {. + tags: [FReadIO, FWriteIO].} = ## Reads a `line` from stdin. `line` must not be ## ``nil``! May throw an IO exception. ## A line of text may be delimited by ``CR``, ``LF`` or @@ -32,7 +34,8 @@ when defined(Windows): else: import readline, history - proc ReadLineFromStdin*(prompt: string): TaintedString = + proc ReadLineFromStdin*(prompt: string): TaintedString {. + tags: [FReadIO, FWriteIO].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) result = TaintedString($buffer) @@ -40,7 +43,8 @@ else: add_history(buffer) readline.free(buffer) - proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool = + proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool {. + tags: [FReadIO, FWriteIO].} = var buffer = readline.readLine(prompt) if isNil(buffer): quit(0) line = TaintedString($buffer) diff --git a/lib/impure/web.nim b/lib/impure/web.nim index a0aea8421..417fe9746 100755 --- a/lib/impure/web.nim +++ b/lib/impure/web.nim @@ -58,5 +58,5 @@ proc URLretrieveString*(url: string): TaintedString = result = stream.data.TaintedString when isMainModule: - echo URLretrieveString("http://nimrod.ethexor.com/") + echo URLretrieveString("http://nimrod-code.org/") |