Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

edoc annotations in src comments

  • Loading branch information...
commit e7bc02e0db2b6795d970847bfa0b3d2eac10e5f3 1 parent 6a61801
Tony Hannan authored
View
2  README.md
@@ -67,7 +67,7 @@ If there are no errors in the sequence of operations then the result of the last
`mongo:find` returns a *cursor* holding the pending list of results, which are accessed using `mongo:next` to get the next result, and `mongo:rest` to get the remaining results. Either one throws `{cursor_expired, Cursor}` if the cursor was idle for more than 10 minutes. This exception is caught by `mongo:do` and returned as `{failure, {cursor_expired, Cursor}}`. `mongo:rest` also closes the cursor, otherwise you should close the cursor when finished using `mongo:close_cursor`.
-See the [*mongo* module](http://github.com/TonyGen/mongodb-erlang/blob/master/src/mongo.erl) for a description of all operations. A type specification is provided with each operation so you know the expected arguments and results. The spec line also has a comment if it performs a side-effect such as IO and what exceptions it may throw. No comment means it is a pure function. Also, see the [*bson* module](http://github.com/TonyGen/bson-erlang/blob/master/src/bson.erl) in the bson application for details on the document type and its value types.
+See the [*mongo*](http://github.com/TonyGen/mongodb-erlang/blob/master/src/mongo.erl) module for a description of all operations. A type specification is provided with each operation so you know the expected arguments and results. The spec line also has a comment if it performs a side-effect such as IO and what exceptions it may throw. No comment means it is a pure function. Also, see the [*bson* module](http://github.com/TonyGen/bson-erlang/blob/master/src/bson.erl) in the bson application for details on the document type and its value types.
### Administering
View
70 src/mongo.erl
@@ -1,4 +1,4 @@
-% Top-level client interface to MongoDB
+%@doc Top-level client interface to MongoDB
-module (mongo).
-export_type ([maybe/1]).
@@ -40,15 +40,15 @@
-type connection() :: mongo_connect:connection().
-spec connect (host()) -> {ok, connection()} | {error, reason()}. % IO
-% Connect to given MongoDB server
+%@doc Connect to given MongoDB server
connect (Host) -> mongo_connect:connect (Host).
-spec disconnect (connection()) -> ok. % IO
-% Close connection to server
+%@doc Close connection to server
disconnect (Conn) -> mongo_connect:close (Conn).
-spec connect_factory (host()) -> pool:factory(connection()).
-% Factory for use with a connection pool. See pool module.
+%@doc Factory for use with a connection pool. See pool module.
connect_factory (Host) -> {Host, fun connect/1, fun disconnect/1, fun mongo_connect:is_closed/1}.
% Replica Set %
@@ -57,15 +57,15 @@ connect_factory (Host) -> {Host, fun connect/1, fun disconnect/1, fun mongo_conn
-type rs_connection() :: mongo_replset:rs_connection().
-spec rs_connect (replset()) -> rs_connection(). % IO
-% Create new cache of connections to replica set members starting with seed members. No connection attempted until rs_primary or rs_secondary_ok called.
+%@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.
rs_connect (Replset) -> mongo_replset:connect (Replset).
-spec rs_disconnect (rs_connection()) -> ok. % IO
-% Close cache of replset connections
+%@doc Close cache of replset connections
rs_disconnect (ReplsetConn) -> mongo_replset:close (ReplsetConn).
-spec rs_connect_factory (replset()) -> pool:factory(rs_connection()).
-% Factory for use with a rs_connection pool. See pool module.
+%@doc Factory for use with a rs_connection pool. See pool module.
rs_connect_factory (Replset) -> {Replset, fun (RS) -> RC = rs_connect (RS), {ok, RC} end, fun rs_disconnect/1, fun mongo_replset:is_closed/1}.
% Action %
@@ -85,7 +85,7 @@ rs_connect_factory (Replset) -> {Replset, fun (RS) -> RC = rs_connect (RS), {ok,
dbconn :: mongo_connect:dbconnection() }).
-spec do (write_mode(), read_mode(), connection() | rs_connection(), db(), action(A)) -> {ok, A} | {failure, failure()}. % IO
-% Execute mongo action under given write_mode, read_mode, connection, and db. Return action result or failure.
+%@doc Execute mongo action under given write_mode, read_mode, connection, and db. Return action result or failure.
do (WriteMode, ReadMode, Connection, Database, Action) -> case connection_mode (ReadMode, Connection) of
{error, Reason} -> {failure, {connection_failure, Reason}};
{ok, Conn} ->
@@ -103,7 +103,7 @@ do (WriteMode, ReadMode, Connection, Database, Action) -> case connection_mode (
end end.
-spec connection_mode (read_mode(), connection() | rs_connection()) -> {ok, connection()} | {error, reason()}. % IO
-% For rs_connection return appropriate primary or secondary connection
+%@doc For rs_connection return appropriate primary or secondary connection
connection_mode (_, Conn = {connection, _, _}) -> {ok, Conn};
connection_mode (master, RsConn = {rs_connection, _, _}) -> mongo_replset:primary (RsConn);
connection_mode (slave_ok, RsConn = {rs_connection, _, _}) -> mongo_replset:secondary_ok (RsConn).
@@ -120,7 +120,7 @@ connection_mode (slave_ok, RsConn = {rs_connection, _, _}) -> mongo_replset:seco
-type error_code() :: integer().
-spec write (mongo_query:write()) -> ok. % Action
-% Do unsafe unacknowledged fast write or safe acknowledged slower write depending on our context. When safe, throw write_failure if acknowledgment (getlasterror) reports error.
+%@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.
write (Write) ->
Context = get (mongo_action_context),
case Context #context.write_mode of
@@ -135,38 +135,38 @@ write (Write) ->
Code -> throw ({write_failure, Code, String}) end end end.
-spec insert (collection(), bson:document()) -> bson:value(). % Action
-% Insert document into collection. Return its '_id' value, which is auto-generated if missing.
+%@doc Insert document into collection. Return its '_id' value, which is auto-generated if missing.
insert (Coll, Doc) -> [Value] = insert_all (Coll, [Doc]), Value.
-spec insert_all (collection(), [bson:document()]) -> [bson:value()]. % Action
-% Insert documents into collection. Return their '_id' values, which are auto-generated if missing.
+%@doc Insert documents into collection. Return their '_id' values, which are auto-generated if missing.
insert_all (Coll, Docs) ->
Docs1 = lists:map (fun assign_id/1, Docs),
write (#insert {collection = Coll, documents = Docs1}),
lists:map (fun (Doc) -> bson:at ('_id', Doc) end, Docs1).
-spec assign_id (bson:document()) -> bson:document(). % IO
-% If doc has no '_id' field then generate a fresh object id for it
+%@doc If doc has no '_id' field then generate a fresh object id for it
assign_id (Doc) -> case bson:lookup ('_id', Doc) of
{_Value} -> Doc;
{} -> bson:append ({'_id', mongodb_app:gen_objectid()}, Doc) end.
-spec save (collection(), bson:document()) -> ok. % Action
-% If document has no '_id' field then insert it, otherwise update it and insert only if missing.
+%@doc If document has no '_id' field then insert it, otherwise update it and insert only if missing.
save (Coll, Doc) -> case bson:lookup ('_id', Doc) of
{} -> insert (Coll, Doc);
{Id} -> repsert (Coll, {'_id', Id}, Doc) end.
-spec replace (collection(), selector(), bson:document()) -> ok. % Action
-% Replace first document selected with given document.
+%@doc Replace first document selected with given document.
replace (Coll, Selector, Doc) -> update (false, false, Coll, Selector, Doc).
-spec repsert (collection(), selector(), bson:document()) -> ok. % Action
-% Replace first document selected with given document, or insert it if selection is empty.
+%@doc Replace first document selected with given document, or insert it if selection is empty.
repsert (Coll, Selector, Doc) -> update (true, false, Coll, Selector, Doc).
-spec modify (collection(), selector(), modifier()) -> ok. % Action
-% Update all documents selected using modifier
+%@doc Update all documents selected using modifier
modify (Coll, Selector, Mod) -> update (false, true, Coll, Selector, Mod).
-spec update (boolean(), boolean(), collection(), selector(), bson:document()) -> ok. % Action
@@ -174,12 +174,12 @@ update (Upsert, MultiUpdate, Coll, Sel, Doc) ->
write (#update {collection = Coll, upsert = Upsert, multiupdate = MultiUpdate, selector = Sel, updater = Doc}).
-spec delete (collection(), selector()) -> ok. % Action
-% Delete selected documents
+%@doc Delete selected documents
delete (Coll, Selector) ->
write (#delete {collection = Coll, singleremove = false, selector = Selector}).
-spec delete_one (collection(), selector()) -> ok. % Action
-% Delete first selected document.
+%@doc Delete first selected document.
delete_one (Coll, Selector) ->
write (#delete {collection = Coll, singleremove = true, selector = Selector}).
@@ -196,15 +196,15 @@ slave_ok (#context {read_mode = master}) -> false.
-type maybe(A) :: {A} | {}.
-spec find_one (collection(), selector()) -> maybe (bson:document()). % Action
-% Return first selected document, if any
+%@doc Return first selected document, if any
find_one (Coll, Selector) -> find_one (Coll, Selector, []).
-spec find_one (collection(), selector(), projector()) -> maybe (bson:document()). % Action
-% Return projection of first selected document, if any. Empty projection [] means full projection.
+%@doc Return projection of first selected document, if any. Empty projection [] means full projection.
find_one (Coll, Selector, Projector) -> find_one (Coll, Selector, Projector, 0).
-spec find_one (collection(), selector(), projector(), skip()) -> maybe (bson:document()). % Action
-% Return projection of Nth selected document, if any. Empty projection [] means full projection.
+%@doc Return projection of Nth selected document, if any. Empty projection [] means full projection.
find_one (Coll, Selector, Projector, Skip) ->
Context = get (mongo_action_context),
Query = #'query' {
@@ -213,19 +213,19 @@ find_one (Coll, Selector, Projector, Skip) ->
mongo_query:find_one (Context #context.dbconn, Query).
-spec find (collection(), selector()) -> cursor(). % Action
-% Return selected documents.
+%@doc Return selected documents.
find (Coll, Selector) -> find (Coll, Selector, []).
-spec find (collection(), selector(), projector()) -> cursor(). % Action
-% Return projection of selected documents. Empty projection [] means full projection.
+%@doc Return projection of selected documents. Empty projection [] means full projection.
find (Coll, Selector, Projector) -> find (Coll, Selector, Projector, 0).
-spec find (collection(), selector(), projector(), skip()) -> cursor(). % Action
-% Return projection of selected documents starting from Nth document. Empty projection means full projection.
+%@doc Return projection of selected documents starting from Nth document. Empty projection means full projection.
find (Coll, Selector, Projector, Skip) -> find (Coll, Selector, Projector, Skip, 0).
-spec find (collection(), selector(), projector(), skip(), batchsize()) -> cursor(). % Action
-% 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.
+%@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.
find (Coll, Selector, Projector, Skip, BatchSize) ->
Context = get (mongo_action_context),
Query = #'query' {
@@ -236,23 +236,23 @@ find (Coll, Selector, Projector, Skip, BatchSize) ->
-type cursor() :: mongo_cursor:cursor().
-spec next (cursor()) -> maybe (bson:document()). % IO throws mongo_connect:failure() & mongo_cursor:expired() (this is a subtype of Action)
-% Return next document in query result cursor, if any.
+%@doc Return next document in query result cursor, if any.
next (Cursor) -> mongo_cursor:next (Cursor).
-spec rest (cursor()) -> [bson:document()]. % IO throws mongo_connect:failure() & mongo_cursor:expired() (this is a subtype of Action)
-% Return remaining documents in query result cursor.
+%@doc Return remaining documents in query result cursor.
rest (Cursor) -> mongo_cursor:rest (Cursor).
-spec close_cursor (cursor()) -> ok. % IO (IO is a subtype of Action)
-% Close cursor
+%@doc Close cursor
close_cursor (Cursor) -> mongo_cursor:close (Cursor).
-spec count (collection(), selector()) -> integer(). % Action
-% Count selected documents
+%@doc Count selected documents
count (Coll, Selector) -> count (Coll, Selector, 0).
-spec count (collection(), selector(), integer()) -> integer(). % Action
-% Count selected documents up to given max number; 0 means no max. Ie. stops counting when max is reached to save processing time.
+%@doc Count selected documents up to given max number; 0 means no max. Ie. stops counting when max is reached to save processing time.
count (Coll, Selector, Limit) ->
CollStr = atom_to_binary (Coll, utf8),
Command = if
@@ -266,7 +266,7 @@ count (Coll, Selector, Limit) ->
-type command() :: mongo_query:command().
-spec command (command()) -> bson:document(). % Action
-% Execute given MongoDB command and return its result.
+%@doc Execute given MongoDB command and return its result.
command (Command) ->
Context = get (mongo_action_context),
mongo_query:command (Context #context.dbconn, Command, slave_ok (Context)).
@@ -277,7 +277,7 @@ command (Command) ->
% List keys and whether ascending (1) or descending (-1). Eg. {x,1, y,-1}
-spec create_index (collection(), key_order()) -> ok. % Action
-% Create non-unique index on given keys in collection
+%@doc Create non-unique index on given keys in collection
create_index (Coll, KeyOrder) ->
create_index (Coll, KeyOrder, non_unique).
@@ -287,7 +287,7 @@ create_index (Coll, KeyOrder) ->
unique_dropdups. % Same as unique, but deletes docs with duplicate index value on index creation
-spec create_index (collection(), key_order(), index_uniqueness()) -> ok. % Action
-% Create index on given keys with given uniqueness
+%@doc Create index on given keys with given uniqueness
create_index (Coll, KeyOrder, Uniqueness) ->
create_index (Coll, KeyOrder, Uniqueness, gen_index_name (KeyOrder)).
@@ -302,7 +302,7 @@ gen_index_name (KeyOrder) ->
bson:doc_foldl (AsName, <<>>, KeyOrder).
-spec create_index (collection(), key_order(), index_uniqueness(), bson:utf8()) -> ok. % Action
-% Create index on given keys with given uniqueness and name
+%@doc Create index on given keys with given uniqueness and name
create_index (Coll, KeyOrder, Uniqueness, IndexName) ->
{Db, _} = (get (mongo_action_context)) #context.dbconn,
{Unique, DropDups} = case Uniqueness of
View
24 src/mongo_connect.erl
@@ -1,4 +1,4 @@
-% Thread-safe TCP connection to a MongoDB server with synchronous call and asynchronous send interface.
+%@doc Thread-safe TCP connection to a MongoDB server with synchronous call and asynchronous send interface.
-module (mongo_connect).
-export_type ([host/0, connection/0, dbconnection/0, failure/0]).
@@ -14,23 +14,23 @@
% Hostname and port. Port defaults to 27017 when missing
-spec host_port (host()) -> host().
-% Port explicitly filled in with defaut if missing
+%@doc Port explicitly filled in with defaut if missing
host_port ({Hostname, Port}) -> {hostname_string (Hostname), Port};
host_port (Hostname) -> {hostname_string (Hostname), 27017}.
-spec hostname_string (inet:hostname()) -> string().
-% Convert possible hostname atom to string
+%@doc Convert possible hostname atom to string
hostname_string (Name) when is_atom (Name) -> atom_to_list (Name);
hostname_string (Name) -> Name.
-spec show_host (host()) -> bson:utf8().
-% UString representation of host, ie. "Hostname:Port"
+%@doc UString representation of host, ie. "Hostname:Port"
show_host (Host) ->
{Hostname, Port} = host_port (Host),
bson:utf8 (Hostname ++ ":" ++ integer_to_list (Port)).
-spec read_host (bson:utf8()) -> host().
-% Interpret ustring as host, ie. "Hostname:Port" -> {Hostname, Port}
+%@doc Interpret ustring as host, ie. "Hostname:Port" -> {Hostname, Port}
read_host (UString) -> case string:tokens (bson:str (UString), ":") of
[Hostname] -> host_port (Hostname);
[Hostname, Port] -> {Hostname, list_to_integer (Port)} end.
@@ -43,21 +43,21 @@ read_host (UString) -> case string:tokens (bson:str (UString), ":") of
% Type not opaque to mongo:connection_mode/2
-spec connect (host()) -> {ok, connection()} | {error, reason()}. % IO
-% Create connection to given MongoDB server or return reason for connection failure.
+%@doc Create connection to given MongoDB server or return reason for connection failure.
connect (Host) -> try mvar:create (fun () -> tcp_connect (host_port (Host)) end, fun gen_tcp:close/1)
of VSocket -> {ok, {connection, host_port (Host), VSocket}}
catch Reason -> {error, Reason} end.
-spec conn_host (connection()) -> host().
-% Host this is connected to
+%@doc Host this is connected to
conn_host ({connection, Host, _VSocket}) -> Host.
-spec close (connection()) -> ok. % IO
-% Close connection.
+%@doc Close connection.
close ({connection, _Host, VSocket}) -> mvar:terminate (VSocket).
-spec is_closed (connection()) -> boolean(). % IO
-% Has connection been closed?
+%@doc Has connection been closed?
is_closed ({connection, _, VSocket}) -> mvar:is_terminated (VSocket).
-type dbconnection() :: {mongo_protocol:db(), connection()}.
@@ -65,7 +65,7 @@ is_closed ({connection, _, VSocket}) -> mvar:is_terminated (VSocket).
-type failure() :: {connection_failure, connection(), reason()}.
-spec call (dbconnection(), [mongo_protocol:notice()], mongo_protocol:request()) -> mongo_protocol:reply(). % IO throws failure()
-% Synchronous send and reply. Notices are sent right before request in single block. Exclusive access to connection during entire call.
+%@doc Synchronous send and reply. Notices are sent right before request in single block. Exclusive access to connection during entire call.
call ({Db, Conn = {connection, _Host, VSocket}}, Notices, Request) ->
{MessagesBin, RequestId} = messages_binary (Db, Notices ++ [Request]),
Call = fun (Socket) ->
@@ -81,7 +81,7 @@ call ({Db, Conn = {connection, _Host, VSocket}}, Notices, Request) ->
exit: {noproc, _} -> throw ({connection_failure, Conn, closed}) end.
-spec send (dbconnection(), [mongo_protocol:notice()]) -> ok. % IO throws failure()
-% Asynchronous send (no reply). Don't know if send succeeded. Exclusive access to the connection during send.
+%@doc Asynchronous send (no reply). Don't know if send succeeded. Exclusive access to the connection during send.
send ({Db, Conn = {connection, _Host, VSocket}}, Notices) ->
{NoticesBin, _} = messages_binary (Db, Notices),
Send = fun (Socket) -> tcp_send (Socket, NoticesBin) end,
@@ -91,7 +91,7 @@ send ({Db, Conn = {connection, _Host, VSocket}}, Notices) ->
exit: {noproc, _} -> throw ({connection_failure, Conn, closed}) end.
-spec messages_binary (mongo_protocol:db(), [mongo_protocol:message()]) -> {binary(), mongo_protocol:requestid()}.
-% Binary representation of messages
+%@doc Binary representation of messages
messages_binary (Db, Messages) ->
Build = fun (Message, {Bin, _}) ->
RequestId = mongodb_app:next_requestid(),
View
18 src/mongo_cursor.erl
@@ -1,4 +1,4 @@
-% A cursor references pending query results on a server.
+%@doc A cursor references pending query results on a server.
% TODO: terminate cursor after idle for 10 minutes.
-module (mongo_cursor).
@@ -22,26 +22,26 @@
-type batch() :: {cursorid(), [bson:document()]}.
-spec cursor (mongo_connect:dbconnection(), collection(), batchsize(), {cursorid(), [bson:document()]}) -> cursor(). % IO
-% Create new cursor from result batch
+%@doc Create new cursor from result batch
cursor (DbConn, Collection, BatchSize, Batch) ->
mvar:new ({{DbConn, Collection, BatchSize}, Batch}, fun finalize/1).
-spec close (cursor()) -> ok. % IO
-% Close cursor
+%@doc Close cursor
close (Cursor) -> mvar:terminate (Cursor).
-spec is_closed (cursor()) -> boolean(). % IO
-% Is cursor closed
+%@doc Is cursor closed
is_closed (Cursor) -> mvar:is_terminated (Cursor).
-spec rest (cursor()) -> [bson:document()]. % IO throws expired() & mongo_connect:failure()
-% Return remaining documents in query result
+%@doc Return remaining documents in query result
rest (Cursor) -> case next (Cursor) of
{} -> [];
{Doc} -> [Doc | rest (Cursor)] end.
-spec next (cursor()) -> maybe (bson:document()). % IO throws expired() & mongo_connect:failure()
-% Return next document in query result or nothing if finished.
+%@doc Return next document in query result or nothing if finished.
next (Cursor) ->
Next = fun ({Env, Batch}) ->
{Batch1, MDoc} = xnext (Env, Batch),
@@ -51,7 +51,7 @@ next (Cursor) ->
catch expired -> close (Cursor), throw ({cursor_expired, Cursor}) end.
-spec xnext (env(), batch()) -> {batch(), maybe (bson:document())}. % IO throws expired & mongo_connect:failure()
-% Get next document in cursor, fetching next batch from server if necessary
+%@doc Get next document in cursor, fetching next batch from server if necessary
xnext (Env = {DbConn, Coll, BatchSize}, {CursorId, Docs}) -> case Docs of
[Doc | Docs1] -> {{CursorId, Docs1}, {Doc}};
[] -> case CursorId of
@@ -62,7 +62,7 @@ xnext (Env = {DbConn, Coll, BatchSize}, {CursorId, Docs}) -> case Docs of
xnext (Env, batch_reply (Reply)) end end.
-spec batch_reply (mongo_protocol:reply()) -> batch(). % IO throws expired
-% Extract next batch of results from reply. Throw expired if cursor not found on server.
+%@doc Extract next batch of results from reply. Throw expired if cursor not found on server.
batch_reply (#reply {
cursornotfound = CursorNotFound, queryerror = false, awaitcapable = _,
cursorid = CursorId, startingfrom = _, documents = Docs }) -> if
@@ -70,7 +70,7 @@ batch_reply (#reply {
true -> {CursorId, Docs} end.
-spec finalize (state()) -> ok. % IO. Result ignored
-% Kill cursor on server if not already
+%@doc Kill cursor on server if not already
finalize ({{DbConn, _, _}, {CursorId, _}}) -> case CursorId of
0 -> ok;
_ -> mongo_connect:send (DbConn, [#killcursor {cursorids = [CursorId]}]) end.
View
6 src/mongo_protocol.erl
@@ -1,4 +1,4 @@
-%% MongoDB wire protocol
+%@doc MongoDB wire protocol
-module(mongo_protocol).
-export_type ([db/0]).
@@ -6,7 +6,7 @@
-export_type ([message/0]).
-export_type ([requestid/0]).
--compile (export_all).
+-export ([bit/1, bool/1, dbcoll/2, put_message/3, get_reply/1]).
-include ("mongo_protocol.hrl").
-include_lib ("bson/include/bson_binary.hrl").
@@ -45,7 +45,7 @@ bool (0) -> false;
bool (1) -> true.
-spec dbcoll (db(), collection()) -> bson:utf8().
-% Concat db and collection name with period (.) in between
+%@doc Concat db and collection name with period (.) in between
dbcoll (Db, Coll) -> <<(atom_to_binary (Db, utf8)) /binary, $., (atom_to_binary (Coll, utf8)) /binary>>.
-type message() :: notice() | request().
View
14 src/mongo_query.erl
@@ -1,4 +1,4 @@
-% write, find, and command operations
+%@doc Write, find, and command operations
-module (mongo_query).
-export_type ([write/0, 'query'/0, command/0]).
@@ -22,7 +22,7 @@
% Reply to getlasterror request.
-spec write (mongo_connect:dbconnection(), write(), getlasterror_request()) -> getlasterror_reply(). % QIO
-% Send write and getlasterror request to mongodb over connection and wait for and return getlasterror reply. Bad getlasterror params are ignored.
+%@doc Send write and getlasterror request to mongodb over connection and wait for and return getlasterror reply. Bad getlasterror params are ignored.
% Caller is responsible for checking for error in reply; if 'err' field is null then success, otherwise it holds error message string.
write (DbConn, Write, GetlasterrorParams) ->
Query = #'query' {batchsize = -1, collection = '$cmd',
@@ -32,14 +32,14 @@ write (DbConn, Write, GetlasterrorParams) ->
Doc.
-spec write (mongo_connect:dbconnection(), write()) -> ok. % IO
-% Send write to mongodb over connection asynchronously. Does not wait for reply hence may silently fail. Doesn't even throw connection failure if connection is closed.
+%@doc Send write to mongodb over connection asynchronously. Does not wait for reply hence may silently fail. Doesn't even throw connection failure if connection is closed.
write (DbConn, Write) ->
mongo_connect:send (DbConn, [Write]).
-type command() :: bson:document().
-spec command (mongo_connect:dbconnection(), command(), boolean()) -> bson:document(). % QIO
-% Send command to mongodb over connection and wait for reply and return it. Boolean arg indicates slave-ok or not. 'bad_command' error if bad command.
+%@doc Send command to mongodb over connection and wait for reply and return it. Boolean arg indicates slave-ok or not. 'bad_command' error if bad command.
command (DbConn, Command, SlaveOk) ->
Query = #'query' {collection = '$cmd', selector = Command, slaveok = SlaveOk},
{Doc} = find_one (DbConn, Query),
@@ -51,7 +51,7 @@ command (DbConn, Command, SlaveOk) ->
-type maybe(A) :: {A} | {}.
-spec find_one (mongo_connect:dbconnection(), 'query'()) -> maybe (bson:document()). % QIO
-% Send read request to mongodb over connection and wait for reply. Return first result or nothing if empty.
+%@doc Send read request to mongodb over connection and wait for reply. Return first result or nothing if empty.
find_one (DbConn, Query) ->
Query1 = Query #'query' {batchsize = -1},
Reply = mongo_connect:call (DbConn, [], Query1),
@@ -59,13 +59,13 @@ find_one (DbConn, Query) ->
case Docs of [] -> {}; [Doc | _] -> {Doc} end.
-spec find (mongo_connect:dbconnection(), 'query'()) -> mongo_cursor:cursor(). % QIO
-% Send read request to mongodb over connection and wait for reply of first batch. Return a cursor holding this batch and able to fetch next batch on demand.
+%@doc Send read request to mongodb over connection and wait for reply of first batch. Return a cursor holding this batch and able to fetch next batch on demand.
find (DbConn, Query) ->
Reply = mongo_connect:call (DbConn, [], Query),
mongo_cursor:cursor (DbConn, Query #'query'.collection, Query #'query'.batchsize, query_reply (Reply)).
-spec query_reply (mongo_protocol:reply()) -> {cursorid(), [bson:document()]}. % QIO
-% Extract cursorid and results from reply. 'bad_query' error if query error.
+%@doc Extract cursorid and results from reply. 'bad_query' error if query error.
query_reply (#reply {
cursornotfound = false, queryerror = QueryError, awaitcapable = _,
cursorid = Cid, startingfrom = _, documents = Docs }) ->
View
24 src/mongo_replset.erl
@@ -1,4 +1,4 @@
-%% Get connection to appropriate server in a replica set
+%@doc Get connection to appropriate server in a replica set
-module (mongo_replset).
-export_type ([replset/0, rs_connection/0]).
@@ -14,14 +14,14 @@
% find (Pred, [A | Tail]) -> case Pred (A) of true -> {A}; false -> find (Pred, Tail) end.
-spec until_success ([A], fun ((A) -> B)) -> B. % EIO, fun EIO
-% Apply fun on each element until one doesn't fail. Fail if all fail or list is empty
+%@doc Apply fun on each element until one doesn't fail. Fail if all fail or list is empty
until_success ([], _Fun) -> throw ([]);
until_success ([A | Tail], Fun) -> try Fun (A)
catch Reason -> try until_success (Tail, Fun)
catch Reasons -> throw ([Reason | Reasons]) end end.
-spec rotate (integer(), [A]) -> [A].
-% Move first N element of list to back of list
+%@doc Move first N element of list to back of list
rotate (N, List) ->
{Front, Back} = lists:split (N, List),
Back ++ Front.
@@ -34,7 +34,7 @@ rotate (N, List) ->
-type rs_name() :: bson:utf8().
-spec connect (replset()) -> rs_connection(). % IO
-% Create new cache of connections to replica set members starting with seed members. No connection attempted until primary or secondary_ok called.
+%@doc Create new cache of connections to replica set members starting with seed members. No connection attempted until primary or secondary_ok called.
connect ({ReplName, Hosts}) ->
Dict = dict:from_list (lists:map (fun (Host) -> {mongo_connect:host_port (Host), {}} end, Hosts)),
{rs_connection, ReplName, mvar:new (Dict)}.
@@ -46,7 +46,7 @@ connect ({ReplName, Hosts}) ->
% All hosts listed in last member_info fetched are keys in dict. Value is {} if no attempt to connect to that host yet
-spec primary (rs_connection()) -> err_or(connection()). % IO
-% Return connection to current primary in replica set
+%@doc Return connection to current primary in replica set
primary (ReplConn) -> try
MemberInfo = fetch_member_info (ReplConn),
primary_conn (2, ReplConn, MemberInfo)
@@ -54,7 +54,7 @@ primary (ReplConn) -> try
catch Reason -> {error, Reason} end.
-spec secondary_ok (rs_connection()) -> err_or(connection()). % IO
-% Return connection to a current secondary in replica set or primary if none
+%@doc Return connection to a current secondary in replica set or primary if none
secondary_ok (ReplConn) -> try
{_Conn, Info} = fetch_member_info (ReplConn),
Hosts = lists:map (fun mongo_connect:read_host/1, bson:at (hosts, Info)),
@@ -64,14 +64,14 @@ secondary_ok (ReplConn) -> try
catch Reason -> {error, Reason} end.
-spec close (rs_connection()) -> ok. % IO
-% Close replset connection
+%@doc Close replset connection
close ({rs_connection, _, VConns}) ->
CloseConn = fun (_, MCon, _) -> case MCon of {Con} -> mongo_connect:close (Con); {} -> ok end end,
mvar:with (VConns, fun (Dict) -> dict:fold (CloseConn, ok, Dict) end),
mvar:terminate (VConns).
-spec is_closed (rs_connection()) -> boolean(). % IO
-% Has replset connection been closed?
+%@doc Has replset connection been closed?
is_closed ({rs_connection, _, VConns}) -> mvar:is_terminated (VConns).
% EIO = IO that may throw error of any type
@@ -80,7 +80,7 @@ is_closed ({rs_connection, _, VConns}) -> mvar:is_terminated (VConns).
% Result of isMaster query on a server connnection. Returned fields are: setName, ismaster, secondary, hosts, [primary]. primary only present when ismaster = false
-spec primary_conn (integer(), rs_connection(), member_info()) -> connection(). % EIO
-% Return connection to primary designated in member_info. Only chase primary pointer N times.
+%@doc Return connection to primary designated in member_info. Only chase primary pointer N times.
primary_conn (0, _ReplConn, MemberInfo) -> throw ({false_primary, MemberInfo});
primary_conn (Tries, ReplConn, {Conn, Info}) -> case bson:at (ismaster, Info) of
true -> Conn;
@@ -91,7 +91,7 @@ primary_conn (Tries, ReplConn, {Conn, Info}) -> case bson:at (ismaster, Info) of
{} -> throw ({no_primary, {Conn, Info}}) end end.
-spec secondary_ok_conn (rs_connection(), [host()]) -> connection(). % EIO
-% Return connection to a live secondaries in replica set, or primary if none
+%@doc Return connection to a live secondaries in replica set, or primary if none
secondary_ok_conn (ReplConn, Hosts) -> try
until_success (Hosts, fun (Host) ->
{Conn, Info} = connect_member (ReplConn, Host),
@@ -99,7 +99,7 @@ secondary_ok_conn (ReplConn, Hosts) -> try
catch _ -> primary_conn (2, ReplConn, fetch_member_info (ReplConn)) end.
-spec fetch_member_info (rs_connection()) -> member_info(). % EIO
-% Retrieve isMaster info from a current known member in replica set. Update known list of members from fetched info.
+%@doc Retrieve isMaster info from a current known member in replica set. Update known list of members from fetched info.
fetch_member_info (ReplConn = {rs_connection, _ReplName, VConns}) ->
OldHosts_ = dict:fetch_keys (mvar:read (VConns)),
{Conn, Info} = until_success (OldHosts_, fun (Host) -> connect_member (ReplConn, Host) end),
@@ -126,7 +126,7 @@ remove_host (Host, Dict) ->
Dict1.
-spec connect_member (rs_connection(), host()) -> member_info(). % EIO
-% Connect to host and verify membership. Cache connection in rs_connection
+%@doc Connect to host and verify membership. Cache connection in rs_connection
connect_member ({rs_connection, ReplName, VConns}, Host) ->
Conn = get_connection (VConns, Host),
Info = try get_member_info (Conn) catch _ ->
View
10 src/mongodb_app.erl
@@ -1,4 +1,4 @@
-%% Init some internal global variables used by mongodb app
+%@doc Init some internal global variables used by mongodb app
-module (mongodb_app).
-behaviour (application).
@@ -17,7 +17,7 @@ stop (_) -> ok.
%% Supervisor callbacks
-%% Create global vars which will be owned by this supervisor (and die with it)
+%@doc Create global vars which will be owned by this supervisor (and die with it)
init ([]) ->
ets:new (?MODULE, [named_table, public]),
ets:insert (?MODULE, [
@@ -29,11 +29,11 @@ init ([]) ->
%% API functions
-spec next_requestid () -> mongo_protocol:requestid(). % IO
-% Fresh request id
+%@doc Fresh request id
next_requestid() -> ets:update_counter (?MODULE, requestid_counter, 1).
-spec gen_objectid () -> bson:objectid(). % IO
-% Fresh object id
+%@doc Fresh object id
gen_objectid() ->
Now = bson:unixtime_to_secs (bson:timenow()),
MPid = ets:lookup_element (?MODULE, oid_machineprocid, 2),
@@ -41,7 +41,7 @@ gen_objectid() ->
bson:objectid (Now, MPid, N).
-spec oid_machineprocid () -> <<_:40>>. % IO
-% Fetch hostname and os pid and compress into a 5 byte id
+%@doc Fetch hostname and os pid and compress into a 5 byte id
oid_machineprocid() ->
OSPid = list_to_integer (os:getpid()),
{ok, Hostname} = inet:gethostname(),
View
4 src/mongodb_tests.erl
@@ -1,6 +1,6 @@
-% Unit tests.
+%@doc Unit tests.
% For test1 to work, a mongodb server must be listening on 127.0.0.1:27017.
-% For test2 to work, a mongodb replica set must be listening on 127.0.0.1:27017 & 127.0.0.1:27018.
+% For test2 to work, a mongodb replica set must be listening on 127.0.0.1:27017 and 127.0.0.1:27018.
-module(mongodb_tests).
-include_lib("eunit/include/eunit.hrl").
View
22 src/mvar.erl
@@ -1,4 +1,4 @@
-% A mvar is a process that holds a value (its content) and provides exclusive access to it. When a mvar terminates it executes it given finalize procedure, which is needed for content that needs to clean up when terminating. When a mvar is created it executes its supplied initialize procedure, which creates the initial content from within the mvar process so if the initial content is another linked dependent process (such as a socket) it will terminate when the mvar terminates without the need for a finalizer. A mvar itself dependently links to its parent process (the process that created it) and thus terminates when its parent process terminates.
+%@doc A mvar is a process that holds a value (its content) and provides exclusive access to it. When a mvar terminates it executes it given finalize procedure, which is needed for content that needs to clean up when terminating. When a mvar is created it executes its supplied initialize procedure, which creates the initial content from within the mvar process so if the initial content is another linked dependent process (such as a socket) it will terminate when the mvar terminates without the need for a finalizer. A mvar itself dependently links to its parent process (the process that created it) and thus terminates when its parent process terminates.
-module (mvar).
-export_type ([mvar/1]).
@@ -18,7 +18,7 @@
% Closes supplied value. Any exception will not be caught causing an exit signal to be sent to parent (creating) process.
-spec create (initializer(A), finalizer(A)) -> mvar(A). % IO throws X
-% Create new mvar with initial content created from initializer (run within new mvar process so it owns it). Any throw in initializer will be caught and re-thrown in the calling process. Other exceptions will not be caught causing an exit signal to be sent to calling process. When the mvar terminates then given finalizer will be executed against current content. Any exception raised in finalizer (when terminating) will be sent as an exit signal to the parent (calling) process.
+%@doc Create new mvar with initial content created from initializer (run within new mvar process so it owns it). Any throw in initializer will be caught and re-thrown in the calling process. Other exceptions will not be caught causing an exit signal to be sent to calling process. When the mvar terminates then given finalizer will be executed against current content. Any exception raised in finalizer (when terminating) will be sent as an exit signal to the parent (calling) process.
create (Initialize, Finalize) ->
Ref = make_ref(),
case gen_server:start_link (?MODULE, {self(), Ref, Initialize, Finalize}, []) of
@@ -26,43 +26,43 @@ create (Initialize, Finalize) ->
ignore -> receive {mvar_init_throw, Ref, Thrown} -> throw (Thrown) end end.
-spec new (A, finalizer(A)) -> mvar(A). % IO
-% Same as `create` except initial value given directly
+%@doc Same as create/2 except initial value given directly
new (Value, Finalize) -> create (fun () -> Value end, Finalize).
-spec new (A) -> mvar(A). % IO
-% Same as `new/2` except no finalizer
+%@doc Same as new/2 except no finalizer
new (Value) -> new (Value, fun (_) -> ok end).
-type modifier(A,B) :: fun ((A) -> {A, B}). % IO throws X
-spec modify (mvar(A), modifier(A,B)) -> B. % IO throws X
-% Atomically modify content and return associated result. Any throw is caught and re-thrown in caller. Errors are not caught and will terminate var and send exit signal to parent.
+%@doc Atomically modify content and return associated result. Any throw is caught and re-thrown in caller. Errors are not caught and will terminate var and send exit signal to parent.
modify (Var, Modify) -> case gen_server:call (Var, {modify, Modify}) of
{ok, B} -> B;
{throw, Thrown} -> throw (Thrown) end.
-spec modify_ (mvar(A), fun ((A) -> A)) -> ok. % IO throws X
-% Same as modify but don't return anything
+%@doc Same as modify but don't return anything
modify_ (Var, Modify) -> modify (Var, fun (A) -> {Modify (A), ok} end).
-spec with (mvar(A), fun ((A) -> B)) -> B. % IO throws X, fun IO throws X
-% Execute Procedure with exclusive access to content but don't modify it.
+%@doc Execute Procedure with exclusive access to content but don't modify it.
with (Var, Act) -> modify (Var, fun (A) -> {A, Act (A)} end).
-spec read (mvar(A)) -> A. % IO
-% Return content
+%@doc Return content
read (Var) -> with (Var, fun (A) -> A end).
-spec write (mvar(A), A) -> A. % IO
-% Change content and return previous content
+%@doc Change content and return previous content
write (Var, Value) -> modify (Var, fun (A) -> {Value, A} end).
-spec terminate (mvar(_)) -> ok. % IO
-% Terminate mvar. Its finalizer will be executed. Future accesses to this mvar will fail, although repeated termination is fine.
+%@doc Terminate mvar. Its finalizer will be executed. Future accesses to this mvar will fail, although repeated termination is fine.
terminate (Var) -> catch gen_server:call (Var, stop), ok.
-spec is_terminated (mvar(_)) -> boolean(). % IO
-% Has mvar been terminated?
+%@doc Has mvar been terminated?
is_terminated (Var) -> not is_process_alive (Var).
% gen_server callbacks %
View
12 src/pool.erl
@@ -1,4 +1,4 @@
-%% A set of N resources handed out randomly, and recreated on expiration
+%@doc A set of N resources handed out randomly, and recreated on expiration
-module (pool).
-export_type ([factory/1, create/1, expire/1, is_expired/1]).
@@ -9,7 +9,7 @@
-type err_or(A) :: {ok, A} | {error, any()}.
-spec trans_error (fun (() -> err_or(A))) -> A. % IO throws any()
-% Convert error return to throw
+%@doc Convert error return to throw
trans_error (Act) -> case Act() of {ok, A} -> A; {error, Reason} -> throw (Reason) end.
-type factory(A) :: {any(), create(A), expire(A), is_expired(A)}.
@@ -23,11 +23,11 @@ trans_error (Act) -> case Act() of {ok, A} -> A; {error, Reason} -> throw (Reaso
% Pool of N resources of type A, created on demand, recreated on expiration, and handed out randomly
-spec new (factory(A), integer()) -> pool(A).
-% Create empty pool that will create and destroy resources using given factory and allow up to N resources at once
+%@doc Create empty pool that will create and destroy resources using given factory and allow up to N resources at once
new (Factory, MaxSize) -> {Factory, mvar:new (array:new (MaxSize, [{fixed, false}, {default, {}}]))}.
-spec get (pool(A)) -> err_or(A). % IO
-% Return a random resource from the pool, creating one if necessary. Error if failed to create
+%@doc Return a random resource from the pool, creating one if necessary. Error if failed to create
get ({{Input,Create,_,IsExpired}, VResources}) ->
New = fun (Array, I) -> Res = trans_error (fun () -> Create (Input) end), {array:set (I, {Res}, Array), Res} end,
Check = fun (Array, I, Res) -> case IsExpired (Res) of true -> New (Array, I); false -> {Array, Res} end end,
@@ -40,12 +40,12 @@ get ({{Input,Create,_,IsExpired}, VResources}) ->
catch Reason -> {error, Reason} end.
-spec close (pool(_)) -> ok. % IO
-% Close pool and all its resources
+%@doc Close pool and all its resources
close ({{_,_,Expire,_}, VResources}) ->
mvar:with (VResources, fun (Array) ->
array:map (fun (_I, MRes) -> case MRes of {Res} -> Expire (Res); {} -> ok end end, Array) end),
mvar:terminate (VResources).
-spec is_closed (pool(_)) -> boolean(). % IO
-% Has pool been closed?
+%@doc Has pool been closed?
is_closed ({_, VResources}) -> mvar:is_terminated (VResources).
Please sign in to comment.
Something went wrong with that request. Please try again.