benoitc / couchbeam

Apache CouchDB client in Erlang
Other
242 stars 113 forks source link

Does it make sense to have options in view and db record? #38

Closed nougad closed 13 years ago

nougad commented 13 years ago

Hi, I open a new server with:

Server = couchbeam:server_connection("localhost", 54994, "", [{basic_auth, {"user", "password"}}]),

then I want the database: {ok, Db} = couchbeam:open_or_create_db(Server, "dbname").

This creates a new database with the auth options in Server. But It saves the empty Options into the #db record:

open_or_create_db(Server, DbName) ->
    open_or_create_db(Server, DbName, [], []).   <<< use empty options

open_or_create_db(#server{options=IbrowseOpts}=Server, DbName, Options, Params) ->
    Url = make_url(Server, DbName, []),
    case request(get, Url, ["200"], IbrowseOpts) of   <<<< Use Options from Server
        {ok, _, _, _} ->
            open_db(Server, DbName, Options);    <<<< copy empty Options
        {error, {ok, "404", _, _}} ->
            create_db(Server, DbName, Options, Params);
        Error ->
            Error
    end.

The Db record with Server and empty options:

{db,{server,"localhost",54994,false,[],
            [{basic_auth,{"user","password"}}]},  <<< options in server
    "dbname",[]}     <<<< empty options

If I try to get db_info from this DB I get an 401 because db_info uses the empty options from db-Record:

db_info(#db{server=Server, name=DbName, options=IbrowseOpts}) ->
    Url = make_url(Server, DbName, []),
    case request(get, Url, ["200"], IbrowseOpts) of  <<<<< Use Empty Options
        {ok, _Status, _Headers, Body} ->
            Infos = couchbeam_util:json_decode(Body),
            {ok, Infos}; 
        {error, {ok, "404", _, _}} ->
            {error, db_not_found};
       Error ->
          Error
    end.

A workaround is to copy all options on every db/view manually:

Server = couchbeam:server_connection("localhost", 54994, "", [{basic_auth, {"user", "password"}}]),
couchbeam:open_or_create_db(Server, "dbname", [{basic_auth, {"user", "password"}}]).

But I expect couchbeam does this for me. One solution is to use always the options in server. For example:

db_info(#db{#server{options=IbrowseOpts}=Server, name=DbName) ->

instead of:

db_info(#db{server=Server, name=DbName, options=IbrowseOpts}) ->

But perhaps it is useful sometimes to have different options in db/view. Then the options must be redundant in server and db/view. But it should copied automatically in all related methods. For example:

open_or_create_db(#server{options=Options}=Server, DbName) ->
    open_or_create_db(Server, DbName, Options, []). <<< copied options from server instead of create empty options

Instead of open_or_create_db method above. If you tell me your preferences I can make you a patch.

benoitc commented 13 years ago

You right. Fixed in last head . Now Server and Database options are merged. If an options is set in Database, its value will be use in place of the Server one.

Ex.:

1> couchbeam:start().
2> S = couchbeam:server_connection("localhost", 5984, "", [{basic_auth, {"guest", "test"}}]).
{server,"localhost",5984,false,[],
        [{basic_auth,{"guest","test"}}]}
3> {ok, Db} = couchbeam:open_db(S, "testdb").
{ok,{db,{server,"localhost",5984,false,[],
                [{basic_auth,{"guest","test"}}]},
        "testdb",
        [{basic_auth,{"guest","test"}}]}}
4> {ok, Db1} = couchbeam:open_db(S, "testdb", [{basic_auth, {"guest1", "test"}}]).
{ok,{db,{server,"localhost",5984,false,[],
                [{basic_auth,{"benoitc","test"}}]},
        "testdb",
        [{basic_auth,{"guest1","test"}}]}}

It's also useful when you set proxy or ssl infos.