mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-04 04:02:41 +00:00
mongodb wrapper properly removed from core
This commit is contained in:
@@ -1,227 +0,0 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## This module implements a higher level wrapper for `mongodb`:idx:. Example:
|
||||
##
|
||||
## .. code-block:: nimrod
|
||||
##
|
||||
## import mongo, db_mongo, oids, json
|
||||
##
|
||||
## var conn = db_mongo.open()
|
||||
##
|
||||
## # construct JSON data:
|
||||
## var data = %{"a": %13, "b": %"my string value",
|
||||
## "inner": %{"i": %71} }
|
||||
##
|
||||
## var id = insertID(conn, "test.test", data)
|
||||
##
|
||||
## for v in find(conn, "test.test", "this.a == 13"):
|
||||
## print v
|
||||
##
|
||||
## delete(conn, "test.test", id)
|
||||
## close(conn)
|
||||
|
||||
import mongo, oids, json
|
||||
|
||||
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 FDB ## effect that denotes a read operation
|
||||
FWriteDb* = object of FDB ## effect that denotes a write operation
|
||||
|
||||
proc dbError*(db: TDbConn, msg: string) {.noreturn.} =
|
||||
## raises an EDb exception with message `msg`.
|
||||
var e: ref EDb
|
||||
new(e)
|
||||
if db.errstr[0] != '\0':
|
||||
e.msg = $db.errstr
|
||||
else:
|
||||
e.msg = $db.err & " " & msg
|
||||
raise e
|
||||
|
||||
proc close*(db: var TDbConn) {.tags: [FDB].} =
|
||||
## closes the database connection.
|
||||
disconnect(db)
|
||||
destroy(db)
|
||||
|
||||
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)
|
||||
|
||||
let x = client(result, host, port.cint)
|
||||
if x != 0'i32:
|
||||
dbError(result, "cannot open: " & host)
|
||||
|
||||
proc jsonToBSon(b: var TBSon, key: string, j: PJsonNode) =
|
||||
case j.kind
|
||||
of JString:
|
||||
add(b, key, j.str)
|
||||
of JInt:
|
||||
add(b, key, j.num)
|
||||
of JFloat:
|
||||
add(b, key, j.fnum)
|
||||
of JBool:
|
||||
addBool(b, key, ord(j.bval))
|
||||
of JNull:
|
||||
addNull(b, key)
|
||||
of JObject:
|
||||
addStartObject(b, key)
|
||||
for k, v in items(j.fields):
|
||||
jsonToBSon(b, k, v)
|
||||
addFinishObject(b)
|
||||
of JArray:
|
||||
addStartArray(b, key)
|
||||
for i, e in pairs(j.elems):
|
||||
jsonToBSon(b, $i, e)
|
||||
addFinishArray(b)
|
||||
|
||||
proc jsonToBSon*(j: PJsonNode, oid: TOid): TBSon =
|
||||
## converts a JSON value into the BSON format. The result must be
|
||||
## ``destroyed`` explicitely!
|
||||
init(result)
|
||||
assert j.kind == JObject
|
||||
add(result, "_id", oid)
|
||||
for key, val in items(j.fields):
|
||||
jsonToBSon(result, key, val)
|
||||
finish(result)
|
||||
|
||||
proc `[]`*(obj: var TBSon, fieldname: cstring): TBSon =
|
||||
## retrieves the value belonging to `fieldname`. Raises `EInvalidKey` if
|
||||
## the attribute does not exist.
|
||||
var it = initIter(obj)
|
||||
let res = find(it, result, fieldname)
|
||||
if res == bkEOO:
|
||||
raise newException(EInvalidIndex, "key not in object")
|
||||
|
||||
proc getId*(obj: var TBSon): TOid =
|
||||
## retrieves the ``_id`` attribute of `obj`.
|
||||
var it = initIter(obj)
|
||||
var b: TBSon
|
||||
let res = find(it, b, "_id")
|
||||
if res == bkOID:
|
||||
result = oidVal(it)[]
|
||||
else:
|
||||
raise newException(EInvalidIndex, "_id not in object")
|
||||
|
||||
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()
|
||||
var x = jsonToBSon(data, result)
|
||||
insert(db, namespace, x, nil)
|
||||
destroy(x)
|
||||
|
||||
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) {.
|
||||
tags: [FReadDB, FWriteDb].} =
|
||||
## updates `obj` in `namespace`.
|
||||
var cond: TBson
|
||||
init(cond)
|
||||
cond.add("_id", getId(obj))
|
||||
finish(cond)
|
||||
update(db, namespace, cond, obj, ord(UPDATE_UPSERT))
|
||||
destroy(cond)
|
||||
|
||||
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) {.
|
||||
tags: [FWriteDb].} =
|
||||
## Deletes the object belonging to `oid`.
|
||||
var cond: TBson
|
||||
init(cond)
|
||||
cond.add("_id", oid)
|
||||
finish(cond)
|
||||
discard remove(db, namespace, cond)
|
||||
destroy(cond)
|
||||
|
||||
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 {.
|
||||
tags: [FReadDB].} =
|
||||
## iterates over any object in `namespace`.
|
||||
var cursor: TCursor
|
||||
init(cursor, db, namespace)
|
||||
while next(cursor) == mongo.OK:
|
||||
yield bson(cursor)[]
|
||||
destroy(cursor)
|
||||
|
||||
iterator find*(db: var TDbConn, namespace: string,
|
||||
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:
|
||||
while next(cursor[]) == mongo.OK:
|
||||
yield bson(cursor[])[]
|
||||
destroy(cursor[])
|
||||
|
||||
proc setupFieldnames(fields: varargs[string]): TBSon =
|
||||
init(result)
|
||||
for x in fields: add(result, x, 1'i32)
|
||||
finish(result)
|
||||
|
||||
iterator find*(db: var TDbConn, namespace: string,
|
||||
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)
|
||||
var cursor = find(db, namespace, query, f, 0'i32, 0'i32, 0'i32)
|
||||
if cursor != nil:
|
||||
while next(cursor[]) == mongo.OK:
|
||||
yield bson(cursor[])[]
|
||||
destroy(cursor[])
|
||||
destroy(f)
|
||||
|
||||
proc setupQuery(query: string): TBSon =
|
||||
init(result)
|
||||
add(result, "$where", query)
|
||||
finish(result)
|
||||
|
||||
iterator find*(db: var TDbConn, namespace: string,
|
||||
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)
|
||||
var q = setupQuery(query)
|
||||
var cursor = find(db, namespace, q, f, 0'i32, 0'i32, 0'i32)
|
||||
if cursor != nil:
|
||||
while next(cursor[]) == mongo.OK:
|
||||
yield bson(cursor[])[]
|
||||
destroy(cursor[])
|
||||
destroy(q)
|
||||
destroy(f)
|
||||
|
||||
when false:
|
||||
# this doesn't work this way; would require low level hacking
|
||||
iterator fieldPairs*(obj: var TBSon): tuple[key: cstring, value: TBSon] =
|
||||
## iterates over `obj` and yields all (key, value)-Pairs.
|
||||
var it = initIter(obj)
|
||||
var v: TBSon
|
||||
while next(it) != bkEOO:
|
||||
let key = key(it)
|
||||
discard init(v, value(it))
|
||||
yield (key, v)
|
||||
@@ -49,7 +49,7 @@ srcdoc2: "pure/parseopt;pure/parseopt2;pure/hashes;pure/strtabs;pure/lexbase"
|
||||
srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
|
||||
srcdoc2: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode"
|
||||
srcdoc2: "impure/zipfiles;pure/htmlgen;pure/parseutils;pure/browsers"
|
||||
srcdoc2: "impure/db_postgres;impure/db_mysql;impure/db_sqlite;impure/db_mongo"
|
||||
srcdoc2: "impure/db_postgres;impure/db_mysql;impure/db_sqlite"
|
||||
srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor"
|
||||
srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
||||
srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes"
|
||||
@@ -72,7 +72,7 @@ webdoc: "wrappers/libuv;wrappers/joyent_http_parser"
|
||||
|
||||
webdoc: "posix/posix;wrappers/odbcsql;impure/dialogs"
|
||||
webdoc: "wrappers/zip/zlib;wrappers/zip/libzip"
|
||||
webdoc: "wrappers/libsvm.nim;wrappers/mongo.nim"
|
||||
webdoc: "wrappers/libsvm.nim"
|
||||
webdoc: "windows"
|
||||
webdoc: "wrappers/readline/readline;wrappers/readline/history"
|
||||
webdoc: "wrappers/readline/rltypedefs"
|
||||
|
||||
Reference in New Issue
Block a user