mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-07 21:43:33 +00:00
SQLite wrapper
This commit is contained in:
@@ -16,7 +16,7 @@ cc = gcc
|
||||
|
||||
path="$lib/pure"
|
||||
path="$lib/impure"
|
||||
path="$lib/wrappers"
|
||||
path="$lib/newwrap"
|
||||
path="$lib/wrappers/cairo"
|
||||
path="$lib/wrappers/gtk"
|
||||
path="$lib/wrappers/lua"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
Mario Ray Mahardhika
|
||||
Philippe Lhoste
|
||||
Alexander R<>dseth
|
||||
Jonathan Plona
|
||||
Mario Ray Mahardhika
|
||||
Dominik Picheta
|
||||
Jonathan Plona
|
||||
Alexander R<>dseth
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Test the new CGI module
|
||||
# Test/show CGI module
|
||||
import strtabs, cgi
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import
|
||||
var hCurl = curl_easy_init()
|
||||
if hCurl != nil:
|
||||
discard curl_easy_setopt(hCurl, CURLOPT_VERBOSE, True)
|
||||
discard curl_easy_setopt(hCurl, CURLOPT_URL, "http://nimrod.ethexor.com")
|
||||
discard curl_easy_setopt(hCurl, CURLOPT_URL, "http://force7.de/nimrod")
|
||||
discard curl_easy_perform(hCurl)
|
||||
curl_easy_cleanup(hCurl)
|
||||
|
||||
@@ -60,12 +60,12 @@ proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string =
|
||||
else:
|
||||
add(result, c)
|
||||
|
||||
proc TryQuery*(db: TDbConn, query: TSqlQuery, args: openarray[string]): bool =
|
||||
proc TryExec*(db: TDbConn, query: TSqlQuery, args: openarray[string]): bool =
|
||||
## tries to execute the query and returns true if successful, false otherwise.
|
||||
var q = dbFormat(query, args)
|
||||
return mysqlRealQuery(db, q, q.len) == 0'i32
|
||||
|
||||
proc Query*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
|
||||
proc Exec*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
|
||||
## executes the query and raises EDB if not successful.
|
||||
var q = dbFormat(query, args)
|
||||
if mysqlRealQuery(db, q, q.len) != 0'i32: dbError(db)
|
||||
@@ -84,7 +84,7 @@ iterator FastRows*(db: TDbConn, query: TSqlQuery,
|
||||
## 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.
|
||||
Query(db, query, args)
|
||||
Exec(db, query, args)
|
||||
var sqlres = mysqlUseResult(db)
|
||||
if sqlres != nil:
|
||||
var L = int(mysql_num_fields(sqlres))
|
||||
@@ -103,7 +103,7 @@ proc GetAllRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): seq[TRow] =
|
||||
## executes the query and returns the whole result dataset.
|
||||
result = @[]
|
||||
Query(db, query, args)
|
||||
Exec(db, query, args)
|
||||
var sqlres = mysqlUseResult(db)
|
||||
if sqlres != nil:
|
||||
var L = int(mysql_num_fields(sqlres))
|
||||
@@ -149,11 +149,11 @@ proc InsertID*(db: TDbConn, query: TSqlQuery, args: openArray[string]): int64 =
|
||||
result = TryInsertID(db, query, args)
|
||||
if result < 0: dbError(db)
|
||||
|
||||
proc QueryAffectedRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openArray[string]): int64 =
|
||||
proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openArray[string]): int64 =
|
||||
## runs the query (typically "UPDATE") and returns the
|
||||
## number of affected rows
|
||||
Query(db, query, args)
|
||||
Exec(db, query, args)
|
||||
result = mysql_affected_rows(db)
|
||||
|
||||
proc Close*(db: TDbConn) =
|
||||
|
||||
@@ -59,15 +59,15 @@ proc dbFormat(formatstr: TSqlQuery, args: openarray[string]): string =
|
||||
else:
|
||||
add(result, c)
|
||||
|
||||
proc TryQuery*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): bool =
|
||||
proc TryExec*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): bool =
|
||||
## 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 Query*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
|
||||
proc Exec*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
|
||||
## executes the query and raises EDB if not successful.
|
||||
var q = dbFormat(query, args)
|
||||
var res = PQExec(db, q)
|
||||
@@ -143,8 +143,8 @@ proc InsertID*(db: TDbConn, query: TSqlQuery,
|
||||
result = TryInsertID(db, query, args)
|
||||
if result < 0: dbError(db)
|
||||
|
||||
proc QueryAffectedRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openArray[string]): int64 =
|
||||
proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openArray[string]): int64 =
|
||||
## executes the query (typically "UPDATE") and returns the
|
||||
## number of affected rows.
|
||||
var q = dbFormat(query, args)
|
||||
|
||||
178
lib/impure/db_sqlite.nim
Normal file
178
lib/impure/db_sqlite.nim
Normal file
@@ -0,0 +1,178 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## A higher level `PostgreSQL`:idx: database wrapper. This interface
|
||||
## is implemented for other databases too.
|
||||
|
||||
import strutils, sqlite3
|
||||
|
||||
type
|
||||
TDbConn* = PSqlite3 ## encapsulates a database connection
|
||||
TRow* = seq[string] ## a row of a dataset
|
||||
EDb* = object of EIO ## exception that is raised if a database error occurs
|
||||
|
||||
TSqlQuery* = distinct string ## an SQL query string
|
||||
|
||||
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:
|
||||
## ``sql"update user set counter = counter + 1"``
|
||||
##
|
||||
## If assertions are turned off, it does nothing. If assertions are turned
|
||||
## on, later versions will check the string for valid syntax.
|
||||
result = TSqlQuery(query)
|
||||
|
||||
proc dbError(db: TDbConn) {.noreturn.} =
|
||||
## raises an EDb exception.
|
||||
var e: ref EDb
|
||||
new(e)
|
||||
e.msg = $sqlite3.errmsg(db)
|
||||
raise e
|
||||
|
||||
proc dbError*(msg: string) {.noreturn.} =
|
||||
## raises an EDb exception with message `msg`.
|
||||
var e: ref EDb
|
||||
new(e)
|
||||
e.msg = msg
|
||||
raise e
|
||||
|
||||
proc dbQuote(s: string): string =
|
||||
result = "'"
|
||||
for c in items(s):
|
||||
if c == '\'': add(result, "''")
|
||||
else: add(result, c)
|
||||
add(result, '\'')
|
||||
|
||||
proc dbFormat(formatstr: TSqlQuery, args: openarray[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)
|
||||
|
||||
proc TryExec*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): bool =
|
||||
## tries to execute the query and returns true if successful, false otherwise.
|
||||
var q = dbFormat(query, args)
|
||||
var stmt: sqlite3.PStmt
|
||||
if prepare_v2(db, q, q.len, stmt, nil) == SQLITE_OK:
|
||||
if step(stmt) == SQLITE_DONE:
|
||||
result = finalize(stmt) == SQLITE_OK
|
||||
|
||||
proc Exec*(db: TDbConn, query: TSqlQuery, args: openarray[string]) =
|
||||
## executes the query and raises EDB if not successful.
|
||||
if not TryExec(db, query, args): dbError(db)
|
||||
|
||||
proc newRow(L: int): TRow =
|
||||
newSeq(result, L)
|
||||
for i in 0..L-1: result[i] = ""
|
||||
|
||||
proc setupQuery(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): PStmt =
|
||||
var q = dbFormat(query, args)
|
||||
if prepare_v2(db, q, q.len, result, nil) != SQLITE_OK: dbError(db)
|
||||
|
||||
proc setRow(stmt: PStmt, r: var TRow, cols: int) =
|
||||
for col in 0..cols-1:
|
||||
setLen(r[col], column_bytes(stmt, col)) # set capacity
|
||||
setLen(r[col], 0)
|
||||
add(r[col], column_text(stmt, col))
|
||||
|
||||
iterator FastRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): TRow =
|
||||
## 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.
|
||||
var stmt = setupQuery(db, query, args)
|
||||
var L = int(columnCount(stmt))
|
||||
var result = newRow(L)
|
||||
while step(stmt) == SQLITE_ROW:
|
||||
setRow(stmt, result, L)
|
||||
yield result
|
||||
if finalize(stmt) != SQLITE_OK: dbError(db)
|
||||
|
||||
proc GetAllRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): seq[TRow] =
|
||||
## 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: openarray[string]): TRow =
|
||||
## same as `FastRows`, but slower and safe.
|
||||
for r in FastRows(db, query, args): yield r
|
||||
|
||||
proc GetValue*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): string =
|
||||
## 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)
|
||||
if step(stmt) == SQLITE_ROW:
|
||||
result = newString(column_bytes(stmt, 0))
|
||||
setLen(result, 0)
|
||||
add(result, column_text(stmt, 0))
|
||||
if finalize(stmt) != SQLITE_OK: dbError(db)
|
||||
else:
|
||||
result = ""
|
||||
|
||||
proc TryInsertID*(db: TDbConn, query: TSqlQuery,
|
||||
args: openarray[string]): int64 =
|
||||
## 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
|
||||
|
||||
proc InsertID*(db: TDbConn, query: TSqlQuery,
|
||||
args: openArray[string]): int64 =
|
||||
## 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
|
||||
## named ``id``.
|
||||
result = TryInsertID(db, query, args)
|
||||
if result < 0: dbError(db)
|
||||
|
||||
proc ExecAffectedRows*(db: TDbConn, query: TSqlQuery,
|
||||
args: openArray[string]): int64 =
|
||||
## executes the query (typically "UPDATE") and returns the
|
||||
## number of affected rows.
|
||||
Exec(db, query, args)
|
||||
result = changes(db)
|
||||
|
||||
proc Close*(db: TDbConn) =
|
||||
## closes the database connection.
|
||||
if sqlite3.close(db) != SQLITE_OK:
|
||||
dbError(db)
|
||||
|
||||
proc Open*(connection, user, password, database: string): TDbConn =
|
||||
## opens a database connection. Raises `EDb` if the connection could not
|
||||
## be established. Only the ``connection`` parameter is used for ``sqlite``.
|
||||
var db: TDbConn
|
||||
if sqlite3.open(connection, db) == SQLITE_OK:
|
||||
return db
|
||||
else:
|
||||
dbError(db)
|
||||
|
||||
when isMainModule:
|
||||
var db = open("db.sql", "", "", "")
|
||||
Exec(db, sql"create table tbl1(one varchar(10), two smallint)", [])
|
||||
exec(db, sql"insert into tbl1 values('hello!',10)", [])
|
||||
exec(db, sql"insert into tbl1 values('goodbye', 20)", [])
|
||||
#db.query("create table tbl1(one varchar(10), two smallint)")
|
||||
#db.query("insert into tbl1 values('hello!',10)")
|
||||
#db.query("insert into tbl1 values('goodbye', 20)")
|
||||
for r in db.rows(sql"select * from tbl1", []):
|
||||
echo(r[0], r[1])
|
||||
|
||||
db_sqlite.close(db)
|
||||
@@ -17,7 +17,7 @@
|
||||
## Currently only requesting URLs is implemented. The implementation depends
|
||||
## on the libcurl library!
|
||||
##
|
||||
## **Deprecated since version 0.8.6:** Use the httpclient module instead.
|
||||
## **Deprecated since version 0.8.6:** Use the ``httpclient`` module instead.
|
||||
##
|
||||
|
||||
{.deprecated.}
|
||||
|
||||
@@ -96,30 +96,24 @@ const
|
||||
SQLITE_TRANSIENT* = cast[pointer](- 1)
|
||||
|
||||
type
|
||||
sqlite_int64* = int64
|
||||
PPPChar* = ptr ptr cstring
|
||||
TSqlite3 {.pure, final.} = object
|
||||
PSqlite3* = ptr TSqlite3
|
||||
PPSqlite3* = ptr PSqlite3
|
||||
TSqlLite3Context{.pure, final.} = object
|
||||
Pcontext* = ptr TSqlLite3Context
|
||||
TContext{.pure, final.} = object
|
||||
Pcontext* = ptr TContext
|
||||
Tstmt{.pure, final.} = object
|
||||
Pstmt* = ptr Tstmt
|
||||
PPsqlite3_stmt* = ptr Pstmt
|
||||
Tvalue{.pure, final.} = object
|
||||
Pvalue* = ptr Tvalue
|
||||
PPsqlite3_value* = ptr Pvalue #Callback function types
|
||||
#Notice that most functions
|
||||
#were named using as prefix the
|
||||
#function name that uses them,
|
||||
#rather than describing their functions
|
||||
Tcallback* = proc (para1: pointer, para2: int32, para3: var cstring,
|
||||
para4: var cstring): int32{.cdecl.}
|
||||
PPValue* = ptr Pvalue
|
||||
|
||||
Tcallback* = proc (para1: pointer, para2: int32, para3,
|
||||
para4: cstringArray): int32{.cdecl.}
|
||||
Tbind_destructor_func* = proc (para1: pointer){.cdecl.}
|
||||
Tcreate_function_step_func* = proc (para1: Pcontext, para2: int32,
|
||||
para3: PPsqlite3_value){.cdecl.}
|
||||
para3: PPValue){.cdecl.}
|
||||
Tcreate_function_func_func* = proc (para1: Pcontext, para2: int32,
|
||||
para3: PPsqlite3_value){.cdecl.}
|
||||
para3: PPValue){.cdecl.}
|
||||
Tcreate_function_final_func* = proc (para1: Pcontext){.cdecl.}
|
||||
Tresult_func* = proc (para1: pointer){.cdecl.}
|
||||
Tcreate_collation_func* = proc (para1: pointer, para2: int32, para3: pointer,
|
||||
@@ -131,7 +125,7 @@ proc close*(para1: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_close
|
||||
proc exec*(para1: PSqlite3, sql: cstring, para3: Tcallback, para4: pointer,
|
||||
errmsg: var cstring): int32{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_exec".}
|
||||
proc last_insert_rowid*(para1: PSqlite3): sqlite_int64{.cdecl, dynlib: Lib,
|
||||
proc last_insert_rowid*(para1: PSqlite3): int64{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_last_insert_rowid".}
|
||||
proc changes*(para1: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_changes".}
|
||||
proc total_changes*(para1: PSqlite3): int32{.cdecl, dynlib: Lib,
|
||||
@@ -183,10 +177,15 @@ proc errcode*(db: PSqlite3): int32{.cdecl, dynlib: Lib, importc: "sqlite3_errcod
|
||||
proc errmsg*(para1: PSqlite3): cstring{.cdecl, dynlib: Lib, importc: "sqlite3_errmsg".}
|
||||
proc errmsg16*(para1: PSqlite3): pointer{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_errmsg16".}
|
||||
proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: PPsqlite3_stmt,
|
||||
proc prepare*(db: PSqlite3, zSql: cstring, nBytes: int32, ppStmt: var PStmt,
|
||||
pzTail: ptr cstring): int32{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_prepare".}
|
||||
proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: PPsqlite3_stmt,
|
||||
|
||||
proc prepare_v2*(db: PSqlite3, zSql: cstring, nByte: cint, ppStmt: var PStmt,
|
||||
pzTail: ptr cstring): cint {.
|
||||
importc: "sqlite3_prepare_v2", cdecl, dynlib: Lib.}
|
||||
|
||||
proc prepare16*(db: PSqlite3, zSql: pointer, nBytes: int32, ppStmt: var PStmt,
|
||||
pzTail: var pointer): int32{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_prepare16".}
|
||||
proc bind_blob*(para1: Pstmt, para2: int32, para3: pointer, n: int32,
|
||||
@@ -196,7 +195,7 @@ proc bind_double*(para1: Pstmt, para2: int32, para3: float64): int32{.cdecl,
|
||||
dynlib: Lib, importc: "sqlite3_bind_double".}
|
||||
proc bind_int*(para1: Pstmt, para2: int32, para3: int32): int32{.cdecl,
|
||||
dynlib: Lib, importc: "sqlite3_bind_int".}
|
||||
proc bind_int64*(para1: Pstmt, para2: int32, para3: sqlite_int64): int32{.cdecl,
|
||||
proc bind_int64*(para1: Pstmt, para2: int32, para3: int64): int32{.cdecl,
|
||||
dynlib: Lib, importc: "sqlite3_bind_int64".}
|
||||
proc bind_null*(para1: Pstmt, para2: int32): int32{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_bind_null".}
|
||||
@@ -248,7 +247,7 @@ proc column_double*(para1: Pstmt, iCol: int32): float64{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_column_double".}
|
||||
proc column_int*(para1: Pstmt, iCol: int32): int32{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_column_int".}
|
||||
proc column_int64*(para1: Pstmt, iCol: int32): sqlite_int64{.cdecl, dynlib: Lib,
|
||||
proc column_int64*(para1: Pstmt, iCol: int32): int64{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_column_int64".}
|
||||
proc column_text*(para1: Pstmt, iCol: int32): cstring{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_column_text".}
|
||||
@@ -283,7 +282,7 @@ proc value_double*(para1: Pvalue): float64{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_value_double".}
|
||||
proc value_int*(para1: Pvalue): int32{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_value_int".}
|
||||
proc value_int64*(para1: Pvalue): sqlite_int64{.cdecl, dynlib: Lib,
|
||||
proc value_int64*(para1: Pvalue): int64{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_value_int64".}
|
||||
proc value_text*(para1: Pvalue): cstring{.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_value_text".}
|
||||
@@ -315,7 +314,7 @@ proc result_error16*(para1: Pcontext, para2: pointer, para3: int32){.cdecl,
|
||||
dynlib: Lib, importc: "sqlite3_result_error16".}
|
||||
proc result_int*(para1: Pcontext, para2: int32){.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_result_int".}
|
||||
proc result_int64*(para1: Pcontext, para2: sqlite_int64){.cdecl, dynlib: Lib,
|
||||
proc result_int64*(para1: Pcontext, para2: int64){.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_result_int64".}
|
||||
proc result_null*(para1: Pcontext){.cdecl, dynlib: Lib,
|
||||
importc: "sqlite3_result_null".}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2009 Andreas Rumpf
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -35,41 +35,41 @@ type
|
||||
iterator objectFields*[T](x: T, skipInherited: bool): tuple[
|
||||
key: string, val: TVariant] {.magic: "ObjectFields"}
|
||||
|
||||
proc `<>`*(x: ordinal): TVariant =
|
||||
proc `?`*(x: ordinal): TVariant =
|
||||
result.kind = vtEnum
|
||||
result.vint = x
|
||||
|
||||
proc `<>`*(x: biggestInt): TVariant =
|
||||
proc `?`*(x: biggestInt): TVariant =
|
||||
result.kind = vtInt
|
||||
result.vint = x
|
||||
|
||||
proc `<>`*(x: char): TVariant =
|
||||
proc `?`*(x: char): TVariant =
|
||||
result.kind = vtChar
|
||||
result.vint = ord(x)
|
||||
|
||||
proc `<>`*(x: bool): TVariant =
|
||||
proc `?`*(x: bool): TVariant =
|
||||
result.kind = vtBool
|
||||
result.vint = ord(x)
|
||||
|
||||
proc `<>`*(x: biggestFloat): TVariant =
|
||||
proc `?`*(x: biggestFloat): TVariant =
|
||||
result.kind = vtFloat
|
||||
result.vfloat = x
|
||||
|
||||
proc `<>`*(x: string): TVariant =
|
||||
proc `?`*(x: string): TVariant =
|
||||
result.kind = vtString
|
||||
result.vstring = x
|
||||
|
||||
proc `<>`*[T](x: openArray[T]): TVariant =
|
||||
proc `?`*[T](x: openArray[T]): TVariant =
|
||||
result.kind = vtSeq
|
||||
newSeq(result.q, x.len)
|
||||
for i in 0..x.len-1: result.q[i] = <>x[i]
|
||||
|
||||
proc `<>`*[T](x: set[T]): TVariant =
|
||||
proc `?`*[T](x: set[T]): TVariant =
|
||||
result.kind = vtSet
|
||||
result.q = @[]
|
||||
for a in items(x): result.q.add(<>a)
|
||||
|
||||
proc `<>`* [T: object](x: T): TVariant {.magic: "ToVariant".}
|
||||
proc `?`* [T: object](x: T): TVariant {.magic: "ToVariant".}
|
||||
## this converts a value to a variant ("boxing")
|
||||
|
||||
proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".}
|
||||
@@ -140,10 +140,10 @@ proc `[]=`* (a, b, c: TVariant) =
|
||||
variantError()
|
||||
else: variantError()
|
||||
|
||||
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[<>b]
|
||||
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[<>b]
|
||||
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[<>b] = c
|
||||
proc `[]=`* (a: TVariant, b: string, c: TVariant) {.inline} = a[<>b] = c
|
||||
proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[?b]
|
||||
proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[?b]
|
||||
proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[?b] = c
|
||||
proc `[]=`* (a: TVariant, b: string, c: TVariant) {.inline} = a[?b] = c
|
||||
|
||||
proc `+`* (x, y: TVariant): TVariant =
|
||||
case x.vtype
|
||||
|
||||
@@ -133,6 +133,22 @@ proc skip(my: var TYamlLexer) =
|
||||
var buf = my.buf
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '#':
|
||||
# skip line comment:
|
||||
inc(pos)
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '\0': break
|
||||
of '\c':
|
||||
pos = lexbase.HandleCR(my, pos)
|
||||
buf = my.buf
|
||||
break
|
||||
of '\L':
|
||||
pos = lexbase.HandleLF(my, pos)
|
||||
buf = my.buf
|
||||
break
|
||||
else:
|
||||
inc(pos)
|
||||
of '/':
|
||||
if buf[pos+1] == '/':
|
||||
# skip line comment:
|
||||
@@ -186,6 +202,26 @@ proc skip(my: var TYamlLexer) =
|
||||
break
|
||||
my.bufpos = pos
|
||||
|
||||
proc parseDirective(my: var TYamlLexer) =
|
||||
var pos = my.bufpos
|
||||
var buf = my.buf
|
||||
inc(pos)
|
||||
while buf[pos] in {'\t', ' '}: inc(pos)
|
||||
while true:
|
||||
case buf[pos]
|
||||
of '\0': break
|
||||
of '\c':
|
||||
pos = lexbase.HandleCR(my, pos)
|
||||
buf = my.buf
|
||||
break
|
||||
of '\L':
|
||||
pos = lexbase.HandleLF(my, pos)
|
||||
buf = my.buf
|
||||
break
|
||||
else:
|
||||
add(my.a, buf[pos])
|
||||
inc(pos)
|
||||
|
||||
proc parseNumber(my: var TYamlLexer) =
|
||||
var pos = my.bufpos
|
||||
var buf = my.buf
|
||||
@@ -230,11 +266,16 @@ proc getTok(my: var TYamlLexer): TTokKind =
|
||||
setLen(my.a, 0)
|
||||
skip(my) # skip whitespace, comments
|
||||
case my.buf[my.bufpos]
|
||||
of '-':
|
||||
inc(my.bufpos)
|
||||
result = tkHyphen
|
||||
of '-', '.', '0'..'9':
|
||||
parseNumber(my)
|
||||
result = tkNumber
|
||||
of '"':
|
||||
result = parseString(my)
|
||||
of '\'':
|
||||
result = parseSingleQuote(my)
|
||||
of '[':
|
||||
inc(my.bufpos)
|
||||
result = tkBracketLe
|
||||
@@ -253,8 +294,30 @@ proc getTok(my: var TYamlLexer): TTokKind =
|
||||
of ':':
|
||||
inc(my.bufpos)
|
||||
result = tkColon
|
||||
of '\0':
|
||||
result = tkEof
|
||||
of '?':
|
||||
inc(my.bufpos)
|
||||
result = tkQust
|
||||
of '!':
|
||||
inc(my.bufpos)
|
||||
result = tkExcl
|
||||
of '&':
|
||||
inc(my.bufpos)
|
||||
result = tkAmp
|
||||
of '*':
|
||||
inc(my.bufpos)
|
||||
result = tkStar
|
||||
of '|':
|
||||
parseLiteralBlockScalar(my)
|
||||
result = tkLiteralBlockScalar
|
||||
of '>':
|
||||
parseFoldedBlockScalar(my)
|
||||
result = tkFoldedBlockScalar
|
||||
of '%':
|
||||
parseDirective(my)
|
||||
result = tkDirective
|
||||
of '@', '`':
|
||||
inc(my.bufpos)
|
||||
result = tkReserved
|
||||
of 'a'..'z', 'A'..'Z', '_':
|
||||
parseName(my)
|
||||
case my.a
|
||||
@@ -262,6 +325,8 @@ proc getTok(my: var TYamlLexer): TTokKind =
|
||||
of "true": result = tkTrue
|
||||
of "false": result = tkFalse
|
||||
else: result = tkError
|
||||
of '\0':
|
||||
result = tkEof
|
||||
else:
|
||||
inc(my.bufpos)
|
||||
result = tkError
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2009 Andreas Rumpf
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -112,8 +112,8 @@ type
|
||||
#were named using as prefix the
|
||||
#function name that uses them,
|
||||
#rather than describing their functions
|
||||
Tsqlite3_callback* = proc (para1: pointer, para2: int32, para3: var cstring,
|
||||
para4: var cstring): int32{.cdecl.}
|
||||
Tsqlite3_callback* = proc (para1: pointer, para2: int32, para3,
|
||||
para4: cstringArray): int32{.cdecl.}
|
||||
Tbind_destructor_func* = proc (para1: pointer){.cdecl.}
|
||||
Tcreate_function_step_func* = proc (para1: Psqlite3_context, para2: int32,
|
||||
para3: PPsqlite3_value){.cdecl.}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
# Hallo world program
|
||||
|
||||
echo("Hi! What's your name?")
|
||||
var name = readLine(stdin)
|
||||
|
||||
if name == "Andreas":
|
||||
echo("What a nice name!")
|
||||
elif name == "":
|
||||
echo("Don't you have a name?")
|
||||
else:
|
||||
echo("Your name is not Andreas...")
|
||||
|
||||
for i in 0..name.len-1:
|
||||
if name[i] == 'm':
|
||||
echo("hey, there is an *m* in your name!")
|
||||
|
||||
echo("Please give your password: (12345)")
|
||||
var pw = readLine(stdin)
|
||||
|
||||
while pw != "12345":
|
||||
echo("Wrong password! Next try: ")
|
||||
pw = readLine(stdin)
|
||||
|
||||
echo("""Login complete!
|
||||
What do you want to do?
|
||||
delete-everything
|
||||
restart-computer
|
||||
go-for-a-walk""")
|
||||
|
||||
case readline(stdin)
|
||||
of "delete-everything", "restart-computer":
|
||||
echo("permission denied")
|
||||
of "go-for-a-walk": echo("please yourself")
|
||||
else: echo("unknown command")
|
||||
5
tests/reject/tatomic.nim
Normal file
5
tests/reject/tatomic.nim
Normal file
@@ -0,0 +1,5 @@
|
||||
var
|
||||
atomic: int
|
||||
|
||||
echo atomic
|
||||
|
||||
14
tests/testdata/doc1.xml
vendored
Normal file
14
tests/testdata/doc1.xml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<root>
|
||||
<tag>
|
||||
<test arg="blah" arg2="test"/>
|
||||
<test2>
|
||||
bla ah absy hsh
|
||||
hsh
|
||||
sjj
|
||||
</test2>
|
||||
<test><teh>bla</teh></test>
|
||||
</tag>
|
||||
</root>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user