在 mnesia 中获取和更新数据

Fetching and updating data in mnesia

我有多个 mnesia 元组,例如(GroupID 是主键)

{GroupID, GroupName, GroupType, GroupDescription, GroupTag, CreatorID, AdminID, MemberList, Counter}.

MemberList = "memberone@xyz,membertwo@xyz,memberthree@xyz".
GroupName = "Any String Value". % e.g.: "basketball"
GroupTag = "comma separated values". % e.g.: "Sports,Cricket,Fifa,Ronaldo"

我会将字符或单词传递给函数。该函数将搜索GroupName和GroupTag中的字符。

如果成功则它将return逗号分隔的GroupID、GroupName、GroupDescription元组;并且应该为相应的行递增计数器。

假设在我的 mnesia 数据库中元组是

{"A", "Cricket", "0", "A group for cricket fans", "Sports, Cricket, Sachin tendulkar", "Xyz", "XYZ", "XYZ", 1},
{"B", "Sports", "0", "A group for Sport fans", "Sports,Cricket,Fifa,Ronaldo,Sachin tendulkar", "Xyz", "XYZ", "XYZ", 0}.

所以如果我搜索 "sac",它应该给出输出

[{"A", "Cricket", "A group for cricket fans"},
 {"B", "Sports", "A group for Sport fans"}] 

A 组的计数器值应为 2(为 1,检查元组的最后一个元素),B 组的计数器值应为 1(为 0,检查元组的最后一个元素)。

有什么指点吗?

据我所知,您不能通过调用从字符串中获取子字符串来构建守卫,因此您不必使用 Erlang 匹配规范,而是必须遍历所有记录并过滤您需要的记录需要。

-module(tuples).
-compile(export_all).

-record(group, {group_id,
        group_name,
        group_type,
        group_description,
        group_tag,
        creator_id,
        admin_id,
        member_list,
        counter}).

start() ->
    mnesia:create_schema([node()]),
    mnesia:start().

stop() ->
    mnesia:stop(),
    mnesia:delete_schema([node()]).

load_data() ->
    mnesia:create_table(group,
            [{attributes, record_info(fields, group)}]),
    Record1 = #group{group_id = "A", 
             group_name = "Cricket",
             group_type = "0",
             group_description = "A group for cricket fans",
             group_tag = "Spots,Cricket,Sachin tendulkar",
             creator_id = "Xyz",
             admin_id = "XYZ",
             member_list = "XYZ",
             counter = 1},
    Record2 = #group{group_id = "B",
             group_name = "Sports",
             group_type = "0",
             group_description = "A group for Sport fans",
             group_tag = "Sports,Cricket,Fifa,Ronaldo,Sachin tendulkar",
             creator_id = "Xyz",
             admin_id = "XYZ",
             member_list = "XYZ",
             counter = 0},
    Insert = fun() -> lists:map(fun(X) -> mnesia:write(X) end, [Record1, Record2]) end,
    mnesia:transaction(Insert).

show_data() ->
    CatchAll = [{'_', [], ['$_']}],
    mnesia:dirty_select(group, CatchAll).

query(Substring) ->
    Update = fun(Record) ->
             NewRecord = Record#group{counter = Record#group.counter + 1},
             mnesia:write(NewRecord),
             NewRecord
         end,

    RequiredFields = fun(Record) -> {Record#group.group_id, Record#group.group_name, Record#group.group_description} end,

    Constraint = 
    fun(Group, Acc) ->
        case string:str(string:to_lower(Group#group.group_name), 
                string:to_lower(Substring)) of
            0 ->
                case string:str(string:to_lower(Group#group.group_tag),
                    string:to_lower(Substring)) of
                0 ->
                    Acc;
                _ ->
                    NewRecord = Update(Group),
                    [RequiredFields(Group) | NewRecord]
                end;
            _->
                NewRecord = Update(Group),
                [RequiredFields(Group) | NewRecord]
        end
    end,
    Find = fun() -> mnesia:foldl(Constraint, [], group) end,
    {_, Data} = mnesia:transaction(Find),
    Data.

并尝试代码:

Eshell V6.4  (abort with ^G)
1> c("tuples.erl").
{ok,tuples}
2> tuples:start().
ok
3> tuples:load_data().
{atomic,[ok,ok]}
4> tuples:show_data().
[{group,"A","Cricket","0","A group for cricket fans",
        "Spots,Cricket,Sachin tendulkar","Xyz","XYZ","XYZ",1},
 {group,"B","Sports","0","A group for Sport fans",
        "Sports,Cricket,Fifa,Ronaldo,Sachin tendulkar","Xyz","XYZ",
        "XYZ",0}]
5> tuples:query("sac").
[{group,"A","Cricket","0","A group for cricket fans",
  "Spots,Cricket,Sachin tendulkar","Xyz","XYZ","XYZ",1}|
 {group,"A","Cricket","0","A group for cricket fans",
  "Spots,Cricket,Sachin tendulkar","Xyz","XYZ","XYZ",2}]
6> tuples:stop().

=INFO REPORT==== 14-Jun-2015::22:14:42 ===
    application: mnesia
    exited: stopped
    type: temporary
ok
7> q().
ok
8>