Make the repo a gen_server
This helps us make sure we only have one thread accessing a particular repo at a time and hopefully help us be more in line with usual erlang practices.
This commit is contained in:
@@ -8,15 +8,15 @@
|
||||
|
||||
-export([lookup/2, id/1]).
|
||||
|
||||
-spec lookup(repo(), oid() | iolist()) -> object().
|
||||
lookup(#repo{handle=RepoHandle}, #oid{oid=Oid}) ->
|
||||
case geef:object_lookup(RepoHandle, Oid) of
|
||||
-spec lookup(pid(), oid() | iolist()) -> object().
|
||||
lookup(Repo, #oid{oid=Oid}) ->
|
||||
case geef_repo:lookup_object(Repo, Oid) of
|
||||
{ok, Type, Handle} ->
|
||||
{ok, #object{type=Type, handle=Handle}};
|
||||
Other ->
|
||||
Other
|
||||
end;
|
||||
lookup(Repo = #repo{}, Id) ->
|
||||
lookup(Repo, Id) ->
|
||||
lookup(Repo, geef_oid:parse(Id)).
|
||||
|
||||
id(#object{handle=Handle}) ->
|
||||
|
||||
@@ -1,39 +1,29 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @author Carlos Martín Nieto <cmn@dwim.me>
|
||||
%%% @copyright (C) 2013, Carlos Martín Nieto
|
||||
%%% @doc
|
||||
%%%
|
||||
%%% @end
|
||||
%%% Created : 6 Apr 2013 by Carlos Martín Nieto <cmn@dwim.me>
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(geef_repo).
|
||||
|
||||
-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1]).
|
||||
-behaviour(gen_server).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
|
||||
terminate/2, code_change/3]).
|
||||
|
||||
%% API
|
||||
-export([open/1, init/2, path/1, workdir/1, odb/1, is_bare/1, references/1, discover/1, lookup_object/2, stop/1]).
|
||||
|
||||
-include("geef_records.hrl").
|
||||
-record(state, {handle}).
|
||||
|
||||
%% @doc The repository's git-dir path
|
||||
-spec path(repo()) -> binary().
|
||||
path(#repo{handle=Handle}) ->
|
||||
geef:repository_get_path(Handle).
|
||||
|
||||
%% @doc The repository's worktree path
|
||||
-spec workdir(repo()) -> binary().
|
||||
workdir(#repo{handle=Handle}) ->
|
||||
geef:repository_get_workdir(Handle).
|
||||
|
||||
%% @doc The repository's current object database. This encompasses all
|
||||
%% the configured backends.
|
||||
-spec odb(repo()) -> {ok, odb} | {error, term}.
|
||||
odb(#repo{handle=Handle}) ->
|
||||
case geef:repository_get_odb(Handle) of
|
||||
{ok, OdbHandle} ->
|
||||
{ok, #odb{handle=OdbHandle}};
|
||||
Other ->
|
||||
Other
|
||||
end.
|
||||
|
||||
%% @doc Whether the repository is bare
|
||||
-spec is_bare(repo()) -> boolean().
|
||||
is_bare(#repo{handle=Handle}) ->
|
||||
geef:repository_is_bare(Handle).
|
||||
|
||||
%% @doc List of references in the repository.
|
||||
-spec references(repo()) -> [binary()].
|
||||
references(#repo{handle=Handle}) ->
|
||||
geef:reference_list(Handle).
|
||||
%%%===================================================================
|
||||
%%% API
|
||||
%%%===================================================================
|
||||
|
||||
%% @doc Discover a repository's path from a path contained inside it
|
||||
-spec discover(iolist()) -> {ok, binary()} | error | {error, term()}.
|
||||
@@ -46,17 +36,121 @@ discover(Path) ->
|
||||
open(Path) ->
|
||||
case geef:repository_open(Path) of
|
||||
{ok, Handle} ->
|
||||
{ok, #repo{handle=Handle}};
|
||||
start_link(Handle);
|
||||
Other ->
|
||||
Other
|
||||
end.
|
||||
|
||||
%% @doc Initialize a new repository
|
||||
-spec init(iolist(), boolean()) -> {ok, repo()} | {error, term()}.
|
||||
-spec init(iolist(), boolean()) -> {ok, pid()} | {error, term()}.
|
||||
init(Path, Bare) ->
|
||||
case geef:repository_init(Path, Bare) of
|
||||
{ok, Handle} ->
|
||||
{ok, #repo{handle=Handle}};
|
||||
start_link(Handle);
|
||||
Other ->
|
||||
Other
|
||||
end.
|
||||
|
||||
%% @doc The repository's git-dir path
|
||||
-spec path(pid()) -> binary().
|
||||
path(Pid) ->
|
||||
gen_server:call(Pid, path).
|
||||
|
||||
%% @doc The repository's worktree path
|
||||
-spec workdir(pid()) -> binary().
|
||||
workdir(Pid) ->
|
||||
gen_server:call(Pid, workdir).
|
||||
|
||||
%% @doc The repository's current object database. This encompasses all
|
||||
%% the configured backends.
|
||||
-spec odb(pid()) -> {ok, odb()} | {error, term}.
|
||||
odb(Pid) ->
|
||||
gen_server:call(Pid, odb).
|
||||
|
||||
%% @doc Whether the repository is bare
|
||||
-spec is_bare(pid()) -> boolean().
|
||||
is_bare(Pid) ->
|
||||
gen_server:call(Pid, bare).
|
||||
|
||||
%% @doc List of references in the repository.
|
||||
-spec references(pid()) -> [binary()].
|
||||
references(Pid) ->
|
||||
gen_server:call(Pid, refs).
|
||||
|
||||
lookup_object(Pid, Oid) ->
|
||||
gen_server:call(Pid, {lookup_object, Oid}).
|
||||
|
||||
stop(Pid) ->
|
||||
gen_server:call(Pid, stop).
|
||||
|
||||
%%%===================================================================
|
||||
%%% gen_server callbacks
|
||||
%%%===================================================================
|
||||
|
||||
%% @private
|
||||
init(Handle) ->
|
||||
{ok, #state{handle=Handle}}.
|
||||
|
||||
%% @private
|
||||
handle_call(path, _From, State = #state{handle=Handle}) ->
|
||||
Reply = geef:repository_get_path(Handle),
|
||||
{reply, Reply, State};
|
||||
handle_call(workdir, _From, State = #state{handle=Handle}) ->
|
||||
Reply = geef:repository_get_workdir(Handle),
|
||||
{reply, Reply, State};
|
||||
handle_call(odb, _From, State = #state{handle=Handle}) ->
|
||||
Reply = handle_odb(Handle),
|
||||
{reply, Reply, State};
|
||||
handle_call(bare, _From, State = #state{handle=Handle}) ->
|
||||
Reply = geef:repository_is_bare(Handle),
|
||||
{reply, Reply, State};
|
||||
handle_call(refs, _From, State = #state{handle=Handle}) ->
|
||||
Reply = geef:reference_list(Handle),
|
||||
{reply, Reply, State};
|
||||
handle_call({lookup_object, Oid}, _From, State = #state{handle=Handle}) ->
|
||||
Reply = geef:object_lookup(Handle, Oid),
|
||||
{reply, Reply, State};
|
||||
handle_call(stop, _From, State) ->
|
||||
{stop, normal, State};
|
||||
handle_call(_Request, _From, State) ->
|
||||
Reply = {error, "Unkown call"},
|
||||
{reply, Reply, State}.
|
||||
|
||||
%% @private
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%% @private
|
||||
terminate(_Reason, _State) ->
|
||||
ok.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% @private
|
||||
%% @doc
|
||||
%% Convert process state when code is changed
|
||||
%%
|
||||
%% @spec code_change(OldVsn, State, Extra) -> {ok, NewState}
|
||||
%% @end
|
||||
%%--------------------------------------------------------------------
|
||||
code_change(_OldVsn, State, _Extra) ->
|
||||
{ok, State}.
|
||||
|
||||
%%%===================================================================
|
||||
%%% Internal functions
|
||||
%%%==================================================================
|
||||
|
||||
-spec start_link(term()) -> {ok, pid()} | ignore | {error, term()}.
|
||||
start_link(Handle) ->
|
||||
gen_server:start_link(?MODULE, Handle, []).
|
||||
|
||||
handle_odb(Handle) ->
|
||||
case geef:repository_get_odb(Handle) of
|
||||
{ok, OdbHandle} ->
|
||||
{ok, #odb{handle=OdbHandle}};
|
||||
Other ->
|
||||
Other
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user