在 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>
我有多个 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>