Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 318 lines (251 sloc) 14.292 kb
e7bc02e edoc annotations in src comments
Tony Hannan authored
1 %@doc Top-level client interface to MongoDB
9a01905 mongo.erl is top-level interface
Tony Hannan authored
2 -module (mongo).
3
4 -export_type ([maybe/1]).
5
f59460d mongo:create_index
Tony Hannan authored
6 -export_type ([host/0, connection/0]).
c6a4913 shorten factory names
Tony Hannan authored
7 -export ([connect/1, disconnect/1, connect_factory/1]).
b802070 is_closed. mongo: replica sets & pools
Tony Hannan authored
8 -export_type ([replset/0, rs_connection/0]).
c6a4913 shorten factory names
Tony Hannan authored
9 -export ([rs_connect/1, rs_disconnect/1, rs_connect_factory/1]).
f59460d mongo:create_index
Tony Hannan authored
10
11 -export_type ([action/1, db/0, write_mode/0, read_mode/0, failure/0]).
9a01905 mongo.erl is top-level interface
Tony Hannan authored
12 -export ([do/5]).
f59460d mongo:create_index
Tony Hannan authored
13
14 -export_type ([collection/0, selector/0, projector/0, skip/0, batchsize/0, modifier/0]).
9a01905 mongo.erl is top-level interface
Tony Hannan authored
15 -export ([insert/2, insert_all/2]).
16 -export ([save/2, replace/3, repsert/3, modify/3]).
17 -export ([delete/2, delete_one/2]).
18 -export ([find_one/2, find_one/3, find_one/4]).
19 -export ([find/2, find/3, find/4, find/5]).
20 -export ([count/2, count/3]).
f59460d mongo:create_index
Tony Hannan authored
21
22 -export_type ([cursor/0]).
23 -export ([next/1, rest/1, close_cursor/1]).
24
25 -export_type ([command/0]).
9a01905 mongo.erl is top-level interface
Tony Hannan authored
26 -export ([command/1]).
27
f59460d mongo:create_index
Tony Hannan authored
28 -export_type ([key_order/0, index_uniqueness/0]).
29 -export ([create_index/2, create_index/3, create_index/4]).
30
9a01905 mongo.erl is top-level interface
Tony Hannan authored
31 -include ("mongo_protocol.hrl").
32
33 -type reason() :: any().
34
b802070 is_closed. mongo: replica sets & pools
Tony Hannan authored
35 % Server %
36
3f71a62 Host can no longer be raw ip address {,,,}. Connection includes host
Tony Hannan authored
37 -type host() :: mongo_connect:host().
38 % Hostname or ip address with or without port. Port defaults to 27017 when missing.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
39 % Eg. "localhost" or {"localhost", 27017}
40 -type connection() :: mongo_connect:connection().
41
42 -spec connect (host()) -> {ok, connection()} | {error, reason()}. % IO
e7bc02e edoc annotations in src comments
Tony Hannan authored
43 %@doc Connect to given MongoDB server
3f71a62 Host can no longer be raw ip address {,,,}. Connection includes host
Tony Hannan authored
44 connect (Host) -> mongo_connect:connect (Host).
9a01905 mongo.erl is top-level interface
Tony Hannan authored
45
46 -spec disconnect (connection()) -> ok. % IO
e7bc02e edoc annotations in src comments
Tony Hannan authored
47 %@doc Close connection to server
9a01905 mongo.erl is top-level interface
Tony Hannan authored
48 disconnect (Conn) -> mongo_connect:close (Conn).
49
c6a4913 shorten factory names
Tony Hannan authored
50 -spec connect_factory (host()) -> pool:factory(connection()).
e7bc02e edoc annotations in src comments
Tony Hannan authored
51 %@doc Factory for use with a connection pool. See pool module.
c6a4913 shorten factory names
Tony Hannan authored
52 connect_factory (Host) -> {Host, fun connect/1, fun disconnect/1, fun mongo_connect:is_closed/1}.
b802070 is_closed. mongo: replica sets & pools
Tony Hannan authored
53
54 % Replica Set %
55
56 -type replset() :: mongo_replset:replset().
57 -type rs_connection() :: mongo_replset:rs_connection().
58
59 -spec rs_connect (replset()) -> rs_connection(). % IO
e7bc02e edoc annotations in src comments
Tony Hannan authored
60 %@doc Create new cache of connections to replica set members starting with seed members. No connection attempted until rs_primary or rs_secondary_ok called.
b802070 is_closed. mongo: replica sets & pools
Tony Hannan authored
61 rs_connect (Replset) -> mongo_replset:connect (Replset).
62
63 -spec rs_disconnect (rs_connection()) -> ok. % IO
e7bc02e edoc annotations in src comments
Tony Hannan authored
64 %@doc Close cache of replset connections
b802070 is_closed. mongo: replica sets & pools
Tony Hannan authored
65 rs_disconnect (ReplsetConn) -> mongo_replset:close (ReplsetConn).
66
c6a4913 shorten factory names
Tony Hannan authored
67 -spec rs_connect_factory (replset()) -> pool:factory(rs_connection()).
e7bc02e edoc annotations in src comments
Tony Hannan authored
68 %@doc Factory for use with a rs_connection pool. See pool module.
c6a4913 shorten factory names
Tony Hannan authored
69 rs_connect_factory (Replset) -> {Replset, fun (RS) -> RC = rs_connect (RS), {ok, RC} end, fun rs_disconnect/1, fun mongo_replset:is_closed/1}.
b802070 is_closed. mongo: replica sets & pools
Tony Hannan authored
70
71 % Action %
72
9a01905 mongo.erl is top-level interface
Tony Hannan authored
73 -type action(A) :: fun (() -> A).
d6fd289 Fix wire protocol bit flags order. Catch not_master read and write er…
Tony Hannan authored
74 % An Action does IO, reads process dict {mongo_action_context, #context{}}, and throws failure()
9a01905 mongo.erl is top-level interface
Tony Hannan authored
75
76 -type failure() ::
d6fd289 Fix wire protocol bit flags order. Catch not_master read and write er…
Tony Hannan authored
77 mongo_connect:failure() | % thrown by read and safe write
78 mongo_query:not_master() | % throws by read and safe write
79 write_failure() | % throws by safe write
80 mongo_cursor:expired(). % thrown by cursor next/rest
9a01905 mongo.erl is top-level interface
Tony Hannan authored
81
82 -record (context, {
83 write_mode :: write_mode(),
84 read_mode :: read_mode(),
85 dbconn :: mongo_connect:dbconnection() }).
86
187d967 mongo:do accepts connnection() or rs_connection()
Tony Hannan authored
87 -spec do (write_mode(), read_mode(), connection() | rs_connection(), db(), action(A)) -> {ok, A} | {failure, failure()}. % IO
e7bc02e edoc annotations in src comments
Tony Hannan authored
88 %@doc Execute mongo action under given write_mode, read_mode, connection, and db. Return action result or failure.
aa1741b fix accepting rs_connection in mongo:do
Tony Hannan authored
89 do (WriteMode, ReadMode, Connection, Database, Action) -> case connection_mode (ReadMode, Connection) of
90 {error, Reason} -> {failure, {connection_failure, Reason}};
91 {ok, Conn} ->
92 PrevContext = get (mongo_action_context),
93 put (mongo_action_context, #context {write_mode = WriteMode, read_mode = ReadMode, dbconn = {Database, Conn}}),
94 try Action() of
95 Result -> {ok, Result}
96 catch
97 throw: E = {connection_failure, _, _} -> {failure, E};
98 throw: E = not_master -> {failure, E};
99 throw: E = {write_failure, _, _} -> {failure, E};
100 throw: E = {cursor_expired, _} -> {failure, E}
101 after
102 case PrevContext of undefined -> erase (mongo_action_context); _ -> put (mongo_action_context, PrevContext) end
103 end end.
104
105 -spec connection_mode (read_mode(), connection() | rs_connection()) -> {ok, connection()} | {error, reason()}. % IO
e7bc02e edoc annotations in src comments
Tony Hannan authored
106 %@doc For rs_connection return appropriate primary or secondary connection
aa1741b fix accepting rs_connection in mongo:do
Tony Hannan authored
107 connection_mode (_, Conn = {connection, _, _}) -> {ok, Conn};
187d967 mongo:do accepts connnection() or rs_connection()
Tony Hannan authored
108 connection_mode (master, RsConn = {rs_connection, _, _}) -> mongo_replset:primary (RsConn);
109 connection_mode (slave_ok, RsConn = {rs_connection, _, _}) -> mongo_replset:secondary_ok (RsConn).
110
9a01905 mongo.erl is top-level interface
Tony Hannan authored
111 % Write %
112
113 -type write_mode() :: unsafe | safe | {safe, mongo_query:getlasterror_request()}.
114 % Every write inside an action() will use this write mode.
115 % unsafe = asynchronous write (no reply) and hence may silently fail;
116 % safe = synchronous write, wait for reply and fail if connection or write failure;
117 % {safe, Params} = same as safe but with extra params for getlasterror, see its documentation.
118
119 -type write_failure() :: {write_failure, error_code(), bson:utf8()}.
120 -type error_code() :: integer().
121
122 -spec write (mongo_query:write()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
123 %@doc Do unsafe unacknowledged fast write or safe acknowledged slower write depending on our context. When safe, throw write_failure if acknowledgment (getlasterror) reports error.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
124 write (Write) ->
125 Context = get (mongo_action_context),
126 case Context #context.write_mode of
127 unsafe -> mongo_query:write (Context #context.dbconn, Write);
128 SafeMode ->
0a8cc8c Documents are now tuples instead of lists
Tony Hannan authored
129 Params = case SafeMode of safe -> {}; {safe, Param} -> Param end,
9a01905 mongo.erl is top-level interface
Tony Hannan authored
130 Ack = mongo_query:write (Context #context.dbconn, Write, Params),
131 case bson:lookup (err, Ack) of
132 {} -> ok; {null} -> ok;
d6fd289 Fix wire protocol bit flags order. Catch not_master read and write er…
Tony Hannan authored
133 {String} -> case bson:at (code, Ack) of
134 10058 -> throw (not_master);
135 Code -> throw ({write_failure, Code, String}) end end end.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
136
137 -spec insert (collection(), bson:document()) -> bson:value(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
138 %@doc Insert document into collection. Return its '_id' value, which is auto-generated if missing.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
139 insert (Coll, Doc) -> [Value] = insert_all (Coll, [Doc]), Value.
140
141 -spec insert_all (collection(), [bson:document()]) -> [bson:value()]. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
142 %@doc Insert documents into collection. Return their '_id' values, which are auto-generated if missing.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
143 insert_all (Coll, Docs) ->
144 Docs1 = lists:map (fun assign_id/1, Docs),
145 write (#insert {collection = Coll, documents = Docs1}),
146 lists:map (fun (Doc) -> bson:at ('_id', Doc) end, Docs1).
147
148 -spec assign_id (bson:document()) -> bson:document(). % IO
e7bc02e edoc annotations in src comments
Tony Hannan authored
149 %@doc If doc has no '_id' field then generate a fresh object id for it
9a01905 mongo.erl is top-level interface
Tony Hannan authored
150 assign_id (Doc) -> case bson:lookup ('_id', Doc) of
151 {_Value} -> Doc;
0a8cc8c Documents are now tuples instead of lists
Tony Hannan authored
152 {} -> bson:append ({'_id', mongodb_app:gen_objectid()}, Doc) end.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
153
154 -spec save (collection(), bson:document()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
155 %@doc If document has no '_id' field then insert it, otherwise update it and insert only if missing.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
156 save (Coll, Doc) -> case bson:lookup ('_id', Doc) of
157 {} -> insert (Coll, Doc);
0a8cc8c Documents are now tuples instead of lists
Tony Hannan authored
158 {Id} -> repsert (Coll, {'_id', Id}, Doc) end.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
159
160 -spec replace (collection(), selector(), bson:document()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
161 %@doc Replace first document selected with given document.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
162 replace (Coll, Selector, Doc) -> update (false, false, Coll, Selector, Doc).
163
164 -spec repsert (collection(), selector(), bson:document()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
165 %@doc Replace first document selected with given document, or insert it if selection is empty.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
166 repsert (Coll, Selector, Doc) -> update (true, false, Coll, Selector, Doc).
167
168 -spec modify (collection(), selector(), modifier()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
169 %@doc Update all documents selected using modifier
9a01905 mongo.erl is top-level interface
Tony Hannan authored
170 modify (Coll, Selector, Mod) -> update (false, true, Coll, Selector, Mod).
171
172 -spec update (boolean(), boolean(), collection(), selector(), bson:document()) -> ok. % Action
173 update (Upsert, MultiUpdate, Coll, Sel, Doc) ->
174 write (#update {collection = Coll, upsert = Upsert, multiupdate = MultiUpdate, selector = Sel, updater = Doc}).
175
176 -spec delete (collection(), selector()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
177 %@doc Delete selected documents
9a01905 mongo.erl is top-level interface
Tony Hannan authored
178 delete (Coll, Selector) ->
179 write (#delete {collection = Coll, singleremove = false, selector = Selector}).
180
181 -spec delete_one (collection(), selector()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
182 %@doc Delete first selected document.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
183 delete_one (Coll, Selector) ->
184 write (#delete {collection = Coll, singleremove = true, selector = Selector}).
185
186 % Read %
187
188 -type read_mode() :: master | slave_ok.
189 % Every query inside an action() will use this mode.
190 % master = Server must be master/primary so reads are consistent (read latest writes).
b802070 is_closed. mongo: replica sets & pools
Tony Hannan authored
191 % slave_ok = Server may be slave/secondary so reads may not be consistent (may read stale data). Slaves will eventually get the latest writes, so technically this is called eventually-consistent.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
192
193 slave_ok (#context {read_mode = slave_ok}) -> true;
194 slave_ok (#context {read_mode = master}) -> false.
195
196 -type maybe(A) :: {A} | {}.
197
198 -spec find_one (collection(), selector()) -> maybe (bson:document()). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
199 %@doc Return first selected document, if any
9a01905 mongo.erl is top-level interface
Tony Hannan authored
200 find_one (Coll, Selector) -> find_one (Coll, Selector, []).
201
202 -spec find_one (collection(), selector(), projector()) -> maybe (bson:document()). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
203 %@doc Return projection of first selected document, if any. Empty projection [] means full projection.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
204 find_one (Coll, Selector, Projector) -> find_one (Coll, Selector, Projector, 0).
205
206 -spec find_one (collection(), selector(), projector(), skip()) -> maybe (bson:document()). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
207 %@doc Return projection of Nth selected document, if any. Empty projection [] means full projection.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
208 find_one (Coll, Selector, Projector, Skip) ->
209 Context = get (mongo_action_context),
210 Query = #'query' {
211 collection = Coll, selector = Selector, projector = Projector,
212 skip = Skip, slaveok = slave_ok (Context) },
213 mongo_query:find_one (Context #context.dbconn, Query).
214
215 -spec find (collection(), selector()) -> cursor(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
216 %@doc Return selected documents.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
217 find (Coll, Selector) -> find (Coll, Selector, []).
218
219 -spec find (collection(), selector(), projector()) -> cursor(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
220 %@doc Return projection of selected documents. Empty projection [] means full projection.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
221 find (Coll, Selector, Projector) -> find (Coll, Selector, Projector, 0).
222
223 -spec find (collection(), selector(), projector(), skip()) -> cursor(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
224 %@doc Return projection of selected documents starting from Nth document. Empty projection means full projection.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
225 find (Coll, Selector, Projector, Skip) -> find (Coll, Selector, Projector, Skip, 0).
226
227 -spec find (collection(), selector(), projector(), skip(), batchsize()) -> cursor(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
228 %@doc Return projection of selected documents starting from Nth document in batches of batchsize. 0 batchsize means default batch size. Negative batch size means one batch only. Empty projection means full projection.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
229 find (Coll, Selector, Projector, Skip, BatchSize) ->
230 Context = get (mongo_action_context),
231 Query = #'query' {
232 collection = Coll, selector = Selector, projector = Projector,
233 skip = Skip, batchsize = BatchSize, slaveok = slave_ok (Context) },
234 mongo_query:find (Context #context.dbconn, Query).
235
236 -type cursor() :: mongo_cursor:cursor().
237
238 -spec next (cursor()) -> maybe (bson:document()). % IO throws mongo_connect:failure() & mongo_cursor:expired() (this is a subtype of Action)
e7bc02e edoc annotations in src comments
Tony Hannan authored
239 %@doc Return next document in query result cursor, if any.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
240 next (Cursor) -> mongo_cursor:next (Cursor).
241
242 -spec rest (cursor()) -> [bson:document()]. % IO throws mongo_connect:failure() & mongo_cursor:expired() (this is a subtype of Action)
e7bc02e edoc annotations in src comments
Tony Hannan authored
243 %@doc Return remaining documents in query result cursor.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
244 rest (Cursor) -> mongo_cursor:rest (Cursor).
245
246 -spec close_cursor (cursor()) -> ok. % IO (IO is a subtype of Action)
e7bc02e edoc annotations in src comments
Tony Hannan authored
247 %@doc Close cursor
9a01905 mongo.erl is top-level interface
Tony Hannan authored
248 close_cursor (Cursor) -> mongo_cursor:close (Cursor).
249
250 -spec count (collection(), selector()) -> integer(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
251 %@doc Count selected documents
9a01905 mongo.erl is top-level interface
Tony Hannan authored
252 count (Coll, Selector) -> count (Coll, Selector, 0).
253
254 -spec count (collection(), selector(), integer()) -> integer(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
255 %@doc Count selected documents up to given max number; 0 means no max. Ie. stops counting when max is reached to save processing time.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
256 count (Coll, Selector, Limit) ->
0a8cc8c Documents are now tuples instead of lists
Tony Hannan authored
257 CollStr = atom_to_binary (Coll, utf8),
258 Command = if
259 Limit =< 0 -> {count, CollStr, 'query', Selector};
260 true -> {count, CollStr, 'query', Selector, limit, Limit} end,
261 Doc = command (Command),
9a01905 mongo.erl is top-level interface
Tony Hannan authored
262 trunc (bson:at (n, Doc)). % Server returns count as float
263
264 % Command %
265
266 -type command() :: mongo_query:command().
267
268 -spec command (command()) -> bson:document(). % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
269 %@doc Execute given MongoDB command and return its result.
9a01905 mongo.erl is top-level interface
Tony Hannan authored
270 command (Command) ->
271 Context = get (mongo_action_context),
272 mongo_query:command (Context #context.dbconn, Command, slave_ok (Context)).
f59460d mongo:create_index
Tony Hannan authored
273
274 % Administration %
275
276 -type key_order() :: bson:document().
277 % List keys and whether ascending (1) or descending (-1). Eg. {x,1, y,-1}
278
279 -spec create_index (collection(), key_order()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
280 %@doc Create non-unique index on given keys in collection
f59460d mongo:create_index
Tony Hannan authored
281 create_index (Coll, KeyOrder) ->
282 create_index (Coll, KeyOrder, non_unique).
283
284 -type index_uniqueness() ::
285 non_unique | % Multiple docs with same index value allowed
286 unique | % At most one doc with same index value, index creation fails otherwise
287 unique_dropdups. % Same as unique, but deletes docs with duplicate index value on index creation
288
289 -spec create_index (collection(), key_order(), index_uniqueness()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
290 %@doc Create index on given keys with given uniqueness
f59460d mongo:create_index
Tony Hannan authored
291 create_index (Coll, KeyOrder, Uniqueness) ->
292 create_index (Coll, KeyOrder, Uniqueness, gen_index_name (KeyOrder)).
293
294 -spec gen_index_name (key_order()) -> bson:utf8().
295 gen_index_name (KeyOrder) ->
296 AsName = fun (Label, Order, Name) -> <<
297 $_,
298 Name /binary,
299 (atom_to_binary (Label, utf8)) /binary,
300 $_,
301 (bson:utf8 (integer_to_list (Order))) /binary >> end,
302 bson:doc_foldl (AsName, <<>>, KeyOrder).
303
304 -spec create_index (collection(), key_order(), index_uniqueness(), bson:utf8()) -> ok. % Action
e7bc02e edoc annotations in src comments
Tony Hannan authored
305 %@doc Create index on given keys with given uniqueness and name
f59460d mongo:create_index
Tony Hannan authored
306 create_index (Coll, KeyOrder, Uniqueness, IndexName) ->
307 {Db, _} = (get (mongo_action_context)) #context.dbconn,
308 {Unique, DropDups} = case Uniqueness of
309 non_unique -> {false, false};
310 unique -> {true, false};
311 unique_dropdups -> {true, true} end,
312 insert ('system.indexes', {
313 ns, mongo_protocol:dbcoll (Db, Coll),
314 key, KeyOrder,
315 name, IndexName,
316 unique, Unique,
317 dropDups, DropDups}).
Something went wrong with that request. Please try again.