Eugen Dubrovin
Eugen Dubrovin

Reputation: 916

How to filter ETS table without ets:select

I have the module where I store some data in ETS table Now I am trying to filter the data iterating the ETS table but always getting empty [List]. (this one is matching every time - matching('$end_of_table', Acc) -> Acc;)

-module(t).
-export([matching/0]).


matching() -> matching(ets:first(auth), []).
matching('$end_of_table', Acc) -> Acc;
matching(Key, Acc) ->
            FromSec = calendar:datetime_to_gregorian_seconds({{2017,1,12}, {11,00,00}}),
            ToSec = calendar:datetime_to_gregorian_seconds({{2017,1,12}, {12,00,00}}), 
    case ets:lookup(auth, Key) of
  [{Login, Pass, TTL, Unix, Unix2}] when Unix2 >= FromSec, Unix2 =< ToSec -> NewAcc = [{Login, Pass, TTL, Unix, Unix2}|Acc],
            N = ets:next(auth, Key),
                    matching(N, NewAcc);
  _ -> N = ets:next(auth, Key),
                    matching(N, Acc)
         end.

May be I have created ETS table incorrectly ?

Upvotes: 2

Views: 208

Answers (2)

Eugen Dubrovin
Eugen Dubrovin

Reputation: 916

Found the answer!

the main thing that unixtime and calendar:datetime_to_gregorian_seconds({{2017,1,12}, {11,00,00}}) are different

so it everything matched to matching('$end_of_table', Acc) -> Acc;

Upvotes: 0

legoscia
legoscia

Reputation: 41648

The variable names Unix and Unix2 suggest that you're storing Unix timestamps, i.e. the number of seconds elapsed since 1970, but the function calendar:datetime_to_gregorian_seconds returns the number of seconds elapsed since the year 0. (See the documentation.) Thus your comparison Unix2 >= FromSec, Unix2 =< ToSec would always be false.

The calendar module uses the offset ?DAYS_FROM_0_TO_1970 * ?SECONDS_PER_DAY to convert between the two, with the macros defined as:

-define(SECONDS_PER_DAY, 86400).
-define(DAYS_FROM_0_TO_1970, 719528).

See for example the implementation of calendar:now_to_datetime/1.

Upvotes: 4

Related Questions