Browse Source

Merge branch 'master' into fix-warnings

Yuri Zhloba 8 years ago
parent
commit
3a76e07f6e

+ 0 - 8
.dialyzer.ignore

@@ -1,8 +0,0 @@
-  erlang:get_module_info/1
-  erlang:get_module_info/2
-  erlang:integer_to_list/1
-  erlang:make_ref/0
-  erlang:md5/1
-  erlang:now/0
-  erlang:phash2/1
-  eunit:test/1

+ 2 - 5
.gitignore

@@ -1,8 +1,5 @@
-.rebar
-TODO.org
-ebin
-TAGS
-.eunit
+_build
 erl_crash.dump
 rebar.lock
 _build
+.idea

+ 10 - 23
Makefile

@@ -1,30 +1,17 @@
 compile:
-	rebar compile skip_deps=true
-
-get-deps:
-	rebar get-deps
-
-compile_all:
-	rebar compile
+	rebar3 compile
 
 eunit:
-	rebar eunit skip_deps=true
-
-clean:
-	rebar clean skip_deps=true
-	rm -f erl_crash.dump
+	rebar3 eunit
 
-clean_all:
-	rebar clean
-	rm -f erl_crash.dump
-
-run:
-	erl -pa ebin +pc unicode
+console:
+	erl -pa _build/default/lib/*/ebin
 
 d:
-	dialyzer --src \
-	-I include -r src test \
-	| fgrep --invert-match --file .dialyzer.ignore
+	rebar3 dialyzer
+
+clean:
+	rebar3 clean
 
-etags:
-	etags src/* include/*
+clean-all:
+	rm -rf _build

+ 20 - 0
herd.iml

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="ERLANG_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="erlang" name="Erlang">
+      <configuration />
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/include" type="erlang-include" />
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
+      <excludeFolder url="file://$MODULE_DIR$/.idea" />
+      <excludeFolder url="file://$MODULE_DIR$/_build" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 0 - 16
include/herd.hrl

@@ -1,16 +0,0 @@
--type(timestamp() :: integer()).
--type(timestamp_micro() :: float()).
-
-%% jiffy json format
--type(json_key() :: atom() | binary()).
--type(json_value() :: atom() | integer() | float() | binary() | json_obj() | [json_value()]).
--type(json_obj() :: {[{json_key(), json_value()}]}).
-
-%% db types (PostgreSQL with epgsql driver)
--type(db_name() :: binary()).
--type(db_type() :: atom()).
--type(db_value() :: term()).
--type(db_row() :: tuple()).
--type(db_column() :: {column, db_name(), db_type(), term(), term(), term()}).
--type(db_select() :: {ok, [db_column()], [db_row()]}).
--type(db_datetime() :: {calendar:date(), {0..23, 0..59, float()}}). % PostgreSQL datetime format: 2014-12-20 17:38:56.475565+03

+ 0 - 2
rebar.config

@@ -1,6 +1,4 @@
 %%-*- mode: erlang -*-
 {erl_opts, [warn_missing_spec]}.
 
-{clean_files, ["*.eunit", "ebin/*.beam"]}.
-
 {deps, []}.

+ 53 - 6
src/herd_datetime.erl

@@ -1,11 +1,25 @@
 -module(herd_datetime).
 
--export([now/0, now_micro/0,
-         datetime_from_db/1,
-         timestamp_to_datetime/1, datetime_to_timestamp/1,
-         datetime_to_ISO/1]).
+-export([
+    now/0, now_micro/0,
+    datetime_from_db/1,
+    timestamp_to_datetime/1,
+    timestamp_to_db_datetime/1,
+    datetime_to_timestamp/1,
+    datetime_to_ISO/1,
+    add_interval/2,
+    subtract_interval/2
+]).
 
--include("herd.hrl").
+-type(timestamp() :: integer()). % seconds, 1476882197
+-type(timestamp_micro() :: float()). % int part in seconds, 1476882197.233323
+
+%% PostgreSQL datetime format: 2014-12-20 17:38:56.475565
+-type(db_datetime() :: {calendar:date(), {0..23, 0..59, float()}}).
+
+-type(time_interval() :: {integer(), week | day | hour | minute | second}).
+
+-define(DAY, 24 * 3600).
 
 
 %%% module API
@@ -15,21 +29,31 @@ now() ->
     os:system_time(seconds).
 
 
+
 -spec now_micro() -> timestamp_micro().
 now_micro() ->
     os:system_time(micro_seconds) * 1.0e-6.
 
 
+
 -spec datetime_from_db(db_datetime()) -> calendar:datetime().
 datetime_from_db({Date, {Hour, Minute, Second}}) ->
     {Date, {Hour, Minute, trunc(Second)}}.
 
 
--spec timestamp_to_datetime(timestamp() | timestamp_micro()) -> calendar:datetime().
+-spec timestamp_to_datetime(timestamp()) -> calendar:datetime().
 timestamp_to_datetime(Timestamp) ->
     calendar:now_to_universal_time({Timestamp div 1000000, Timestamp rem 1000000, 0}).
 
 
+-spec timestamp_to_db_datetime(timestamp_micro()) -> db_datetime().
+timestamp_to_db_datetime(Timestamp) ->
+    T = trunc(Timestamp),
+    MicroSecs = Timestamp - T,
+    {D, {H, M, S}} = calendar:now_to_universal_time({T div 1000000, T rem 1000000, 0}),
+    {D, {H, M, S + MicroSecs}}.
+
+
 -spec datetime_to_timestamp(calendar:datetime()) -> timestamp().
 datetime_to_timestamp(DateTime) ->
     % 62167219200 == calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}})
@@ -41,3 +65,26 @@ datetime_to_ISO({{Year, Month, Day}, {Hour, Minute, Second}}) ->
     lists:flatten(
         io_lib:format("~4..0b-~2..0b-~2..0bT~2..0b:~2..0b:~2..0b",
                       [Year, Month, Day, Hour, Minute, trunc(Second)])).
+
+
+-spec add_interval(calendar:datetime(), time_interval()) -> calendar:datetime().
+add_interval(Datetime, {W, week}) ->
+    add_interval(Datetime, {W * 7 * ?DAY, second});
+
+add_interval(Datetime, {D, day}) ->
+    add_interval(Datetime, {D * ?DAY, second});
+
+add_interval(Datetime, {H, hour}) ->
+    add_interval(Datetime, {H * 3600, second});
+
+add_interval(Datetime, {M, minute}) ->
+    add_interval(Datetime, {M * 60, second});
+
+add_interval(Datetime, {S, second}) ->
+    T = datetime_to_timestamp(Datetime),
+    timestamp_to_datetime(T + S).
+
+
+-spec subtract_interval(calendar:datetime(), time_interval()) -> calendar:datetime().
+subtract_interval(Datetime, {M, Type}) ->
+    add_interval(Datetime, {-M, Type}).

+ 10 - 1
src/herd_db.erl

@@ -2,7 +2,16 @@
 
 -export([epgsql_res_to_json/1]).
 
--include("herd.hrl").
+-type(json_key() :: atom() | binary()).
+-type(json_value() :: atom() | integer() | float() | binary() | json_obj() | [json_value()]).
+-type(json_obj() :: {[{json_key(), json_value()}]}).
+
+-type(db_name() :: binary()).
+-type(db_type() :: atom()).
+-type(db_value() :: term()).
+-type(db_row() :: tuple()).
+-type(db_column() :: {column, db_name(), db_type(), term(), term(), term()}).
+-type(db_select() :: {ok, [db_column()], [db_row()]}).
 
 
 %%% module API

+ 1 - 0
src/herd_rand.erl

@@ -45,3 +45,4 @@ md5hex(Str) ->
 %% generates random md5 hash
 -spec hex() -> string().
 hex() -> md5hex(integer_to_list(erlang:phash2({os:system_time(micro_seconds), make_ref()}))).
+

+ 19 - 0
src/herd_reconnect.erl

@@ -0,0 +1,19 @@
+-module(herd_reconnect).
+
+-export([exp_backoff/3, exp_backoff/4]).
+
+
+-spec exp_backoff(integer(), integer(), integer()) -> integer().
+exp_backoff(Attempt, BaseTimeout, MaxTimeout) ->
+    exp_backoff(Attempt, 10, BaseTimeout, MaxTimeout).
+
+
+-spec exp_backoff(integer(), integer(), integer(), integer()) -> integer().
+exp_backoff(Attempt, MaxAttempt, _BaseTimeout, MaxTimeout) when Attempt >= MaxAttempt ->
+    Half = MaxTimeout div 2,
+    Half + random:uniform(Half);
+
+exp_backoff(Attempt, _MaxAttempt, BaseTimeout, MaxTimeout) ->
+    Timeout = min(erlang:round(math:pow(2, Attempt) * BaseTimeout), MaxTimeout),
+    Half = Timeout div 2,
+    Half + random:uniform(Half).

+ 72 - 0
test/herd_datetime_tests.erl

@@ -0,0 +1,72 @@
+-module(herd_datetime_tests).
+-include_lib("eunit/include/eunit.hrl").
+
+-spec datetime_from_db_test() -> ok.
+datetime_from_db_test() ->
+    ?assertEqual({{2016, 11, 18}, {13, 55, 12}},
+        herd_datetime:datetime_from_db({{2016, 11, 18}, {13, 55, 12.632}})),
+    ok.
+
+
+-spec timestamp_to_datetime_test() -> ok.
+timestamp_to_datetime_test() ->
+    ?assertEqual({{2016,11,18},{10,57,44}},
+        herd_datetime:timestamp_to_datetime(1479466664)),
+    ok.
+
+-spec timestamp_to_db_datetime_test() -> ok.
+timestamp_to_db_datetime_test() ->
+    {{2016,11,18},{10,57,S}} = herd_datetime:timestamp_to_db_datetime(1479466664.123456),
+    ?assert(abs(S - 44.123456) < 0.0000001),
+    ok.
+
+
+-spec datetime_to_ISO_test() -> ok.
+datetime_to_ISO_test() ->
+    ?assertEqual("2016-11-18T13:55:12",
+        herd_datetime:datetime_to_ISO({{2016, 11, 18}, {13, 55, 12}})),
+    ok.
+
+
+-spec add_interval_test() -> ok.
+add_interval_test() ->
+    DT = {{2016, 11, 18}, {13, 55, 12}},
+    ?assertEqual({{2016, 11, 18}, {13, 55, 14}},
+        herd_datetime:add_interval(DT, {2, second})),
+    ?assertEqual({{2016, 11, 18}, {14, 2, 12}},
+        herd_datetime:add_interval(DT, {7, minute})),
+    ?assertEqual({{2016, 11, 18}, {15, 55, 12}},
+        herd_datetime:add_interval(DT, {2, hour})),
+    ?assertEqual({{2016, 11, 19}, {3, 55, 12}},
+        herd_datetime:add_interval(DT, {14, hour})),
+    ?assertEqual({{2016, 11, 20}, {13, 55, 12}},
+        herd_datetime:add_interval(DT, {2, day})),
+    ?assertEqual({{2016, 12, 8}, {13, 55, 12}},
+        herd_datetime:add_interval(DT, {20, day})),
+    ?assertEqual({{2016, 11, 25}, {13, 55, 12}},
+        herd_datetime:add_interval(DT, {1, week})),
+    ?assertEqual({{2016, 12, 2}, {13, 55, 12}},
+        herd_datetime:add_interval(DT, {2, week})),
+    ok.
+
+
+-spec subtract_interval_test() -> ok.
+subtract_interval_test() ->
+    DT = {{2016, 11, 18}, {13, 55, 12}},
+    ?assertEqual({{2016, 11, 18}, {13, 55, 10}},
+        herd_datetime:subtract_interval(DT, {2, second})),
+    ?assertEqual({{2016, 11, 18}, {13, 48, 12}},
+        herd_datetime:subtract_interval(DT, {7, minute})),
+    ?assertEqual({{2016, 11, 18}, {11, 55, 12}},
+        herd_datetime:subtract_interval(DT, {2, hour})),
+    ?assertEqual({{2016, 11, 17}, {23, 55, 12}},
+        herd_datetime:subtract_interval(DT, {14, hour})),
+    ?assertEqual({{2016, 11, 16}, {13, 55, 12}},
+        herd_datetime:subtract_interval(DT, {2, day})),
+    ?assertEqual({{2016, 10, 29}, {13, 55, 12}},
+        herd_datetime:subtract_interval(DT, {20, day})),
+    ?assertEqual({{2016, 11, 11}, {13, 55, 12}},
+        herd_datetime:subtract_interval(DT, {1, week})),
+    ?assertEqual({{2016, 11, 4}, {13, 55, 12}},
+        herd_datetime:subtract_interval(DT, {2, week})),
+    ok.

+ 1 - 1
test/herd_db_test.erl → test/herd_db_tests.erl

@@ -1,4 +1,4 @@
--module(herd_db_test).
+-module(herd_db_tests).
 
 -include_lib("eunit/include/eunit.hrl").
 

+ 1 - 1
test/herd_simple_formats_test.erl → test/herd_simple_formats_tests.erl

@@ -1,4 +1,4 @@
--module(herd_simple_formats_test).
+-module(herd_simple_formats_tests).
 
 -include_lib("eunit/include/eunit.hrl").
 

+ 1 - 1
test/herd_string_test.erl → test/herd_string_tests.erl

@@ -1,4 +1,4 @@
--module(herd_string_test).
+-module(herd_string_tests).
 
 -include_lib("eunit/include/eunit.hrl").