Add the ability to pass flags to the open_database function.
This commit is contained in:
parent
5b2ed7f0a1
commit
c5e50712e1
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue