erlang各种有用的函数包括一些有用nif封装,还有一些性能测试case。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 line
4.9 KiB

4 年之前
  1. %%--------------------------------------
  2. %% @Module : auto_id
  3. %% @Author : smxx
  4. %% @Created : 2013.03.01
  5. %% @Description: 设置数据表的自增ID初值
  6. %%--------------------------------------
  7. -module(auto_id).
  8. -compile([export_all]).
  9. -include("auto_id.hrl").
  10. %%设置自增ID初值(服务节点才需要处理. 其他不管)
  11. set_auto_increment(server) ->
  12. ServerNum = config:get_server_num(),
  13. io:format("~n--------------------------------------------------~n"),
  14. io:format("Start checking tables Auto Increment...~n"),
  15. io:format("Current Server Num: ~p~n", [ServerNum]),
  16. io:format("--------------------------------------------------~n"),
  17. F = fun(TableName) ->
  18. case get_auto_increment_width(TableName) of
  19. no_match ->
  20. io:format("Table: ~p found NO AUTO_INCREMENT fields, check your configuration!~n", [TableName]);
  21. Width -> %%字段宽度
  22. case Width of
  23. 20 ->
  24. Start = ServerNum * ?SPACE20 + 1,
  25. End = (ServerNum + 1) * ?SPACE20;
  26. 11 ->
  27. Start = ServerNum * ?SPACE11 + 1,
  28. End = (ServerNum + 1) * ?SPACE11
  29. end,
  30. CurrentOffset = get_auto_increment_offset(TableName),
  31. if
  32. %% CurrentOffset >= Start andalso CurrentOffset < End -> %%已经设置好了
  33. %% io:format("Table: ~p \tAUTO_INCREMENT OFFSET ->\tOK~n", [TableName]),
  34. %% io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n~n", [CurrentOffset, Start, End]);
  35. %% CurrentOffset >= End ->
  36. %% io:format("Table: ~p \tAUTO_INCREMENT OFFSET -> OUT OF RANGE~n", [TableName]),
  37. %% io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n~n", [CurrentOffset, Start, End]);
  38. CurrentOffset > ?SPACE20 -> %% 已经设置过了偏移量
  39. io:format("Table: ~p \t AUTO_INCREMENT OFFSET ->\tOK~n", [TableName]),
  40. io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n~n", [CurrentOffset, Start, End]);
  41. true ->
  42. io:format("Table: ~p \tAUTO_INCREMENT OFFSET -> NOT SET~n", [TableName]),
  43. io:format("\t\tCurrent: ~p, Start: ~p, End:~p~n", [CurrentOffset, Start, End]),
  44. io:format("\t\tSetting to: ~p", [Start]),
  45. case set_auto_increment_offset(TableName, Start) of
  46. true -> io:format(" -> OK~n~n");
  47. _ -> io:format(" -> Failed~n~n")
  48. end
  49. end
  50. end
  51. end,
  52. lists:foreach(F, ?AUTO_ID_TABLES),
  53. io:format("~nTables Auto Increment Done~n"),
  54. io:format("--------------------------------------------------~n");
  55. set_auto_increment(_) ->
  56. skip.
  57. %%Auto_Increment字段在第11位
  58. get_auto_increment_offset(TableName) ->
  59. Sql = lists:concat(["show table status where name='", TableName, "'"]),
  60. case lists:nth(11, db_esql:get_row(Sql)) of
  61. Offset when is_integer(Offset) ->
  62. Offset;
  63. _Error ->
  64. io:format("ERROR when getting Auto_Increment for table ~p~n", [TableName]),
  65. error
  66. end.
  67. %%获取数据表的AUTO_INCREMENT字段的宽度
  68. get_auto_increment_width(TableName) ->
  69. Sql = lists:concat(["show create table ", TableName]),
  70. case db_esql:get_row(Sql) of
  71. {db_error, _} ->
  72. error;
  73. [_, A | _] ->
  74. CreateTableList = re:split(A, "[\n]", [{return, binary}]),
  75. search_auto_increment(CreateTableList)
  76. end.
  77. %%设置AUTO_INCREMENT的值
  78. set_auto_increment_offset(TableName, Offset) ->
  79. Sql = io_lib:format("alter table ~s auto_increment=~s;", [atom_to_list(TableName), integer_to_list(Offset)]),
  80. case db_esql:execute_sql(Sql) of
  81. {db_error, _} ->
  82. false;
  83. _Result ->
  84. %io:format("Result: ~p~n", [Result])
  85. true
  86. end.
  87. %%搜索有没有含AUTO_INCRMENT字段的行
  88. %%如果没有,返回no_match
  89. %%如果有: 搜索AUTO_INCREMENT行中"int(xx)"并返回xx的值, 没有返回no_match
  90. search_auto_increment([]) ->
  91. no_match;
  92. search_auto_increment([L | T]) ->
  93. Line = binary_to_list(L),
  94. case re:run(Line, "AUTO_INCREMENT", [caseless]) of %%匹配AUTO_INCREMENT行
  95. {match, _} -> %%有
  96. search_int_width(Line);
  97. _Other ->
  98. search_auto_increment(T)
  99. end.
  100. %%搜索"int(xx)"并返回xx的值, 没有返回no_match
  101. search_int_width(Line) ->
  102. case re:run(Line, "int", [caseless]) of
  103. {match, [{Idx1, L1} | _]} -> %%匹配上,Idx1, L1是"int"起始坏置及长度
  104. Idx = min(Idx1 + L1 + 1, length(Line)),
  105. case lists:sublist(Line, Idx, 4) of %%取"(xx)"这一段, 最多取4字符
  106. [40, A, B, 41] -> %%40为"(", 41为")",长度为两数字
  107. list_to_integer([A, B]);
  108. [40, A, 41] -> %%长度为1数字
  109. list_to_integer([A]);
  110. _Other ->
  111. no_match
  112. end;
  113. _Other ->
  114. no_match
  115. end.