diff options
Diffstat (limited to 'src/mem3/src/mem3_util.erl')
-rw-r--r-- | src/mem3/src/mem3_util.erl | 64 |
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}) |