Add the ability to pass flags to the open_database function.

This commit is contained in:
Phillip Toland 2008-12-10 10:59:40 -06:00
parent 5b2ed7f0a1
commit c5e50712e1
3 changed files with 47 additions and 21 deletions

View file

@ -17,7 +17,7 @@
/**
* Function prototypes
*/
static int open_database(const char* name, DBTYPE type, PortData* data, int* errno);
static int open_database(const char* name, DBTYPE type, unsigned int flags, PortData* data, int* errno);
static int close_database(int dbref, PortData* data);
static void do_async_put(void* arg);
@ -79,6 +79,8 @@ static hive_hash* G_DATABASES_NAMES;
#define WRITE_LOCK(L) erl_drv_rwlock_rwlock(L)
#define WRITE_UNLOCK(L) erl_drv_rwlock_rwunlock(L)
#define DECODE_UINT(B) (unsigned int)(B[0] + (B[1] << 8) + (B[2] << 16) + (B[3] << 24))
#define RETURN_BH(bh, outbuf) *outbuf = (char*)bh.bin; return bh.bin->orig_size;
#define RETURN_INT(val, outbuf) { \
@ -206,12 +208,13 @@ static int bdberl_drv_control(ErlDrvData handle, unsigned int cmd,
case CMD_OPEN_DB:
{
// Extract the type code and filename from the inbuf
// Inbuf is: <<Type:8, Name/bytes, 0:8>>
DBTYPE type = (DBTYPE)((char)*inbuf);
char* name = (char*)(inbuf+1);
// Inbuf is: <<Flags:32, Type:8, Name/bytes, 0:8>>
unsigned int flags = DECODE_UINT(inbuf);
DBTYPE type = (DBTYPE)inbuf[4];
char* name = (char*)(inbuf+5);
int dbref;
int status;
int rc = open_database(name, type, d, &dbref);
int rc = open_database(name, type, flags, d, &dbref);
if (rc == 0)
{
status = STATUS_OK;
@ -420,7 +423,7 @@ static void bdberl_drv_process_exit(ErlDrvData handle, ErlDrvMonitor *monitor)
{
}
static int open_database(const char* name, DBTYPE type, PortData* data, int* dbref_res)
static int open_database(const char* name, DBTYPE type, unsigned int flags, PortData* data, int* dbref_res)
{
*dbref_res = -1;
@ -502,9 +505,9 @@ static int open_database(const char* name, DBTYPE type, PortData* data, int* dbr
WRITE_UNLOCK(G_DATABASES_RWLOCK);
return rc;
}
// Attempt to open our database
rc = db->open(db, 0, name, 0, type, DB_CREATE | DB_AUTO_COMMIT | DB_THREAD, 0);
rc = db->open(db, 0, name, 0, type, flags, 0);
if (rc != 0)
{
// Failure while opening the database -- cleanup the handle, drop the lock

View file

@ -7,7 +7,7 @@
-module(bdberl_port).
-export([new/0,
open_database/3,
open_database/3, open_database/4,
close_database/2,
txn_begin/1, txn_commit/1, txn_abort/1,
put/4,
@ -26,6 +26,16 @@
-define(DB_TYPE_BTREE, 1).
-define(DB_TYPE_HASH, 2).
-define(DB_AUTO_COMMIT, 16#00000100).
-define(DB_CREATE, 16#00000001).
-define(DB_EXCL, 16#00000400).
-define(DB_MULTIVERSION, 16#00000008).
-define(DB_NOMMAP, 16#00000010).
-define(DB_RDONLY, 16#00000080).
-define(DB_READ_UNCOMMITTED, 16#00000200).
-define(DB_THREAD, 16#00000004).
-define(DB_TRUNCATE, 16#00008000).
-define(STATUS_OK, 0).
-define(STATUS_ERROR, 1).
@ -44,14 +54,17 @@ new() ->
Port = open_port({spawn, bdberl_drv}, [binary]),
{ok, Port}.
open_database(Port, Name, Type) ->
open_database(Port, Name, Type, [create, auto_commit, threaded]).
open_database(Port, Name, Type, Opts) ->
%% Map database type into an integer code
case Type of
btree -> TypeCode = ?DB_TYPE_BTREE;
hash -> TypeCode = ?DB_TYPE_HASH
end,
Cmd = <<TypeCode:8/native-integer, (list_to_binary(Name))/bytes, 0:8/native-integer>>,
end,
Flags = process_flags(Opts),
Cmd = <<Flags:32/unsigned-native-integer, TypeCode:8/native-integer, (list_to_binary(Name))/bytes, 0:8/native-integer>>,
case erlang:port_control(Port, ?CMD_OPEN_DB, Cmd) of
<<?STATUS_OK:8, DbRef:32/native>> ->
{ok, DbRef};
@ -140,3 +153,19 @@ to_binary(Term) ->
Bin = term_to_binary(Term),
{size(Bin), Bin}.
process_flags([Flag]) ->
flag_value(Flag);
process_flags([Flag|Flags]) ->
flag_value(Flag) bor process_flags(Flags).
flag_value(Flag) ->
case Flag of
auto_commit -> ?DB_AUTO_COMMIT;
create -> ?DB_CREATE;
exclusive -> ?DB_EXCL;
multiversion -> ?DB_MULTIVERSION;
no_mmap -> ?DB_NOMMAP;
readonly -> ?DB_RDONLY;
threaded -> ?DB_THREAD;
truncate -> ?DB_TRUNCATE
end.

View file

@ -12,12 +12,12 @@ all() ->
% [test_db].
[test_put, test_txn].
init_per_testcase(TestCase, Config) ->
init_per_testcase(_TestCase, Config) ->
Config.
end_per_testcase(TestCase, _Config) ->
end_per_testcase(_TestCase, _Config) ->
ok.
test_db(_Config) ->
{ok, P} = bdberl_port:new(),
@ -71,9 +71,3 @@ test_txn(_Config) ->
ok = bdberl_port:txn_begin(P),
not_found = bdberl_port:get(P, 0, akey),
ok = bdberl_port:txn_commit(P).