summaryrefslogtreecommitdiff
path: root/src/mem3/src/mem3_util.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mem3/src/mem3_util.erl')
-rw-r--r--src/mem3/src/mem3_util.erl64
1 files changed, 57 insertions, 7 deletions
diff --git a/src/mem3/src/mem3_util.erl b/src/mem3/src/mem3_util.erl
index 28cb17778..005a6b1bc 100644
--- a/src/mem3/src/mem3_util.erl
+++ b/src/mem3/src/mem3_util.erl
@@ -14,7 +14,8 @@
-export([name_shard/2, create_partition_map/5, build_shards/2,
n_val/2, q_val/1, to_atom/1, to_integer/1, write_db_doc/1, delete_db_doc/1,
- shard_info/1, ensure_exists/1, open_db_doc/1, get_or_create_db/2]).
+ shard_info/1, ensure_exists/1, open_db_doc/1, update_db_doc/1]).
+-export([get_or_create_db/2, get_or_create_db_int/2]).
-export([is_deleted/1, rotate_list/2]).
-export([get_shard_opts/1, get_engine_opt/1, get_props_opt/1]).
-export([get_shard_props/1, find_dirty_shards/0]).
@@ -116,6 +117,34 @@ write_db_doc(DbName, #doc{id=Id, body=Body} = Doc, ShouldMutate) ->
couch_db:close(Db)
end.
+update_db_doc(Doc) ->
+ update_db_doc(mem3_sync:shards_db(), Doc, true).
+
+update_db_doc(DbName, #doc{id=Id, body=Body} = Doc, ShouldMutate) ->
+ {ok, Db} = couch_db:open(DbName, [?ADMIN_CTX]),
+ try couch_db:open_doc(Db, Id, [ejson_body]) of
+ {ok, #doc{body = Body}} ->
+ % the doc is already in the desired state, we're done here
+ ok;
+ {ok, #doc{body = Body1}} ->
+ % the doc has a new body to be written
+ {ok, _} = couch_db:update_doc(Db, Doc#doc{body=Body1}, []),
+ ok;
+ {not_found, _} when ShouldMutate ->
+ try couch_db:update_doc(Db, Doc, []) of
+ {ok, _} ->
+ ok
+ catch conflict ->
+ % check to see if this was a replication race or a different edit
+ update_db_doc(DbName, Doc, false)
+ end;
+ _ ->
+ % the doc already exists in a different state
+ conflict
+ after
+ couch_db:close(Db)
+ end.
+
delete_db_doc(DocId) ->
gen_server:cast(mem3_shards, {cache_remove, DocId}),
delete_db_doc(mem3_sync:shards_db(), DocId, true).
@@ -240,7 +269,7 @@ db_props_from_json([{K, V} | Rest]) ->
[{K, V} | db_props_from_json(Rest)].
n_val(undefined, NodeCount) ->
- n_val(config:get("cluster", "n", "3"), NodeCount);
+ n_val(config:get_integer("cluster", "n", 3), NodeCount);
n_val(N, NodeCount) when is_list(N) ->
n_val(list_to_integer(N), NodeCount);
n_val(N, NodeCount) when is_integer(NodeCount), N > NodeCount ->
@@ -508,18 +537,39 @@ sort_ranges_fun({B1, _}, {B2, _}) ->
B1 =< B2.
+add_db_config_options(DbName, Options) ->
+ DbOpts = case mem3:dbname(DbName) of
+ DbName -> [];
+ MDbName -> mem3_shards:opts_for_db(MDbName)
+ end,
+ merge_opts(DbOpts, Options).
+
+
get_or_create_db(DbName, Options) ->
+ case couch_db:open(DbName, Options) of
+ {ok, _} = OkDb ->
+ OkDb;
+ {not_found, no_db_file} ->
+ try
+ Options1 = [{create_if_missing, true} | Options],
+ Options2 = add_db_config_options(DbName, Options1),
+ couch_db:open(DbName, Options2)
+ catch error:database_does_not_exist ->
+ throw({error, missing_target})
+ end;
+ Else ->
+ Else
+ end.
+
+
+get_or_create_db_int(DbName, Options) ->
case couch_db:open_int(DbName, Options) of
{ok, _} = OkDb ->
OkDb;
{not_found, no_db_file} ->
try
- DbOpts = case mem3:dbname(DbName) of
- DbName -> [];
- MDbName -> mem3_shards:opts_for_db(MDbName)
- end,
Options1 = [{create_if_missing, true} | Options],
- Options2 = merge_opts(DbOpts, Options1),
+ Options2 = add_db_config_options(DbName, Options1),
couch_db:open_int(DbName, Options2)
catch error:database_does_not_exist ->
throw({error, missing_target})