-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcrud.nim
152 lines (144 loc) · 5.58 KB
/
crud.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import tables, sequtils, asyncdispatch
import ../core/[bson, types, wire, utils]
import diagnostic
import multisock
## Query and Write Operation Commands
## **********************************
##
## This APIs can be referred `here`_. This module handling all main
## CRUD operations and all of these are returning BsonDocument to
## give a higher-level APIs to handle the document.
##
## One caveat that's different from the `Mongo documentation`__ is
## each of these API has additional parameter ``explain`` string
## which default to "" (empty string), or ``explainVerbosity``
## in case ``explain`` already defined before.
## Any non empty ``explain`` value will regarded as Cached Query
## and will invoke the ``diagnostic.explain``.
## Available ``explain`` values are "allPlansExecution", "queryPlanner",
## and "executionStats".
##
## The usage of ``getLastError`` discouraged as it's backward compability
## with older Mongo version and unnecessary with Acknowledged Query
## as the error immediately returned when operation failed.
##
## All APIs are async.
##
## .. _here: https://docs.mongodb.com/manual/reference/command/nav-crud/
##
## __ here_
proc find*(db: Database[AsyncSocket], coll: string,query = bson(),
sort = bsonNull(), selector = bsonNull(), hint = bsonNull(),
skip = 0, limit = 0, batchSize = 101, singleBatch = false, comment = "",
maxTimeMS = 0, readConcern = bsonNull(),
max = bsonNull(), min = bsonNull(), returnKey = false, showRecordId = false,
tailable = false, awaitData = false, oplogReplay = false,
noCursorTimeout = false, partial = false,
collation = bsonNull(), explain = ""): Future[BsonDocument]{.multisock, gcsafe.} =
var q = bson({ find: coll, filter: query })
for field, val in {
"sort": sort,
"projection": selector,
"hint": hint}.toTable:
var ff = field
q.addOptional(move ff, val)
q["skip"] = skip
q["limit"] = limit
q["batchSize"] = batchSize
q.addConditional("singleBatch", singleBatch)
if comment != "":
q["comment"] = comment
if maxTimeMS > 0: q["maxTimeMS"] = maxTimeMS
for k,v in { "readConcern": readConcern,
"max": max, "min": min }.toTable:
var kk = k
q.addOptional(move kk, v)
for k,v in {
"returnKey": returnKey,
"showRecordId": showRecordId,
"tailable": tailable,
"awaitData": awaitData,
"oplogReplay": oplogReplay,
"noCursorTimeout": noCursorTimeout,
"allowPartialResults": partial
}.toTable:
var kk = k
q.addConditional(move kk, v)
q.addOptional("collation", collation)
if explain != "": result = await db.explain(q, explain)
else: result = await crudops(db, q)
proc getMore*(db: Database[AsyncSocket], cursorId: int64, collname: string, batchSize: int,
maxTimeMS = -1): Future[BsonDocument]{.multisock.} =
var q = bson({
getMore: cursorId,
collection: collname,
batchSize: batchSize,
})
# added guard to fix this https://jira.mongodb.org/browse/DOCS-13346
if maxTimeMS >= 0 and db.db.isTailable:
q["maxTimeMS"] = maxTimeMS
result = await db.crudops(q)
proc insert*(db: Database[AsyncSocket], coll: string, documents: seq[BsonDocument],
ordered = true, wt = bsonNull(), bypass = false, explain = ""):
Future[BsonDocument] {.multisock.} =
var q = bson({
insert: coll,
documents: documents.map(toBson),
ordered: ordered,
})
q.addWriteConcern(db, wt)
q.addConditional("bypassDocumentValidation", bypass)
if explain != "": result = await db.explain(q, explain, command = ckWrite)
else: result = await db.crudops(q, cmd = ckWrite)
proc delete*(db: Database[AsyncSocket], coll: string, deletes: seq[BsonDocument],
ordered = true, wt = bsonNull(), explain = ""):
Future[BsonDocument]{.multisock.} =
var q = bson({
delete: coll,
deletes: deletes.map toBson,
ordered: ordered,
})
q.addWriteConcern(db, wt)
if explain != "": result = await db.explain(q, explain, command = ckWrite)
else: result = await db.crudops(q, cmd = ckWrite)
proc update*(db: Database[AsyncSocket], coll: string, updates: seq[BsonDocument],
ordered = true, wt = bsonNull(), bypass = false, explain = ""):
Future[BsonDocument]{.multisock.} =
var q = bson({
update: coll,
updates: updates.map toBson,
ordered: ordered,
})
q.addWriteConcern(db, wt)
q.addConditional("bypassDocumentValidation", bypass)
if explain != "": result = await db.explain(q, explain, command = ckWrite)
else: result = await db.crudops(q, cmd = ckWrite)
proc findAndModify*(db: Database[AsyncSocket], coll: string, query = bson(),
sort = bsonNull(), remove = false, update = bsonNull(),
`new` = false, fields = bsonNull(), upsert = false, bypass = false,
wt = bsonNull(), collation = bsonNull(),
arrayFilters: seq[BsonDocument] = @[], explain = ""): Future[BsonDocument]{.multisock.} =
var q = bson({
findAndModify: coll,
query: query,
})
let bopts = [("sort", sort), ("update", update), ("fields", fields)]
let conds = [("remove", remove), ("new", `new`), ("upsert", upsert)]
for i in 0 .. conds.high:
var b = bopts[i]
q.addOptional(move b[0], b[1])
var c = conds[i]
q.addConditional(move c[0], c[1])
q.addConditional("bypassDocumentValidation", bypass)
q.addWriteConcern(db, wt)
q.addOptional("collation", collation)
if arrayFilters.len > 0:
q["arrayFilters"] = arrayFilters.map toBson
if explain != "": result = await db.explain(q, explain, command = ckWrite)
else: result = await db.crudops(q, cmd = ckWrite)
proc getLastError*(db: Database[AsyncSocket], opt = bson()): Future[BsonDocument]{.multisock.} =
var q = bson({ getLastError: 1 })
for k, v in opt:
var kk = k
q[move kk] = v
result = await db.crudops(q)