增加数据统计代码
This commit is contained in:
parent
a2157d8afa
commit
2c6705b680
@ -65,6 +65,20 @@
|
|||||||
increment_id = 0 :: integer()
|
increment_id = 0 :: integer()
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
%% 统计项
|
||||||
|
-record(option, {
|
||||||
|
success_num = 0,
|
||||||
|
fail_num = 0
|
||||||
|
}).
|
||||||
|
|
||||||
|
%% 统计累加器
|
||||||
|
-record(totalizator, {
|
||||||
|
key :: {SceneId :: integer(), Date :: calendar:date()},
|
||||||
|
scene_id :: integer(),
|
||||||
|
date :: calendar:date(),
|
||||||
|
option :: #option{}
|
||||||
|
}).
|
||||||
|
|
||||||
%% 北向数据
|
%% 北向数据
|
||||||
-record(north_data, {
|
-record(north_data, {
|
||||||
id = 0 :: integer(),
|
id = 0 :: integer(),
|
||||||
|
|||||||
35
apps/iot/src/http_handler/totalizator_handler.erl
Normal file
35
apps/iot/src/http_handler/totalizator_handler.erl
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author licheng5
|
||||||
|
%%% @copyright (C) 2020, <COMPANY>
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 26. 4月 2020 3:36 下午
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(totalizator_handler).
|
||||||
|
-author("licheng5").
|
||||||
|
-include("iot.hrl").
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([handle_request/4]).
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
%% helper methods
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
%% 重新加载对应的主机信息
|
||||||
|
handle_request("POST", "/totalizator/query", _, #{<<"scene_ids">> := SceneIds, <<"dates">> := Dates0}) when is_list(SceneIds), is_list(Dates0) ->
|
||||||
|
Dates = lists:map(fun(Date) ->
|
||||||
|
[Year0, Month0, Day0] = binary:split(Date, <<"-">>, [global]),
|
||||||
|
Year = binary_to_integer(Year0),
|
||||||
|
Month = binary_to_integer(Month0),
|
||||||
|
Day = binary_to_integer(Day0),
|
||||||
|
{Year, Month, Day}
|
||||||
|
end, Dates0),
|
||||||
|
|
||||||
|
List = mnesia_totalizator:query(SceneIds, Dates),
|
||||||
|
{ok, 200, iot_util:json_data(List)};
|
||||||
|
|
||||||
|
handle_request(_, Path, _, _) ->
|
||||||
|
Path1 = list_to_binary(Path),
|
||||||
|
{ok, 200, iot_util:json_error(-1, <<"url: ", Path1/binary, " not found??">>)}.
|
||||||
@ -44,6 +44,7 @@ start_http_server() ->
|
|||||||
{'_', [
|
{'_', [
|
||||||
{"/host/[...]", http_protocol, [host_handler]},
|
{"/host/[...]", http_protocol, [host_handler]},
|
||||||
{"/device/[...]", http_protocol, [device_handler]},
|
{"/device/[...]", http_protocol, [device_handler]},
|
||||||
|
{"/totalizator/[...]", http_protocol, [totalizator_handler]},
|
||||||
{"/test/[...]", http_protocol, [test_handler]},
|
{"/test/[...]", http_protocol, [test_handler]},
|
||||||
{"/ws", ws_channel, []}
|
{"/ws", ws_channel, []}
|
||||||
]}
|
]}
|
||||||
@ -69,11 +70,11 @@ start_udp_server() ->
|
|||||||
|
|
||||||
%% 启动内存数据库
|
%% 启动内存数据库
|
||||||
start_mnesia() ->
|
start_mnesia() ->
|
||||||
QueueTab = 'queue_data:zhongdian',
|
|
||||||
%% 启动数据库
|
%% 启动数据库
|
||||||
ok = mnesia:start(),
|
ok = mnesia:start(),
|
||||||
Tables = mnesia:system_info(tables),
|
Tables = mnesia:system_info(tables),
|
||||||
LoadTables = [id_generator, QueueTab],
|
|
||||||
|
LoadTables = [id_generator, totalizator, 'queue_data:zhongdian'],
|
||||||
case lists:all(fun(Tab) -> lists:member(Tab, Tables) end, LoadTables) of
|
case lists:all(fun(Tab) -> lists:member(Tab, Tables) end, LoadTables) of
|
||||||
true ->
|
true ->
|
||||||
lager:debug("[iot_app] waiting for mnesia start: ~p", [LoadTables]),
|
lager:debug("[iot_app] waiting for mnesia start: ~p", [LoadTables]),
|
||||||
@ -91,20 +92,10 @@ start_mnesia() ->
|
|||||||
ok = mnesia:start(),
|
ok = mnesia:start(),
|
||||||
|
|
||||||
%% 创建数据库表
|
%% 创建数据库表
|
||||||
|
|
||||||
%% id生成器
|
%% id生成器
|
||||||
mnesia:create_table(id_generator, [
|
mnesia_id_generator:create_table(),
|
||||||
{attributes, record_info(fields, id_generator)},
|
|
||||||
{record_name, id_generator},
|
|
||||||
{disc_copies, [node()]},
|
|
||||||
{type, ordered_set}
|
|
||||||
]),
|
|
||||||
|
|
||||||
%% 数据转发缓存表
|
%% 数据转发缓存表
|
||||||
mnesia:create_table(QueueTab, [
|
mnesia_queue:create_table(),
|
||||||
{attributes, record_info(fields, north_data)},
|
%% 大数据统计表
|
||||||
{record_name, north_data},
|
mnesia_totalizator:create_table()
|
||||||
{disc_copies, [node()]},
|
|
||||||
{type, ordered_set}
|
|
||||||
])
|
|
||||||
end.
|
end.
|
||||||
@ -8,9 +8,19 @@
|
|||||||
%%%-------------------------------------------------------------------
|
%%%-------------------------------------------------------------------
|
||||||
-module(mnesia_id_generator).
|
-module(mnesia_id_generator).
|
||||||
-author("aresei").
|
-author("aresei").
|
||||||
|
-include("iot.hrl").
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([next_id/1]).
|
-export([next_id/1, create_table/0]).
|
||||||
|
|
||||||
|
create_table() ->
|
||||||
|
%% id生成器
|
||||||
|
mnesia:create_table(id_generator, [
|
||||||
|
{attributes, record_info(fields, id_generator)},
|
||||||
|
{record_name, id_generator},
|
||||||
|
{disc_copies, [node()]},
|
||||||
|
{type, ordered_set}
|
||||||
|
]).
|
||||||
|
|
||||||
next_id(Tab) when is_atom(Tab) ->
|
next_id(Tab) when is_atom(Tab) ->
|
||||||
mnesia:dirty_update_counter(id_generator, Tab, 1).
|
mnesia:dirty_update_counter(id_generator, Tab, 1).
|
||||||
@ -13,8 +13,18 @@
|
|||||||
-define(TAB_NAME, 'queue_data:zhongdian').
|
-define(TAB_NAME, 'queue_data:zhongdian').
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
|
-export([create_table/0]).
|
||||||
-export([insert/1, delete/1, table_size/0, dirty_fetch_next/1]).
|
-export([insert/1, delete/1, table_size/0, dirty_fetch_next/1]).
|
||||||
|
|
||||||
|
create_table() ->
|
||||||
|
%% 数据转发缓存表
|
||||||
|
mnesia:create_table(?TAB_NAME, [
|
||||||
|
{attributes, record_info(fields, north_data)},
|
||||||
|
{record_name, north_data},
|
||||||
|
{disc_copies, [node()]},
|
||||||
|
{type, ordered_set}
|
||||||
|
]).
|
||||||
|
|
||||||
-spec insert(#north_data{}) -> ok | {error, Reason :: any()}.
|
-spec insert(#north_data{}) -> ok | {error, Reason :: any()}.
|
||||||
insert(Item = #north_data{}) ->
|
insert(Item = #north_data{}) ->
|
||||||
Id = mnesia_id_generator:next_id(?TAB_NAME),
|
Id = mnesia_id_generator:next_id(?TAB_NAME),
|
||||||
|
|||||||
103
apps/iot/src/mnesia/mnesia_totalizator.erl
Normal file
103
apps/iot/src/mnesia/mnesia_totalizator.erl
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
%%% @author aresei
|
||||||
|
%%% @copyright (C) 2023, <COMPANY>
|
||||||
|
%%% @doc
|
||||||
|
%%%
|
||||||
|
%%% @end
|
||||||
|
%%% Created : 26. 7月 2023 10:40
|
||||||
|
%%%-------------------------------------------------------------------
|
||||||
|
-module(mnesia_totalizator).
|
||||||
|
-author("aresei").
|
||||||
|
-include("iot.hrl").
|
||||||
|
-include_lib("stdlib/include/qlc.hrl").
|
||||||
|
|
||||||
|
-define(TAB_NAME, totalizator).
|
||||||
|
|
||||||
|
%% API
|
||||||
|
-export([create_table/0]).
|
||||||
|
-export([increment_success/2, increment_fail/2, delete/2, table_size/0, query/2]).
|
||||||
|
|
||||||
|
create_table() ->
|
||||||
|
%% id生成器
|
||||||
|
mnesia:create_table(?TAB_NAME, [
|
||||||
|
{attributes, record_info(fields, totalizator)},
|
||||||
|
{record_name, totalizator},
|
||||||
|
{disc_copies, [node()]},
|
||||||
|
{type, ordered_set}
|
||||||
|
]).
|
||||||
|
|
||||||
|
-spec query(SceneIds :: [integer()], Dates :: [calendar:date()]) -> [map()].
|
||||||
|
query(SceneIds, Dates) when is_list(SceneIds), is_list(Dates) ->
|
||||||
|
lists:map(fun(Date) ->
|
||||||
|
Scenes = lists:map(fun(SceneId) ->
|
||||||
|
Key = {SceneId, Date},
|
||||||
|
case mnesia:dirty_read(?TAB_NAME, Key) of
|
||||||
|
[R | _] ->
|
||||||
|
to_map(R);
|
||||||
|
[] ->
|
||||||
|
#{<<"scene_id">> => SceneId, <<"success_num">> => 0, <<"fail_num">> => 0}
|
||||||
|
end
|
||||||
|
end, SceneIds),
|
||||||
|
#{<<"date">> => format_date(Date), <<"scenes">> => Scenes}
|
||||||
|
end, Dates).
|
||||||
|
|
||||||
|
-spec increment_success(SceneId :: integer(), IncNum :: integer()) -> ok | {error, Reason :: any()}.
|
||||||
|
increment_success(SceneId, IncNum) when is_integer(SceneId), is_integer(IncNum) ->
|
||||||
|
increment(SceneId, success, IncNum).
|
||||||
|
|
||||||
|
-spec increment_fail(SceneId :: integer(), IncNum :: integer()) -> ok | {error, Reason :: any()}.
|
||||||
|
increment_fail(SceneId, IncNum) when is_integer(SceneId), is_integer(IncNum) ->
|
||||||
|
increment(SceneId, fail, IncNum).
|
||||||
|
|
||||||
|
-spec increment(SceneId :: integer(), Type :: atom(), IncNum :: integer()) -> ok | {error, Reason :: any()}.
|
||||||
|
increment(SceneId, Type, IncNum) when is_integer(SceneId), is_integer(IncNum), is_atom(Type) ->
|
||||||
|
{Date, _} = calendar:local_time(),
|
||||||
|
Key = {SceneId, Date},
|
||||||
|
Fun = fun() ->
|
||||||
|
case mnesia:read(?TAB_NAME, Key) of
|
||||||
|
[R = #totalizator{option = Option = #option{success_num = SuccessNum, fail_num = FailNum}} | _] ->
|
||||||
|
NOption = case Type of
|
||||||
|
success ->
|
||||||
|
Option#option{success_num = SuccessNum + IncNum};
|
||||||
|
fail ->
|
||||||
|
Option#option{fail_num = FailNum + IncNum}
|
||||||
|
end,
|
||||||
|
NR = R#totalizator{option = NOption},
|
||||||
|
mnesia:write(?TAB_NAME, NR, write);
|
||||||
|
[] ->
|
||||||
|
Option = case Type of
|
||||||
|
success ->
|
||||||
|
#option{success_num = IncNum};
|
||||||
|
fail ->
|
||||||
|
#option{fail_num = IncNum}
|
||||||
|
end,
|
||||||
|
R = #totalizator{key = Key, scene_id = SceneId, date = Date, option = Option},
|
||||||
|
mnesia:write(?TAB_NAME, R, write)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
case mnesia:transaction(Fun) of
|
||||||
|
{atomic, ok} ->
|
||||||
|
ok;
|
||||||
|
{aborted, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec delete(SceneId :: integer(), Date :: calendar:date()) -> ok | {error, Reason :: any()}.
|
||||||
|
delete(SceneId, Date) when is_integer(SceneId), is_tuple(Date) ->
|
||||||
|
case mnesia:transaction(fun() -> mnesia:delete(?TAB_NAME, {SceneId, Date}, write) end) of
|
||||||
|
{atomic, ok} ->
|
||||||
|
ok;
|
||||||
|
{aborted, Reason} ->
|
||||||
|
{error, Reason}
|
||||||
|
end.
|
||||||
|
|
||||||
|
-spec table_size() -> integer().
|
||||||
|
table_size() ->
|
||||||
|
mnesia:table_info(?TAB_NAME, size).
|
||||||
|
|
||||||
|
to_map(#totalizator{scene_id = SceneId, option = #option{success_num = SuccessNum, fail_num = FailNum}}) ->
|
||||||
|
#{<<"scene_id">> => SceneId, <<"success_num">> => SuccessNum, <<"fail_num">> => FailNum}.
|
||||||
|
|
||||||
|
format_date({Year, Month, Day}) ->
|
||||||
|
iolist_to_binary(io_lib:format("~b-~2..0b-~2..0b", [Year, Month, Day])).
|
||||||
Loading…
x
Reference in New Issue
Block a user