#
#
# 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 is a wrapper for the `mongodb`:idx: client C library.
## It allows you to connect to a mongo-server instance, send commands and
## receive replies.
#
# Copyright 2009-2011 10gen Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import oids, times
{.deadCodeElim: on.}
when defined(windows):
const
mongodll* = "mongoc.dll"
bsondll* = "bson.dll"
elif defined(macosx):
const
mongodll* = "libmongoc.dylib"
bsondll* = "libbson.dylib"
else:
const
mongodll* = "libmongoc.so"
bsondll* = "libbson.so"
#
# This package supports both compile-time and run-time determination of CPU
# byte order. If ARCH_IS_BIG_ENDIAN is defined as 0, the code will be
# compiled to run only on little-endian CPUs; if ARCH_IS_BIG_ENDIAN is
# defined as non-zero, the code will be compiled to run only on big-endian
# CPUs; if ARCH_IS_BIG_ENDIAN is not defined, the code will be compiled to
# run on either big- or little-endian CPUs, but will run slightly less
# efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
#
type
Tmd5_state*{.pure, final.} = object
count*: array[0..2 - 1, int32] # message length in bits, lsw first
abcd*: array[0..4 - 1, int32] # digest buffer
buf*: array[0..64 - 1, byte] # accumulate block
proc sock_init*(): cint{.stdcall, importc: "mongo_sock_init", dynlib: mongodll.}
const
OK* = 0
ERROR* = - 1
SIZE_OVERFLOW* = 1
defaultHost* = "127.0.0.1"
defaultPort* = 27017
type
TValidity* = enum ## validity
VALID = 0, ## BSON is valid and UTF-8 compliant.
NOT_UTF8 = (1 shl 1), ## A key or a string is not valid UTF-8.
FIELD_HAS_DOT = (1 shl 2), ## Warning: key contains '.' character.
FIELD_INIT_DOLLAR = (1 shl 3), ## Warning: key starts with '$' character.
ALREADY_FINISHED = (1 shl 4) ## Trying to modify a finished BSON object.
TBinarySubtype* = enum
BIN_BINARY = 0, BIN_FUNC = 1, BIN_BINARY_OLD = 2, BIN_UUID = 3, BIN_MD5 = 5,
BIN_USER = 128
TBsonKind* {.size: sizeof(cint).} = enum
bkEOO = 0,
bkDOUBLE = 1,
bkSTRING = 2,
bkOBJECT = 3,
bkARRAY = 4,
bkBINDATA = 5,
bkUNDEFINED = 6,
bkOID = 7,
bkBOOL = 8,
bkDATE = 9,
bkNULL = 10,
bkREGEX = 11,
bkDBREF = 12, #*< Deprecated.
bkCODE = 13,
bkSYMBOL = 14,
bkCODEWSCOPE = 15,
bkINT = 16,
bkTIMESTAMP = 17,
bkLONG = 18
TBsonBool* = cint
TIter* {.pure, final.} = object
cur*: cstring
first*: TBsonBool
TBson* {.pure, final.} = object
data*: cstring
cur*: cstring
dataSize*: cint
finished*: TBsonBool
stack*: array[0..32 - 1, cint]
stackPos*: cint
err*: cint ## Bitfield representing errors or warnings on this buffer
errstr*: cstring ## A string representation of the most recent error
## or warning.
TDate* = int64
# milliseconds since epoch UTC
type
TTimestamp*{.pure, final.} = object ## a timestamp
i*: cint # increment
t*: cint # time in seconds
proc create*(): ptr TBson{.stdcall, importc: "bson_create", dynlib: bsondll.}
proc dispose*(b: ptr TBson){.stdcall, importc: "bson_dispose", dynlib: bsondll.}
proc size*(b: var TBson): cint {.stdcall, importc: "bson_size", dynlib: bsondll.}
## Size of a BSON object.
proc bufferSize*(b: var TBson): cint{.stdcall, importc: "bson_buffer_size",
dynlib: bsondll.}
## Buffer size of a BSON object.
proc print*(b: var TBson){.stdcall, importc: "bson_print", dynlib: bsondll.}
## Print a string representation of a BSON object.
proc print*(TBson: cstring, depth: cint) {.stdcall,
importc: "bson_print_raw", dynlib: bsondll.}
## Print a string representation of a BSON object up to `depth`.
proc data*(b: var TBson): cstring{.stdcall, importc: "bson_data",
dynlib: bsondll.}
## Return a pointer to the raw buffer stored by this bson object.
proc find*(it: var TIter, obj: var TBson, name: cstring): TBsonKind {.stdcall,
importc: "bson_find", dynlib: bsondll.}
## Advance `it` to the named field. `obj` is the BSON object to use.
## `name` is the name of the field to find. Returns the type of the found
## object or ``bkEOO`` if it is not found.
proc createIter*(): ptr TIter{.stdcall, importc: "bson_iterator_create",
dynlib: bsondll.}
proc dispose*(a2: ptr TIter){.stdcall, importc: "bson_iterator_dispose",
dynlib: bsondll.}
proc initIter*(b: var TBson): TIter =
## Initialize a bson iterator from the value `b`.
proc iterator_init(i: var TIter, b: var TBson){.stdcall,
importc: "bson_iterator_init", dynlib: bsondll.}
iterator_init(result, b)
proc fromBuffer*(i: var TIter, buffer: cstring) {.stdcall,
importc: "bson_iterator_from_buffer", dynlib: bsondll.}
## Initialize a bson iterator from a cstring buffer. Note
## that this is mostly used internally.
proc more*(i: var TIter): bool =
## Check to see if the bson_iterator has more data.
proc iterator_more(i: var TIter): TBsonBool{.stdcall,
importc: "bson_iterator_more", dynlib: bsondll.}
result = iterator_more(i) != 0'i32
proc next*(i: var TIter): TBsonKind {.stdcall,
importc: "bson_iterator_next", dynlib: bsondll.}
## Point the iterator at the next BSON object.
proc kind*(i: var TIter): TBsonKind{.stdcall,
importc: "bson_iterator_type", dynlib: bsondll.}
## Get the type of the BSON object currently pointed to by the iterator.
proc key*(i: var TIter): cstring{.stdcall,
importc: "bson_iterator_key", dynlib: bsondll.}
## Get the key of the BSON object currently pointed to by the iterator.
proc value*(i: var TIter): cstring{.stdcall,
importc: "bson_iterator_value", dynlib: bsondll.}
## Get the value of the BSON object currently pointed to by the iterator.
proc floatVal*(i: var TIter): float {.stdcall,
importc: "bson_iterator_double", dynlib: bsondll.}
## Get the double value of the BSON object currently pointed to by the
## iterator.
proc intVal*(i: var TIter): cint{.stdcall, importc: "bson_iterator_int",
dynlib: bsondll.}
## Get the int value of the BSON object currently pointed to by the iterator.
proc int64Val*(i: var TIter): int64{.stdcall,
importc: "bson_iterator_long", dynlib: bsondll.}
## Get the long value of the BSON object currently pointed to by the iterator.
proc timestamp*(i: var TIter): Ttimestamp {.stdcall,
importc: "bson_iterator_timestamp", dynlib: bsondll.}
# return the bson timestamp as a whole or in parts
proc timestampTime*(i: var TIter): cint {.stdcall,
importc: "bson_iterator_timestamp_time", dynlib: bsondll.}
# return the bson timestamp as a whole or in parts
proc timestampIncrement*(i: var TIter): cint{.stdcall,
importc: "bson_iterator_timestamp_increment", dynlib: bsondll.}
# return the bson timestamp as a whole or in parts
proc boolVal*(i: var TIter): TBsonBool{.stdcall,
importc: "bson_iterator_bool", dynlib: bsondll.}
## Get the boolean value of the BSON object currently pointed to by
## the iterator.
##
## | false: boolean false, 0 in any type, or null
## | true: anything else (even empty strings and objects)
proc floatRaw*(i: var TIter): cdouble{.stdcall,
importc: "bson_iterator_double_raw", dynlib: bsondll.}
## Get the double value of the BSON object currently pointed to by the
## iterator. Assumes the correct type is used.
proc intRaw*(i: var TIter): cint{.stdcall,
importc: "bson_iterator_int_raw", dynlib: bsondll.}
## Get the int value of the BSON object currently pointed to by the
## iterator. Assumes the correct type is used.
proc int64Raw*(i: var TIter): int64{.stdcall,
importc: "bson_iterator_long_raw", dynlib: bsondll.}
## Get the long value of the BSON object currently pointed to by the
## iterator. Assumes the correct type is used.
proc boolRaw*(i: var TIter): TBsonBool{.stdcall,
importc: "bson_iterator_bool_raw", dynlib: bsondll.}
## Get the bson_bool_t value of the BSON object currently pointed to by the
## iterator. Assumes the correct type is used.
proc oidVal*(i: var TIter): ptr TOid {.stdcall,
importc: "bson_iterator_oid", dynlib: bsondll.}
## Get the bson_oid_t value of the BSON object currently pointed to by the
## iterator.
proc strVal*(i: var TIter): cstring {.stdcall,
importc: "bson_iterator_string", dynlib: bsondll.}
## Get the string value of the BSON object currently pointed to by the
## iterator.
proc strLen*(i: var TIter): cint {.stdcall,
importc: "bson_iterator_string_len", dynlib: bsondll.}
## Get the string length of the BSON object currently pointed to by the
## iterator.
proc code*(i: var TIter): cstring {.stdcall,
importc: "bson_iterator_code", dynlib: bsondll.}
## Get the code value of the BSON object currently pointed to by the
## iterator. Works with bson_code, bson_codewscope, and BSON_STRING
## returns ``nil`` for everything else.
proc codeScope*(i: var TIter, scope: var TBson) {.stdcall,
importc: "bson_iterator_code_scope", dynlib: bsondll.}
## Calls bson_empty on scope if not a bson_codewscope
proc date*(i: var TIter): Tdate {.stdcall,
importc: "bson_iterator_date", dynlib: bsondll.}
## Get the date value of the BSON object currently pointed to by the
## iterator.
proc time*(i: var TIter): TTime {.stdcall,
importc: "bson_iterator_time_t", dynlib: bsondll.}
## Get the time value of the BSON object currently pointed to by the
## iterator.
proc binLen*(i: var TIter): cint {.stdcall,
importc: "bson_iterator_bin_len", dynlib: bsondll.}
## Get the length of the BSON binary object currently pointed to by the
## iterator.
proc binType*(i: var TIter): char {.stdcall,
importc: "bson_iterator_bin_type", dynlib: bsondll.}
## Get the type of the BSON binary object currently pointed to by the
## iterator.
proc binData*(i: var TIter): cstring {.stdcall,
importc: "bson_iterator_bin_data", dynlib: bsondll.}
## Get the value of the BSON binary object currently pointed to by the
## iterator.
proc regex*(i: var TIter): cstring {.stdcall,
importc: "bson_iterator_regex", dynlib: bsondll.}
## Get the value of the BSON regex object currently pointed to by the
## iterator.
proc regexOpts*(i: var TIter): cstring {.stdcall,
importc: "bson_iterator_regex_opts", dynlib: bsondll.}
## Get the options of the BSON regex object currently pointed to by the
## iterator.
proc subobject*(i: var TIter, sub: var TBson) {.stdcall,
importc: "bson_iterator_subobject", dynlib: bsondll.}
## Get the BSON subobject currently pointed to by the
## iterator.
proc subiterator*(i: var TIter, sub: var TIter) {.stdcall,
importc: "bson_iterator_subiterator", dynlib: bsondll.}
## Get a bson_iterator that on the BSON subobject.
# ----------------------------
# BUILDING
# ----------------------------
proc init*(b: var TBson) {.stdcall, importc: "bson_init", dynlib: bsondll.}
## Initialize a new bson object. If not created
## with bson_new, you must initialize each new bson
## object using this function.
##
## When finished, you must pass the bson object to bson_destroy().
proc init*(b: var TBson, data: cstring): cint {.stdcall,
importc: "bson_init_data", dynlib: bsondll.}
## Initialize a BSON object, and point its data
## pointer to the provided `data`.
## Returns OK or ERROR.
proc initFinished*(b: var TBson, data: cstring): cint {.stdcall,
importc: "bson_init_finished_data", dynlib: bsondll.}
proc initSize*(b: var TBson, size: cint) {.stdcall, importc: "bson_init_size",
dynlib: bsondll.}
## Initialize a BSON object, and set its buffer to the given size.
## Returns OK or ERROR.
proc ensureSpace*(b: var TBson, bytesNeeded: cint): cint {.stdcall,
importc: "bson_ensure_space", dynlib: bsondll.}
## Grow a bson object. `bytesNeeded` is the additional number of bytes needed.
proc finish*(b: var TBson): cint{.stdcall, importc: "bson_finish",
dynlib: bsondll, discardable.}
## Finalize a bson object. Returns the standard error code.
## To deallocate memory, call destroy on the bson object.
proc destroy*(b: var TBson){.stdcall, importc: "bson_destroy", dynlib: bsondll.}
## Destroy a bson object.
proc empty*(obj: var TBson) {.stdcall, importc: "bson_empty",
dynlib: bsondll.}
## Sets a pointer to a static empty BSON object.
## `obj` is the BSON object to initialize.
proc copy*(outp, inp: var TBson): cint{.stdcall, importc: "bson_copy",
dynlib: bsondll.}
## Make a complete copy of the a BSON object.
## The source bson object must be in a finished
## state; otherwise, the copy will fail.
proc add*(b: var TBson, name: cstring, oid: TOid) =
## adds an OID to `b`.
proc appendOid(b: var TBson, name: cstring, oid: ptr TOid): cint {.stdcall,
importc: "bson_append_oid", dynlib: bsondll.}
var oid = oid
discard appendOid(b, name, addr(oid))
proc add*(b: var TBson, name: cstring, i: cint): cint{.stdcall,
importc: "bson_append_int", dynlib: bsondll, discardable.}
## Append an int to a bson.
proc add*(b: var TBson, name: cstring, i: int64): cint{.stdcall,
importc: "bson_append_long", dynlib: bsondll, discardable.}
## Append an long to a bson.
proc add*(b: var TBson, name: cstring, d: float): cint{.stdcall,
importc: "bson_append_double", dynlib: bsondll, discardable.}
## Append an double to a bson.
proc add*(b: var TBson, name: cstring, str: cstring): cint {.stdcall,
importc: "bson_append_string", dynlib: bsondll, discardable.}
## Append a string to a bson.
proc add*(b: var TBson, name: cstring, str: cstring, len: cint): cint{.
stdcall, importc: "bson_append_string_n", dynlib: bsondll, discardable.}
## Append len bytes of a string to a bson.
proc add*(b: var TBson, name: cstring, str: string) =
## Append a Nimrod string `str` to a bson.
discard add(b, name, str, str.len.cint)
proc addSymbol*(b: var TBson, name: cstring, str: cstring): cint{.stdcall,
importc: "bson_append_symbol", dynlib: bsondll, discardable.}
## Append a symbol to a bson.
proc addSymbol*(b: var TBson, name: cstring, str: cstring, len: cint): cint{.
stdcall, importc: "bson_append_symbol_n", dynlib: bsondll, discardable.}
## Append len bytes of a symbol to a bson.
proc addCode*(b: var TBson, name: cstring, str: cstring): cint{.stdcall,
importc: "bson_append_code", dynlib: bsondll, discardable.}
## Append code to a bson.
proc addCode*(b: var TBson, name: cstring, str: cstring, len: cint): cint{.
stdcall, importc: "bson_append_code_n", dynlib: bsondll, discardable.}
## Append len bytes of code to a bson.
proc addCode*(b: var TBson, name: cstring, code: cstring,
scope: var TBson): cint{.stdcall,
importc: "bson_append_code_w_scope", dynlib: bsondll, discardable.}
## Append code to a bson with scope.
proc addCode*(b: var TBson, name: cstring, code: cstring,
size: cint, scope: var TBson): cint{.stdcall,
importc: "bson_append_code_w_scope_n", dynlib: bsondll, discardable.}
## Append len bytes of code to a bson with scope.
proc addBinary*(b: var TBson, name: cstring, typ: char, str: cstring,
len: cint): cint{.stdcall, importc: "bson_append_binary",
dynlib: bsondll, discardable.}
## Append binary data to a bson.
proc addBinary*(b: var TBson, name: cstring, data: string) =
## Append binary data to a bson.
addBinary(b, name, '\5', data, data.len.cint)
proc addBool*(b: var TBson, name: cstring, v: TBsonBool): cint{.stdcall,
importc: "bson_append_bool", dynlib: bsondll, discardable.}
## Append a bson_bool_t to a bson.
proc addNull*(b: var TBson, name: cstring): cint {.stdcall,
importc: "bson_append_null", dynlib: bsondll, discardable.}
## Append a null value to a bson.
proc addUndefined*(b: var TBson, name: cstring): cint{.stdcall,
importc: "bson_append_undefined", dynlib: bsondll, discardable.}
## Append an undefined value to a bson.
proc addRegex*(b: var TBson, name: cstring, pattern: cstring, opts: cstring): cint{.
stdcall, importc: "bson_append_regex", dynlib: bsondll, discardable.}
## Append a regex value to a bson.
proc add*(b: var TBson, name: cstring, TBson: var TBson): cint {.stdcall,
importc: "bson_append_bson", dynlib: bsondll, discardable.}
## Append bson data to a bson.
proc addElement*(b: var TBson, name_or_null: cstring, elem: var TIter): cint{.
stdcall, importc: "bson_append_element", dynlib: bsondll, discardable.}
## Append a BSON element to a bson from the current point of an iterator.
proc addTimestamp*(b: var TBson, name: cstring, ts: var TTimestamp): cint{.
stdcall, importc: "bson_append_timestamp", dynlib: bsondll, discardable.}
## Append a bson_timestamp_t value to a bson.
proc addTimestamp2*(b: var TBson, name: cstring, time: cint, increment: cint): cint{.
stdcall, importc: "bson_append_timestamp2", dynlib: bsondll, discardable.}
proc addDate*(b: var TBson, name: cstring, millis: TDate): cint{.stdcall,
importc: "bson_append_date", dynlib: bsondll, discardable.}
## Append a bson_date_t value to a bson.
proc addTime*(b: var TBson, name: cstring, secs: TTime): cint{.stdcall,
importc: "bson_append_time_t", dynlib: bsondll, discardable.}
## Append a time_t value to a bson.
proc addStartObject*(b: var TBson, name: cstring): cint {.stdcall,
importc: "bson_append_start_object", dynlib: bsondll, discardable.}
## Start appending a new object to a bson.
proc addStartArray*(b: var TBson, name: cstring): cint {.stdcall,
importc: "bson_append_start_array", dynlib: bsondll, discardable.}
## Start appending a new array to a bson.
proc addFinishObject*(b: var TBson): cint {.stdcall,
importc: "bson_append_finish_object", dynlib: bsondll, discardable.}
## Finish appending a new object or array to a bson.
proc addFinishArray*(b: var TBson): cint {.stdcall,
importc: "bson_append_finish_array", dynlib: bsondll, discardable.}
## Finish appending a new object or array to a bson. This
## is simply an alias for bson_append_finish_object.
proc numstr*(str: cstring, i: cint){.stdcall, importc: "bson_numstr",
dynlib: bsondll.}
proc incnumstr*(str: cstring){.stdcall, importc: "bson_incnumstr",
dynlib: bsondll.}
type
TErrHandler* = proc (errmsg: cstring){.
stdcall.} ## an error handler. Error handlers shouldn't return!
proc setBsonErrHandler*(func: TErrHandler): TErrHandler {.stdcall,
importc: "set_bson_err_handler", dynlib: bsondll.}
## Set a function for error handling.
## Returns the old error handling function, or nil.
proc fatal*(ok: cint){.stdcall, importc: "bson_fatal", dynlib: bsondll.}
## does nothing if ok != 0. Exit fatally.
proc fatal*(ok: cint, msg: cstring){.stdcall, importc: "bson_fatal_msg",
dynlib: bsondll.}
## Exit fatally with an error message.
proc builderError*(b: var TBson){.stdcall, importc: "bson_builder_error",
dynlib: bsondll.}
## Invoke the error handler, but do not exit.
proc int64ToDouble*(i64: int64): cdouble {.stdcall,
importc: "bson_int64_to_double", dynlib: bsondll.}
## Cast an int64_t to double. This is necessary for embedding in
## certain environments.
const
MAJOR* = 0
MINOR* = 4
PATCH* = 0
type
TError*{.size: sizeof(cint).} = enum ## connection errors
CONN_SUCCESS = 0, ## Connection success!
CONN_NO_SOCKET, ## Could not create a socket.
CONN_FAIL, ## An error occured while calling connect().
CONN_ADDR_FAIL, ## An error occured while calling getaddrinfo().
CONN_NOT_MASTER, ## Warning: connected to a non-master node (read-only).
CONN_BAD_SET_NAME, ## Given rs name doesn't match this replica set.
CONN_NO_PRIMARY, ## Can't find primary in replica set. Connection closed.
IO_ERROR, ## An error occurred while reading or writing on the socket.
READ_SIZE_ERROR, ## The response is not the expected length.
COMMAND_FAILED, ## The command returned with 'ok' value of 0.
BSON_INVALID, ## BSON not valid for the specified op.
BSON_NOT_FINISHED ## BSON object has not been finished.
TCursorError*{.size: sizeof(cint).} = enum ## cursor error
CURSOR_EXHAUSTED, ## The cursor has no more results.
CURSOR_INVALID, ## The cursor has timed out or is not recognized.
CURSOR_PENDING, ## Tailable cursor still alive but no data.
CURSOR_QUERY_FAIL, ## The server returned an '$err' object, indicating query failure.
## See conn.lasterrcode and conn.lasterrstr for details.
CURSOR_BSON_ERROR ## Something is wrong with the BSON provided. See conn.err
## for details.
TCursorFlags* = enum ## cursor flags
CURSOR_MUST_FREE = 1, ## mongo_cursor_destroy should free cursor.
CURSOR_QUERY_SENT = (1 shl 1) ## Initial query has been sent.
TindexOpts* = enum
INDEX_UNIQUE = (1 shl 0), INDEX_DROP_DUPS = (1 shl 2),
INDEX_BACKGROUND = (1 shl 3), INDEX_SPARSE = (1 shl 4)
TupdateOpts* = enum
UPDATE_UPSERT = 0x00000001,
UPDATE_MULTI = 0x00000002,
UPDATE_BASIC = 0x00000004
TCursorOpts* = enum
TAILABLE = (1 shl 1), ## Create a tailable cursor.
SLAVE_OK = (1 shl 2), ## Allow queries on a non-primary node.
NO_CURSOR_TIMEOUT = (1 shl 4), ## Disable cursor timeouts.
AWAIT_DATA = (1 shl 5), ## Momentarily block for more data.
EXHAUST = (1 shl 6), ## Stream in multiple 'more' packages.
PARTIAL = (1 shl 7) ## Allow reads even if a shard is down.
Toperations* = enum
OP_MSG = 1000, OP_UPDATE = 2001, OP_INSERT = 2002, OP_QUERY = 2004,
OP_GET_MORE = 2005, OP_DELETE = 2006, OP_KILL_CURSORS = 2007
THeader* {.pure, final.} = object
len*: cint
id*: cint
responseTo*: cint
op*: cint
TMessage* {.pure, final.} = object
head*: Theader
data*: char
TReplyFields*{.pure, final.} = object
flag*: cint # FIX THIS COMMENT non-zero on failure
cursorID*: int64
start*: cint
num*: cint
TReply*{.pure, final.} = object
head*: Theader
fields*: Treply_fields
objs*: char
THostPort*{.pure, final.} = object
host*: array[0..255 - 1, char]
port*: cint
next*: ptr THostPort
TReplset*{.pure, final.} = object ## replset
seeds*: ptr THostPort ## List of seeds provided by the user.
hosts*: ptr THostPort ## List of host/ports given by the replica set
name*: cstring ## Name of the replica set.
primary_connected*: TBsonBool ## Primary node connection status.
TMongo*{.pure, final.} = object ## mongo
primary*: ptr THostPort ## Primary connection info.
replset*: ptr TReplSet ## replset object if connected to a replica set.
sock*: cint ## Socket file descriptor.
flags*: cint ## Flags on this connection object.
conn_timeout_ms*: cint ## Connection timeout in milliseconds.
op_timeout_ms*: cint ## Read and write timeout in milliseconds.
connected*: TBsonBool ## Connection status.
err*: TError ## Most recent driver error code.
errstr*: array[0..128 - 1, char] ## String version of most recent driver error code.
lasterrcode*: cint ## getlasterror code given by the server on error.
lasterrstr*: cstring ## getlasterror string generated by server.
TCursor*{.pure, final.} = object ## cursor
reply*: ptr TReply ## reply is owned by cursor
conn*: ptr TMongo ## connection is *not* owned by cursor
ns*: cstring ## owned by cursor
flags*: cint ## Flags used internally by this drivers.
seen*: cint ## Number returned so far.
current*: TBson ## This cursor's current bson object.
err*: TCursorError ## Errors on this cursor.
query*: ptr TBson ## Bitfield containing cursor options.
fields*: ptr TBson ## Bitfield containing cursor options.
options*: cint ## Bitfield containing cursor options.
limit*: cint ## Bitfield containing cursor options.
skip*: cint ## Bitfield containing cursor options.
# Connection API
proc createMongo*(): ptr TMongo{.stdcall, importc: "mongo_create", dynlib: mongodll.}
proc dispose*(conn: ptr TMongo){.stdcall, importc: "mongo_dispose",
dynlib: mongodll.}
proc getErr*(conn: var TMongo): cint{.stdcall, importc: "mongo_get_err",
dynlib: mongodll.}
proc isConnected*(conn: var TMongo): cint{.stdcall,
importc: "mongo_is_connected", dynlib: mongodll.}
proc getOpTimeout*(conn: var TMongo): cint{.stdcall,
importc: "mongo_get_op_timeout", dynlib: mongodll.}
proc getPrimary*(conn: var TMongo): cstring{.stdcall,
importc: "mongo_get_primary", dynlib: mongodll.}
proc getSocket*(conn: var TMongo): cint {.stdcall, importc: "mongo_get_socket",
dynlib: mongodll.}
proc getHostCount*(conn: var TMongo): cint{.stdcall,
importc: "mongo_get_host_count", dynlib: mongodll.}
proc getHost*(conn: var TMongo, i: cint): cstring {.stdcall,
importc: "mongo_get_host", dynlib: mongodll.}
proc createCursor*(): ptr TCursor{.stdcall, importc: "mongo_cursor_create",
dynlib: mongodll.}
proc dispose*(cursor: ptr TCursor){.stdcall,
importc: "mongo_cursor_dispose", dynlib: mongodll.}
proc getServerErr*(conn: var TMongo): cint{.stdcall,
importc: "mongo_get_server_err", dynlib: mongodll.}
proc getServerErrString*(conn: var TMongo): cstring{.stdcall,
importc: "mongo_get_server_err_string", dynlib: mongodll.}
proc init*(conn: var TMongo){.stdcall, importc: "mongo_init", dynlib: mongodll.}
## Initialize a new mongo connection object. You must initialize each mongo
## object using this function.
## When finished, you must pass this object to ``destroy``.
proc connect*(conn: var TMongo, host: cstring = defaultHost,
port: cint = defaultPort): cint {.stdcall,
importc: "mongo_connect", dynlib: mongodll.}
## Connect to a single MongoDB server.
proc replsetInit*(conn: var TMongo, name: cstring){.stdcall,
importc: "mongo_replset_init", dynlib: mongodll.}
## Set up this connection object for connecting to a replica set.
## To connect, pass the object to replsetConnect.
## `name` is the name of the replica set to connect to.
proc replsetAddSeed*(conn: var TMongo, host: cstring = defaultHost,
port: cint = defaultPort){.stdcall,
importc: "mongo_replset_add_seed", dynlib: mongodll.}
## Add a seed node to the replica set connection object.
## You must specify at least one seed node before connecting
## to a replica set.
proc parseHost*(hostString: cstring, hostPort: var ThostPort){.stdcall,
importc: "mongo_parse_host", dynlib: mongodll.}
## Utility function for converting a host-port string to a mongo_host_port.
## `hostString` is a string containing either a host or a host and port
## separated by a colon.
## `hostPort` is the mongo_host_port object to write the result to.
proc replsetConnect*(conn: var TMongo): cint{.stdcall,
importc: "mongo_replset_connect", dynlib: mongodll.}
## Connect to a replica set.
## Before passing a connection object to this function, you must already
## have called setReplset and replsetAddSeed.
proc setOpTimeout*(conn: var TMongo, millis: cint): cint{.stdcall,
importc: "mongo_set_op_timeout", dynlib: mongodll.}
## Set a timeout for operations on this connection. This
## is a platform-specific feature, and only work on Unix-like
## systems. You must also compile for linux to support this.
proc checkConnection*(conn: var TMongo): cint {.stdcall,
importc: "mongo_check_connection", dynlib: mongodll.}
## Ensure that this connection is healthy by performing
## a round-trip to the server.
## Returns OK if connected; otherwise ERROR.
proc reconnect*(conn: var TMongo): cint {.stdcall, importc: "mongo_reconnect",
dynlib: mongodll.}
## Try reconnecting to the server using the existing connection settings.
## This function will disconnect the current socket. If you've authenticated,
## you'll need to re-authenticate after calling this function.
proc disconnect*(conn: var TMongo){.stdcall, importc: "mongo_disconnect",
dynlib: mongodll.}
## Close the current connection to the server. After calling
## this function, you may call reconnect with the same
## connection object.
proc destroy*(conn: var TMongo){.stdcall, importc: "mongo_destroy",
dynlib: mongodll.}
## Close any existing connection to the server and free all allocated
## memory associated with the conn object.
## You must always call this function when finished with the connection
## object.
proc insert*(conn: var TMongo, ns: cstring, data: var TBson): cint{.stdcall,
importc: "mongo_insert", dynlib: mongodll, discardable.}
## Insert a BSON document into a MongoDB server. This function
## will fail if the supplied BSON struct is not UTF-8 or if
## the keys are invalid for insert (contain '.' or start with '$').
proc insertBatch*(conn: var TMongo, ns: cstring,
data: ptr ptr TBson, num: cint): cint{.
stdcall, importc: "mongo_insert_batch", dynlib: mongodll, discardable.}
## Insert a batch of BSON documents into a MongoDB server. This function
## will fail if any of the documents to be inserted is invalid.
## `num` is the number of documents in data.
proc update*(conn: var TMongo, ns: cstring, cond, op: var TBson,
flags: cint): cint{.stdcall, importc: "mongo_update",
dynlib: mongodll, discardable.}
## Update a document in a MongoDB server.
##
## | conn a mongo object.
## | ns the namespace.
## | cond the bson update query.
## | op the bson update data.
## | flags flags for the update.
## | returns OK or ERROR with error stored in conn object.
proc remove*(conn: var TMongo, namespace: cstring, cond: var TBson): cint{.stdcall,
importc: "mongo_remove", dynlib: mongodll.}
## Remove a document from a MongoDB server.
##
## | conn a mongo object.
## | ns the namespace.
## | cond the bson query.
## | returns OK or ERROR with error stored in conn object.
proc find*(conn: var TMongo, namespace: cstring, query, fields: var TBson,
limit, skip: cint, options: cint): ptr TCursor{.stdcall,
importc: "mongo_find", dynlib: mongodll.}
## Find documents in a MongoDB server.
##
## | conn a mongo object.
## | ns the namespace.
## | query the bson query.
## | fields a bson document of fields to be returned.
## | limit the maximum number of documents to return.
## | skip the number of documents to skip.
## | options A bitfield containing cursor options.
## | returns A cursor object allocated on the heap or nil if
## an error has occurred. For finer-grained error checking,
## use the cursor builder API instead.
proc init*(cursor: var TCursor, conn: var TMongo, namespace: cstring){.stdcall,
importc: "mongo_cursor_init", dynlib: mongodll.}
## Initalize a new cursor object.
##
## The namespace is represented as the database
## name and collection name separated by a dot. e.g., "test.users".
proc setQuery*(cursor: var TCursor, query: var TBson) {.stdcall,
importc: "mongo_cursor_set_query", dynlib: mongodll.}
## Set the bson object specifying this cursor's query spec. If
## your query is the empty bson object "{}", then you need not
## set this value.
##
## `query` is a bson object representing the query spec. This may
## be either a simple query spec or a complex spec storing values for
## $query, $orderby, $hint, and/or $explain. See
## http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol for details.
proc setFields*(cursor: var TCursor, fields: var TBson){.stdcall,
importc: "mongo_cursor_set_fields", dynlib: mongodll.}
## Set the fields to return for this cursor. If you want to return
## all fields, you need not set this value.
## `fields` is a bson object representing the fields to return.
## See http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields.
proc setSkip*(cursor: var TCursor, skip: cint){.stdcall,
importc: "mongo_cursor_set_skip", dynlib: mongodll.}
## Set the number of documents to skip.
proc setLimit*(cursor: var TCursor, limit: cint){.stdcall,
importc: "mongo_cursor_set_limit", dynlib: mongodll.}
## Set the number of documents to return.
proc setOptions*(cursor: var TCursor, options: cint){.stdcall,
importc: "mongo_cursor_set_options", dynlib: mongodll.}
## Set any of the available query options (e.g., TAILABLE).
## See `TCursorOpts` for available constants.
proc data*(cursor: var TCursor): cstring {.stdcall,
importc: "mongo_cursor_data", dynlib: mongodll.}
## Return the current BSON object data as a ``cstring``. This is useful
## for creating bson iterators.
proc bson*(cursor: var TCursor): ptr TBson{.stdcall,
importc: "mongo_cursor_bson", dynlib: mongodll.}
## Return the current BSON object.
proc next*(cursor: var TCursor): cint {.stdcall,
importc: "mongo_cursor_next", dynlib: mongodll.}
## Iterate the cursor, returning the next item. When successful,
## the returned object will be stored in cursor.current;
proc destroy*(cursor: var TCursor): cint {.stdcall,
importc: "mongo_cursor_destroy", dynlib: mongodll, discardable.}
## Destroy a cursor object. When finished with a cursor, you
## must pass it to this function.
proc findOne*(conn: var TMongo, namespace: cstring, query: var TBson,
fields: var TBson, outp: var TBson): cint{.stdcall,
importc: "mongo_find_one", dynlib: mongodll.}
## Find a single document in a MongoDB server.
##
## | conn a mongo object.
## | ns the namespace.
## | query the bson query.
## | fields a bson document of the fields to be returned.
## | outp a bson document in which to put the query result.
## outp can be nil if you don't care about results. Useful for commands.
proc count*(conn: var TMongo, db: cstring, coll: cstring, query: var TBson): cdouble{.
stdcall, importc: "mongo_count", dynlib: mongodll.}
## Count the number of documents in a collection matching a query.
##
## | conn a mongo object.
## | db the db name.
## | coll the collection name.
## | query the BSON query.
## | returns the number of matching documents. If the command fails,
## ERROR is returned.
proc createIndex*(conn: var TMongo, namespace: cstring, key: var TBson,
options: cint, outp: var TBson): cint {.stdcall,
importc: "mongo_create_index", dynlib: mongodll.}
## Create a compouned index.
##
## | conn a mongo object.
## | ns the namespace.
## | data the bson index data.
## | options a bitfield for setting index options. Possibilities include
## INDEX_UNIQUE, INDEX_DROP_DUPS, INDEX_BACKGROUND,
## and INDEX_SPARSE.
## | out a bson document containing errors, if any.
## | returns MONGO_OK if index is created successfully; otherwise, MONGO_ERROR.
proc createSimpleIndex*(conn: var TMongo, namespace, field: cstring,
options: cint, outp: var TBson): TBsonBool {.stdcall,
importc: "mongo_create_simple_index", dynlib: mongodll.}
## Create an index with a single key.
##
## | conn a mongo object.
## | ns the namespace.
## | field the index key.
## | options index options.
## | out a BSON document containing errors, if any.
## | returns true if the index was created.
# ----------------------------
# COMMANDS
# ----------------------------
proc runCommand*(conn: var TMongo, db: cstring, command: var TBson,
outp: var TBson): cint{.stdcall, importc: "mongo_run_command",
dynlib: mongodll.}
## Run a command on a MongoDB server.
##
## | conn a mongo object.
## | db the name of the database.
## | command the BSON command to run.
## | out the BSON result of the command.
## | returns OK if the command ran without error.
proc simpleIntCommand*(conn: var TMongo, db: cstring, cmd: cstring, arg: cint,
outp: var TBson): cint{.stdcall,
importc: "mongo_simple_int_command", dynlib: mongodll.}
## Run a command that accepts a simple string key and integer value.
##
## | conn a mongo object.
## | db the name of the database.
## | cmd the command to run.
## | arg the integer argument to the command.
## | out the BSON result of the command.
## | returns OK or an error code.
proc simpleStrCommand*(conn: var TMongo, db: cstring, cmd: cstring,
arg: cstring, outp: var TBson): cint{.stdcall,
importc: "mongo_simple_str_command", dynlib: mongodll.}
## Run a command that accepts a simple string key and value.
##
## | conn a mongo object.
## | db the name of the database.
## | cmd the command to run.
## | arg the string argument to the command.
## | out the BSON result of the command.
## | returns true if the command ran without error.
proc cmdDropDb*(conn: var TMongo, db: cstring): cint{.stdcall,
importc: "mongo_cmd_drop_db", dynlib: mongodll.}
## Drop a database.
##
## | conn a mongo object.
## | db the name of the database to drop.
## | returns OK or an error code.
proc cmdDropCollection*(conn: var TMongo, db: cstring, collection: cstring,
outp: var TBson): cint{.stdcall,
importc: "mongo_cmd_drop_collection", dynlib: mongodll.}
## Drop a collection.
##
## | conn a mongo object.
## | db the name of the database.
## | collection the name of the collection to drop.
## | out a BSON document containing the result of the command.
## | returns true if the collection drop was successful.
proc cmdAddUser*(conn: var TMongo, db: cstring, user: cstring, pass: cstring): cint{.
stdcall, importc: "mongo_cmd_add_user", dynlib: mongodll.}
## Add a database user.
##
## | conn a mongo object.
## | db the database in which to add the user.
## | user the user name
## | pass the user password
## | returns OK or ERROR.
proc cmdAuthenticate*(conn: var TMongo, db: cstring, user: cstring,
pass: cstring): cint{.stdcall,
importc: "mongo_cmd_authenticate", dynlib: mongodll.}
## Authenticate a user.
##
## | conn a mongo object.
## | db the database to authenticate against.
## | user the user name to authenticate.
## | pass the user's password.
## | returns OK on sucess and ERROR on failure.
proc cmdIsMaster*(conn: var TMongo, outp: var TBson): TBsonBool {.stdcall,
importc: "mongo_cmd_ismaster", dynlib: mongodll.}
## Check if the current server is a master.
##
## | conn a mongo object.
## | outp a BSON result of the command.
## | returns true if the server is a master.
proc cmdGetLastError*(conn: var TMongo, db: cstring, outp: var TBson): cint{.
stdcall, importc: "mongo_cmd_get_last_error", dynlib: mongodll.}
## Get the error for the last command with the current connection.
##
## | conn a mongo object.
## | db the name of the database.
## | outp a BSON object containing the error details.
## | returns OK or ERROR
proc cmdGetPrevError*(conn: var TMongo, db: cstring, outp: var TBson): cint{.
stdcall, importc: "mongo_cmd_get_prev_error", dynlib: mongodll.}
## Get the most recent error with the current connection.
##
## | conn a mongo object.
## | db the name of the database.
## | outp a BSON object containing the error details.
## | returns OK or ERROR.
proc cmdResetError*(conn: var TMongo, db: cstring){.stdcall,
importc: "mongo_cmd_reset_error", dynlib: mongodll.}
## Reset the error state for the connection. `db` is the name of the database.
# gridfs.h
const
DEFAULT_CHUNK_SIZE* = 262144
type
TOffset* = int64
# A GridFS represents a single collection of GridFS files in the database.
type
TGridfs*{.pure, final.} = object
client*: ptr TMongo ## The client to db-connection.
dbname*: cstring ## The root database name
prefix*: cstring ## The prefix of the GridFS's collections,
## default is nil
files_ns*: cstring ## The namespace where the file's metadata
## is stored
chunks_ns*: cstring ## The namespace where the files's data is
## stored in chunks
# A GridFile is a single GridFS file.
type
TGridFile*{.pure, final.} = object
gfs*: ptr TGridfs ## GridFS where the GridFile is located
meta*: ptr TBson ## GridFile's bson object where all
## its metadata is located
pos*: TOffset ## position is the offset in the file
id*: TOid ## files_id of the gridfile
remote_name*: cstring ## name of the gridfile as a string
content_type*: cstring ## gridfile's content type
length*: TOffset ## length of this gridfile
chunk_num*: cint ## number of the current chunk being written to
pending_data*: cstring ## buffer storing data still to be
## written to chunks
pending_len*: cint ## length of pending_data buffer
proc createGridfs*(): ptr TGridfs{.stdcall, importc: "gridfs_create", dynlib: mongodll.}
proc dispose*(gfs: ptr TGridfs){.stdcall, importc: "gridfs_dispose",
dynlib: mongodll.}
proc createGridfile*(): ptr TGridFile{.stdcall, importc: "gridfile_create",
dynlib: mongodll.}
proc dispose*(gf: ptr TGridFile){.stdcall, importc: "gridfile_dispose",
dynlib: mongodll.}
proc getDescriptor*(gf: var TGridFile, outp: var TBson){.stdcall,
importc: "gridfile_get_descriptor", dynlib: mongodll.}
proc init*(client: var TMongo, dbname: cstring, prefix: cstring,
gfs: var TGridfs): cint{.stdcall, importc: "gridfs_init",
dynlib: mongodll.}
## Initializes a GridFS object
##
## | client - db connection
## | dbname - database name
## | prefix - collection prefix, default is fs if NULL or empty
## | gfs - the GridFS object to initialize
## | returns - OK or ERROR.
proc destroy*(gfs: var TGridfs){.stdcall, importc: "gridfs_destroy",
dynlib: mongodll.}
## Destroys a GridFS object. Call this when finished with the object.
proc writerInit*(gfile: var TGridFile, gfs: var TGridfs, remote_name: cstring,
content_type: cstring){.stdcall,
importc: "gridfile_writer_init", dynlib: mongodll.}
## Initializes a gridfile for writing incrementally with ``writeBuffer``.
## Once initialized, you can write any number of buffers with ``writeBuffer``.
## When done, you must call ``writerDone`` to save the file metadata.
proc writeBuffer*(gfile: var TGridFile, data: cstring, length: TOffset){.
stdcall, importc: "gridfile_write_buffer", dynlib: mongodll.}
## Write to a GridFS file incrementally. You can call this function any number
## of times with a new buffer each time. This allows you to effectively
## stream to a GridFS file. When finished, be sure to call ``writerDone``.
proc writerDone*(gfile: var TGridFile): cint{.stdcall,
importc: "gridfile_writer_done", dynlib: mongodll.}
## Signal that writing of this gridfile is complete by
## writing any buffered chunks along with the entry in the
## files collection. Returns OK or ERROR.
proc storeBuffer*(gfs: var TGridfs, data: cstring, length: TOffset,
remotename: cstring, contenttype: cstring): cint{.stdcall,
importc: "gridfs_store_buffer", dynlib: mongodll.}
## Store a buffer as a GridFS file.
##
## | gfs - the working GridFS
## | data - pointer to buffer to store in GridFS
## | length - length of the buffer
## | remotename - filename for use in the database
## | contenttype - optional MIME type for this object
## | returns - MONGO_OK or MONGO_ERROR.
proc storeFile*(gfs: var TGridfs, filename: cstring, remotename: cstring,
contenttype: cstring): cint{.stdcall,
importc: "gridfs_store_file", dynlib: mongodll.}
## Open the file referenced by filename and store it as a GridFS file.
##
## | gfs - the working GridFS
## | filename - local filename relative to the process
## | remotename - optional filename for use in the database
## | contenttype - optional MIME type for this object
## | returns - OK or ERROR.
proc removeFilename*(gfs: var TGridfs, filename: cstring){.stdcall,
importc: "gridfs_remove_filename", dynlib: mongodll.}
## Removes the files referenced by filename from the db.
proc findQuery*(gfs: var TGridfs, query: var TBson, gfile: var TGridFile): cint{.
stdcall, importc: "gridfs_find_query", dynlib: mongodll.}
## Find the first file matching the provided query within the
## GridFS files collection, and return the file as a GridFile.
## Returns OK if successful, ERROR otherwise.
proc findFilename*(gfs: var TGridfs, filename: cstring, gfile: var TGridFile): cint{.
stdcall, importc: "gridfs_find_filename", dynlib: mongodll.}
## Find the first file referenced by filename within the GridFS
## and return it as a GridFile. Returns OK or ERROR.
proc init*(gfs: var TGridfs, meta: var TBson, gfile: var TGridFile): cint{.
stdcall, importc: "gridfile_init", dynlib: mongodll.}
## Initializes a GridFile containing the GridFS and file bson.
proc destroy*(gfile: var TGridFile){.stdcall, importc: "gridfile_destroy",
dynlib: mongodll.}
## Destroys the GridFile.
proc exists*(gfile: var TGridFile): TBsonBool{.stdcall,
importc: "gridfile_exists", dynlib: mongodll.}
## Returns whether or not the GridFile exists.
proc getFilename*(gfile: var TGridFile): cstring{.stdcall,
importc: "gridfile_get_filename", dynlib: mongodll.}
## Returns the filename of GridFile.
proc getChunksize*(gfile: var TGridFile): cint{.stdcall,
importc: "gridfile_get_chunksize", dynlib: mongodll.}
## Returns the size of the chunks of the GridFile.
proc getContentlength*(gfile: var TGridFile): TOffset{.stdcall,
importc: "gridfile_get_contentlength", dynlib: mongodll.}
## Returns the length of GridFile's data.
proc getContenttype*(gfile: var TGridFile): cstring{.stdcall,
importc: "gridfile_get_contenttype", dynlib: mongodll.}
## Returns the MIME type of the GridFile (nil if no type specified).
proc getUploaddate*(gfile: var TGridFile): Tdate{.stdcall,
importc: "gridfile_get_uploaddate", dynlib: mongodll.}
## Returns the upload date of GridFile.
proc getMd5*(gfile: var TGridFile): cstring {.stdcall,
importc: "gridfile_get_md5", dynlib: mongodll.}
## Returns the MD5 of GridFile.
proc getField*(gfile: var TGridFile, name: cstring): cstring{.stdcall,
importc: "gridfile_get_field", dynlib: mongodll.}
## Returns the field in GridFile specified by name. Returns the data of the
## field specified (nil if none exists).
proc getBoolean*(gfile: var TGridFile, name: cstring): TBsonBool{.stdcall,
importc: "gridfile_get_boolean", dynlib: mongodll.}
## Returns a boolean field in GridFile specified by name.
proc getMetadata*(gfile: var TGridFile, outp: var TBson){.stdcall,
importc: "gridfile_get_metadata", dynlib: mongodll.}
## Returns the metadata of GridFile (an empty bson is returned if none
## exists).
proc getNumchunks*(gfile: var TGridFile): cint{.stdcall,
importc: "gridfile_get_numchunks", dynlib: mongodll.}
## Returns the number of chunks in the GridFile.
proc getChunk*(gfile: var TGridFile, n: cint, outp: var TBson){.stdcall,
importc: "gridfile_get_chunk", dynlib: mongodll.}
## Returns chunk `n` of GridFile.
proc getChunks*(gfile: var TGridFile, start: cint, size: cint): ptr TCursor{.
stdcall, importc: "gridfile_get_chunks", dynlib: mongodll.}
## Returns a mongo_cursor of `size` chunks starting with chunk `start`.
## The cursor must be destroyed after use.
proc writeFile*(gfile: ptr TGridFile, stream: TFile): TOffset{.stdcall,
importc: "gridfile_write_file", dynlib: mongodll.}
## Writes the GridFile to a stream.
proc read*(gfile: var TGridFile, size: TOffset, buf: cstring): TOffset{.stdcall,
importc: "gridfile_read", dynlib: mongodll.}
## Reads length bytes from the GridFile to a buffer
## and updates the position in the file.
## (assumes the buffer is large enough)
## (if size is greater than EOF gridfile_read reads until EOF).
## Returns the number of bytes read.
proc seek*(gfile: var TGridFile, offset: TOffset): TOffset{.stdcall,
importc: "gridfile_seek", dynlib: mongodll.}
## Updates the position in the file
## (If the offset goes beyond the contentlength,
## the position is updated to the end of the file.)
## Returns the offset location