%%--------------------------------------
|
|
%% @Module : auto_id
|
|
%% @Author : smxx
|
|
%% @Created : 2013.03.01
|
|
%% @Description: 设置数据表的自增ID初值
|
|
%%--------------------------------------
|
|
-module(auto_id).
|
|
-compile([export_all]).
|
|
-include("auto_id.hrl").
|
|
|
|
%%设置自增ID初值(服务节点才需要处理. 其他不管)
|
|
set_auto_increment(server) ->
|
|
ServerNum = config:get_server_num(),
|
|
io:format("~n--------------------------------------------------~n"),
|
|
io:format("Start checking tables Auto Increment...~n"),
|
|
io:format("Current Server Num: ~p~n", [ServerNum]),
|
|
io:format("--------------------------------------------------~n"),
|
|
F = fun(TableName) ->
|
|
case get_auto_increment_width(TableName) of
|
|
no_match ->
|
|
io:format("Table: ~p found NO AUTO_INCREMENT fields, check your configuration!~n", [TableName]);
|
|
Width -> %%字段宽度
|
|
case Width of
|
|
20 ->
|
|
Start = ServerNum * ?SPACE20 + 1,
|
|
End = (ServerNum + 1) * ?SPACE20;
|
|
11 ->
|
|
Start = ServerNum * ?SPACE11 + 1,
|
|
End = (ServerNum + 1) * ?SPACE11
|
|
end,
|
|
CurrentOffset = get_auto_increment_offset(TableName),
|
|
if
|
|
%% CurrentOffset >= Start andalso CurrentOffset < End -> %%已经设置好了
|
|
%% io:format("Table: ~p \tAUTO_INCREMENT OFFSET ->\tOK~n", [TableName]),
|
|
%% io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n~n", [CurrentOffset, Start, End]);
|
|
%% CurrentOffset >= End ->
|
|
%% io:format("Table: ~p \tAUTO_INCREMENT OFFSET -> OUT OF RANGE~n", [TableName]),
|
|
%% io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n~n", [CurrentOffset, Start, End]);
|
|
CurrentOffset > ?SPACE20 -> %% 已经设置过了偏移量
|
|
io:format("Table: ~p \t AUTO_INCREMENT OFFSET ->\tOK~n", [TableName]),
|
|
io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n~n", [CurrentOffset, Start, End]);
|
|
|
|
true ->
|
|
io:format("Table: ~p \tAUTO_INCREMENT OFFSET -> NOT SET~n", [TableName]),
|
|
io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n", [CurrentOffset, Start, End]),
|
|
io:format("\t\tSetting to: ~p", [Start]),
|
|
case set_auto_increment_offset(TableName, Start) of
|
|
true -> io:format(" -> OK~n~n");
|
|
_ -> io:format(" -> Failed~n~n")
|
|
end
|
|
end
|
|
end
|
|
end,
|
|
lists:foreach(F, ?AUTO_ID_TABLES),
|
|
io:format("~nTables Auto Increment Done~n"),
|
|
io:format("--------------------------------------------------~n");
|
|
set_auto_increment(_) ->
|
|
skip.
|
|
|
|
%%Auto_Increment字段在第11位
|
|
get_auto_increment_offset(TableName) ->
|
|
Sql = lists:concat(["show table status where name='", TableName, "'"]),
|
|
case lists:nth(11, db_esql:get_row(Sql)) of
|
|
Offset when is_integer(Offset) ->
|
|
Offset;
|
|
_Error ->
|
|
io:format("ERROR when getting Auto_Increment for table ~p~n", [TableName]),
|
|
error
|
|
end.
|
|
|
|
%%获取数据表的AUTO_INCREMENT字段的宽度
|
|
get_auto_increment_width(TableName) ->
|
|
Sql = lists:concat(["show create table ", TableName]),
|
|
case db_esql:get_row(Sql) of
|
|
{db_error, _} ->
|
|
error;
|
|
[_, A | _] ->
|
|
CreateTableList = re:split(A, "[\n]", [{return, binary}]),
|
|
search_auto_increment(CreateTableList)
|
|
end.
|
|
|
|
%%设置AUTO_INCREMENT的值
|
|
set_auto_increment_offset(TableName, Offset) ->
|
|
Sql = io_lib:format("alter table ~s auto_increment=~s;", [atom_to_list(TableName), integer_to_list(Offset)]),
|
|
case db_esql:execute_sql(Sql) of
|
|
{db_error, _} ->
|
|
false;
|
|
_Result ->
|
|
%io:format("Result: ~p~n", [Result])
|
|
true
|
|
end.
|
|
|
|
%%搜索有没有含AUTO_INCRMENT字段的行
|
|
%%如果没有,返回no_match
|
|
%%如果有: 搜索AUTO_INCREMENT行中"int(xx)"并返回xx的值, 没有返回no_match
|
|
search_auto_increment([]) ->
|
|
no_match;
|
|
search_auto_increment([L | T]) ->
|
|
Line = binary_to_list(L),
|
|
case re:run(Line, "AUTO_INCREMENT", [caseless]) of %%匹配AUTO_INCREMENT行
|
|
{match, _} -> %%有
|
|
search_int_width(Line);
|
|
_Other ->
|
|
search_auto_increment(T)
|
|
end.
|
|
|
|
%%搜索"int(xx)"并返回xx的值, 没有返回no_match
|
|
search_int_width(Line) ->
|
|
case re:run(Line, "int", [caseless]) of
|
|
{match, [{Idx1, L1} | _]} -> %%匹配上,Idx1, L1是"int"起始坏置及长度
|
|
Idx = min(Idx1 + L1 + 1, length(Line)),
|
|
case lists:sublist(Line, Idx, 4) of %%取"(xx)"这一段, 最多取4字符
|
|
[40, A, B, 41] -> %%40为"(", 41为")",长度为两数字
|
|
list_to_integer([A, B]);
|
|
[40, A, 41] -> %%长度为1数字
|
|
list_to_integer([A]);
|
|
_Other ->
|
|
no_match
|
|
end;
|
|
_Other ->
|
|
no_match
|
|
end.
|
|
|
|
|