Current section
Files
Jump to
Current section
Files
stdlib/Database/Mnesia.erl
%%---------------------------------------------------------------------------
%% |
%% Module : Mnesia
%% Copyright : (c) 2020-2021 EMQ Technologies Co., Ltd.
%% License : BSD-style (see the LICENSE file)
%%
%% Maintainer : Feng Lee, feng@emqx.io
%% Yang M, yangm@emqx.io
%% Stability : experimental
%% Portability : portable
%%
%% The Mnesia Database FFI module.
%%
%%---------------------------------------------------------------------------
-module('Database.Mnesia.FFI').
-include("../Foreign.hrl").
-export([ addTableCopy/3
, addTableIndex/2
, clearTable/1
, createSchema/1
, createTable/2
, delTableCopy/2
, delTableIndex/2
, delete/2
, deleteWithLock/3
, deleteObject/2
, deleteObjectWithLock/3
, deleteTable/1
, dirtyDeleteObject/2
, next/2
, prev/2
, wread/2
, writeWith/2
, write/1
, writeWithLock/3
, transaction/1
, transactionWithRetry/2
, changeTableAccessMode/2
, changeTableLoadOrder/2
, changeTableMajority/2
, forceLoadTable/1
, moveTableCopy/3
, readWithLock/3
, setMasterNodes/1
, setMasterNodesWithTable/2
, syncTransaction/1
, syncTransactionWithRetries/2
, activity/2
, foldl/3
, foldr/3
, changeConfig/2
, dumpTables/1
, lockRecord/3
, lockTable/2
, lockGlobal/3
, matchObjectWith/3
, matchObject/1
, sdelete/2
, sdeleteObject/1
, swrite/1
, transformTable/4
, subscribe/1
, unsubscribe/1
, setDebugLevel/1
, dirtyMatchObjectWith/2
, dirtyMatchObject/1
]).
addTableCopy(Tab, N, ST) ->
?IO(return(mnesia:add_table_copy(Tab, N, toErl(ST)))).
addTableIndex(Tab, I) ->
?IO(return(mnesia:add_table_index(Tab, I))).
clearTable(Tab) ->
?IO(return(mnesia:clear_table(Tab))).
createSchema(Nodes) ->
?IO(case mnesia:create_schema(Nodes) of
ok -> ok;
{error, Reason} -> error(Reason)
end).
createTable(Name, Options) ->
?IO(return(mnesia:create_table(Name, parseOpts(maps:to_list(Options), [])))).
delTableCopy(Tab, Node) ->
?IO(return(mnesia:del_table_copy(Tab, Node))).
delTableIndex(Tab, I) ->
?IO(return(mnesia:delTableIndex(Tab, I))).
delete(Tab, Key) ->
?IO(mnesia:delete(Tab, Key, write)).
deleteWithLock(Tab, Key, Lock) ->
?IO(mnesia:delete(Tab, Key, toErl(Lock))).
deleteObject(Tab, Rec) ->
?IO(mnesia:delete_object(Tab, Rec, write)).
deleteObjectWithLock(Tab, Rec, Lock) ->
?IO(mnesia:delete_object(Tab, Rec, toErl(Lock))).
deleteTable(Tab) ->
?IO(return(mnesia:delete_table(Tab))).
dirtyDeleteObject(Tab, Rec) ->
?IO(mnesia:dirty_delete_object(Tab, Rec)).
next(Tab, Key1) ->
?IO(case mnesia:next(Tab, Key1) of
'$end_of_table' -> {'Nothing'};
Key2 -> {'Just', Key2}
end).
prev(Tab, Key1) ->
?IO(case mnesia:prev(Tab, Key1) of
'$end_of_table' -> {'Nothing'};
Key2 -> {'Just', Key2}
end).
wread(Tab, Key) ->
?IO(mnesia:read(Tab, Key, write)).
writeWith(Tab, Rec) ->
?IO(mnesia:write(Tab, Rec, write)).
write(Rec) ->
?IO(mnesia:write(Rec)).
writeWithLock(Tab, Rec, Lock) ->
?IO(mnesia:write(Tab, Rec, toErl(Lock))).
transaction(Fun) ->
?IO(transReturn(mnesia:transaction(Fun))).
transactionWithRetry(Fun, Retries) ->
?IO(transReturn(mnesia:transaction(Fun, decRet(Retries)))).
changeTableAccessMode(Table, Acc) ->
?IO(return(mnesia:change_table_access_mode(Table, toErl(Acc)))).
changeTableLoadOrder(Table, V) ->
?IO(return(mnesia:change_table_load_order(Table, V))).
changeTableMajority(Table, B) ->
?IO(return(mnesia:change_table_majority(Table, B))).
forceLoadTable(Table) ->
?IO(return(mnesia:forceLoadTable(Table))).
moveTableCopy(Table, From, To) ->
?IO(return(mnesia:move_table_copy(Table, From, To))).
readWithLock(Table, K, LockKind) ->
?IO((mnesia:read(Table, K, toErl(LockKind)))).
setMasterNodes(Nodes) ->
?IO(return(mnesia:set_master_nodes(Nodes))).
setMasterNodesWithTable(Table, Nodes) ->
?IO(return(mnesia:set_master_nodes(Table, Nodes))).
syncTransaction(Fun) ->
?IO(transReturn(mnesia:sync_transaction(Fun))).
syncTransactionWithRetries(Fun, Retries) ->
?IO(transReturn(mnesia:sync_transaction(Fun, decRet(Retries)))).
activity(Activity, Fun) ->
?IO((mnesia:activity(decAct(Activity), Fun))).
foldl(Fun, Acc0, Tab) ->
?IO(mnesia:foldl(fun(R, Acc) -> (Fun(R))(Acc) end, Acc0, Tab)).
foldr(Fun, Acc0, Tab) ->
?IO(mnesia:foldr(fun(R, Acc) -> (Fun(R))(Acc) end, Acc0, Tab)).
changeConfig(ConfigKey, ConfigVal) ->
?IO(decConfig(mnesia:change_config(decConfig(ConfigKey), decConfig(ConfigVal)))).
dumpTables(Tabs) ->
?IO(return(mnesia:dump_tables(Tabs))).
lockRecord(Table, Key, LockKind) ->
?IO(mnesia:lock({record, Table, Key}, toErl(LockKind))).
lockTable(Table, LockKind) ->
?IO(mnesia:lock({table, Table}, toErl(LockKind))).
lockGlobal(Key, Nodes, LockKind) ->
?IO(mnesia:lock({global, Key, Nodes}, toErl(LockKind))).
matchObjectWith(Table, Pattern, LockKind) ->
?IO(mnesia:match_object(Table, Pattern, toErl(LockKind))).
matchObject(Pattern) ->
?IO(mnesia:match_object(element(1, Pattern), Pattern, read)).
sdelete(Table, Key) ->
?IO(mnesia:s_delete({Table, Key})).
sdeleteObject(Tuple) ->
?IO(mnesia:s_delete_object(Tuple)).
swrite(Tuple) ->
?IO(mnesia:s_write(Tuple)).
transformTable(Table, Fun, NewA, RecName) ->
?IO(return(mnesia:transform_table(Table, Fun, NewA, RecName))).
subscribe(What) ->
?IO(decSubRes(mnesia:subscribe(decWhat(What)))).
unsubscribe(What) ->
?IO(decSubRes(mnesia:unsubscribe(decWhat(What)))).
setDebugLevel(DebugLevel) ->
?IO(encDeubg(mnesia:set_debug_level(decDeubg(DebugLevel)))).
dirtyMatchObjectWith(Table, Pattern) ->
?IO((mnesia:dirty_match_object(Table, Pattern))).
dirtyMatchObject(Pattern) ->
?IO((mnesia:dirty_match_object(Pattern))).
%%---------------------------------------------------------------------------
%% | Internal functions
%%---------------------------------------------------------------------------
parseOpts([{tableType, {'Set'}}|Opts], Acc) ->
parseOpts(Opts, [{type, set}|Acc]);
parseOpts([{tableType, {'OrderedSet'}}|Opts], Acc) ->
parseOpts(Opts, [{type, ordered_set}|Acc]);
parseOpts([{tableType, {'Bag'}}|Opts], Acc) ->
parseOpts(Opts, [{type, bag}|Acc]);
parseOpts([{tableType, {'DuplicateBag'}}|Opts], Acc) ->
parseOpts(Opts, [{type, duplicate_bag}|Acc]);
parseOpts([{accessMode, {'ReadWrite'}}|Opts], Acc) ->
parseOpts(Opts, [{access_mode, read_write}|Acc]);
parseOpts([{accessMode, {'ReadOnly'}}|Opts], Acc) ->
parseOpts(Opts, [{access_mode, read_only}|Acc]);
parseOpts([{attributes, Attrs}|Opts], Acc) ->
parseOpts(Opts, [{attributes, Attrs}|Acc]);
parseOpts([{discCopies, Nodes}|Opts], Acc) ->
parseOpts(Opts, [{disc_copies, Nodes}|Acc]);
parseOpts([{discOnlyCopies, Nodes}|Opts], Acc) ->
parseOpts(Opts, [{disc_only_copies, Nodes}|Acc]);
parseOpts([{index, Attrs}|Opts], Acc) ->
parseOpts(Opts, [{index, Attrs}|Acc]);
parseOpts([{loadOrder, Order}|Opts], Acc) ->
parseOpts(Opts, [{load_order, Order}|Acc]);
parseOpts([{majority, Bool}|Opts], Acc) ->
parseOpts(Opts, [{majority, Bool}|Acc]);
parseOpts([{ramCopies, Nodes}|Opts], Acc) ->
parseOpts(Opts, [{ram_copies, Nodes}|Acc]);
parseOpts([{recordName, Name}|Opts], Acc) ->
parseOpts(Opts, [{record_name, Name}|Acc]);
parseOpts([{localContent, Bool}|Opts], Acc) ->
parseOpts(Opts, [{local_content, Bool}|Acc]);
parseOpts([], Acc) -> Acc.
toErl({'RLock'}) -> read;
toErl({'WLock'}) -> write;
toErl({'StickyWLock'}) -> sticky_write;
toErl({'ReadOnly'}) -> read_only;
toErl({'ReadWrite'}) -> read_write.
return({atomic, ok}) -> ok;
return({aborted, Reason}) -> error(Reason).
transReturn({atomic, V}) -> V;
transReturn({aborted, Reason}) -> error(Reason).
decRet({'MaxTime', V}) -> V;
decRet({'Infinity'}) -> infinity.
decAct({'AsyncDirty'}) -> async_dirty;
decAct({'SyncDirty'}) -> sync_dirty;
decAct({'Transaction'}) -> transaction;
decAct({'SyncTransaction'}) -> sync_transaction.
decConfig({'ExtraDbNodes'}) -> extra_db_nodes;
decConfig({'DcDumpLimit'}) -> dc_dump_limit;
decConfig({'Nodes', Nodes}) -> Nodes;
decConfig({'Number', N}) -> N;
decConfig({'ok', Config}) -> Config;
decConfig({'error', T}) -> error(T);
decConfig(T) -> T.
decWhat({'WSystem'}) -> system;
decWhat({'WActivity'}) -> activity;
decWhat({'WTable', Table}) -> {'table', Table, simple}.
decSubRes({ok, Node}) -> Node;
decSubRes({error, Reason}) -> error(Reason).
decDeubg({'Dnone'}) -> none;
decDeubg({'Dverbose'}) -> verbose;
decDeubg({'Ddebug'}) -> debug;
decDeubg({'Dtrace'}) -> trace.
encDeubg(none) -> {'Dnone'};
encDeubg(verbose) -> {'Dverbose'};
encDeubg(debug) -> {'Ddebug'};
encDeubg(trace) -> {'Dtrace'}.