summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul J. Davis <paul.joseph.davis@gmail.com>2019-03-26 17:51:18 -0500
committerPaul J. Davis <paul.joseph.davis@gmail.com>2019-03-26 17:51:18 -0500
commit971bb98989c7226bb96f38e13cb4a61acbbb12d2 (patch)
tree5c08e6a5d0a6fe439a9ddec79e8cac348823371a
parent628795ab535e05531fd35db29564979284184b2f (diff)
downloadcouchdb-971bb98989c7226bb96f38e13cb4a61acbbb12d2.tar.gz
Bug fixes
-rw-r--r--FDB_NOTES.md3
-rw-r--r--src/chttpd/src/chttpd_auth_request.erl6
-rw-r--r--src/chttpd/src/chttpd_db.erl64
-rw-r--r--src/fabric/src/fabric2_db.erl85
-rw-r--r--src/fabric/src/fabric2_fdb.erl48
-rw-r--r--src/fabric/src/fabric2_server.erl6
6 files changed, 102 insertions, 110 deletions
diff --git a/FDB_NOTES.md b/FDB_NOTES.md
index 62faf651f..86fec262d 100644
--- a/FDB_NOTES.md
+++ b/FDB_NOTES.md
@@ -55,4 +55,5 @@ Things of Note
would require us having the entire FDI, however it'd be wasteful to return
all of that in an open_revs call, but bug compatibility ftw!)
-12. \ No newline at end of file
+12. Is it possible that a server_admin can delete a db without being able
+ to open it? If so that's probably changed behavior. \ No newline at end of file
diff --git a/src/chttpd/src/chttpd_auth_request.erl b/src/chttpd/src/chttpd_auth_request.erl
index c9ca18d70..77a800500 100644
--- a/src/chttpd/src/chttpd_auth_request.erl
+++ b/src/chttpd/src/chttpd_auth_request.erl
@@ -101,7 +101,8 @@ server_authorization_check(#httpd{path_parts=[<<"_", _/binary>>|_]}=Req) ->
require_admin(Req).
db_authorization_check(#httpd{path_parts=[DbName|_],user_ctx=Ctx}=Req) ->
- fabric_security:check_is_member(DbName, Ctx),
+ {ok, Db} = fabric2_db:open(DbName, [{user_ctx, Ctx}]),
+ fabric2_db:check_is_member(Db),
Req.
require_admin(Req) ->
@@ -109,7 +110,8 @@ require_admin(Req) ->
Req.
require_db_admin(#httpd{path_parts=[DbName|_],user_ctx=Ctx}=Req) ->
- Sec = fabric2:get_security(DbName),
+ {ok, Db} = fabric2_db:open(DbName, [{user_ctx, Ctx}]),
+ Sec = fabric2_db:get_security(Db),
case is_db_admin(Ctx,Sec) of
true -> Req;
false -> throw({unauthorized, <<"You are not a server or db admin.">>})
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index bf7b8691e..4c2e33eae 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -351,8 +351,8 @@ handle_design_info_req(Req, _Db, _DDoc) ->
create_db_req(#httpd{}=Req, DbName) ->
couch_httpd:verify_is_server_admin(Req),
DocUrl = absolute_uri(Req, "/" ++ couch_util:url_encode(DbName)),
- case fabric2:create_db(DbName) of
- ok ->
+ case fabric2_db:create(DbName, []) of
+ {ok, _} ->
send_json(Req, 201, [{"Location", DocUrl}], {[{ok, true}]});
{error, file_exists} ->
chttpd:send_error(Req, file_exists);
@@ -362,7 +362,7 @@ create_db_req(#httpd{}=Req, DbName) ->
delete_db_req(#httpd{}=Req, DbName) ->
couch_httpd:verify_is_server_admin(Req),
- case fabric2:delete_db(DbName, []) of
+ case fabric2_db:delete(DbName, []) of
ok ->
send_json(Req, 200, {[{ok, true}]});
Error ->
@@ -370,13 +370,13 @@ delete_db_req(#httpd{}=Req, DbName) ->
end.
do_db_req(#httpd{path_parts=[DbName|_], user_ctx=Ctx}=Req, Fun) ->
- Db = fabric2:open_db(DbName, [{user_ctx, Ctx}]),
+ {ok, Db} = fabric2_db:open(DbName, [{user_ctx, Ctx}]),
Fun(Req, Db).
db_req(#httpd{method='GET',path_parts=[DbName]}=Req, Db) ->
% measure the time required to generate the etag, see if it's worth it
T0 = os:timestamp(),
- {ok, DbInfo} = fabric2:get_db_info(Db),
+ {ok, DbInfo} = fabric2_db:get_db_info(Db),
DeltaT = timer:now_diff(os:timestamp(), T0) / 1000,
couch_stats:update_histogram([couchdb, dbinfo], DeltaT),
send_json(Req, {DbInfo});
@@ -399,7 +399,7 @@ db_req(#httpd{method='POST', path_parts=[DbName], user_ctx=Ctx}=Req, Db) ->
"ok" ->
% async_batching
spawn(fun() ->
- case catch(fabric2:update_doc(Db, Doc2, Options)) of
+ case catch(fabric2_db:update_doc(Db, Doc2, Options)) of
{ok, _} ->
chttpd_stats:incr_writes(),
ok;
@@ -419,7 +419,7 @@ db_req(#httpd{method='POST', path_parts=[DbName], user_ctx=Ctx}=Req, Db) ->
% normal
DocUrl = absolute_uri(Req, [$/, couch_util:url_encode(DbName),
$/, couch_util:url_encode(DocId)]),
- case fabric2:update_doc(Db, Doc2, Options) of
+ case fabric2_db:update_doc(Db, Doc2, Options) of
{ok, NewRev} ->
chttpd_stats:incr_writes(),
HttpCode = 201;
@@ -494,7 +494,7 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>], user_ctx=Ctx}=Req,
true -> [all_or_nothing|Options];
_ -> Options
end,
- case fabric2:update_docs(Db, Docs, Options2) of
+ case fabric2_db:update_docs(Db, Docs, Options2) of
{ok, Results} ->
% output the results
chttpd_stats:incr_writes(length(Results)),
@@ -513,7 +513,7 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>], user_ctx=Ctx}=Req,
send_json(Req, 417, ErrorsJson)
end;
false ->
- case fabric2:update_docs(Db, Docs, [replicated_changes|Options]) of
+ case fabric2_db:update_docs(Db, Docs, [replicated_changes|Options]) of
{ok, Errors} ->
chttpd_stats:incr_writes(length(Docs)),
ErrorsJson = lists:map(fun update_doc_result_to_json/1, Errors),
@@ -877,7 +877,7 @@ db_doc_req(#httpd{method='GET', mochi_req=MochiReq}=Req, Db, DocId) ->
Doc = couch_doc_open(Db, DocId, Rev, Options2),
send_doc(Req, Doc, Options2);
_ ->
- case fabric2:open_revs(Db, DocId, Revs, Options) of
+ case fabric2_db:open_revs(Db, DocId, Revs, Options) of
{ok, []} when Revs == all ->
chttpd:send_error(Req, {not_found, missing});
{ok, Results} ->
@@ -928,7 +928,7 @@ db_doc_req(#httpd{method='POST', user_ctx=Ctx}=Req, Db, DocId) ->
Doc = couch_doc_from_req(Req, Db, DocId, Json);
false ->
Rev = couch_doc:parse_rev(list_to_binary(couch_util:get_value("_rev", Form))),
- Doc = case fabric2:open_revs(Db, DocId, [Rev], []) of
+ Doc = case fabric2_db:open_revs(Db, DocId, [Rev], []) of
{ok, [{ok, Doc0}]} ->
chttpd_stats:incr_reads(),
Doc0;
@@ -957,7 +957,7 @@ db_doc_req(#httpd{method='POST', user_ctx=Ctx}=Req, Db, DocId) ->
NewDoc = Doc#doc{
atts = UpdatedAtts ++ OldAtts2
},
- case fabric2:update_doc(Db, NewDoc, Options) of
+ case fabric2_db:update_doc(Db, NewDoc, Options) of
{ok, NewRev} ->
chttpd_stats:incr_writes(),
HttpCode = 201;
@@ -1006,7 +1006,7 @@ db_doc_req(#httpd{method='PUT', user_ctx=Ctx}=Req, Db, DocId) ->
Doc = couch_doc_from_req(Req, Db, DocId, chttpd:json_body(Req)),
spawn(fun() ->
- case catch(fabric2:update_doc(Db, Doc, Options)) of
+ case catch(fabric2_db:update_doc(Db, Doc, Options)) of
{ok, _} ->
chttpd_stats:incr_writes(),
ok;
@@ -1040,7 +1040,7 @@ db_doc_req(#httpd{method='COPY', user_ctx=Ctx}=Req, Db, SourceDocId) ->
% open old doc
Doc = couch_doc_open(Db, SourceDocId, SourceRev, []),
% save new doc
- case fabric2:update_doc(Db,
+ case fabric2_db:update_doc(Db,
Doc#doc{id=TargetDocId, revs=TargetRevs}, [{user_ctx,Ctx}]) of
{ok, NewTargetRev} ->
chttpd_stats:incr_writes(),
@@ -1263,31 +1263,7 @@ http_code_from_status(Status) ->
end.
update_doc(Db, DocId, #doc{deleted=Deleted, body=DocBody}=Doc, Options) ->
- {_, Ref} = spawn_monitor(fun() ->
- try fabric2:update_doc(Db, Doc, Options) of
- Resp ->
- exit({exit_ok, Resp})
- catch
- throw:Reason ->
- exit({exit_throw, Reason});
- error:Reason ->
- exit({exit_error, Reason});
- exit:Reason ->
- exit({exit_exit, Reason})
- end
- end),
- Result = receive
- {'DOWN', Ref, _, _, {exit_ok, Ret}} ->
- Ret;
- {'DOWN', Ref, _, _, {exit_throw, Reason}} ->
- throw(Reason);
- {'DOWN', Ref, _, _, {exit_error, Reason}} ->
- erlang:error(Reason);
- {'DOWN', Ref, _, _, {exit_exit, Reason}} ->
- erlang:exit(Reason)
- end,
-
- case Result of
+ case fabric2_db:update_doc(Db, Doc, Options) of
{ok, NewRev} ->
Accepted = false;
{accepted, NewRev} ->
@@ -1345,7 +1321,7 @@ couch_doc_from_req(Req, Db, DocId, Json) ->
couch_doc_open(Db, DocId, Rev, Options) ->
case Rev of
nil -> % open most recent rev
- case fabric2:open_doc(Db, DocId, Options) of
+ case fabric2_db:open_doc(Db, DocId, Options) of
{ok, Doc} ->
chttpd_stats:incr_reads(),
Doc;
@@ -1353,7 +1329,7 @@ couch_doc_open(Db, DocId, Rev, Options) ->
throw(Error)
end;
_ -> % open a specific rev (deletions come back as stubs)
- case fabric2:open_revs(Db, DocId, [Rev], Options) of
+ case fabric2_db:open_revs(Db, DocId, [Rev], Options) of
{ok, [{ok, Doc}]} ->
chttpd_stats:incr_reads(),
Doc;
@@ -1529,7 +1505,7 @@ db_attachment_req(#httpd{method=Method, user_ctx=Ctx}=Req, Db, DocId, FileNamePa
couch_db:validate_docid(Db, DocId),
#doc{id=DocId};
Rev ->
- case fabric2:open_revs(Db, DocId, [Rev], [{user_ctx,Ctx}]) of
+ case fabric2_db:open_revs(Db, DocId, [Rev], [{user_ctx,Ctx}]) of
{ok, [{ok, Doc0}]} ->
chttpd_stats:incr_reads(),
Doc0;
@@ -1545,7 +1521,7 @@ db_attachment_req(#httpd{method=Method, user_ctx=Ctx}=Req, Db, DocId, FileNamePa
atts = NewAtt ++ [A || A <- Atts, couch_att:fetch(name, A) /= FileName]
},
W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))),
- case fabric2:update_doc(Db, DocEdited, [{user_ctx,Ctx}, {w,W}]) of
+ case fabric2_db:update_doc(Db, DocEdited, [{user_ctx,Ctx}, {w,W}]) of
{ok, UpdatedRev} ->
chttpd_stats:incr_writes(),
HttpCode = 201;
@@ -1901,7 +1877,7 @@ bulk_get_open_doc_revs1(Db, Props, Options, {DocId, Revs}) ->
bulk_get_open_doc_revs1(Db, Props, Options, {DocId, Revs, Options1})
end;
bulk_get_open_doc_revs1(Db, Props, _, {DocId, Revs, Options}) ->
- case fabric2:open_revs(Db, DocId, Revs, Options) of
+ case fabric2_db:open_revs(Db, DocId, Revs, Options) of
{ok, []} ->
RevStr = couch_util:get_value(<<"rev">>, Props),
Error = {RevStr, <<"not_found">>, <<"missing">>},
diff --git a/src/fabric/src/fabric2_db.erl b/src/fabric/src/fabric2_db.erl
index d172209bd..88f6bd953 100644
--- a/src/fabric/src/fabric2_db.erl
+++ b/src/fabric/src/fabric2_db.erl
@@ -124,7 +124,7 @@
-include_lib("couch/include/couch_db.hrl").
--include_lib("fabric/include/fabric2.hrl").
+-include("fabric2.hrl").
-define(DBNAME_REGEX,
@@ -138,18 +138,19 @@
create(DbName, Options) ->
Result = transactional(DbName, Options, fun(TxDb) ->
- case fabric2_fdb:db_exists(TxDb) of
+ case fabric2_fdb:exists(TxDb) of
true ->
{error, file_exists};
false ->
- fabric2_fdb:db_create(TxDb)
+ fabric2_fdb:create(TxDb, Options)
end
end),
% We cache outside of the transaction so that we're sure
% that this request created the database
case Result of
#{} = Db ->
- fabric2_server:store(Db);
+ ok = fabric2_server:store(Db),
+ {ok, Db#{tx => undefined}};
Error ->
Error
end.
@@ -159,27 +160,29 @@ open(DbName, Options) ->
case fabric2_server:fetch(DbName) of
#{} = Db ->
with_tx(Db, fun(TxDb) ->
- case fabric2_fdb:db_is_current(TxDb) of
+ case fabric2_fdb:is_current(TxDb) of
true ->
- Db;
+ {ok, maybe_set_user_ctx(Db, Options)};
false ->
- Reopened = fabric2_fdb:db_open(TxDb),
- fabric2_server:store(Reopened)
+ Reopened = fabric2_fdb:open(TxDb, Options),
+ ok = fabric2_server:store(Reopened),
+ {ok, Reopened}
end
end);
undefined ->
transactional(DbName, Options, fun(TxDb) ->
- Opened = fabric2_fdb:db_open(TxDb),
- fabric2_server:store(Opened)
+ Opened = fabric2_fdb:open(TxDb, Options),
+ ok = fabric2_server:store(Opened),
+ {ok, Opened#{tx => undefined}}
end)
end.
delete(DbName, Options) ->
% This will throw if the db does not exist
- Db = open(DbName, Options),
+ {ok, Db} = open(DbName, Options),
with_tx(Db, fun(TxDb) ->
- fabric2_fdb:db_delete(TxDb)
+ fabric2_fdb:delete(TxDb)
end).
@@ -237,7 +240,7 @@ get_compactor_pid(#{} = _Db) ->
get_db_info(#{} = Db) ->
DbProps = with_tx(Db, fun(TxDb) ->
- fabric2_fdb:db_get_info(TxDb)
+ fabric2_fdb:get_info(TxDb)
end),
BaseProps = [
@@ -296,7 +299,7 @@ get_security(#{security_doc := SecurityDoc}) ->
get_update_seq(#{} = Db) ->
- case fabric2_fdb:db_get_changes(Db, [{limit, 1}, {reverse, true}]) of
+ case fabric2_fdb:get_changes(Db, [{limit, 1}, {reverse, true}]) of
[] ->
fabric2_util:to_hex(<<0:80>>);
[{Seq, _}] ->
@@ -346,14 +349,14 @@ is_system_db_name(DbName) when is_binary(DbName) ->
set_revs_limit(#{} = Db, RevsLimit) ->
RevsLimBin = ?uint2bin(RevsLimit),
with_tx(Db, fun(TxDb) ->
- fabric2_fdb:db_set_config(TxDb, <<"revs_limit">>, RevsLimBin)
+ fabric2_fdb:set_config(TxDb, <<"revs_limit">>, RevsLimBin)
end).
set_security(#{} = Db, Security) ->
SecBin = ?JSON_ENCODE(Security),
with_tx(Db, fun(TxDb) ->
- fabric2_fdb:db_set_config(TxDb, <<"security_doc">>, SecBin)
+ fabric2_fdb:set_config(TxDb, <<"security_doc">>, SecBin)
end).
@@ -388,36 +391,35 @@ open_doc(#{} = Db, DocId, _Options) ->
end).
-open_doc_revs(Db, FDI, Revs, Options) ->
- #full_doc_info{
- id = Id,
- rev_tree = RevTree
- } = FDI,
+open_doc_revs(Db, DocId, Revs, Options) ->
Latest = lists:member(latest, Options),
- {Found, Missing} = case Revs of
- all ->
- {couch_key_tree:get_all_leafs(RevTree), []};
- _ when Latest ->
- couch_key_tree:get_key_leafs(RevTree, Revs);
- _ ->
- couch_key_tree:get(RevTree, Revs)
- end,
- Docs = with_tx(Db, fun(TxDb) ->
- lists:map(fun({Value, {Pos, [Rev | _]} = RevPath}) ->
+ with_tx(Db, fun(TxDb) ->
+ #full_doc_info{
+ rev_tree = RevTree
+ } = fabric2_db:get_full_doc_info(TxDb, DocId),
+ {Found, Missing} = case Revs of
+ all ->
+ {couch_key_tree:get_all_leafs(RevTree), []};
+ _ when Latest ->
+ couch_key_tree:get_key_leafs(RevTree, Revs);
+ _ ->
+ couch_key_tree:get(RevTree, Revs)
+ end,
+ Docs = lists:map(fun({Value, {Pos, [Rev | _]} = RevPath}) ->
case Value of
?REV_MISSING ->
% We have the rev in our list but know nothing about it
{{not_found, missing}, {Pos, Rev}};
_ ->
- case fabric2_fdb:get_doc_body(TxDb, Id, RevPath) of
+ case fabric2_fdb:get_doc_body(TxDb, DocId, RevPath) of
#doc{} = Doc -> {ok, Doc};
Else -> {Else, {Pos, Rev}}
end
end
- end, Found)
- end),
- MissingDocs = [{{not_found, missing}, MRev} || MRev <- Missing],
- {ok, Docs ++ MissingDocs}.
+ end, Found),
+ MissingDocs = [{{not_found, missing}, MRev} || MRev <- Missing],
+ {ok, Docs ++ MissingDocs}
+ end).
update_doc(Db, Doc) ->
@@ -477,6 +479,15 @@ new_revid(Doc) ->
Doc#doc{revs = {OldStart + 1, [Rev | OldRevs]}}.
+maybe_set_user_ctx(Db, Options) ->
+ case fabric2_util:get_value(user_ctx, Options) of
+ #user_ctx{} = UserCtx ->
+ set_user_ctx(Db, UserCtx);
+ undefined ->
+ Db
+ end.
+
+
is_member(Db) ->
{SecProps} = get_security(Db),
case is_admin(Db) of
@@ -589,7 +600,7 @@ update_doc_int(#{} = Db, #doc{} = Doc0, Options) ->
end,
NewExists = not FDI3#full_doc_info.deleted,
- ok = fabric2_fdb:write_doc(Db, FDI3, Doc3),
+ ok = fabric2_fdb:store_doc(Db, FDI3, Doc3),
case {OldExists, NewExists} of
{false, true} ->
diff --git a/src/fabric/src/fabric2_fdb.erl b/src/fabric/src/fabric2_fdb.erl
index e5bd81a63..68d148ea0 100644
--- a/src/fabric/src/fabric2_fdb.erl
+++ b/src/fabric/src/fabric2_fdb.erl
@@ -16,8 +16,8 @@
-export([
init/3,
- create/1,
- open/1,
+ create/2,
+ open/2,
delete/1,
exists/1,
is_current/1,
@@ -71,15 +71,15 @@
% Various utility macros
--define(REQUIRE_TX(Db), {erlfdb_transaction, _} = maps:get(Db, tx)).
+-define(REQUIRE_TX(Db), {erlfdb_transaction, _} = maps:get(tx, Db)).
-define(REQUIRE_CURRENT(Db), true = is_current(Db)).
-define(UNSET_VS, {versionstamp, 16#FFFFFFFFFFFFFFFF, 16#FFFF}).
init(Tx, DbName, Options) ->
- Root = erlfdb_directory:get_root(),
- CouchDB = erlfdb_directory:create_or_open(Root, [<<"couchdb">>]),
+ Root = erlfdb_directory:root(),
+ CouchDB = erlfdb_directory:create_or_open(Tx, Root, [<<"couchdb">>]),
Prefix = erlfdb_directory:get_name(CouchDB),
#{
name => DbName,
@@ -89,7 +89,7 @@ init(Tx, DbName, Options) ->
}.
-create(#{} = Db) ->
+create(#{} = Db, Options) ->
?REQUIRE_TX(Db),
#{
name := DbName,
@@ -120,17 +120,18 @@ create(#{} = Db) ->
erlfdb:set(Tx, Key, V)
end, Defaults),
+ UserCtx = fabric2_util:get_value(user_ctx, Options, #user_ctx{}),
Version = erlfdb:wait(erlfdb:get(Tx, ?METADATA_VERSION_KEY)),
Db#{
uuid => UUID,
db_prefix => DbPrefix,
- version => Version,
+ md_version => Version,
revs_limit => 1000,
security_doc => {[]},
validate_doc_update_funs => [],
- user_ctx => #user_ctx{},
+ user_ctx => UserCtx,
before_doc_update => undefined,
after_doc_update => undefined
@@ -138,7 +139,7 @@ create(#{} = Db) ->
}.
-open(#{} = Db0) ->
+open(#{} = Db0, Options) ->
?REQUIRE_TX(Db0),
#{
name := DbName,
@@ -152,13 +153,14 @@ open(#{} = Db0) ->
not_found -> erlang:error(database_does_not_exist)
end,
+ UserCtx = fabric2_util:get_value(user_ctx, Options, #user_ctx{}),
Version = erlfdb:wait(erlfdb:get(Tx, ?METADATA_VERSION_KEY)),
Db1 = Db0#{
- db_preix => DbPrefix,
- version => Version,
+ db_prefix => DbPrefix,
+ md_version => Version,
- user_ctx => #user_ctx{},
+ user_ctx => UserCtx,
% Place holders until we implement these
% bits.
@@ -167,14 +169,14 @@ open(#{} = Db0) ->
after_doc_read => undefined
},
- lists:foldl(fun({Key, Val}) ->
+ lists:foldl(fun({Key, Val}, DbAcc) ->
case Key of
<<"uuid">> ->
- Db1#{uuid => Val};
+ DbAcc#{uuid => Val};
<<"revs_limit">> ->
- Db1#{revs_limit => ?bin2uint(Val)};
+ DbAcc#{revs_limit => ?bin2uint(Val)};
<<"security_doc">> ->
- Db1#{security_doc => ?JSON_DECODE(Val)}
+ DbAcc#{security_doc => ?JSON_DECODE(Val)}
end
end, Db1, get_config(Db1)).
@@ -188,10 +190,10 @@ delete(#{} = Db) ->
db_prefix := DbPrefix
} = Db,
- DbKey = erlfdb_tuple:pack({?DBS, DbName}, LayerPrefix),
+ DbKey = erlfdb_tuple:pack({?ALL_DBS, DbName}, LayerPrefix),
erlfdb:clear(Tx, DbKey),
erlfdb:clear_range_startswith(Tx, DbPrefix),
- bump_metadata_version(Db),
+ bump_metadata_version(Tx),
ok.
@@ -229,14 +231,14 @@ get_info(#{} = Db) ->
db_prefix := DbPrefix
} = Db,
- {CStart, CEnd} = erlfdb_tuple:pack({?DB_CHANGES}, DbPrefix),
+ {CStart, CEnd} = erlfdb_tuple:range({?DB_CHANGES}, DbPrefix),
ChangesFuture = erlfdb:get_range(Tx, CStart, CEnd, [
{streaming_mode, exact},
{limit, 1},
{reverse, true}
]),
- StatsPrefix = erlfdb_tuple:pack(?DB_STATS, DbPrefix),
+ StatsPrefix = erlfdb_tuple:pack({?DB_STATS}, DbPrefix),
MetaFuture = erlfdb:get_range_startswith(Tx, StatsPrefix),
RawSeq = case erlfdb:wait(ChangesFuture) of
@@ -279,10 +281,10 @@ get_config(#{} = Db) ->
db_prefix := DbPrefix
} = Db,
- {Start, End} = erlfdb_tuple:pack({?DB_CONFIG}, DbPrefix),
+ {Start, End} = erlfdb_tuple:range({?DB_CONFIG}, DbPrefix),
Future = erlfdb:get_range(Tx, Start, End),
- lists:map(fun(K, V) ->
+ lists:map(fun({K, V}) ->
{?DB_CONFIG, Key} = erlfdb_tuple:unpack(K, DbPrefix),
{Key, V}
end, erlfdb:wait(Future)).
@@ -389,7 +391,7 @@ get_changes(#{} = Db, Options) ->
db_prefix := DbPrefix
} = Db,
- {CStart, CEnd} = erlfdb_tuple:pack({?DB_CHANGES}, DbPrefix),
+ {CStart, CEnd} = erlfdb_tuple:range({?DB_CHANGES}, DbPrefix),
Future = erlfdb:get_range(Tx, CStart, CEnd, Options),
lists:map(fun({Key, Val}) ->
{?DB_CHANGES, Seq} = erlfdb_tuple:unpack(Key, DbPrefix),
diff --git a/src/fabric/src/fabric2_server.erl b/src/fabric/src/fabric2_server.erl
index 9a0e4fac2..1e086ca99 100644
--- a/src/fabric/src/fabric2_server.erl
+++ b/src/fabric/src/fabric2_server.erl
@@ -51,11 +51,11 @@ fetch(DbName) when is_binary(DbName) ->
store(#{name := DbName} = Db0) when is_binary(DbName) ->
Db1 = Db0#{
- tx => undefined,
- user_ctx => #user_ctx{}
+ tx := undefined,
+ user_ctx := #user_ctx{}
},
true = ets:insert(?MODULE, {DbName, Db1}),
- Db1.
+ ok.
init(_) ->