Maxim Sokhatsky 12 years ago
parent
commit
dab949015d

+ 35 - 0
README.md

@@ -0,0 +1,35 @@
+KVS Framework
+=============
+
+Overview
+--------
+
+This is database handling application that hides database access
+and provides high-level rich API to stored and extend following data:
+
+* Acl
+* Users
+* Groups
+* Subscriptions
+* Feeds
+* Accounts
+* Meetings
+* Payments
+
+Store Backends
+--------------
+
+Currently kvs includes following store backends:
+
+* Mnesia
+* Riak, supports secondary indexes via LevelDB
+
+Credits
+-------
+
+* Maxim Sokhatsky
+* Andrii Zadorozhnii
+* Alex Kalenuk
+* Sergey Polkovnikov
+
+OM A HUM

+ 3 - 1
include/accounts.hrl

@@ -1,7 +1,6 @@
 -type currency()         :: internal | quota | game_points | money | bonus.
 -type account_id()       :: {string(), currency()}. %% {username, currency}.
 -type transaction_id()   :: string().
--type transaction_info() :: #tx_payment{} | #tx_admin_change{} | #tx_default_assignment{}.
 
 -record(account, {
         id :: account_id(),
@@ -12,6 +11,9 @@
 -record(tx_payment,{ id :: integer() }).
 -record(tx_admin_change,{ reason :: binary() }).
 -record(tx_default_assignment,{ }).
+
+-type transaction_info() :: #tx_payment{} | #tx_admin_change{} | #tx_default_assignment{}.
+
 -record(user_transaction, {user,top}).
 -record(transaction, {
         id :: transaction_id(),

+ 4 - 2
include/acls.hrl

@@ -1,8 +1,10 @@
--record(acl, {id,
+-record(acl, {
+        id,
         resource,
         top}).
 
--record(acl_entry, {id,
+-record(acl_entry, {
+        id,
         entry_id,
         acl_id,
         accessor,

+ 1 - 0
include/config.hrl

@@ -0,0 +1 @@
+-record(config, {key, value}).

+ 1 - 1
include/feeds.hrl

@@ -90,4 +90,4 @@
         user_id,    % user id
         entries = 0,    % number of entries
         comments = 0   % number of comments
-    }).
+        }).

+ 3 - 2
include/groups.hrl

@@ -13,12 +13,13 @@
         entries_count = 0 :: integer()  
         }).
 
--record(group_subscriptions, {
+-record(group_subscription, {
+        key,
         user_id,
         group_id,
         user_type,
         user_posts_count = 0 :: integer() % we need this for sorting and counting is expensive
         }).
 
-define(GROUP_EXCHANGE(GroupId), list_to_binary("group_exchange."++GroupId++".fanout")).
+-define(GROUP_EXCHANGE(GroupId), list_to_binary("group_exchange."++GroupId++".fanout")).
 

+ 1 - 0
include/meetings.hrl

@@ -34,5 +34,6 @@
         game_id, % { game id that user played under that team }
         realname,
         points, % [{money,Point},{bonus,Points}]
+        quota,
         other }).
 

+ 21 - 0
include/translations.hrl

@@ -0,0 +1,21 @@
+-record(translation, {english, lang, word}).
+
+-define(URL_DICTIONARY, [
+                         {"account", "es", "cuenta"},
+                         {"admin", "es", "administracion"},
+                         {"dashboard", "es", "panel-principal"},
+                         {"friends", "es", "amigos"},
+                         {"gifts", "es", "regalos"},
+                         {"groups", "es", "grupos"},
+                         {"invite", "es", "invitar"},
+                         {"login", "es", "ingresar"},
+                         {"main", "es", "principal"},
+                         {"privacy", "es", "privacidad"},
+                         {"social", "es", "social"},
+                         {"terms", "es", "terminos"},
+                         {"view", "es", "ver"},
+                         {"group", "es", "grupo"},
+                         {"contact", "es", "contacto"},
+                         {"success", "es", "exito"},
+                         {"fail", "es", "suspender"}
+                         ]).

+ 1 - 2
include/types.hrl

@@ -3,8 +3,7 @@
 
 -type username_type() :: string().
 -type id_type() :: integer().
--type user_state() :: 'ok' | 'not_verified' | 'banned'.
+-type user_state() :: ok | not_verified | banned.
 -type proplist() :: [proplists:property()].
 
-
 -endif.

+ 9 - 6
include/users.hrl

@@ -5,6 +5,7 @@
         password,
         facebook_id,
         twitter_id,
+        auth,
         email,
         avatar,
         name = undefined,
@@ -14,8 +15,9 @@
         location,
         education,
         register_date,
-        status = 'not_verified' :: user_state() | '_',
+        status = not_verified :: user_state() | '_',
         verification_code :: string() | '_',
+        zone,
         type,
         feed,
         direct,
@@ -23,6 +25,7 @@
         pinned,
         comments,
         discussions,
+        transactions,
         team,
         aclver}).
 
@@ -56,9 +59,10 @@
         id,
         aclver}).
 
--record(subsctiptioins,{
-        {who,
-         whom}).
+-record(subscription,{
+        key,
+        who,
+        whom}).
 
 -record(forget_password, {
         token :: string(),
@@ -87,8 +91,7 @@
 -record(user_bought_gifts, {
         username,
         timestamp,
-        gift_id
-    }).
+        gift_id }).
 
 -record(user_count, {count}).
 -record(twitter_oauth, {user_id, token, secret}).

+ 1 - 1
rebar.config

@@ -1,5 +1,5 @@
 {lib_dirs, ["..","/mnt/glusterfs/apps/riak_bin"]}.
 {deps_dir, ["deps"]}.
 {deps,[
-    {mqs,        ".*",    {git, "git@github.com:synrc/white_rabbit.git", "master"}}
+    {mqs,        ".*",    {git, "git@github.com:synrc/mqs.git", "master"}}
 ]}.

+ 27 - 27
src/accounts.erl

@@ -1,7 +1,7 @@
 -module(accounts).
--include("accounts.hrl").
--include("membership_packages.hrl").
--include("log.hrl").
+-include_lib("kvs/include/accounts.hrl").
+-include_lib("kvs/include/membership_packages.hrl").
+-include_lib("kvs/include/log.hrl").
 
 -export([debet/2, credit/2, balance/2, create_account/1, create_account/2]).
 -export([transaction/4, transaction/5]).
@@ -13,8 +13,8 @@ transaction(Account, Currency, 0, TransactionInfo) ->
     ?WARNING("zero transaction: Account=~p, Currency=~p,TransactionInfo=~p", [Account, Currency, TransactionInfo]), 
     ok;
 transaction(Account, Currency, Amount, TransactionInfo) when Amount /= 0->
-    {Remitter, Acceptor} = if Amount > 0 -> {?SYSTEM_ACCOUNT_ID, Account};
-                                    true -> {Account, ?SYSTEM_ACCOUNT_ID} end,
+    {Remitter, Acceptor} = if Amount > 0 -> {system, Account};
+                                    true -> {Account, system} end,
     transaction(Remitter, Acceptor, Currency, abs(Amount), TransactionInfo).
 
 %% @doc Add new transaction, will change state of accouts. All transactions
@@ -60,10 +60,10 @@ create_account(AccountId) ->
 
 %% @doc Create account for specified currency.
 create_account(AccountId, Currency) ->
-    Account = #account{id = ?ACC_ID(AccountId, Currency),
+    Account = #account{id = {AccountId, Currency},
                        credit = 0, debet = 0, last_change = 0},
 
-    case store:put(Account) of
+    case kvs:put(Account) of
          ok -> ok;
          Error -> ?ERROR("create_account: put to db error: ~p", [Error]),
                   {error, unable_to_store_account}
@@ -80,14 +80,14 @@ check_quota(User) ->
 -spec check_quota(User::string(), Amount::integer()) -> ok | {error, soft_limit} | {error, hard_limit}.
 
 check_quota(User, Amount) ->
-    SoftLimit = store:get_config("accounts/quota_limit/soft",  -20),
+    SoftLimit = kvs:get_config("accounts/quota_limit/soft",  -20),
     {ok, Balance} = balance(User, quota),
     BalanceAfterChange = Balance - Amount,
     if
         BalanceAfterChange > SoftLimit ->
             ok;
         true ->
-            HardLimit = store:get(config, "accounts/quota_limit/hard",  -100),
+            HardLimit = kvs:get(config, "accounts/quota_limit/hard",  -100),
             if
                 BalanceAfterChange =< HardLimit ->
                     {error, hard_limit};
@@ -100,15 +100,15 @@ commit_transaction(#transaction{remitter = R, acceptor = A,  currency = Currency
     case change_accounts(R, A, Currency, Amount) of
          ok -> nsx_msg:notify_transaction(R,TX),
                nsx_msg:notify_transaction(A,TX);
-         Error -> 
-            case TX#transaction.info of
-                #ti_game_event{} ->
-                    nsx_msg:notify_transaction(R,TX),
-                    nsx_msg:notify_transaction(A,TX);
-                _ ->
-                    ?ERROR("commit transaction error: change accounts ~p", [Error]),
-                    Error
-            end
+         Error ->  skip
+%            case TX#transaction.info of
+%                #tx_game_event{} ->
+%                    nsx_msg:notify_transaction(R,TX),
+%                    nsx_msg:notify_transaction(A,TX);
+%                _ ->
+%                    ?ERROR("commit transaction error: change accounts ~p", [Error]),
+%                    Error
+%            end
     end.
 
 change_accounts(Remitter, Acceptor, Currency, Amount) ->
@@ -124,7 +124,7 @@ change_accounts(Remitter, Acceptor, Currency, Amount) ->
                     %% increase debet of acceptor, last change is positive
                     AA1 = AA#account{debet = AA#account.debet + Amount,
                     last_change = Amount},
-                    store:put([AA1, RA1]);
+                    kvs:put([AA1, RA1]);
                 {error, Reason} ->
                     {error, {remitter_balance, Reason}}
                end;
@@ -136,20 +136,20 @@ change_accounts(Remitter, Acceptor, Currency, Amount) ->
             {error, both_accounts_unavailable}
     end.
 
-check_remitter_balance(#account{id = ?ACC_ID(?SYSTEM_ACCOUNT_ID, _)}, _) -> ok;
+check_remitter_balance(#account{id = {system, _}}, _) -> ok;
 check_remitter_balance(_Account, _Amount) -> ok.
 
 get_account(Account, Currency) ->
-    case store:get(account, ?ACC_ID(Account, Currency)) of
+    case kvs:get(account, {Account, Currency}) of
          {ok, #account{} = AR} -> AR;
          _ -> {error, account_not_found}
     end.
 
-get_currencies() -> [?CURRENCY_GAME_POINTS,
-                     ?CURRENCY_KAKUSH_CURRENCY,
-                     ?CURRENCY_KAKUSH,
-                     ?CURRENCY_QUOTA,
-                     ?CURRENCY_MONEY].
+get_currencies() -> [internal,
+                     currency,
+                     money,
+                     quota,
+                     points].
 
 generate_id() ->
     {MegSec, Sec, MicroSec} = now(),
@@ -157,7 +157,7 @@ generate_id() ->
     lists:concat([MegSec*1000000000000, Sec*1000000, MicroSec, "-", H]).
 
 user_paid(UId) ->
-    {_, UP} = store:get(user_purchase, UId),
+    {_, UP} = kvs:get(user_purchase, UId),
     case UP of
         notfound -> false;
         #user_purchase{top = undefined} -> false;

+ 17 - 37
src/acls.erl

@@ -2,89 +2,69 @@
 -author('Vladimir Baranov <baranoff.vladimir@gmail.com>').
 -compile(export_all).
 
--include("acls.hrl").
--include("users.hrl").
--include("groups.hrl").
--include("feeds.hrl").
+-include_lib("kvs/include/acls.hrl").
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/groups.hrl").
+-include_lib("kvs/include/feeds.hrl").
 
 define_access(default  = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action);
 define_access({user, _Username} = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action);
 define_access({user_type, _Usertype} = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action);
 define_access({ip, _Ip} = Accessor, Resource, Action) -> do_define_access(Accessor, Resource, Action).
 
-do_define_access(Accessor, Resource, Action) -> store:acl_add_entry(select_type(Resource), Accessor, Action).
+do_define_access(Accessor, Resource, Action) -> kvs:acl_add_entry(select_type(Resource), Accessor, Action).
 
 check(Keys) ->
-    Acls = [Acl || {ok, Acl = #acl_entry{}} <-
-                       [store:get(acl_entry, Key) || Key <- Keys]],
-
+    Acls = [Acl || {ok, Acl = #acl_entry{}} <- [kvs:get(acl_entry, Key) || Key <- Keys]],
     case Acls of
         [] -> none;
-        [#acl_entry{action = Action} | _] ->
-            Action
-    end.
+        [#acl_entry{action = Action} | _] -> Action end.
 
 check_access(#user{username = UId, type = UType}, #feed{id = FId}) ->
     Feed = {feed, FId},
-    Query = [ {{user, UId}, Feed},
-              {{user_type, UType}, Feed},
-              {default, Feed}],
+    Query = [ {{user, UId}, Feed}, {{user_type, UType}, Feed}, {default, Feed}],
     check(Query);
 
 check_access(#user{username = UId, type = UType}, #group{username = GId}) ->
     Group = {group, GId},
-    Query = [ {{user, UId}, Group},
-              {{user_type, UType}, Group},
-              {default, Group}],
+    Query = [ {{user, UId}, Group}, {{user_type, UType}, Group}, {default, Group}],
     check(Query);
 
 
 check_access(#user{username = AId, type = AType}, #user{username = RId}) ->
     User = {user, RId},
-    Query = [ {{user, AId}, User},
-              {{user_type, AType}, User},
-              {default, User} ],
+    Query = [ {{user, AId}, User}, {{user_type, AType}, User}, {default, User} ],
     check(Query);
 
 check_access({user_type, Type}, #user{username = RId}) ->
     User = {user, RId},
-    Query = [ {{user_type, Type}, User},
-              {default, User} ],
+    Query = [ {{user_type, Type}, User}, {default, User} ],
     check(Query);
 
 check_access({user_type, Type}, #feed{id = FId}) ->
     Feed = {feed, FId},
-    Query = [ {{user_type, Type}, Feed},
-              {default, Feed} ],
+    Query = [ {{user_type, Type}, Feed}, {default, Feed} ],
     check(Query);
 
 check_access({user_type, Type}, #group{username = GId}) ->
     Group = {group, GId},
-    Query = [{{user_type, Type}, Group},
-             {default, Group}],
+    Query = [{{user_type, Type}, Group}, {default, Group}],
     check(Query);
 
 check_access({ip, _Ip} = Accessor, {feature, _Feature} = Resource) ->
-    Query = [{Accessor, Resource},
-             {default, Resource}],
+    Query = [{Accessor, Resource}, {default, Resource}],
     check(Query);
 
 check_access(#user{username = AId, type = AType}, {feature, _Feature} = R) ->
-    Query = [ {{user, AId}, R},
-              {{user_type, AType}, R},
-              {default, R} ],
+    Query = [ {{user, AId}, R}, {{user_type, AType}, R}, {default, R} ],
     check(Query);
 
-%% for testing purposes
 check_access(UId, {feature, _Feature} = Resource) ->
     case users:get_user(UId) of
-        {ok, User} ->
-            check_access(User, Resource);
-        E ->
-            E
+        {ok, User} -> check_access(User, Resource);
+        E -> E
     end.
 
-
 select_type(#user{username = UId}) -> {user, UId};
 select_type(#group{username = GId}) -> {group, GId};
 select_type(#feed{id = FId}) -> {feed, FId};

+ 3 - 3
src/comments.erl

@@ -4,12 +4,12 @@
 
 add(EId, User, Value) ->  add(EId, User, Value, []).
 add(EId, User, Value, Medias) ->
-    CId = store:next_id("comment"),
+    CId = kvs:next_id("comment"),
     R = #comment{id = {CId, EId}, comment_id = CId, entry_id = EId,
                  content = Value, author_id = User, media = Medias, create_time = now() },
-    case store:put(R) of
+    case kvs:put(R) of
         ok -> {ok, R};
         A -> A end.
 
 select_by_entry_id(EntryId) ->
-    store:comments_by_entry(EntryId).
+    kvs:comments_by_entry(EntryId).

+ 58 - 66
src/feeds.erl

@@ -1,29 +1,29 @@
 -module(feeds).
 -compile(export_all).
--include("feeds.hrl").
--include("users.hrl").
--include("groups.hrl").
--include("log.hrl").
+-include_lib("kvs/include/feeds.hrl").
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/groups.hrl").
+-include_lib("kvs/include/log.hrl").
 
 create() ->
-    FId = store:next_id("feed", 1),
-    ok = store:put(#feed{id = FId} ),
+    FId = kvs:next_id("feed", 1),
+    ok = kvs:put(#feed{id = FId} ),
     FId.
 
 add_direct_message(FId, User, Desc) -> add_direct_message(FId, User, utils:uuid_ex(), Desc).
 add_direct_message(FId, User, EntryId, Desc) -> add_direct_message(FId, User, undefined, EntryId, Desc, []).
-add_direct_message(FId, User, To, EntryId, Desc, Medias) -> store:feed_add_direct_message(FId, User, To, EntryId, Desc, Medias).
-add_group_entry(FId, User, EntryId, Desc, Medias) -> store:feed_add_entry(FId, User, EntryId, Desc, Medias).
-add_group_entry(FId, User, To, EntryId, Desc, Medias, Type) -> store:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, "").
+add_direct_message(FId, User, To, EntryId, Desc, Medias) -> kvs:feed_add_direct_message(FId, User, To, EntryId, Desc, Medias).
+add_group_entry(FId, User, EntryId, Desc, Medias) -> kvs:feed_add_entry(FId, User, EntryId, Desc, Medias).
+add_group_entry(FId, User, To, EntryId, Desc, Medias, Type) -> kvs:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, "").
 add_entry(FId, User, EntryId, Desc) -> add_entry(FId, User, EntryId, Desc, []).
-add_entry(FId, User, EntryId, Desc, Medias) -> store:feed_add_entry(FId, User, EntryId, Desc, Medias).
-add_entry(FId, User, To, EntryId, Desc, Medias, Type) -> store:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, "").
-add_shared_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy) -> store:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy).
+add_entry(FId, User, EntryId, Desc, Medias) -> kvs:feed_add_entry(FId, User, EntryId, Desc, Medias).
+add_entry(FId, User, To, EntryId, Desc, Medias, Type) -> kvs:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, "").
+add_shared_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy) -> kvs:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy).
 
 add_like(Fid, Eid, Uid) ->
     Write_one_like = fun(Next) ->
-        Self_id = store:next_id("one_like", 1),   
-        store:put(#one_like{    % add one like
+        Self_id = kvs:next_id("one_like", 1),   
+        kvs:put(#one_like{    % add one like
             id = Self_id,
             user_id = Uid,
             entry_id = Eid,
@@ -34,28 +34,28 @@ add_like(Fid, Eid, Uid) ->
         Self_id
     end,
     % add entry - like
-    case store:get(entry_likes, Eid) of
+    case kvs:get(entry_likes, Eid) of
         {ok, ELikes} -> 
-            store:put(ELikes#entry_likes{
+            kvs:put(ELikes#entry_likes{
                 one_like_head = Write_one_like(ELikes#entry_likes.one_like_head), 
                 total_count = ELikes#entry_likes.total_count + 1
             });
         {error, notfound} ->
-            store:put(#entry_likes{
+            kvs:put(#entry_likes{
                 entry_id = Eid,                
                 one_like_head = Write_one_like(undefined),
                 total_count = 1
             })
     end,
     % add user - like
-    case store:get(user_likes, Uid) of
+    case kvs:get(user_likes, Uid) of
         {ok, ULikes} -> 
-            store:put(ULikes#user_likes{
+            kvs:put(ULikes#user_likes{
                 one_like_head = Write_one_like(ULikes#user_likes.one_like_head),
                 total_count = ULikes#user_likes.total_count + 1
             });
         {error, notfound} ->
-            store:put(#user_likes{
+            kvs:put(#user_likes{
                 user_id = Uid,                
                 one_like_head = Write_one_like(undefined),
                 total_count = 1
@@ -65,7 +65,7 @@ add_like(Fid, Eid, Uid) ->
 % statistics
 
 get_entries_count(Uid) ->
-    case store:get(user_etries_count, Uid) of
+    case kvs:get(user_etries_count, Uid) of
         {ok, UEC} -> 
             UEC#user_etries_count.entries;
         {error, notfound} ->
@@ -73,24 +73,24 @@ get_entries_count(Uid) ->
     end.
 
 get_comments_count(Uid) ->
-    case store:get(user_etries_count, Uid) of
+    case kvs:get(user_etries_count, Uid) of
         {ok, UEC} -> 
             UEC#user_etries_count.comments;
         {error, notfound} ->
             0
     end.
 
-get_feed(FId) -> store:get(feed, FId).
-get_entries_in_feed(FId) -> store:entries_in_feed(FId).
-get_entries_in_feed(FId, Count) -> store:entries_in_feed(FId, Count).
-get_entries_in_feed(FId, StartFrom, Count) -> store:entries_in_feed(FId, StartFrom, Count).
-get_direct_messages(FId, Count) -> store:entries_in_feed(FId, undefined, Count).
-get_direct_messages(FId, StartFrom, Count) -> store:entries_in_feed(FId, StartFrom, Count).
-get_entries_in_feed(FId, StartFrom, Count, FromUserId)-> Entries = store:entries_in_feed(FId, StartFrom, Count),
+get_feed(FId) -> kvs:get(feed, FId).
+get_entries_in_feed(FId) -> kvs:entries_in_feed(FId).
+get_entries_in_feed(FId, Count) -> kvs:entries_in_feed(FId, Count).
+get_entries_in_feed(FId, StartFrom, Count) -> kvs:entries_in_feed(FId, StartFrom, Count).
+get_direct_messages(FId, Count) -> kvs:entries_in_feed(FId, undefined, Count).
+get_direct_messages(FId, StartFrom, Count) -> kvs:entries_in_feed(FId, StartFrom, Count).
+get_entries_in_feed(FId, StartFrom, Count, FromUserId)-> Entries = kvs:entries_in_feed(FId, StartFrom, Count),
     [E || #entry{from = From} = E <- Entries, From == FromUserId].
 
 create_message(Table) ->
-    EId = store:next_id("entry", 1),
+    EId = kvs:next_id("entry", 1),
     #entry{id = {EId, system_info},
         entry_id = EId,
         from = system,
@@ -102,109 +102,101 @@ create_message(Table) ->
 remove_entry(FeedId, EId) ->
     {ok, #feed{top = TopId} = Feed} = get_feed(FeedId),
 
-    case store:get(entry, {EId, FeedId}) of
+    case kvs:get(entry, {EId, FeedId}) of
         {ok, #entry{prev = Prev, next = Next}}->
             ?INFO("P: ~p, N: ~p", [Prev, Next]),
-            case store:get(entry, Next) of
-                {ok, NE} -> store:put(NE#entry{prev = Prev});
+            case kvs:get(entry, Next) of
+                {ok, NE} -> kvs:put(NE#entry{prev = Prev});
                 _ -> ok
             end,
-            case store:get(entry, Prev) of
-                {ok, PE} -> store:put(PE#entry{next = Next});
+            case kvs:get(entry, Prev) of
+                {ok, PE} -> kvs:put(PE#entry{next = Next});
                 _ -> ok
             end,
 
             case TopId of
-                {EId, FeedId} -> store:put(Feed#feed{top = Prev});
+                {EId, FeedId} -> kvs:put(Feed#feed{top = Prev});
                 _ -> ok
             end;
         {error, notfound} -> ?INFO("Not found"), ok
     end,
-    store:delete(entry, {EId, FeedId}).
+    kvs:delete(entry, {EId, FeedId}).
 
 edit_entry(FeedId, EId, NewDescription) ->
-    case store:entry_by_id({EId, FeedId}) of
+    case kvs:entry_by_id({EId, FeedId}) of
         {ok, OldEntry} ->
             NewEntryRaw =  OldEntry#entry{description = NewDescription,
                                           raw_description = NewDescription},
             NewEntry = feedformat:format(NewEntryRaw),
-            store:put(NewEntry);
+            kvs:put(NewEntry);
         {error, notfound}->
             {error, notfound}
     end.
 
 remove_entry_comments(FId, EId) ->
-    AllComments = store:comments_by_entry(FId, EId),
+    AllComments = kvs:comments_by_entry(FId, EId),
     [begin
-          store:delete(comment, ID),
-          remove_media(M)
+          kvs:delete(comment, ID)
      end || #comment{id = ID, media = M} <- AllComments].
 
 entry_add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias) ->
-     case store:entry_by_id({EntryId, FId}) of
+     case kvs:entry_by_id({EntryId, FId}) of
          {ok, _E} ->
-             store:add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias);
+             kvs:add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias);
          _ ->
              ok
      end.
 
-remove_media([]) -> ok;
-remove_media([#media{url=undefined, thumbnail_url=undefined}|T]) -> remove_media(T);
-remove_media([#media{url=undefined, thumbnail_url=TUrl}|T]) -> file:delete(?ROOT ++ TUrl), remove_media(T);
-remove_media([#media{url=Url, thumbnail_url=undefined}|T]) -> file:delete(?ROOT ++ Url), remove_media(T);
-remove_media([#media{url=Url, thumbnail_url=TUrl}|T]) -> file:delete(?ROOT ++ Url),file:delete(?ROOT ++ TUrl), remove_media(T).
-
-
 get_one_like_list(undefined) -> [];
-get_one_like_list(Id) -> {ok, OneLike} = store:get(one_like, Id),
+get_one_like_list(Id) -> {ok, OneLike} = kvs:get(one_like, Id),
     [OneLike] ++ get_one_like_list(OneLike#one_like.next).
 
 get_entries_likes(Entry_id) ->
-    case store:get(entry_likes, Entry_id) of
+    case kvs:get(entry_likes, Entry_id) of
         {ok, Likes} -> get_one_like_list(Likes#entry_likes.one_like_head);
         {error, notfound} -> []
     end.
 
 get_entries_likes_count(Entry_id) ->
-    case store:get(entry_likes, Entry_id) of
+    case kvs:get(entry_likes, Entry_id) of
         {ok, Likes} ->
             Likes#entry_likes.total_count;
         {error, notfound} -> 0
     end.
 
 get_user_likes_count(UserId) ->
-    case store:get(user_likes, UserId) of
+    case kvs:get(user_likes, UserId) of
         {ok, Likes} -> Likes#user_likes.total_count;
         {error, notfound} -> 0
     end.
 
 get_user_likes(UserId) ->
-    case store:get(user_likes, UserId) of
+    case kvs:get(user_likes, UserId) of
         {ok, Likes} -> get_one_like_list(Likes#user_likes.one_like_head);
         {error, notfound} -> []
     end.
 
 get_one_like_list(undefined, _) -> [];
 get_one_like_list(_, 0) -> [];
-get_one_like_list(Id, N) -> {ok, OneLike} = store:get(one_like, Id),
+get_one_like_list(Id, N) -> {ok, OneLike} = kvs:get(one_like, Id),
     [OneLike] ++ get_one_like_list(OneLike#one_like.next, N-1).
 
 get_user_likes(UserId, {Page, PageAmount}) ->
-    case store:get(user_likes, UserId) of
+    case kvs:get(user_likes, UserId) of
         {ok, Likes} -> lists:nthtail((Page-1)*PageAmount, get_one_like_list(Likes#user_likes.one_like_head, PageAmount*Page));
         {error, notfound} -> []
     end.
 
-% we have same in nsm_user? Why?
-is_subscribed_user(UserUidWho, UserUidWhom) -> nsm_users:is_user_subscr(UserUidWho, UserUidWhom).
-user_subscription_count(UserUid) -> length(nsm_users:list_subscr(UserUid)).
-user_friends_count(UserUid) -> length(nsm_users:list_subscr_me(UserUid)).
+% we have same in user? Why?
+is_subscribed_user(UserUidWho, UserUidWhom) -> users:is_user_subscr(UserUidWho, UserUidWhom).
+user_subscription_count(UserUid) -> length(users:list_subscr(UserUid)).
+user_friends_count(UserUid) -> length(users:list_subscr_me(UserUid)).
 
 get_comments_entries(UserUid, _, _Page, _PageAmount) ->
-    Pids = [Eid || #comment{entry_id=Eid} <- store:select(comment,
+    Pids = [Eid || #comment{entry_id=Eid} <- kvs:select(comment,
         fun(#comment{author_id=Who}) when Who=:=UserUid ->true;(_)->false end)],
     %?PRINT({"GCE pids length: ", length(Pids)}),
-    lists:flatten([store:select(entry,[{where, fun(#entry{entry_id=ID})-> ID=:=Pid end},
+    lists:flatten([kvs:select(entry,[{where, fun(#entry{entry_id=ID})-> ID=:=Pid end},
         {order, {1, descending}},{limit, {1,1}}]) || Pid <- Pids]).
 
 get_my_discussions(_FId, Page, PageAmount, UserUid) ->
@@ -212,9 +204,9 @@ get_my_discussions(_FId, Page, PageAmount, UserUid) ->
         0 -> 1
         ;M-> M
     end,
-    Pids = [Eid || #comment{entry_id=Eid} <- store:select(comment,
+    Pids = [Eid || #comment{entry_id=Eid} <- kvs:select(comment,
         fun(#comment{author_id=Who}) when Who=:=UserUid ->true;(_)->false end)],
-    lists:flatten([store:select(entry,[{where, fun(#entry{entry_id=ID})-> ID=:=Pid end},
+    lists:flatten([kvs:select(entry,[{where, fun(#entry{entry_id=ID})-> ID=:=Pid end},
         {order, {1, descending}},{limit, {1,1}}]) || Pid <- Pids]).
 
 test_likes() ->

+ 25 - 29
src/groups.erl

@@ -1,13 +1,13 @@
 -module(groups).
 -compile(export_all).
--include("users.hrl").
--include("groups.hrl").
--include("feeds.hrl").
--include("log.hrl").
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/groups.hrl").
+-include_lib("kvs/include/feeds.hrl").
+-include_lib("kvs/include/log.hrl").
 
 retrieve_groups(User) ->
     ?INFO("retrieve_groups: ~p",[User]),
-    case list_groups_per_user(User) of
+    case participate(User) of
          [] -> [];
          Gs -> UC_GId = lists:sublist(lists:reverse(
                               lists:sort([{group_members_count(GId), GId} || GId <- Gs])), 
@@ -18,9 +18,9 @@ retrieve_groups(User) ->
                [X||X<-Result,X/=undefined] end.
 
 create_group_directly_to_db(UId, GId, Name, Desc, Publicity) ->
-    FId = store:feed_create(),
+    FId = kvs:feed_create(),
     CTime = erlang:now(),
-    store:put(#group{username = GId,
+    kvs:put(#group{username = GId,
                       name = Name,
                       description = Desc,
                       publicity = Publicity,
@@ -35,10 +35,10 @@ create_group_directly_to_db(UId, GId, Name, Desc, Publicity) ->
 add_to_group(Who, GId, Type, Owner) -> nsx_msg:notify(["subscription", "user", Owner, "add_to_group"], {GId, Who, Type}).
 
 add_to_group_directly_to_db(UId, GId, Type) ->
-    store:put(#group_subs{user_id=UId, group_id=GId, user_type=Type}),
-    {ok, Group} = store:get(group, GId),
+    kvs:put(#group_subscription{key={UId,GId},user_id=UId, group_id=GId, user_type=Type}),
+    {ok, Group} = kvs:get(group, GId),
     GU = Group#group.users_count,
-    store:put(Group#group{users_count = GU+1}).
+    kvs:put(Group#group{users_count = GU+1}).
 
 delete_group(GId) ->
     {_, Group} = get_group(GId),
@@ -46,25 +46,25 @@ delete_group(GId) ->
         notfound -> ok;
         _ ->
             nsx_msg:notify([feed, delete, GId], empty),
-            store:delete_by_index(group_subs, <<"group_subs_group_id_bin">>, GId),         
-            store:delete(feed, Group#group.feed),
-            store:delete(group, GId),
+            kvs:delete_by_index(group_subscription, <<"group_subs_group_id_bin">>, GId),         
+            kvs:delete(feed, Group#group.feed),
+            kvs:delete(group, GId),
             % unbind exchange
-            {ok, Channel} = nsm_mq:open([]),
+            {ok, Channel} = mqs:open([]),
             Routes = users:rk_group_feed(GId),
-            nsm_users:unbind_group_exchange(Channel, GId, Routes),
-            nsm_mq_channel:close(Channel)
+            users:unbind_group_exchange(Channel, GId, Routes),
+            mqs_channel:close(Channel)
     end.
 
-list_groups_per_user(UId) -> [GId || #group_subs{group_id=GId} <- store:all_by_index(group_subs, <<"group_subs_user_id_bin">>, UId) ].
-list_group_members(GId) -> [UId || #group_subs{user_id=UId, user_type=UT} <- store:all_by_index(group_subs, <<"group_subs_group_id_bin">>, GId), UT == member ].
-list_group_members_by_type(GId, Type) -> [UId || #group_subs{user_id=UId, user_type=UT} <- store:all_by_index(group_subs, <<"group_subs_group_id_bin">>, GId), UT == Type ].
-list_group_members_with_types(GId) -> [{UId, UType} || #group_subs{user_id=UId, user_type=UType} <- store:all_by_index(group_subs, <<"group_subs_group_id_bin">>, list_to_binary(GId)) ].
+participate(UId) -> [GId || #group_subscription{group_id=GId} <- kvs:all_by_index(group_subs, <<"group_subs_user_id_bin">>, UId) ].
+members(GId) -> [UId || #group_subscription{user_id=UId, user_type=UT} <- kvs:all_by_index(group_subs, <<"group_subs_group_id_bin">>, GId), UT == member ].
+members_by_type(GId, Type) -> [UId || #group_subscription{user_id=UId, user_type=UT} <- kvs:all_by_index(group_subs, <<"group_subs_group_id_bin">>, GId), UT == Type ].
+members_with_types(GId) -> [{UId, UType} || #group_subscription{user_id=UId, user_type=UType} <- kvs:all_by_index(group_subs, <<"group_subs_group_id_bin">>, list_to_binary(GId)) ].
 
-get_group(GId) -> store:get(group, GId).
+get_group(GId) -> kvs:get(group, GId).
 
 user_is_owner(UId, GId) ->
-    {R, Group} = store:get(group, GId),
+    {R, Group} = kvs:get(group, GId),
     case R of
         ok -> case Group#group.owner of
                 UId -> true;
@@ -74,21 +74,17 @@ user_is_owner(UId, GId) ->
     end.
 
 user_in_group(UId, GId) ->
-    case store:get(group_subs, {UId, GId}) of
+    case kvs:get(group_subs, {UId, GId}) of
         {error, notfound} -> false;
         _ -> true
     end.
 
 group_user_type(UId, GId) ->
-    case store:get(group_subs, {UId, GId}) of
+    case kvs:get(group_subs, {UId, GId}) of
         {error, notfound} -> not_in_group;
-        {ok, #group_subs{user_type=Type}} -> Type
+        {ok, #group_subscription{user_type=Type}} -> Type
     end.
 
-get_all_groups() -> store:all(group).
-get_popular_groups() -> ["kakaranet", "yeniler"].   % :-)
-
-%% join if group public, or send join request to group
 join_group(GId, User) ->
     {ok, Group} = get_group(GId),
     case Group of

+ 15 - 15
src/invites.erl

@@ -1,11 +1,11 @@
 -module(invites).
 -compile(export_all).
--include_lib("users.hrl").
--include_lib("invites.hrl").
--include_lib("log.hrl").
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/invites.hrl").
+-include_lib("kvs/include/log.hrl").
 
 %% use rpc call to web node to get gettext support
--define(TXT2(Key, Lang), rpc:call(?WEBSERVER_NODE, gettext, key2str, [Key, Lang])).
+-define(TXT2(Key, Lang), gettext:key2str(Key, Lang)).
 
 generate_code(User) -> generate_code(User, undefined).
 generate_code(#user{username = User}, Mail) -> generate_code(User, Mail);
@@ -16,12 +16,12 @@ generate_code(User, Mail) when is_list(User);
                        create_date = erlang:now(),
                        recipient = Mail,
                        issuer = User},
-    %store:put(Rec),
+    %kvs:put(Rec),
     nsx_msg:notify(["invite", "user", User, "add_invite_to_issuer"], {Rec}),
     {ok, Code}.
 
 check_code(Code) ->
-    case store:get(invite_code, Code) of
+    case kvs:get(invite_code, Code) of
         {ok, Invite} ->
             case Invite of
                 Invite when Invite#invite_code.created_user =/= undefined ->
@@ -36,13 +36,13 @@ check_code(Code) ->
 use_code(Code, #user{username = UN}) ->
     use_code(Code, UN);
 use_code(Code, User) when is_list(User) ->
-    case store:get(invite_code, Code) of
+    case kvs:get(invite_code, Code) of
         {ok, Invite} ->
-            Result = store:put(Invite#invite_code{created_user = User}),
+            Result = kvs:put(Invite#invite_code{created_user = User}),
             %% add to tree
             Parent = Invite#invite_code.issuer,
             Parent /= undefined andalso
-                store:put_into_invitation_tree(Parent, User, Code),
+                kvs:put_into_invitation_tree(Parent, User, Code),
             ?INFO("Put code: parent ~p, user: ~p, Code: ~p", [Parent, User, Code]),
             Result;
         {error, _} ->
@@ -50,10 +50,10 @@ use_code(Code, User) when is_list(User) ->
     end.
 
 get_user_code(#user{username = UN}) -> get_user_code(UN);
-get_user_code(User) when is_list(User) -> store:invite_code_by_issuer(User).
+get_user_code(User) when is_list(User) -> kvs:invite_code_by_issuer(User).
 get_code_per_created_user(#user{username = UN}) -> get_code_per_created_user(UN);
-get_code_per_created_user(User) -> store:invite_code_by_user(User).
-get_all_code() -> store:all(invite_code).
+get_code_per_created_user(User) -> kvs:invite_code_by_user(User).
+get_all_code() -> kvs:all(invite_code).
 
 code() ->
     <<A:(16*8), _/binary>> = crypto:rand_bytes(16),
@@ -66,20 +66,20 @@ send_invite_email(User, Email, UserName, Text) ->
 
 -spec send_invite_email(record(user), string(), string(), string(), string()) -> {ok, string()} | {error, atom()}.
 send_invite_email(User, Email, UserName, Text, Lang) ->
-    case rpc:call(?WEBSERVER_NODE,validator_is_email,validate,["", Email]) of
+    case validator_is_email:validate("", Email) of
 	true ->
 	    case length(UserName)>0 of
 		true ->
 		    Code = generate_code(User, Email),
 		    ?INFO("Code: ~p",[Code]),
 		    {ok, InviteCode} = Code,
-		    Url = rpc:call(?WEBSERVER_NODE, site_utils, create_url_invite, [InviteCode]),
+		    Url = site_utils:create_url_invite(InviteCode),
 		    ?INFO("Invite url: ~p, InviteCode: ~p",[Url,InviteCode]),
 		    FromUser = case User#user.username of
 				   S when is_list(S) -> S;
 				   undefined -> ?TXT2("'kakaranet robot'", Lang)
 			       end,
-		    {Subject, Content} = rpc:call(?WEBSERVER_NODE,site_utils,invite_message,[FromUser, Url, Text, UserName, Lang]),
+		    {Subject, Content} = site_utils:invite_message(FromUser, Url, Text, UserName, Lang),
                     nsx_msg:notify_email(Subject, Content, Email),
 		    {ok, InviteCode};
 		_ ->

+ 2 - 2
src/store.app.src → src/kvs.app.src

@@ -1,9 +1,9 @@
-{application, store,
+{application, kvs,
  [
   {description, "Distributed Persistance"},
   {vsn, "1"},
   {registered, []},
   {applications, [kernel,stdlib,riak_kv,mqs]},
-  {mod, { store_app, []}},
+  {mod, { kvs_app, []}},
   {env, []}
  ]}.

+ 380 - 0
src/kvs.erl

@@ -0,0 +1,380 @@
+-module(kvs).
+-author('Maxim Sokhatsky <maxim@synrc.com>').
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/translations.hrl").
+-include_lib("kvs/include/groups.hrl").
+-include_lib("kvs/include/feeds.hrl").
+-include_lib("kvs/include/acls.hrl").
+-include_lib("kvs/include/meetings.hrl").
+-include_lib("kvs/include/invites.hrl").
+-include_lib("kvs/include/config.hrl").
+-include_lib("kvs/include/accounts.hrl").
+-include_lib("kvs/include/log.hrl").
+-include_lib("kvs/include/membership_packages.hrl").
+-include_lib("stdlib/include/qlc.hrl").
+-compile(export_all).
+
+-define(DBA, store_riak).
+
+start() -> DBA = ?DBA, DBA:start().
+dir() -> DBA = ?DBA, DBA:dir().
+purchases(UserId) -> DBA = ?DBA, DBA:purchases(UserId).
+transactions(UserId) -> DBA = ?DBA, DBA:transactions(UserId).
+stop() -> DBA = ?DBA, DBA:stop().
+initialize() -> DBA = ?DBA, DBA:initialize().
+delete() -> DBA = ?DBA, DBA:delete().
+init_indexes() -> DBA = ?DBA, DBA:init_indexes().
+
+init_db() ->
+    case kvs:get(user,"alice") of
+       {error,_} ->
+            DBA = ?DBA,
+            DBA:init_db(),
+            add_seq_ids(),
+            accounts:create_account(system),
+            add_sample_users(),
+            add_sample_packages(),
+            add_translations(),
+            pointing_rules:setup(),
+            add_configs(),
+            case is_production() of
+                false ->
+%                    add_affiliates(),
+%                    add_contracts(),
+                    add_purchases();
+                true ->
+                    do_nothing
+            end;
+            %gifts_tools:import_all();
+       {ok,_} -> ignore
+    end.
+
+is_production() ->
+    case kvs:get(config, "debug/production", false) of
+        {ok, true} -> true;
+        _ -> false
+    end.
+
+add_purchases() ->
+%    ?INFO("~w:add_purchases/0 Started", [?MODULE]),
+    {ok, Pkg1} = membership_packages:get_package(1),
+    {ok, Pkg2} = membership_packages:get_package(2),
+    {ok, Pkg3} = membership_packages:get_package(3),
+    {ok, Pkg4} = membership_packages:get_package(4),
+    PList = [{"doxtop", Pkg1},{"maxim", Pkg2},{"maxim",Pkg4}, {"kate", Pkg3} ],
+    [ok = add_purchase(U, P) || {U, P} <- PList],
+%    ?INFO("~w:add_purchases/0 Finished", [?MODULE]),
+    ok.
+
+add_purchase(UserId, Package) ->
+    {ok, MPId} = membership_packages:add_purchase(
+                         #membership_purchase{user_id=UserId, membership_package=Package }),
+%    ?INFO("Purchase Added: ~p",[MPId]),
+    membership_packages:set_purchase_state(MPId, ?MP_STATE_DONE, undefined).
+
+
+
+add_seq_ids() ->
+    Init = fun(Key) ->
+           case kvs:get(id_seq, Key) of
+                {error, _} -> ok = kvs:put(#id_seq{thing = Key, id = 0});
+                {ok, _} -> ignore
+           end
+    end,
+    Init("meeting"),
+    Init("user_transaction"),
+    Init("transaction"),
+    Init("team"),
+    Init("membership_purchase"),
+    Init("table"),
+    Init("acl"),
+    Init("acl_entry"),
+    Init("feed"),
+    Init("entry"),
+    Init("like_entry"),
+    Init("likes"),
+    Init("one_like"),
+    Init("comment"),
+    Init("save_table").
+
+add_translations() ->
+    lists:foreach(fun({English, Lang, Word}) ->
+                          ok = kvs:put(#translation{english = English, lang = "en",  word = English}),
+                          ok = kvs:put(#translation{english = English, lang = Lang,  word = Word}),
+              ok
+    end, ?URL_DICTIONARY).
+
+add_sample_users() ->
+    UserList = [
+                     #user{username = "maxim", password="kaka15ra",
+                           name = "Maxim", surname = "Sokhatsky", feed = feed_create(),
+                           type = admin, direct = feed_create(),
+                           sex=m,
+                           status=ok,
+                           team = create_team("tours"),
+                           email="maxim.sokhatsky@gmail.com"},
+                     #user{username = "doxtop", password="password",
+                           feed = feed_create(),
+                           name = "Andrii Zadorozhnii",
+                           email="doxtop@synrc.com",
+                           type=admin,
+                           team = create_team("tours"), direct = feed_create(),
+                           status=ok,
+                           age={1981,9,29},
+                           register_date={1345,14071,852889}
+                     } 
+         ],
+
+
+    ?INFO("creating groups"),
+
+    users:init_mq("ahmettez", ["kakaranet", "yeniler"]),
+
+    GId1  = groups:create_group_directly_to_db("ahmettez", "kakaranet", "Kakaranet", "Kakaranet'e Hoşgeldiniz", public),
+    GId2  = groups:create_group_directly_to_db("ahmettez", "yeniler", "Yeniler", "So, you must be new here.", public),
+
+    ?INFO("adding users accounts"),
+    [ begin
+          accounts:create_account(Me#user.username),
+          accounts:transaction(Me#user.username, quota, kvs:get_config("accounts/default_quota", 300), #tx_default_assignment{}),
+          kvs:put(Me#user{password = utils:sha(Me#user.password),
+                                starred = feed_create(),
+                                pinned = feed_create()})
+      end || Me <- UserList],
+    ?INFO("adding users to groups"),
+    [ begin
+          users:init_mq(Me#user.username, [GId1, GId2]),
+          groups:add_to_group_directly_to_db(Me#user.username, GId1, member),
+          groups:add_to_group_directly_to_db(Me#user.username, GId2, member)
+      end || Me <- UserList ],
+    acls:define_access({user, "maxim"},    {feature, admin}, allow),
+    acls:define_access({user_type, admin}, {feature, admin}, allow),
+    ?INFO("making all users each other friends"),
+    [[case Me == Her of
+        true -> ok;
+        false -> userss:subscr_user(Me#user.username, Her#user.username)
+    end || Her <- UserList] || Me <- UserList].
+
+add_sample_packages() -> membership_packages:add_sample_data().
+version() -> ?INFO("version: ~p", [1]).
+
+% blocking
+
+block_user(Who, Whom) -> DBA=?DBA, DBA:block_user(Who, Whom).
+list_blocks(Who) -> DBA=?DBA, DBA:list_blocks(Who).
+unblock_user(Who, Whom) -> DBA=?DBA, DBA:unblock_user(Who, Whom).
+list_blocked_me(Me) -> DBA=?DBA, DBA:list_blocked_me(Me).
+is_user_blocked(Who, Whom) -> DBA=?DBA, DBA:is_user_blocked(Who, Whom).
+
+% configs
+
+add_configs() ->
+    %% smtp
+    kvs:put(#config{key="smtp/user",     value="noreply@kakaranet.com"}),
+    kvs:put(#config{key="smtp/password", value="kakam41l"}),
+    kvs:put(#config{key="smtp/host",     value="posta.kakaranet.com"}),
+    kvs:put(#config{key="smtp/port",     value=465}),
+    kvs:put(#config{key="smtp/with_ssl", value=true}),
+
+    %% accounts
+    kvs:put(#config{key="accounts/default_quota", value=2000}),
+    kvs:put(#config{key="accounts/quota_limit/soft",  value=-30}),
+    kvs:put(#config{key="accounts/quota_limit/hard",  value=-100}),
+
+    %%  purchases
+    kvs:put(#config{key= "purchase/notifications/email",  value=["maxim@synrc.com"]}),
+
+    %%  delivery
+    kvs:put(#config{key= "delivery/notifications/email",  value=["maxim@synrc.com"]}),
+
+    %% tournament, elimination, Tour time limit
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/1", value = 30*60*1000}),
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/2", value = 30*60*1000}),
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/3", value = 30*60*1000}),
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/4", value = 25*60*1000}),
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/5", value = 25*60*1000}),
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/6", value = 25*60*1000}),
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/7", value = 20*60*1000}),
+    kvs:put(#config{key= "games/okey/trn/elim/tour_time_limit/8", value = 20*60*1000}).
+
+% put
+
+-spec put(tuple() | [tuple()]) -> ok.
+put(Record) ->
+%    ?INFO("db:put ~p",[Record]),
+    DBA=?DBA,
+    DBA:put(Record).
+
+
+put_if_none_match(Record) ->
+%    ?INFO("db:put_if_none_match ~p",[Record]),
+    DBA=?DBA,
+    DBA:put_if_none_match(Record).
+
+% update
+
+update(Record, Meta) ->
+%    ?INFO("db:update ~p",[Record]),
+    DBA=?DBA,
+    DBA:update(Record, Meta).
+
+% get
+
+-spec get(atom(), term()) -> {ok, tuple()} | {error, not_found | duplicated}.
+get(RecordName, Key) ->
+    DBA=?DBA,
+    case C = DBA:get(RecordName, Key) of
+    {ok,_R} ->
+%        ?INFO("db:get ~p,", [{RecordName, Key}]),
+        C;
+    A -> A
+    end.
+
+get_for_update(RecordName, Key) ->
+%    ?INFO("db:get_for_update ~p,", [{RecordName, Key}]),
+    DBA=?DBA,
+    DBA:get_for_update(RecordName, Key).
+
+get(RecordName, Key, Default) ->
+    DBA=?DBA,
+    case DBA:get(RecordName, Key) of
+	{ok,{RecordName,Key,Value}} ->
+	    ?INFO("db:get config value ~p,", [{RecordName, Key, Value}]),
+	    {ok,Value};
+	{error, _B} ->
+	    ?INFO("db:get new config value ~p,", [{RecordName, Key, Default}]),
+	    DBA:put({RecordName,Key,Default}),
+	    {ok,Default}
+    end.
+
+get_config(Key, Default) -> {ok, Value} = get(config, Key, Default), Value.
+get_word(Word) -> get(ut_word,Word).
+get_translation({Lang,Word}) -> DBA=?DBA, DBA:get_translation({Lang,Word}).
+
+% delete
+
+delete(Keys) -> DBA=?DBA, DBA:delete(Keys).
+delete(Tab, Key) -> ?INFO("db:delete ~p:~p",[Tab, Key]), DBA=?DBA,DBA:delete(Tab, Key).
+delete_by_index(Tab, IndexId, IndexVal) -> DBA=?DBA,DBA:delete_by_index(Tab, IndexId, IndexVal).
+% select
+
+multi_select(RecordName, Keys) -> DBA=?DBA,DBA:multi_select(RecordName, Keys).
+select(From, PredicateFunction) -> ?INFO("db:select ~p, ~p",[From,PredicateFunction]), DBA=?DBA, DBA:select(From, PredicateFunction).
+count(RecordName) -> DBA=?DBA,DBA:count(RecordName).
+all(RecordName) -> DBA=?DBA,DBA:all(RecordName).
+all_by_index(RecordName, Index, IndexValue) -> DBA=?DBA,DBA:all_by_index(RecordName, Index, IndexValue).
+
+% id generator
+
+next_id(RecordName) -> DBA=?DBA,DBA:next_id(RecordName).
+next_id(RecordName, Incr) -> DBA=?DBA,DBA:next_id(RecordName, Incr).
+next_id(RecordName, Default, Incr) -> DBA=?DBA,DBA:next_id(RecordName, Default, Incr).
+
+% browser counter
+
+delete_browser_counter_older_than(MinTS) -> DBA=?DBA,DBA:delete_browser_counter_older_than(MinTS).
+browser_counter_by_game(Game) -> DBA=?DBA,DBA:browser_counter_by_game(Game).
+
+% invites
+
+unused_invites() -> DBA=?DBA,DBA:unused_invites().
+user_by_verification_code(Code) -> DBA=?DBA,DBA:user_by_verification_code(Code).
+user_by_facebook_id(FBId) -> DBA=?DBA,DBA:user_by_facebook_id(FBId).
+user_by_email(Email) -> DBA=?DBA,DBA:user_by_email(Email).
+user_by_username(Name) -> DBA=?DBA,DBA:user_by_username(Name).
+add_invite_to_issuer(User, O) -> DBA=?DBA,DBA:add_invite_to_issuer(User, O).
+invite_code_by_issuer(User) -> DBA=?DBA,DBA:invite_code_by_issuer(User).
+invite_code_by_user(User) -> DBA=?DBA,DBA:invite_code_by_user(User).
+
+% game info
+
+get_save_tables(Id) -> DBA=?DBA,DBA:get_save_tables(Id).
+save_game_table_by_id(Id) -> DBA=?DBA,DBA:save_game_table_by_id(Id).
+
+% feeds
+
+feed_add_direct_message(FId, User, To, EntryId, Desc, Medias) -> DBA=?DBA,DBA:feed_add_direct_message(FId, User, To, EntryId, Desc, Medias).
+feed_add_entry(FId, User, EntryId, Desc, Medias) -> DBA=?DBA,DBA:feed_add_entry(FId, User, EntryId, Desc, Medias).
+feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy) -> DBA=?DBA,DBA:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy).
+acl_add_entry(AclId, Accessor, Action) -> DBA=?DBA,DBA:acl_add_entry(AclId, Accessor, Action).
+acl_entries(AclId) -> DBA=?DBA,DBA:acl_entries(AclId).
+entry_by_id(EntryId) -> DBA=?DBA,DBA:entry_by_id(EntryId).
+comment_by_id(CommentId) -> DBA=?DBA,DBA:comment_by_id(CommentId).
+comments_by_entry({_EId, _FId} = EntryId) -> DBA=?DBA,DBA:comments_by_entry(EntryId).
+entries_in_feed(FeedId) -> DBA=?DBA,DBA:entries_in_feed(FeedId, undefined, all).
+entries_in_feed(FeedId, Count) -> DBA=?DBA,DBA:entries_in_feed(FeedId, undefined, Count).
+entries_in_feed(FeedId, StartFrom, Count) -> DBA=?DBA, DBA:entries_in_feed(FeedId, StartFrom, Count).
+add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias) -> DBA=?DBA, DBA:feed_add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias).
+feed_direct_messages(FId, StartFrom, Count) ->  DBA=?DBA, DBA:entries_in_feed(FId, StartFrom, Count).
+
+% tournaments
+
+tournament_waiting_queue(TID) -> DBA=?DBA, DBA:tournament_waiting_queue(TID).
+join_tournament(UID,TID) -> DBA=?DBA, DBA:join_tournament(UID,TID).
+leave_tournament(UID,TID) -> DBA=?DBA, DBA:leave_tournament(UID,TID).
+tournament_pop_waiting_player(TID) -> DBA=?DBA, DBA:tournament_pop_waiting_player(TID).
+user_tournaments(UID) -> DBA=?DBA, DBA:user_tournaments(UID).
+
+add_transaction_to_user(User, Tx) -> DBA=?DBA, DBA:add_transaction_to_user(User, Tx).
+get_purchases_by_user(User, Count, States) -> DBA=?DBA, DBA:get_purchases_by_user(User, Count, States).
+get_purchases_by_user(User, StartFromPurchase, Count, States) -> DBA=?DBA, DBA:get_purchases_by_user(User, StartFromPurchase, Count, States).
+
+fast_timeouts() ->
+    kvs:put({config,"games/okey/robot_delay_normal",100}),
+    kvs:put({config,"games/okey/challenge_timeout_normal",5000}),
+    kvs:put({config,"games/okey/turn_timeout_normal",200}).
+
+make_admin(User) ->
+    {ok,U} = kvs:get(user, User),
+    kvs:put(U#user{type = admin}),
+    acls:define_access({user, U#user.username}, {feature, admin}, allow),
+    acls:define_access({user_type, admin}, {feature, admin}, allow),
+    ok.
+
+make_rich(User) -> 
+    Q = kvs:get_config("accounts/default_quota",  300),
+    accounts:transaction(User, quota, Q * 100, #tx_default_assignment{}),
+    accounts:transaction(User, internal, Q, #tx_default_assignment{}),
+    accounts:transaction(User, currency, Q * 2, #tx_default_assignment{}).
+
+feed_create() ->
+    FId = kvs:next_id("feed", 1),
+    ok = kvs:put(#feed{id = FId} ),
+    FId.
+
+create_team(Name) ->
+    TID = kvs:next_id("team",1),
+    ok = kvs:put(Team = #team{id=TID,name=Name}),
+    TID.
+
+
+list_to_term(String) ->
+    {ok, T, _} = erl_scan:string(String++"."),
+    case erl_parse:parse_term(T) of
+        {ok, Term} ->
+            Term;
+        {error, Error} ->
+            Error
+    end.
+
+list_buckets() ->
+    [list_to_term(B) || B <- store_riak:dir()].
+
+save_db(Path) ->
+    Data = lists:append([all(B) || B <- list_buckets()]),
+    salode:save(Path, Data).
+
+load_db(Path) ->
+    sore_riak:clean(),
+    add_seq_ids(),
+    AllEntries = salode:load(Path),
+    [{_,_,{_,Handler}}] = ets:lookup(config, "riak_client"),
+    [case is_tuple(E) of
+        false -> skip;
+        true ->  put(E) 
+    end || E <- AllEntries].
+
+make_paid_fake(UId) ->
+    put({user_purchase, UId, "fake_purchase"}).
+
+

+ 3 - 3
src/store_app.erl → src/kvs_app.erl

@@ -1,9 +1,9 @@
--module(store_app).
+-module(kvs_app).
 -behaviour(application).
 -export([start/2, stop/1, wait_vnodes/0]).
 
 wait_riak() ->
-    case nsm_db:put({test,ok}) of
+    case kvs:put({test,ok}) of
          ok -> stop;
          _ -> wait_riak()
     end.
@@ -18,7 +18,7 @@ wait_vnodes() ->
     _ -> error end.
 
 start(_StartType, _StartArgs) ->
-    nsm_db_sup:start_link().
+    kvs_sup:start_link().
 
 stop(_State) ->
     ok.

+ 5 - 5
src/store_sup.erl → src/kvs_sup.erl

@@ -1,4 +1,4 @@
--module(store_sup).
+-module(kvs_sup).
 -behaviour(supervisor).
 -export([start_link/0, stop_riak/0]).
 -export([init/1]).
@@ -32,23 +32,23 @@ init([]) ->
     0 ->
 
     error_logger:info_msg("Waiting for Riak to Start...."),
-    store:start(),
+    kvs:start(),
     error_logger:info_msg("Waiting for Riak to Initialize...."),
     store_app:wait_vnodes();
     _ -> skip end,
 
-    store:initialize(),
+    kvs:initialize(),
 
  case nsx_opt:get_env(nsp_srv,riak_srv_node,0) of
     0 ->
 
-    store:init_indexes(),
+    kvs:init_indexes(),
     case nsx_opt:get_env(store,sync_nodes,false) of
          true -> [ error_logger:info_msg("Joined: ~p ~p~n", [N, riak_core:join(N)]) || N <- nsx_opt:get_env(store, nodes, []) -- [node()] ];
          false -> skip
     end,
     case  nsx_opt:get_env(store,pass_init_db, true) of 
-         false -> store:init_db();
+         false -> kvs:init_db();
          true -> pass
     end;
     _ -> skip

+ 8 - 15
src/map_reduce.erl

@@ -29,7 +29,7 @@ get_single_tables(Setting,UId,GameFSM,_Convert, LeftList) ->
                    end end,
 
     Cursor = fun(Id,FilterFree,FilterUser) ->
-                qlc:cursor(qlc:q([V || {{_,_,_K},_,V=#game_table{creator=C,
+                qlc:cursor(qlc:q([V || {{_,_,_K},_,V={game_table,creator=C,
                                                    rounds=R, game_type=G,
                                                    users=U, game_speed=S,
                                                    game_mode=GM,
@@ -89,7 +89,7 @@ map_call(NodeType,Module,Fun,Args=[ID|Rest],NodeHash0) ->
                       5 -> nsx_opt:get_env(store,DefaultNodeAtom,'maxim@synrc.com');
                       _ -> list_to_atom(NodeType ++ "@srv" ++ 
                            integer_to_list(NodeHash(ID)) ++
-                           ".kakaranet.com") end,
+                           ".synrc.com") end,
 
     ?INFO("map_call: ~p",[{ServerNode,Module,Fun,Args}]),
     rpc:call(ServerNode,Module,Fun,Args).
@@ -97,16 +97,9 @@ map_call(NodeType,Module,Fun,Args=[ID|Rest],NodeHash0) ->
 string_map(X) -> lists:foldl(fun(A,Sum)->A+Sum end,0,X) rem 3+1.
 long_map(X)   -> X div 1000000.
  
-consumer_pid(Args)       -> map_call("app", nsm_bg,pid,Args,string_map).
-cached_feed(Args)        -> map_call("app", nsm_writer,cached_feed,Args,string_map).
-cached_direct(Args)      -> map_call("app", nsm_writer,cached_direct,Args,string_map).
-cached_friends(Args)     -> map_call("app", nsm_writer,cached_friends,Args,string_map).
-cached_groups(Args)      -> map_call("app", nsm_writer,cached_groups,Args,string_map).
-start_lobby(Args)        -> map_call("game",nsm_srv_tournament_lobby_sup,start_lobby,Args,long_map).
-lobby_history(Args)      -> map_call("game",nsm_srv_tournament_lobby,chat_history,Args,long_map).
-start_tournament(Args)   -> map_call("game",game_manager,start_tournament,Args,long_map).
-tournament_started(Args) -> map_call("game",game_manager,  get_tournament,Args,long_map).
-store_token(Args)        -> map_call("game",auth_server,store_token,Args,long_map).
-delete_table(Args)       -> map_call("game",game_manager,destroy_game,Args,long_map).
-public_table(Args)       -> map_call("public",view_table,get_table,Args,long_map).
-start_worker(Args)       -> map_call("app",nsm_launcher,start_worker,Args,string_map). % nsm_queries:start_worker(["doxtop",Type,Feed,Direct]).
+consumer_pid(Args)       -> map_call("app", feed_server,pid,Args,string_map).
+cached_feed(Args)        -> map_call("app", feed_writer,cached_feed,Args,string_map).
+cached_direct(Args)      -> map_call("app", feed_writer,cached_direct,Args,string_map).
+cached_friends(Args)     -> map_call("app", feed_writer,cached_friends,Args,string_map).
+cached_groups(Args)      -> map_call("app", feed_writer,cached_groups,Args,string_map).
+start_worker(Args)       -> map_call("app", feed_launcher,start_worker,Args,string_map).

+ 19 - 19
src/meetings.erl

@@ -1,11 +1,11 @@
 -module(meetings).
--include("users.hrl").
--include("meetings.hrl").
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/meetings.hrl").
 -compile(export_all).
 
 create_team(Name) ->
-    TID = store:next_id("team",1),
-    ok = store:put(Team = #team{id=TID,name=Name}),
+    TID = kvs:next_id("team",1),
+    ok = kvs:put(Team = #team{id=TID,name=Name}),
     TID.
 
 create(UID, Name) -> create(UID, Name, "", date(), time(), 100, 100, undefined, pointing, game_okey, standard, 8, slow).
@@ -14,7 +14,7 @@ create(UID, Name, Desc, Date, Time, Players, Quota, Awards, Type, Game, Mode, To
     TID = rpc:call(NodeAtom, game_manager, gen_game_id, []),
 
     CTime = erlang:now(),
-    ok = store:put(#tournament{name = Name,
+    ok = kvs:put(#meeting{name = Name,
                                    id = TID,
                                    description = Desc,
                                    quota = Quota,
@@ -35,26 +35,26 @@ create(UID, Name, Desc, Date, Time, Players, Quota, Awards, Type, Game, Mode, To
     TID.
 
 get(TID) ->
-    case store:get(tournament, TID) of
+    case kvs:get(meeting, TID) of
         {ok, Tournament} -> Tournament;
-        {error, not_found} -> #tournament{};
-        {error, notfound} -> #tournament{}
+        {error, not_found} -> #meeting{};
+        {error, notfound} -> #meeting{}
     end.
 
 start(_TID) -> ok.
-join(UID, TID) -> store:join_tournament(UID, TID).
-remove(UID, TID) -> store:leave_tournament(UID, TID).
-waiting_player(TID) -> store:tournament_pop_waiting_player(TID).
-joined_users(TID) -> store:tournament_waiting_queue(TID).
-user_tournaments(UID) -> store:user_tournaments(UID).
+join(UID, TID) -> kvs:join_tournament(UID, TID).
+remove(UID, TID) -> kvs:leave_tournament(UID, TID).
+waiting_player(TID) -> kvs:tournament_pop_waiting_player(TID).
+joined_users(TID) -> kvs:tournament_waiting_queue(TID).
+user_tournaments(UID) -> kvs:user_tournaments(UID).
 user_joined(TID, UID) -> 
     AllJoined = [UId || #play_record{who = UId} <- joined_users(TID)],
     lists:member(UID, AllJoined).
-all() -> store:all(tournament).
+all() -> kvs:all(tournament).
 user_is_team_creator(_UID, _TID) -> true.
 list_users_per_team(_TeamID) -> [].
-destroy(TID) -> store:delete_by_index(play_record, <<"play_record_tournament_bin">>, TID),
-                          store:delete(tournament,TID).
-clear() -> [destroy(T#tournament.id) || T <- store:all(tournament)].
-lost() -> lists:usort([erlang:element(3, I) || I <- store:all(play_record)]).
-fake_join(TID) -> [nsm_tournaments:join(nsm_auth:ima_gio2(X),TID)||X<-lists:seq(1,30)].
+destroy(TID) -> kvs:delete_by_index(play_record, <<"play_record_tournament_bin">>, TID),
+                          kvs:delete(tournament,TID).
+clear() -> [destroy(T#meeting.id) || T <- kvs:all(meeting)].
+lost() -> lists:usort([erlang:element(3, I) || I <- kvs:all(play_record)]).
+fake_join(TID) -> [meetings:join(auth:ima_gio2(X),TID)||X<-lists:seq(1,30)].

+ 28 - 62
src/membership_packages.erl

@@ -15,7 +15,7 @@ add_package(#membership_package{}=Package)->
 
 -spec get_package(any())-> {ok, #membership_package{}} | {error, Reason::any()}.
 get_package(PackageId)->
-    case store:get(membership_package, PackageId) of
+    case kvs:get(membership_package, PackageId) of
         {ok, #membership_package{} = Package}->
             {ok, Package};
         {error, Reason}->
@@ -33,7 +33,7 @@ list_packages(Options) ->
 
 -spec list_packages()->[#membership_package{}].
 list_packages()->
-     store:all(membership_package).
+     kvs:all(membership_package).
 
 -spec available_for_sale(package_id(), boolean()) -> ok | {error, any()}.
 available_for_sale(PackageId, State) ->
@@ -56,7 +56,7 @@ add_purchase(#membership_purchase{} = MP) ->
 
 -spec add_purchase(#membership_purchase{}, purchase_state(), StateInfo::any()) -> {ok, PurchaseId::string()}.
 add_purchase(#membership_purchase{} = MP, State0, Info) ->
-    case store:get(membership_purchase, MP#membership_purchase.id) of
+    case kvs:get(membership_purchase, MP#membership_purchase.id) of
         {ok, _} -> {error, already_bought_that_one};
         {error, notfound} ->
             %% fill needed fields
@@ -85,12 +85,12 @@ add_purchase(#membership_purchase{} = MP, State0, Info) ->
 
             ?INFO("Purchase added ~p ~p",[Purchase#membership_purchase.user_id, Purchase]),
 
-            nsm_riak:add_purchase_to_user(Purchase#membership_purchase.user_id, Purchase)
+            store_riak:add_purchase_to_user(Purchase#membership_purchase.user_id, Purchase)
     end.
 
 -spec get_purchase(string())-> {ok, #membership_purchase{}} | {error, Reason::any()}.
 get_purchase(PurchaseId)->
-    case store:get(membership_purchase, PurchaseId) of
+    case kvs:get(membership_purchase, PurchaseId) of
         {ok, #membership_purchase{} = Package}->
             {ok, Package};
         {error, Reason}->
@@ -99,7 +99,7 @@ get_purchase(PurchaseId)->
 
 -spec set_purchase_state(term(), purchase_state(), term()) -> ok.
 set_purchase_state(MPId, NewState, Info) ->
-    case store:get(membership_purchase, MPId) of 
+    case kvs:get(membership_purchase, MPId) of 
       {ok, MP} ->
 
     Time = now(),
@@ -122,12 +122,12 @@ set_purchase_state(MPId, NewState, Info) ->
     NewMP=MP#membership_purchase{state = NewState,
                                          end_time = EndTime,
                                          state_log = NewStateLog},
-    store:put(NewMP),
+    kvs:put(NewMP),
 
     if
         NewState == ?MP_STATE_DONE ->
-            charge_user_account(MP),
-            nsm_affiliates:purchase_hook(NewMP);
+            charge_user_account(MP);
+%            affiliates:purchase_hook(NewMP);
         true ->
             ok
     end,
@@ -139,31 +139,31 @@ set_purchase_state(MPId, NewState, Info) ->
 
 -spec set_purchase_info(term(), term()) -> ok | {error, not_found}.
 set_purchase_info(MPId, Info) ->
-    {ok, MP} = store:get(membership_purchase, MPId),
-    store:put(MP#membership_purchase{info = Info}).
+    {ok, MP} = kvs:get(membership_purchase, MPId),
+    kvs:put(MP#membership_purchase{info = Info}).
 
 set_purchase_external_id(MPId, ExternalId) ->
-    {ok, MP} = store:get(membership_purchase, MPId),
+    {ok, MP} = kvs:get(membership_purchase, MPId),
     case MP#membership_purchase.external_id of
         ExternalId ->
             ok;
         _ ->
-            store:put(MP#membership_purchase{external_id = ExternalId})
+            kvs:put(MP#membership_purchase{external_id = ExternalId})
     end.
 
 -spec create_storage()-> ok.
 create_storage()->
     %% FIXME: usage of direct mnesia calls
-    ok = nsm_mnesia:create_table(membership_package,
+    ok = store_mnesia:create_table(membership_package,
                                     record_info(fields, membership_package),
                                     [{storage, permanent}]),
-    ok = nsm_mnesia:create_table(membership_purchase,
+    ok = store_mnesia:create_table(membership_purchase,
                                     record_info(fields, membership_purchase),
                                     [{storage, permanent}]).
 
 -spec list_purchases() -> list(#membership_purchase{}).
 list_purchases() ->
-    store:all(membership_purchase).
+    kvs:all(membership_purchase).
 
 -spec list_purchases(SelectOptions::list()) -> list(#membership_purchase{}).
 list_purchases(SelectOptions) ->
@@ -177,7 +177,7 @@ list_purchases(SelectOptions) ->
 -spec purchase_id() -> string().
 purchase_id() ->
     %% get next generated id for membership purchase
-    NextId = store:next_id("membership_purchase"),
+    NextId = kvs:next_id("membership_purchase"),
     lists:concat([timestamp(), "_", NextId]).
 
 
@@ -243,10 +243,10 @@ add_sample_data()->
     Enabled = [P#membership_package{available_for_sale = true} ||
                   P <- WithPaymentTypes],
 
-    store:put(Enabled).
+    kvs:put(Enabled).
 
 generate_id()->
-    Id = store:next_id("membership_package"),
+    Id = kvs:next_id("membership_package"),
     integer_to_list(Id).
 
 %% return default value if value match Undefined spec
@@ -267,14 +267,14 @@ charge_user_account(MP) ->
     Quota = Package#membership_package.quota,
     UserId = MP#membership_purchase.user_id,
 
-    PaymentTransactionInfo = #ti_payment{id=MP#membership_purchase.id},
+    PaymentTransactionInfo = #tx_payment{id=MP#membership_purchase.id},
 
     try
         ?INFO("charge user account. OrderId: ~p, User: ~p, Kakush:~p, Quota:~p",
               [OrderId, UserId, Kakush, Quota]),
 
-        nsm_accounts:transaction(UserId, ?CURRENCY_KAKUSH, Kakush, PaymentTransactionInfo),
-        nsm_accounts:transaction(UserId, ?CURRENCY_QUOTA, Quota, PaymentTransactionInfo)
+        accounts:transaction(UserId, internal, Kakush, PaymentTransactionInfo),
+        accounts:transaction(UserId, quota, Quota, PaymentTransactionInfo)
     catch
         _:E ->
             ?ERROR("unable to charge user account. User=~p, OrderId=~p. Error: ~p",
@@ -285,12 +285,12 @@ charge_user_account(MP) ->
 %% get all records from database, filter them with predicate.
 %% FIXME: temporary hack to provide mnesias select functionality with riak
 select(RecordType, Predicate) ->
-    All = store:all(RecordType),
+    All = kvs:all(RecordType),
 	lists:filter(Predicate, All).
 
 
 save_package(Package) ->
-    case store:put([Package]) of
+    case kvs:put([Package]) of
         ok ->
             {ok, Package#membership_package.id};
         {error, Reason}->
@@ -317,20 +317,7 @@ check_conditions([], _, true) -> true.
 
 %% @private
 delete_package(PackageId) ->
-    store:delete(membership_package, PackageId).
-
-%%
-%% Tests
-%%
-%-ifdef(TEST).
-
-packages_test_()->
-    {setup, fun setup/0, fun cleanup/1,
-     {with, [fun list_/1,
-             fun get_/1,
-             fun change_availability_/1]}
-    }.
-
+    kvs:delete(membership_package, PackageId).
 
 setup() ->
     % Uncomment to run tests with dbg:
@@ -367,40 +354,19 @@ setup() ->
 cleanup(Ids) ->
     [ok = delete_package(PackageId) || PackageId <- Ids].
 
-list_(_Packages)->
-    ?assertMatch([#membership_package{no=1}], ?MODULE:list_packages([{payment_type, test_payment_x}])),
-
-    ?assertEqual([], ?MODULE:list_packages([{payment_type, test_payment_y},
-                                            {available_for_sale, true}])),
-    YPaymentTypePackages = ?MODULE:list_packages([{payment_type, test_payment_y}]),
-    YPaymentTypePackagesNumbers = lists:sort([No || #membership_package{no=No} <- YPaymentTypePackages]),
-    ?assertMatch([2,3], YPaymentTypePackagesNumbers).
-
-get_([Id|_])->
-    ?assertMatch({ok, #membership_package{id=Id}}, ?MODULE:get_package(Id)),
-    ?assertMatch({error, _}, ?MODULE:get_package(-1)).
-
-change_availability_([Id | _]) ->
-    [begin
-         ?assertEqual(ok, ?MODULE:available_for_sale(Id, State)),
-         ?assertMatch({ok, #membership_package{id=Id, available_for_sale = State}},
-                      ?MODULE:get_package(Id))
-     end || State <- [true, false]].
-
-
 get_monthly_purchase_limit() ->
-    MostExpencivePackageWorth = lists:max([P#membership_package.amount || P <- store:all(membership_package), P#membership_package.available_for_sale]),
+    MostExpencivePackageWorth = lists:max([P#membership_package.amount || P <- kvs:all(membership_package), P#membership_package.available_for_sale]),
     ?MP_MONTHLY_LIMIT_MULTIPLIER * MostExpencivePackageWorth.
 
 check_limit_over(UId, PackageId) ->
     Limit = ?MP_MONTHLY_LIMIT_MULTIPLIER, %get_monthly_purchase_limit(),
-    {ok, Package} = nsm_membership_packages:get_package(PackageId),
+    {ok, Package} = membership_packages:get_package(PackageId),
     PackagePrice = Package#membership_package.amount,
     {{CurYear, CurMonth, _}, _} = calendar:now_to_datetime(now()),
     UserMonthlyPurchases = [begin
         {{Year, Month, _}, _} = calendar:now_to_datetime(P#membership_purchase.start_time),
         {Year, Month, P}
-    end || P <- store:purchases(UId)],
+    end || P <- kvs:purchases(UId)],
     ThisMonthPurchases = [P || {Y, M, P} <- UserMonthlyPurchases, Y == CurYear, M == CurMonth],
     ThisMonthTotal = lists:sum([(P#membership_purchase.membership_package)#membership_package.amount || P <- ThisMonthPurchases]),
     (ThisMonthTotal + PackagePrice) > Limit.

+ 0 - 727
src/store.erl

@@ -1,727 +0,0 @@
-% This is database handling application that hides database access
-% and provides high-level rich API to stored data:
-%
-%    - acl
-%    - affiliates
-%    - users
-%    - groups
-%    - subscriptions
-%    - feeds
-%    - invites
-%    - translations
-%    - accounts
-%    - tournaments
-%    - payments
-%    - scoring
-%
-% Currently nsm_db supports following store backends:
-%
-%    - Mnesia
-%    - Riak
-
--module(store).
--author('Maxim Sokhatsky <maxim@synrc.com>').
-
--include("users.hrl").
--include("groups.hrl").
--include("feeds.hrl").
--include("acls.hrl").
--include("meetings.hrl").
--include("invites.hrl").
--include("attachments.hrl").
--include("accounts.hrl").
--include("log.hrl").
--include("membership_packages.hrl").
--include_lib("stdlib/include/qlc.hrl").
--compile(export_all).
-
-start() -> DBA = ?DBA, DBA:start().
-dir() -> DBA = ?DBA, DBA:dir().
-purchases(UserId) -> DBA = ?DBA, DBA:purchases(UserId).
-transactions(UserId) -> DBA = ?DBA, DBA:transactions(UserId).
-stop() -> DBA = ?DBA, DBA:stop().
-initialize() -> DBA = ?DBA, DBA:initialize().
-delete() -> DBA = ?DBA, DBA:delete().
-init_indexes() -> DBA = ?DBA, DBA:init_indexes().
-
-init_db() ->
-    case nsm_db:get(user,"alice") of
-       {error,_} ->
-            DBA = ?DBA,
-            DBA:init_db(),
-            add_seq_ids(),
-            nsm_accounts:create_account(?SYSTEM_ACCOUNT_ID),
-            add_sample_users(),
-            add_sample_packages(),
-            add_translations(),
-            pointing_rules:setup(),
-            add_configs(),
-            case is_production() of
-                false ->
-                    add_affiliates(),
-                    add_contracts(),
-                    add_purchases();
-                true ->
-                    do_nothing
-            end,
-            nsm_gifts_tools:import_all();
-       {ok,_} -> ignore
-    end.
-
-is_production() ->
-    case nsm_db:get(config, "debug/production", false) of
-        {ok, true} -> true;
-        _ -> false
-    end.
-
-add_affiliates() ->
-%    ?INFO("~w:add_affiliates/0 Started", [?MODULE]),
-    nsm_affiliates:create_affiliate("kunthar"),
-    nsm_affiliates:create_affiliate("alice"),
-    nsm_affiliates:create_affiliate("maxim"),
-    nsm_affiliates:reg_follower("demo1", "kunthar", 1),
-    nsm_affiliates:reg_follower("demo2", "kunthar", 1),
-    nsm_affiliates:reg_follower("kate", "kunthar", 2),
-%    ?INFO("~w:add_affiliates/0 Finished", [?MODULE]),
-    ok.
-
-add_contracts() ->
-   ?INFO("~w:add_contracts/0 Started", [?MODULE]),
-    {CurDate, _} = calendar:now_to_local_time(now()),
-    CurDateDays = calendar:date_to_gregorian_days(CurDate),
-    StartDate = calendar:gregorian_days_to_date(CurDateDays - 15),
-    FinishDate = calendar:gregorian_days_to_date(CurDateDays + 15),
-    catch nsm_affiliates:create_contract("kunthar", "Test contract", % THIS BROKES CONSISTENCY ON BOOT
-                                         StartDate, FinishDate,
-                                         2, 10.2),
-   ?INFO("~w:add_contracts/0 Finished", [?MODULE]),
-    ok.
-
-add_purchases() ->
-%    ?INFO("~w:add_purchases/0 Started", [?MODULE]),
-    {ok, Pkg1} = nsm_membership_packages:get_package(1),
-    {ok, Pkg2} = nsm_membership_packages:get_package(2),
-    {ok, Pkg3} = nsm_membership_packages:get_package(3),
-    {ok, Pkg4} = nsm_membership_packages:get_package(4),
-    PList = [{"kunthar", Pkg1},{"maxim", Pkg2},{"maxim",Pkg4}, {"kate", Pkg3} ],
-    [ok = add_purchase(U, P) || {U, P} <- PList],
-%    ?INFO("~w:add_purchases/0 Finished", [?MODULE]),
-    ok.
-
-add_purchase(UserId, Package) ->
-    {ok, MPId} = nsm_membership_packages:add_purchase(
-                         #membership_purchase{user_id=UserId, membership_package=Package }),
-%    ?INFO("Purchase Added: ~p",[MPId]),
-    nsm_membership_packages:set_purchase_state(MPId, ?MP_STATE_DONE, undefined).
-
-
-
-add_seq_ids() ->
-    Init = fun(Key) ->
-           case nsm_db:get(id_seq, Key) of
-                {error, _} -> ok = nsm_db:put(#id_seq{thing = Key, id = 0});
-                {ok, _} -> ignore
-           end
-    end,
-    Init("player_scoring"),
-    Init("scoring_record"),
-    Init("tournament"),
-    Init("user_transaction"),
-    Init("transaction"),
-    Init("team"),
-    Init("membership_purchase"),
-    Init("table"),
-    Init("acl"),
-    Init("acl_entry"),
-    Init("feed"),
-    Init("entry"),
-    Init("like_entry"),
-    Init("likes"),
-    Init("one_like"),
-    Init("comment"),
-    Init("save_table").
-
-add_translations() ->
-    lists:foreach(fun({English, Lang, Word}) ->
-                          ok = nsm_db:put(#ut_word{english = English, lang = "en",  word = English}),
-                          ok = nsm_db:put(#ut_word{english = Word,    lang = Lang,  word = Word}),
-                          ok = nsm_db:put(#ut_translation{source = {Lang, Word},    word = English}),
-                          ok = nsm_db:put(#ut_translation{source = {"en", English}, word = English}),
-                          ok = nsm_db:put(#ut_translation{source = {Lang, English}, word = Word}),
-              ok
-    end, ?URI_DICTIONARY).
-
-create_tour_users(A,B,Groups) ->
-    ImagioUsers = nsm_auth:imagionary_users(),
-    TourUsers =  [#user{username = nsm_auth:ima_gio(N,ImagioUsers),
-                            password="password",
-                            feed = feed_create(),
-                            name = nsm_auth:ima_gio(N,ImagioUsers),
-                            team = create_team("tours"), direct = feed_create(),
-                            status=ok,
-                            age={1981,9,29},
-                            register_date={1345,14071,852889}
-                           } || N <- lists:seq(A, B)],
-    [ begin
-          [nsm_groups:add_to_group_directly_to_db(Me#user.username, GId, member)||GId<-Groups],
-          nsm_users:init_mq(Me#user.username, Groups),
-          nsm_accounts:create_account(Me#user.username),
-          nsm_accounts:transaction(Me#user.username,
-                                   ?CURRENCY_QUOTA,
-                                   nsm_db:get_config("accounts/default_quota",  300),
-                                   #ti_default_assignment{}),
-          nsm_db:put(Me#user{password = utils:sha(Me#user.password),
-                                starred = feed_create(),
-                                pinned = feed_create()})
-      end || Me <- TourUsers].
-
-create_tour_users2(A,B,Groups) ->
-    ImagioUsers = nsm_auth:imagionary_users2(),
-    TourUsers =  [#user{username = nsm_auth:ima_gio2(N,ImagioUsers),
-                            password="password",
-                            feed = feed_create(),
-                            name = nsm_auth:ima_gio2(N,ImagioUsers),
-                            team = create_team("tours"), direct = feed_create(),
-                            status=ok,
-                            age={1981,9,29},
-                            register_date={1345,14071,852889}
-                           } || N <- lists:seq(A, B)],
-    [ begin
-          [nsm_groups:add_to_group_directly_to_db(Me#user.username, GId, member)||GId<-Groups],
-          nsm_users:init_mq(Me#user.username, Groups),
-          nsm_accounts:create_account(Me#user.username),
-          nsm_accounts:transaction(Me#user.username,
-                                   ?CURRENCY_QUOTA,
-                                   nsm_db:get_config("accounts/default_quota",  300),
-                                   #ti_default_assignment{}),
-          nsm_db:put(Me#user{password = utils:sha(Me#user.password),
-                                starred = feed_create(),
-                                pinned = feed_create()})
-      end || Me <- TourUsers].
-
-add_sample_users() ->
-    UserList =
-                    [#user{username = "demo1", password="kakara20",
-                           name = "Demo", surname = "Nstration", feed = feed_create(),
-                           type = admin, direct = feed_create(),
-                           sex=m,
-                           status=ok,
-                           team = create_team("tours"),
-                           email="demo1@kakaranet.com"},
-                     #user{username = "demo2", password="kakara20",
-                           name = "Demo2 User", surname = "Two", feed = feed_create(),
-                           type = admin, direct = feed_create(),
-                           status=ok,
-                           team = create_team("tours"),
-                           sex=m},
-                     #user{username = "maxim", password="kaka15ra",
-                           name = "Maxim", surname = "Sokhatsky", feed = feed_create(),
-                           type = admin, direct = feed_create(),
-                           sex=m,
-                           status=ok,
-                           team = create_team("tours"),
-                           email="maxim.sokhatsky@gmail.com"},
-                     #user{username = "ahmettez", password="kaka15ra",
-                           name = "Ahmet", surname = "Tez", feed = feed_create(),
-                           type = admin, direct = feed_create(),
-                           sex=m,
-                           status=ok,
-                           team = create_team("tours"),
-                           email="tez.ahmettez@gmail.com"},
-                     #user{username = "kunthar", password="kaka1224", name = "Kunthar", feed = feed_create(),
-                           type = admin, direct = feed_create(),
-                           sex=m,
-                           status=ok,
-                           team = create_team("tours"),
-                           email="kunthar@gmail.com"},
-                     #user{username = "sustel", password="kaka15ra", name = "Sustel",
-                           feed = feed_create(), direct = feed_create(),
-                           type = admin,
-                           team = create_team("tours"),
-                           status=ok,
-                           email = "sinanustel@gmail.com",
-                           sex=m},
-                     #user{username = "kate", password="kaka15ra",
-                           name = "Kate", surname = "Foxconn", feed = feed_create(),
-                           status=ok, direct = feed_create(),
-                           email="kate@synrc.com",
-                           team = create_team("tours"),
-                           sex=f},
-                     #user{username = "alice", password="kaka15ra",
-                           name = "Alicja", surname = "Example", feed = feed_create(),
-                           team = create_team("tours"), direct = feed_create(),
-                           facebook_id = "1234567890",
-                           email="alice@synrc.com",
-                           status=ok,
-                           sex=f},
-                     #user{username = "commonuser", password="123456",
-                           name = "Usert", surname = "Userson", feed = feed_create(),
-                           team = create_team("tours"), direct = feed_create(),
-                           status=ok,
-                           email="commonuser@synrc.com",
-                           sex="male",
-                           location="İstanbul",
-                           age={1986,4,3},
-                           education="highschool",
-                           register_date={1345,14070,852889}
-                     },
-                     #user{username = "imagia", password="123456",
-                           name = "Ima", surname = "Gionari", feed = feed_create(),
-                           team = create_team("tours"), direct = feed_create(),
-                           status=ok,
-                           sex="female",
-                           location="Ankara",
-                           age={1988,4,3},
-                           education="elementary school",
-                           register_date={1345,14070,852889}
-                     },
-                     #user{username = "willbe", password="123456",
-                           name = "Will", surname = "Beimagionary", feed = feed_create(),
-                           team = create_team("tours"), direct = feed_create(),
-                           status=ok,
-                           sex="male",
-                           location="Ankara",
-                           age={1985,8,3},
-                           education="Bc. S.",
-                           register_date={1345,14070,852889}
-                     },
-                     #user{username = "nata88", password="123456",
-                           name = "Nata", surname = "Eightyeight", feed = feed_create(),
-                           team = create_team("tours"), direct = feed_create(),
-                           status=ok,
-                           sex="female",
-                           location="Ankara",
-                           age={1985,8,3},
-                           education="Bc. S.",
-                           register_date={1345,14070,852889}
-                     },
-                     #user{username = "serg", password="kaka1224",
-                           name = "Serg", surname = "Polkovnikov", feed = feed_create(),
-                           team = create_team("tours"), direct = feed_create(),
-                           status=ok,
-                           sex="male",
-                           location="İstanbul",
-                           age={1976,1,8},
-                           education="Ph. D.",
-                           register_date={1345,14070,852889}
-                     },
-                     #user{username = "doxtop", password="password",
-                           feed = feed_create(),
-                           name = "Andrii Zadorozhnii",
-                           email="doxtop@synrc.com",
-                           type=admin,
-                           team = create_team("tours"), direct = feed_create(),
-                           status=ok,
-                           age={1981,9,29},
-                           register_date={1345,14071,852889}
-                     } 
-         ],
-
-
-    ?INFO("creating groups"),
-
-    nsm_users:init_mq("ahmettez", ["kakaranet", "yeniler"]),
-
-    GId1  = nsm_groups:create_group_directly_to_db("ahmettez", "kakaranet", "Kakaranet", "Kakaranet'e Hoşgeldiniz", public),
-    GId2  = nsm_groups:create_group_directly_to_db("ahmettez", "yeniler", "Yeniler", "So, you must be new here.", public),
-
-    create_tour_users(1,386,[GId1,GId2]),
-
-    ?INFO("adding users accounts"),
-    [ begin
-          nsm_accounts:create_account(Me#user.username),
-          nsm_accounts:transaction(Me#user.username, ?CURRENCY_QUOTA, nsm_db:get_config("accounts/default_quota", 300), #ti_default_assignment{}),
-          nsm_db:put(Me#user{password = utils:sha(Me#user.password),
-                                starred = feed_create(),
-                                pinned = feed_create()})
-      end || Me <- UserList],
-    ?INFO("adding users to groups"),
-    [ begin
-          nsm_users:init_mq(Me#user.username, [GId1, GId2]),
-          %subscribe_user_to_list(Me#user.username, UserList),
-          case Me#user.username of
-              "ahmettez" -> ok; % ahmettez already in groups, as admin
-              _ ->
-                  nsm_groups:add_to_group_directly_to_db(Me#user.username, GId1, member),
-                  nsm_groups:add_to_group_directly_to_db(Me#user.username, GId2, member)
-          end
-      end || Me <- UserList ],
-    %% define access for Maxim to feature admin
-    nsm_acl:define_access({user, "maxim"},    {feature, admin}, allow),
-    nsm_acl:define_access({user_type, admin}, {feature, admin}, allow),
-
-    ?INFO("making all users each other friends"),
-
-    [[case Me == Her of
-        true -> ok;
-        false -> nsm_users:subscr_user(Me#user.username, Her#user.username)
-    end || Her <- UserList] || Me <- UserList].
-
-add_sample_packages() -> nsm_membership_packages:add_sample_data().
-version() -> ?INFO("version: ~p", [?VERSION]).
-
-% blocking
-
-block_user(Who, Whom) -> DBA=?DBA, DBA:block_user(Who, Whom).
-list_blocks(Who) -> DBA=?DBA, DBA:list_blocks(Who).
-unblock_user(Who, Whom) -> DBA=?DBA, DBA:unblock_user(Who, Whom).
-list_blocked_me(Me) -> DBA=?DBA, DBA:list_blocked_me(Me).
-is_user_blocked(Who, Whom) -> DBA=?DBA, DBA:is_user_blocked(Who, Whom).
-
-% configs
-
-add_configs() ->
-    %% smtp
-    nsm_db:put(#config{key="smtp/user",     value="noreply@kakaranet.com"}),
-    nsm_db:put(#config{key="smtp/password", value="kakam41l"}),
-    nsm_db:put(#config{key="smtp/host",     value="posta.kakaranet.com"}),
-    nsm_db:put(#config{key="smtp/port",     value=465}),
-    nsm_db:put(#config{key="smtp/with_ssl", value=true}),
-
-    %% accounts
-    nsm_db:put(#config{key="accounts/default_quota", value=2000}),
-    nsm_db:put(#config{key="accounts/quota_limit/soft",  value=-30}),
-    nsm_db:put(#config{key="accounts/quota_limit/hard",  value=-100}),
-
-    %%  purchases
-    nsm_db:put(#config{key= "purchase/notifications/email",  value=["maxim@synrc.com"]}),
-
-    %%  delivery
-    nsm_db:put(#config{key= "delivery/notifications/email",  value=["maxim@synrc.com"]}),
-
-    %% tournament, elimination, Tour time limit
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/1", value = 30*60*1000}),
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/2", value = 30*60*1000}),
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/3", value = 30*60*1000}),
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/4", value = 25*60*1000}),
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/5", value = 25*60*1000}),
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/6", value = 25*60*1000}),
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/7", value = 20*60*1000}),
-    nsm_db:put(#config{key= "games/okey/trn/elim/tour_time_limit/8", value = 20*60*1000}).
-
-% put
-
--spec put(tuple() | [tuple()]) -> ok.
-put(Record) ->
-%    ?INFO("db:put ~p",[Record]),
-    DBA=?DBA,
-    DBA:put(Record).
-
-
-put_if_none_match(Record) ->
-%    ?INFO("db:put_if_none_match ~p",[Record]),
-    DBA=?DBA,
-    DBA:put_if_none_match(Record).
-
-% update
-
-update(Record, Meta) ->
-%    ?INFO("db:update ~p",[Record]),
-    DBA=?DBA,
-    DBA:update(Record, Meta).
-
-% get
-
--spec get(atom(), term()) -> {ok, tuple()} | {error, not_found | duplicated}.
-get(RecordName, Key) ->
-    DBA=?DBA,
-    case C = DBA:get(RecordName, Key) of
-    {ok,_R} ->
-%        ?INFO("db:get ~p,", [{RecordName, Key}]),
-        C;
-    A -> A
-    end.
-
-get_for_update(RecordName, Key) ->
-%    ?INFO("db:get_for_update ~p,", [{RecordName, Key}]),
-    DBA=?DBA,
-    DBA:get_for_update(RecordName, Key).
-
-get(RecordName, Key, Default) ->
-    DBA=?DBA,
-    case DBA:get(RecordName, Key) of
-	{ok,{RecordName,Key,Value}} ->
-	    ?INFO("db:get config value ~p,", [{RecordName, Key, Value}]),
-	    {ok,Value};
-	{error, _B} ->
-	    ?INFO("db:get new config value ~p,", [{RecordName, Key, Default}]),
-	    DBA:put({RecordName,Key,Default}),
-	    {ok,Default}
-    end.
-
-get_config(Key, Default) -> {ok, Value} = get(config, Key, Default), Value.
-get_word(Word) -> get(ut_word,Word).
-get_translation({Lang,Word}) -> DBA=?DBA, DBA:get_translation({Lang,Word}).
-
-% delete
-
-delete(Keys) -> DBA=?DBA, DBA:delete(Keys).
-delete(Tab, Key) -> ?INFO("db:delete ~p:~p",[Tab, Key]), DBA=?DBA,DBA:delete(Tab, Key).
-delete_by_index(Tab, IndexId, IndexVal) -> DBA=?DBA,DBA:delete_by_index(Tab, IndexId, IndexVal).
-% select
-
-multi_select(RecordName, Keys) -> DBA=?DBA,DBA:multi_select(RecordName, Keys).
-select(From, PredicateFunction) -> ?INFO("db:select ~p, ~p",[From,PredicateFunction]), DBA=?DBA, DBA:select(From, PredicateFunction).
-count(RecordName) -> DBA=?DBA,DBA:count(RecordName).
-all(RecordName) -> DBA=?DBA,DBA:all(RecordName).
-all_by_index(RecordName, Index, IndexValue) -> DBA=?DBA,DBA:all_by_index(RecordName, Index, IndexValue).
-
-% id generator
-
-next_id(RecordName) -> DBA=?DBA,DBA:next_id(RecordName).
-next_id(RecordName, Incr) -> DBA=?DBA,DBA:next_id(RecordName, Incr).
-next_id(RecordName, Default, Incr) -> DBA=?DBA,DBA:next_id(RecordName, Default, Incr).
-
-% browser counter
-
-delete_browser_counter_older_than(MinTS) -> DBA=?DBA,DBA:delete_browser_counter_older_than(MinTS).
-browser_counter_by_game(Game) -> DBA=?DBA,DBA:browser_counter_by_game(Game).
-
-% invites
-
-unused_invites() -> DBA=?DBA,DBA:unused_invites().
-user_by_verification_code(Code) -> DBA=?DBA,DBA:user_by_verification_code(Code).
-user_by_facebook_id(FBId) -> DBA=?DBA,DBA:user_by_facebook_id(FBId).
-user_by_email(Email) -> DBA=?DBA,DBA:user_by_email(Email).
-user_by_username(Name) -> DBA=?DBA,DBA:user_by_username(Name).
-add_invite_to_issuer(User, O) -> DBA=?DBA,DBA:add_invite_to_issuer(User, O).
-invite_code_by_issuer(User) -> DBA=?DBA,DBA:invite_code_by_issuer(User).
-invite_code_by_user(User) -> DBA=?DBA,DBA:invite_code_by_user(User).
-
-% game info
-
-get_save_tables(Id) -> DBA=?DBA,DBA:get_save_tables(Id).
-save_game_table_by_id(Id) -> DBA=?DBA,DBA:save_game_table_by_id(Id).
-
-% feeds
-
-feed_add_direct_message(FId, User, To, EntryId, Desc, Medias) -> DBA=?DBA,DBA:feed_add_direct_message(FId, User, To, EntryId, Desc, Medias).
-feed_add_entry(FId, User, EntryId, Desc, Medias) -> DBA=?DBA,DBA:feed_add_entry(FId, User, EntryId, Desc, Medias).
-feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy) -> DBA=?DBA,DBA:feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy).
-acl_add_entry(AclId, Accessor, Action) -> DBA=?DBA,DBA:acl_add_entry(AclId, Accessor, Action).
-acl_entries(AclId) -> DBA=?DBA,DBA:acl_entries(AclId).
-entry_by_id(EntryId) -> DBA=?DBA,DBA:entry_by_id(EntryId).
-comment_by_id(CommentId) -> DBA=?DBA,DBA:comment_by_id(CommentId).
-comments_by_entry({_EId, _FId} = EntryId) -> DBA=?DBA,DBA:comments_by_entry(EntryId).
-entries_in_feed(FeedId) -> DBA=?DBA,DBA:entries_in_feed(FeedId, undefined, all).
-entries_in_feed(FeedId, Count) -> DBA=?DBA,DBA:entries_in_feed(FeedId, undefined, Count).
-entries_in_feed(FeedId, StartFrom, Count) -> DBA=?DBA, DBA:entries_in_feed(FeedId, StartFrom, Count).
-add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias) -> DBA=?DBA, DBA:feed_add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias).
-feed_direct_messages(FId, StartFrom, Count) ->  DBA=?DBA, DBA:entries_in_feed(FId, StartFrom, Count).
-
-% tournaments
-
-tournament_waiting_queue(TID) -> DBA=?DBA, DBA:tournament_waiting_queue(TID).
-join_tournament(UID,TID) -> DBA=?DBA, DBA:join_tournament(UID,TID).
-leave_tournament(UID,TID) -> DBA=?DBA, DBA:leave_tournament(UID,TID).
-tournament_pop_waiting_player(TID) -> DBA=?DBA, DBA:tournament_pop_waiting_player(TID).
-%play_record_add_entry(TeamId, UserId, Tournament, GameId) -> DBA=?DBA, DBA:play_record_add_entry(TeamId, UserId, Tournament, GameId).
-user_tournaments(UID) -> DBA=?DBA, DBA:user_tournaments(UID).
-
-groups_184_update() -> % predefined group creation
-    nsm_groups:create_group("ahmettez", "kakaranet", "Kakaranet", "Kakaranet'e Hoşgeldiniz", public),
-    nsm_groups:create_group("ahmettez", "yeniler", "Yeniler", "So, you must be new here.", public).
-
-subscriptions_update() -> % public beta
-    catch(nsm_db:delete(subscription,"kikiri")),
-
-    Subscriptions = nsm_db:all(subscription),
-    lists:foreach(fun (Subscription) ->
-
-       case Subscription of
-
-            {subscription,User,ToList} ->
-
-       ?INFO("User, ToList: ~p ~p",[User,ToList]),
-       lists:foreach(fun(Sub) ->
-          case Sub of
-             {subscription,User,To} ->
-                  ?INFO("User, To: ~p ~p",[User,To]),
-                  NewSubs = lists:foldl(fun({subscription,A,T},Acc) ->
-                            ?INFO("User: ~p",[A]),
-                            R = nsm_db:get(user,T),
-                            case R of
-                                  {ok,{user,_,_,_,_,_,Name,Surname,_,_,_,_,_,_,_,_,_,_,_,_}} ->
-				            Acc ++ [{subscription,A,T,[Name,32,Surname]}];
-                                   {error,_} -> Acc
-                             end
-                  end,[],ToList),
-                  nsm_db:put({subscription,User,NewSubs,undefined}),
-                  ok;
-             _ -> io:format("Unknown: ~p",[Sub])
-          end
-       end, ToList);
-
-           _ -> io:format("new: ~p",[Subscription])
-
-       end
-
-    end, Subscriptions).
-
-subscriptions_to_subs() ->
-    [[nsm_db:put(#subs{who=Who, whom=Whom}) || #subscription{who=Who, whom=Whom} <- Subs] 
-    || #subscription{who=_, whom=Subs} <- nsm_db:all(subscription)].
-
-%% mebership purchases
-
-add_transaction_to_user(User, Tx) -> DBA=?DBA, DBA:add_transaction_to_user(User, Tx).
-get_purchases_by_user(User, Count, States) -> DBA=?DBA, DBA:get_purchases_by_user(User, Count, States).
-get_purchases_by_user(User, StartFromPurchase, Count, States) -> DBA=?DBA, DBA:get_purchases_by_user(User, StartFromPurchase, Count, States).
-
-%% invitation tree
-
-%% @doc Put invite to tree. Parent is user who has invited User.
-
--spec put_into_invitation_tree(Parent::string()|{root}, User::string(), InviteCode::string()) -> ok.
-
-put_into_invitation_tree(Parent, User, InviteCode) -> DBA=?DBA, DBA:put_into_invitation_tree(Parent, User, InviteCode).
-
-
-%% @doc build invitaion tree. Depth is shows how many levels of children will be
-%%      returned. Children will de abbed to children field of the #invitaion_tree
-%%      record.
-
--spec invitation_tree(StartFrom::string()|{root}, Depth::integer()|all) ->
-          [#invitation_tree{}].
-
-invitation_tree(StartFrom, Depth) -> DBA=?DBA, DBA:invitation_tree(StartFrom, Depth).
-
-fast_timeouts() ->
-    nsm_db:put({config,"games/okey/robot_delay_normal",100}),
-    nsm_db:put({config,"games/okey/challenge_timeout_normal",5000}),
-    nsm_db:put({config,"games/okey/turn_timeout_normal",200}).
-
-make_admin(User) ->
-    {ok,U} = nsm_db:get(user, User),
-    nsm_db:put(U#user{type = admin}),
-    nsm_acl:define_access({user, U#user.username}, {feature, admin}, allow),
-    nsm_acl:define_access({user_type, admin}, {feature, admin}, allow),
-    ok.
-
-make_rich(User) -> 
-    Q = nsm_db:get_config("accounts/default_quota",  300),
-    nsm_accounts:transaction(User, ?CURRENCY_QUOTA, Q * 100, #ti_default_assignment{}),
-    nsm_accounts:transaction(User, ?CURRENCY_KAKUSH, Q, #ti_default_assignment{}),
-    nsm_accounts:transaction(User, ?CURRENCY_KAKUSH_CURRENCY, Q * 2, #ti_default_assignment{}).
-
-feed_create() ->
-    FId = nsm_db:next_id("feed", 1),
-    ok = nsm_db:put(#feed{id = FId} ),
-    FId.
-
-create_team(Name) ->
-    TID = nsm_db:next_id("team",1),
-    ok = nsm_db:put(Team = #team{id=TID,name=Name}),
-    TID.
-
-
-list_to_term(String) ->
-    {ok, T, _} = erl_scan:string(String++"."),
-    case erl_parse:parse_term(T) of
-        {ok, Term} ->
-            Term;
-        {error, Error} ->
-            Error
-    end.
-
-list_buckets() ->
-    [list_to_term(B) || B <- nsm_riak:dir()].
-
-save_db(Path) ->
-    Data = lists:append([all(B) || B <- list_buckets()]),
-    salode:save(Path, Data).
-
-load_db(Path) ->
-    nsm_riak:clean(),
-    add_seq_ids(),
-    AllEntries = salode:load(Path),
-    [{_,_,{_,Handler}}] = ets:lookup(config, "riak_client"),
-    [case is_tuple(E) of
-        false -> skip;
-        true ->
-            case element(1, E) of
-                gifts_categories -> %%%%%%%%%%%%%%%%%%%% gifts 
-                    ?INFO("GiftCat: ~p",[E]),
-                    Id = E#gifts_category.id,
-                    ParentId = E#gifts_category.parent,
-                    Obj1 = riak_object:new(<<"gifts_categories">>, term_to_binary(Id), E),
-                    Indices = [{"bucket_bin", <<"gifts_categories">>},
-                               {"catparent_bin", term_to_binary(ParentId)}],
-                    Meta = dict:store(<<"index">>, Indices, dict:new()),
-                    Obj2 = riak_object:update_metadata(Obj1, Meta),
-                    ok = Handler:put(Obj2, []);
-                gift -> 
-                    ?INFO("Gift: ~p",[E]),
-                    Id = E#gift.id,
-                    Cats = E#gift.categories,
-                    Obj1 = riak_object:new(<<"gifts">>, term_to_binary(Id), E),
-                    Indices = [{"bucket_bin", <<"gifts">>} |
-                             [{"categoty_bin", term_to_binary(CatId)} ||
-                              CatId <- lists:usort(Cats)]],
-                    Meta = dict:store(<<"index">>, Indices, dict:new()),
-                    Obj2 = riak_object:update_metadata(Obj1, Meta),
-                    ok = Handler:put(Obj2, []);
-                transaction ->
-                    ?INFO("Tx: ~p",[E]),
-                        case E of {transaction,Id,T,Am,R,A,C,I} ->
-                         Tx = #transaction{id = Id, commit_time = T,  amount = Am, remitter =R, acceptor = A, currency =C, info = I},
-                         %add_transaction_to_user(A,Tx);
-                         put(Tx);
-                         _ -> skip 
-                        end;
-                group ->
-                    ?INFO("Grp: ~p",[E]),
-                        case E of {group,A1,A2,A3,A4,A5,A6,A7,A8} ->
-                         Grp = {group,A1,A2,A3,A4,A5,A6,A7,A8,0,0},
-                         put(Grp);
-                         _ -> put(E)
-                        end;
-                user ->
-                    ?INFO("Usr: ~p",[E]),
-                        case E of {user,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,
-                                        A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,
-                                        A21,A22,A23} ->
-                                   Usr = {user,A1,A2,A3,undefined,A4,A5,A6,A7,A8,A9,A10,
-                                        A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,
-                                        A21,A22,A23},
-                         put(Usr);
-                         _ -> put(E)
-                        end;
-%                tournament -> skip;
-                user_address -> 
-                    ?INFO("UA: ~p",[E]),
-                        case E of
-                            {user_address, UId, A, C, D, PC} -> put({user_address, UId, A, C, D, PC, "", ""});
-                            {user_address, UId, A, C, D, PC, P} -> put({user_address, UId, A, C, D, PC, P, ""});
-                            _ -> put(E)
-                        end;
-                play_record -> 
-                    ?INFO("PR: ~p",[E]),
-                        case E of {play_record, Who, _Id, Tournament, Team, Game_id, Entry_id, _Score_points, _Next, _Prev} ->
-                            PR = {play_record, Who, Tournament, Team, Game_id, Who, 0, 0, 0, 0, []},
-                        put(PR);
-                        _ -> put(E)
-                        end;
-                membership_purchase ->
-                    ?INFO("Mp: ~p",[E]),
-                        case E of {membership_purchase,Id,T,User,S,Pkg,Time,Time2,L,Type} ->
-                         Mp = #membership_purchase{id = Id, external_id = T,
-                                                   user_id = User, state = S,
-                                                   membership_package = Pkg, next = undefined,
-                                                   prev = undefined, start_time = Time,
-                                                   end_time = Time2, state_log = L,
-                                                   info = Type},
-
-                         put(Mp);
-                         _ -> skip 
-                        end;
-                _ -> %%%%%%%%%%%%%%%%%%%% all the rest
-                    ?INFO("Reg: ~p",[E]),
-                    put(E) 
-            end
-    end || E <- AllEntries].
-
-make_paid_fake(UId) ->
-    put({user_purchase, UId, "fake_purchase"}).
-
-

+ 0 - 312
src/store_mnesia.erl

@@ -1,312 +0,0 @@
--module(store_mnesia).
--author('Fernando Benavides <fernando.benavides@inakanetworks.com>').
--include("config.hrl").
--include("user.hrl").
--include("feed.hrl").
--include("acl.hrl").
--include("invite.hrl").
--include("attachment.hrl").
--include("table.hrl").
--include("uri_translator.hrl").
--include_lib("stdlib/include/qlc.hrl").
--compile(export_all).
-
-start() ->
-    mnesia:start(),
-    mnesia:change_table_copy_type(schema, node(), disc_copies).
-
-stop() -> mnesia:stop().
-initialize() -> mnesia:create_schema([node()]).
-delete() -> mnesia:delete_schema([node()]).
-
-init_db() ->
-    ok = create_table(acl, record_info(fields, acl), [{storage, permanent}]),
-    ok = create_table(comment, record_info(fields, comment), [{storage, permanent}, {type, ordered_set}]),
-    ok = add_table_index(comment, entry_id),
-    ok = create_table(feed, record_info(fields, feed), [{storage, permanent}]),
-    ok = create_table(entry, record_info(fields, entry), [{storage, permanent}, {type, ordered_set}]),
-    ok = add_table_index(entry, feed_id),
-    ok = add_table_index(entry, entry_id),
-    ok = add_table_index(entry, from),
-    ok = create_table(forget_password, record_info(fields, forget_password), [{storage, permanent}]),
-    ok = create_table(prohibited, record_info(fields, prohibited), [{storage, permanent}, {type, bag}]),
-    ok = create_table(group_member, record_info(fields, group_member), [{storage, permanent}, {type, bag}]),
-    ok = create_table(group_member_rev, record_info(fields, group_member_rev), [{storage, permanent}, {type, bag}]),
-    ok = create_table(group, record_info(fields, group), [{storage, permanent}]),
-    ok = add_table_index(group_member, id),
-    ok = create_table(invite_code, record_info(fields, invite_code), [{storage, permanent}]),
-    ok = add_table_index(invite_code, issuer),
-    ok = add_table_index(invite_code, created_user),
-    ok = create_table(user, record_info(fields, user), [{storage, permanent}]),
-    ok = create_table(user_status, record_info(fields, user_status), [{storage, permanent}]),
-    ok = create_table(subscription, record_info(fields, subscription), [{storage, permanent}, {type, bag}]),
-    ok = create_table(subscription_rev, record_info(fields, subscription_rev), [{storage, permanent}, {type, bag}]),
-    ok = add_table_index(user, verification_code),
-    ok = add_table_index(user, facebook_id),
-    ok = add_table_index(user, email),
-    ok = create_table(uploads, record_info(fields, uploads), [{storage, permanent}, {type, set}]),
-    ok = create_table(save_game_table, record_info(fields, save_game_table), [{storage, permanent}, {type, bag}]),
-    ok = add_table_index(save_game_table, id),
-    ok = create_table(id_seq, record_info(fields, id_seq), [{storage, permanent}]),
-    ok = create_table(feature, record_info(fields, feature), [{storage, permanent}]),
-    ok = create_table(ut_word, record_info(fields, ut_word), [{storage, permanent}, {type, bag}]),
-    ok = create_table(ut_translation, record_info(fields, ut_translation), [{storage, permanent}, {type, ordered_set}]),
-    nsm_membership_packages:create_storage(),
-    ok.
-
-put(Records) when is_list(Records) -> void(fun() -> lists:foreach(fun mnesia:write/1, Records) end);
-put(Record) -> put([Record]).
-
-delete(Keys) when is_list(Keys) -> void(fun() -> lists:foreach(fun mnesia:delete_object/1, Keys) end);
-delete(Keys) -> delete([Keys]).
-delete(Tab, Key) -> mnesia:transaction(fun()-> mnesia:delete({Tab, Key}) end), ok.
-
-multi_select(RecordName, Keys) when is_list(Keys) -> flatten(fun() -> [mnesia:read({RecordName, Key}) || Key <- Keys] end).
-
-select(From, PredicateFunction) when is_function(PredicateFunction) -> exec(qlc:q([Record || Record <- mnesia:table(From), apply(PredicateFunction, [Record])]));
-select(From, [{where, Fn}, {order, {Idx, Order}}]) -> exec(qlc:q([R || R <- qlc:keysort(Idx, mnesia:table(From), [{order, Order}]), apply(Fn, [R])]));
-select(From, [{where, Fn}, {order, {Idx, Order}}, {limit, {1, Length}}]) ->
-    {atomic, Recs} = mnesia:transaction(fun()->
-        QC = qlc:cursor(qlc:q(
-            [R || R <- qlc:keysort(Idx, mnesia:table(From), [{order, Order}]), apply(Fn, [R])])),
-        Ret = qlc:eval(qlc:next_answers(QC, Length)),
-        qlc:delete_cursor(QC),
-        Ret
-    end),
-    Recs;
-
-select(From, [{where, Fn}, {order, {Idx, Order}}, {limit, {Offset, Length}}]) ->
-    {atomic, Recs} = mnesia:transaction(fun()->
-        QC = qlc:cursor(qlc:q(
-            [R || R <- qlc:keysort(Idx, mnesia:table(From), [{order, Order}]), apply(Fn, [R])])),
-        qlc:next_answers(QC, Offset - 1),
-        Ret = qlc:eval(qlc:next_answers(QC, Length)),
-        qlc:delete_cursor(QC),
-        Ret
-    end),
-    Recs;
-select(RecordName, Key) ->
-    many(fun() -> mnesia:read({RecordName, Key}) end).
-
-get(RecordName, Key) -> just_one(fun() -> mnesia:read(RecordName, Key) end).
-
-get_word(Word) ->
-    case mnesia:transaction(fun() -> mnesia:match_object(#ut_word{english = Word, lang = '_', word = Word}) end) of
-        {atomic, []} -> {error, not_found};
-        {atomic, [R]} -> {ok, R};
-        {atomic, [A|_]} -> A;
-        _ -> {error, not_found}
-    end.
-
-get_translation({Lang, Word}) -> get(ut_translation, {Lang, Word}).
-count(RecordName) -> mnesia:table_info(RecordName, size).
-
-all(RecordName) ->
-    flatten(fun() ->
-                    Lists = mnesia:all_keys(RecordName),
-                    [ mnesia:read({RecordName, G}) || G <- Lists ]
-            end).
-
-next_id(RecordName) ->
-    next_id(RecordName, 1).
-
-next_id(RecordName, Incr) ->
-    [RecordStr] = io_lib:format("~p",[RecordName]),
-    mnesia:dirty_update_counter({id_seq, RecordStr}, Incr).
-
-unused_invites() ->
-    {atomic, Result} =
-        mnesia:transaction(
-          fun() ->
-                  length(mnesia:match_object(#invite_code{created_user=undefined, _='_'}))
-          end),
-    Result.
-
-user_by_verification_code(Code) -> just_one(fun() -> mnesia:match_object(#user{verification_code = Code, _='_'}) end).
-user_by_facebook_id(FBId) -> just_one(fun() -> mnesia:index_read(user, FBId, facebook_id) end).
-user_by_email(Email) -> just_one(fun() -> mnesia:index_read(user, Email, email) end).
-user_by_username(Name) -> just_one(fun() -> mnesia:match_object(#user{username = Name, _='_'}) end).
-invite_code_by_issuer(User) -> just_one(fun() -> mnesia:match_object(#invite_code{issuer = User, _='_'}) end).
-invite_code_by_user(User) -> just_one(fun() -> mnesia:match_object(#invite_code{created_user = User, _='_'}) end).
-
-add_to_group(UId, GId, Type) ->
-    store:put([#group_member{who = UId,
-                                 group = GId,
-                                 id = {UId, GId},
-                                 type = Type},
-                   #group_member_rev{group = GId,
-                                     who = UId,
-                                     type = Type}]).
-
-remove_from_group(UId, GId) ->
-    throw({error, needs_fix}),
-    Type = zzzz,
-    store:delete([#group_member{who = UId,
-                                    group = GId,
-                                    id = {UId, GId},
-                                    type = Type},
-                      #group_member_rev{group = GId,
-                                        who = UId,
-                                        type = Type}]).
-
-list_membership(#user{username = UId}) -> list_membership(UId);
-list_membership(UId) when is_list(UId) -> store:select(group_member, UId).
-list_membership_count(#user{username = UId}) -> list_membership_count(UId);
-list_membership_count(UId) when is_list(UId) -> [{G, length(list_group_users(element(3, G)))} || G <-store:select(group_member, UId)].
-list_group_users(GId) -> store:select(group_member_rev, GId).
-membership(UserId, GroupId) -> just_one(fun() -> mnesia:match_object(#group_member{id = {UserId, GroupId}, _='_'}) end).
-get_save_tables(UId) -> store:select(save_game_table,UId).
-ave_game_table_by_id(Id) -> just_one(fun() -> mnesia:match_object(#save_game_table{id = Id, _='_'}) end).
-
-just_one(Fun) ->
-    case mnesia:transaction(Fun) of
-        {atomic, []} -> {error, not_found};
-        {atomic, [R]} -> {ok, R};
-        {atomic, [_|_]} -> {error, duplicated};
-        _ -> {error, not_found}
-    end.
-
-flatten(Fun) ->
-    case mnesia:transaction(Fun) of
-        {atomic, R} -> lists:flatten(R);
-        _ -> []
-    end.
-
-many(Fun) ->
-    case mnesia:transaction(Fun) of
-        {atomic, R} -> R;
-        _ -> []
-    end.
-
-void(Fun) ->
-    case mnesia:transaction(Fun) of
-        {atomic, ok} -> ok;
-        {aborted, Error} -> {error, Error}
-    end.
-
-create_table(Record, RecordInfo,  Opts0) ->
-    Attr = [{attributes, RecordInfo}],
-    Opts = transform_opts(Opts0),
-    AllOpts = lists:concat([Opts, Attr]),
-    case mnesia:create_table(Record, lists:flatten(AllOpts)) of
-        {atomic,ok}                          -> ok;
-        {aborted, {already_exists, Record}}  -> ok;
-        {aborted, Err}                       -> {error, Err}
-    end.
-
-add_table_index(Record, Field) ->
-    case mnesia:add_table_index(Record, Field) of
-        {atomic, ok}                        -> ok;
-        {aborted,{already_exists,Record,_}} -> ok;
-        {aborted, Err}                       -> {error, Err}
-    end.
-
-transform_opts(Opts) -> transform_opts(Opts, []).
-transform_opts([], Acc) -> lists:reverse(Acc);
-transform_opts([{storage, Value} | Rest], Acc0) ->
-    NewOpts = storage_to_mnesia_type(Value),
-    Acc = [NewOpts | Acc0],
-    transform_opts(Rest, Acc);
-transform_opts([Other | Rest], Acc0) ->
-    Acc = [Other | Acc0],
-    transform_opts(Rest, Acc).
-
-storage_to_mnesia_type(permanent) -> {disc_copies, [node()]};
-storage_to_mnesia_type(temporary) -> {ram_copies, [node()]};
-storage_to_mnesia_type(ondisk) -> {disc_only_copies, [node()]}.
-
-exec(Q) -> F = fun() -> qlc:e(Q) end, {atomic, Val} = mnesia:transaction(F), Val.
-
-subscribe_user(MeId, FrId) -> store:put([#subscription{who = MeId, whom = FrId},
-                              #subscription_rev{whom = FrId, who = MeId}]).
-
-remove_subscription(MeId, FrId) -> store:delete([#subscription{who = MeId, whom = FrId},
-                                   #subscription_rev{whom = FrId, who = MeId}]).
-
-list_subscriptions(#user{username = UId}) -> list_subscriptions(UId);
-list_subscriptions(UId) when is_list(UId) -> select(subscription,UId).
-list_subscription_me(UId) -> select(subscription_rev, UId).
-
-is_user_subscribed(Who, Whom) ->
-    case select(subscription,fun(#subscription{who=W1,whom=W2}) when W1=:=Who,W2=:=Whom->true;(_)->false end) of
-        [] -> false
-        ;_ -> true
-    end.
-
-% feeds
-
-feed_add_direct_message(FId, User, Desc, Medias) ->
-    EId = store:next_id(entry, 1),
-    Entry  = #entry{id = {EId, FId},
-                    entry_id = EId,
-                    feed_id = FId,
-                    from = User,
-                    media = Medias,
-                    created_time = now(),
-                    description = Desc,
-                    type = {user, direct}},
-
-    ModEntry = feedformat:format(Entry),
-    case store:put(ModEntry) of
-        ok ->
-            {ok, ModEntry}
-        % ;Error -> {error, Error} %% put always return true
-    end.
-
-feed_add_entry(FId, User, Desc, Medias) ->
-    EId = store:next_id(entry, 1),
-    Entry  = #entry{id = {EId, FId},
-                    entry_id = EId,
-                    feed_id = FId,
-                    from = User,
-                    media = Medias,
-                    created_time = now(),
-                    description = Desc},
-
-    ModEntry = feedformat:format(Entry),
-    case store:put(ModEntry) of
-        ok ->
-            {ok, ModEntry}
-        % ;Error -> {error, Error} %% put always return true
-    end.
-
-entry_by_id(EntryId) -> just_one(fun() -> mnesia:match_object(#entry{entry_id = EntryId, _='_'}) end).
-comment_by_id(CommentId) -> just_one(fun() -> mnesia:match_object(#comment{comment_id = CommentId, _='_'}) end).
-comments_by_entry(EntryId) -> lists:reverse(many(fun() -> mnesia:match_object(#comment{entry_id = EntryId, _='_'}) end)).
-feed_entries(FeedId) -> feed_entries(FeedId, '_').
-feed_entries(FeedId, UserId) -> lists:reverse(many(fun() -> mnesia:match_object(#entry{feed_id = FeedId, from = UserId, _='_'}) end)).
-feed_entries(FId, Page, PageAmount) -> entries_in_feed(FId, Page, PageAmount).
-feed_entries(FId, Page, PageAmount, CurrentUser, CurrentFId) -> entries_in_feed(FId, Page, PageAmount, CurrentUser, CurrentFId).
-
-entries_in_feed(FId, 1, PageAmount) ->
-    F=fun(X) when element(4,X)=:=FId-> true;(_)->false end,
-    store:select(entry,[{where, F},{order, {1, descending}},{limit, {1,PageAmount}}]);
-entries_in_feed(FId, Page, PageAmount) when is_integer(Page), Page>1->
-    Offset=(Page-1)*PageAmount,
-    F=fun(X) when element(4,X)=:=FId-> true;(_)->false end,
-    store:select(entry,[{where, F},{order, {1, descending}},{limit, {Offset,PageAmount}}]).
-entries_in_feed(FId, 1, PageAmount, CurrentUser, CurrentFId) ->
-    F=fun(X) when element(4,X)=:=FId andalso (element(9,X)=:={user,normal} orelse element(1,element(9,X))=:=system)-> true;
-         (X) when element(5,X)=:=CurrentUser,element(9,X)=:={user,direct}-> true;
-         (X) when element(4,X)=:=CurrentFId,element(9,X)=:={user,direct} -> true;
-         (_)->false end,
-    store:select(entry,[{where, F},{order, {1, descending}},{limit, {1,PageAmount}}]);
-entries_in_feed(FId, Page, PageAmount, CurrentUser, CurrentFId) when is_integer(Page), Page>1->
-    Offset=(Page-1)*PageAmount,
-    F=fun(X) when element(4,X)=:=FId andalso (element(9,X)=:={user,normal} orelse element(1,element(9,X))=:=system)-> true;
-         (X) when element(5,X)=:=CurrentUser,element(9,X)=:={user,direct}-> true;
-         (X) when element(4,X)=:=CurrentFId,element(9,X)=:={user,direct} -> true;
-         (_)->false end,
-    store:select(entry,[{where, F},{order, {1, descending}},{limit, {Offset,PageAmount}}]).
-
-feed_direct_messages(_FId, Page, PageAmount, CurrentUser, CurrentFId) when is_integer(Page), Page>0->
-    Offset= case (Page-1)*PageAmount of
-        0 -> 1
-        ;M-> M
-    end,
-    F=fun(X) when element(5,X)=:=CurrentUser,element(9,X)=:={user,direct}-> true;
-         (X) when element(4,X)=:=CurrentFId,element(9,X)=:={user,direct} -> true;
-         (_)->false end,
-    store:select(entry,[{where, F},{order, {1, descending}},{limit, {Offset,PageAmount}}]).
-
-acl_add_entry(_A,_B,_C) -> ok.

+ 137 - 744
src/store_riak.erl

@@ -1,52 +1,41 @@
 -module(store_riak).
 -author('Maxim Sokhatsky <maxim@synrc.com>').
--include("users.hrl").
--include("feeds.hrl").
--include("acls.hrl").
--include("invites.hrl").
--include("attachments.hrl").
--include("meetings.hrl").
--include("membership_packages.hrl").
--include("accounts.hrl").
--include("log.hrl").
+-include_lib("kvs/include/config.hrl").
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/groups.hrl").
+-include_lib("kvs/include/feeds.hrl").
+-include_lib("kvs/include/acls.hrl").
+-include_lib("kvs/include/invites.hrl").
+-include_lib("kvs/include/meetings.hrl").
+-include_lib("kvs/include/membership_packages.hrl").
+-include_lib("kvs/include/accounts.hrl").
+-include_lib("kvs/include/log.hrl").
 -include_lib("stdlib/include/qlc.hrl").
 -compile(export_all).
 
 -define(BUCKET_INDEX, "bucket_bin").
 -define(MD_INDEX, <<"index">>).
--define(COUNTERS_BUCKET_ID_SEQ, <<"id_seq">>).
 
 delete() -> ok.
 start() -> ok.
 stop() -> stopped.
 
 initialize() ->
-    C = riak:client_connect(?RIAKSERVER_NODE),
+    C = riak:client_connect('node_runner@127.0.0.1'),
     ets:new(config, [named_table,{keypos,#config.key}]),
     ets:insert(config, #config{ key = "riak_client", value = C}),
     ok.
 
-
 init_indexes() ->
     C = riak_client(),
-    ok = C:set_bucket(t_to_b(mhits), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(affiliates_rels), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(affiliates_contracts), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(affiliates_purchases), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(affiliates_contract_types), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(?COUNTERS_BUCKET_ID_SEQ, [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(subs), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(group_subs), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(user_bought_gifts), [{backend, leveldb_backend}]),
-    ok = C:set_bucket(t_to_b(play_record), [{backend, leveldb_backend}]),
-    ok = nsm_gifts_db:init_indexes().
-
-init_db() ->
-%    ?INFO("~w:init_db/0: started", [?MODULE]),
-    C = riak_client(),
-    ok = nsm_affiliates:init_db(),
-    ok = nsm_gifts_db:init_db(),
-%    ?INFO("~w:init_db/0: done", [?MODULE]),
+    C:set_bucket(key_to_bin(id_seq), [{backend, leveldb_backend}]),
+    C:set_bucket(key_to_bin(subscription), [{backend, leveldb_backend}]),
+    C:set_bucket(key_to_bin(user), [{backend, leveldb_backend}]),
+    C:set_bucket(key_to_bin(group), [{backend, leveldb_backend}]),
+    C:set_bucket(key_to_bin(translation), [{backend, leveldb_backend}]),
+    C:set_bucket(key_to_bin(group_subscription), [{backend, leveldb_backend}]),
+    C:set_bucket(key_to_bin(user_bought_gifts), [{backend, leveldb_backend}]),
+    C:set_bucket(key_to_bin(play_record), [{backend, leveldb_backend}]),
     ok.
 
 dir() ->
@@ -54,42 +43,6 @@ dir() ->
     {ok,Buckets} = C:list_buckets(),
     [binary_to_list(X)||X<-Buckets].
 
-clean() ->
-    riak_clean(mhits),
-    riak_clean(affiliates_contracts), riak_clean(affiliates_rels), riak_clean(affiliates_counters), riak_clean(affiliates_purchases), riak_clean(affiliates_contract_types),
-    riak_clean(gifts_counters), riak_clean(gifts_config), riak_clean(gifts),
-    riak_clean(play_record), riak_clean(player_scoring), riak_clean(scoring_record), riak_clean(personal_score), riak_clean(pointing_rule),
-    riak_clean(tournament), riak_clean(team),
-    riak_clean(membership_package), riak_clean(user_purchase), riak_clean(membership_purchase),
-    riak_clean(group),
-    riak_clean(browser_counter),
-    riak_clean(invite_code), riak_clean(forget_password),
-    riak_clean(user), riak_clean(user_by_email), riak_clean(user_by_facebook_id), riak_clean(user_address),
-    riak_clean(uploads),
-    riak_clean(acl), riak_clean(acl_entry),
-    riak_clean(account), riak_clean(transaction),
-    riak_clean(feature),
-    riak_clean(table),
-    riak_clean(config),
-    riak_clean(user_transaction),
-    riak_clean(save_game_table),
-    riak_clean(save_table),
-    riak_clean(game_table),
-    riak_clean(entry), riak_clean(likes), riak_clean(one_like), riak_clean(feed), riak_clean(comment),
-    riak_clean(group_member), riak_clean(group_member_rev), riak_clean(subscription), riak_clean(subscription_rev),
-    riak_clean(subs), riak_clean(group_subs), riak_clean(user_bought_gifts),
-    riak_clean(ut_word), riak_clean(ut_translation),
-    riak_clean(active_users_top),
-    riak_clean(user_counter),
-    riak_clean(twitter_oauth),
-    riak_clean(facebook_oauth),
-    riak_clean(hidden_feed),
-    riak_clean("unsuported"),
-    riak_clean("__riak_client_test__"),
-    riak_clean(id_seq),
-    C=riak_client(),
-    C:list_buckets().
-
 riak_clean(Table) when is_list(Table)->
     C = riak_client(),
     {ok,Keys}=C:list_keys(erlang:list_to_binary(Table)),
@@ -98,146 +51,41 @@ riak_clean(Table) ->
     C = riak_client(),
     [TableStr] = io_lib:format("~p",[Table]),
     {ok,Keys}=C:list_keys(erlang:list_to_binary(TableStr)),
-    [ store:delete(Table,key_to_bin(Key)) || Key <- Keys].
+    [ kvs:delete(Table,key_to_bin(Key)) || Key <- Keys].
 
-% Convert Erlang records to Riak objects
-make_object(T, Class) ->
-    Obj1 = make_obj(T, Class),
-    Bucket = r_to_b(T),
+make_object(T) ->
+    Bucket = element(1,T),
+    Key = element(2,T),
+    Obj1 = riak_object:new(key_to_bin(Bucket), key_to_bin(Key), T),
     Indices = [{?BUCKET_INDEX, Bucket} | make_indices(T)], %% Usefull only for level_db buckets
     Meta = dict:store(?MD_INDEX, Indices, dict:new()),
     Obj2 = riak_object:update_metadata(Obj1, Meta),
     Obj2.
 
-%% Record to bucket id
-r_to_b(R) -> t_to_b(element(1,R)).
-
-%% Table id to bucket id
-t_to_b(T) -> 
-    %% list_to_binary(atom_to_list(T)). FIXME: This should be after we eleminate {transaction,_} tables
-                                                % no. We use complex keys for leveldb now
-    [StringBucket] = io_lib:format("~p",[T]),
-    erlang:list_to_binary(StringBucket).
-
-%% Create indicies for the record
-make_indices(#mhits{word = Word, ip = IP, date = Date}) -> [{<<"mhits_date_bin">>, key_to_bin(Date)},
-                                                            {<<"mhits_word_date_bin">>, key_to_bin({Word, Date})},
-                                                            {<<"mhits_word_ip_date_bin">>, key_to_bin({Word,IP,Date})},
-                                                            {<<"mhits_word_bin">>, key_to_bin(Word)},
-                                                            {<<"mhits_word_ip_bin">>, key_to_bin({Word,IP})},
-                                                            {<<"mhits_ip_bin">>, key_to_bin(IP)},
-                                                            {<<"mhits_ip_date_bin">>, key_to_bin({IP, Date})}];
-make_indices(#affiliates_contracts{owner = OwnerId}) -> [{<<"owner_bin">>, key_to_bin(OwnerId)}];
-make_indices(#affiliates_purchases{owner_id = OwnerId, contract_id = ContractId}) -> [{<<"owner_bin">>, key_to_bin(OwnerId)},
-                                                                                      {<<"contract_bin">>, key_to_bin(ContractId)}];
-make_indices(#affiliates_rels{user = OwnerId, affiliate = OwnerId}) -> [{<<"owner_bin">>, key_to_bin(OwnerId)},
-                                                                        {<<"affiliate_bin">>, key_to_bin(1)}];
-make_indices(#affiliates_rels{affiliate = OwnerId}) -> [{<<"owner_bin">>, key_to_bin(OwnerId)}];
-make_indices(#subs{who=Who, whom=Whom}) -> [{<<"subs_who_bin">>, key_to_bin(Who)},
-                                            {<<"subs_whom_bin">>, key_to_bin(Whom)}];
-make_indices(#group_subs{user_id=UId, group_id=GId}) -> [{<<"group_subs_user_id_bin">>, key_to_bin(UId)},
-                                            {<<"group_subs_group_id_bin">>, key_to_bin(GId)}];
-make_indices(#play_record{who=UId, tournament=TId, team=TEId}) -> [{<<"play_record_who_bin">>, key_to_bin(UId)},
-                                            {<<"play_record_tournament_bin">>, key_to_bin(TId)}];
+make_indices(#subscription{who=Who, whom=Whom}) -> [{<<"subs_who_bin">>, key_to_bin(Who)}, {<<"subs_whom_bin">>, key_to_bin(Whom)}];
+make_indices(#group_subscription{user_id=UId, group_id=GId}) -> [{<<"group_subs_user_bin">>, key_to_bin(UId)}, {<<"group_subs_group_bin">>, key_to_bin(GId)}];
 make_indices(#user_bought_gifts{username=UId}) -> [{<<"user_bought_gifts_username_bin">>, key_to_bin(UId)}];
-
+make_indices(#user{username=UId,zone=Zone}) -> [{<<"user_bin">>, key_to_bin(UId)},{<<"user_zone_bin">>, key_to_bin(Zone)}];
 make_indices(_Record) -> [].
 
-
-make_obj(#mhits{word=W, ip=IP, date=D}=T, mhits) -> riak_object:new(r_to_b(T), key_to_bin({W,IP,D}), T);
-make_obj(T, affiliates_contract_types) -> riak_object:new(r_to_b(T), key_to_bin(T#affiliates_contract_types.id), T);
-make_obj(T, affiliates_contracts) -> riak_object:new(r_to_b(T), key_to_bin(T#affiliates_contracts.id), T);
-make_obj(T, affiliates_look_perms) -> riak_object:new(r_to_b(T), key_to_bin(T#affiliates_look_perms.user_id), T);
-make_obj(T, affiliates_purchases) -> #affiliates_purchases{contract_id = ContractId, user_id = UserId} = T,
-                                     riak_object:new(r_to_b(T), key_to_bin({ContractId, UserId}), T);
-make_obj(T, affiliates_rels) -> riak_object:new(r_to_b(T), key_to_bin(T#affiliates_rels.user), T);
-make_obj(T, subs) -> [Key] = io_lib:format("~p", [{T#subs.who, T#subs.whom}]), riak_object:new(r_to_b(T), list_to_binary(Key), T);
-make_obj(T, group_subs) -> [Key] = io_lib:format("~p", [{T#group_subs.user_id, T#group_subs.group_id}]), riak_object:new(r_to_b(T), list_to_binary(Key), T);
-make_obj(T, play_record) -> [Key] = io_lib:format("~p", [{T#play_record.who, T#play_record.tournament}]), riak_object:new(r_to_b(T), list_to_binary(Key), T);
-make_obj(T, user_bought_gifts) -> [Key] = io_lib:format("~p", [{T#user_bought_gifts.username, T#user_bought_gifts.timestamp}]), riak_object:new(r_to_b(T), list_to_binary(Key), T);
-make_obj(T, account) -> [Key] = io_lib:format("~p", [T#account.id]), riak_object:new(<<"account">>, list_to_binary(Key), T);
-make_obj(T, feed) -> riak_object:new(<<"feed">>, list_to_binary(integer_to_list(T#feed.id)), T);
-make_obj(T, user) -> riak_object:new(<<"user">>, list_to_binary(T#user.username), T);
-make_obj(T, user_address) -> riak_object:new(<<"user_address">>, list_to_binary(T#user_address.username), T);
-make_obj(T, game_table) -> riak_object:new(<<"game_table">>, list_to_binary(T#game_table.id), T);
-make_obj(T, player_scoring) -> riak_object:new(<<"player_scoring">>, list_to_binary(T#player_scoring.id), T);
-make_obj(T, scoring_record) -> riak_object:new(<<"scoring_record">>, list_to_binary(integer_to_list(T#scoring_record.id)), T);
-make_obj(T, personal_score) -> riak_object:new(<<"personal_score">>, list_to_binary(T#personal_score.uid), T);
-make_obj(T, save_game_table) -> riak_object:new(<<"save_game_table">>, list_to_binary(integer_to_list(T#save_game_table.id)), T);
-make_obj(T, feature) -> riak_object:new(<<"feature">>, list_to_binary(T#feature.name), T);
-make_obj(T, config) -> riak_object:new(<<"config">>, list_to_binary(T#config.key), T);
-make_obj(T = {user_by_email, _User, Email}, user_by_email) -> riak_object:new(<<"user_by_email">>, list_to_binary(Email), T);
-make_obj(T = {user_by_verification_code, _User, Code}, user_by_verification_code) -> riak_object:new(<<"user_by_verification_code">>, list_to_binary(Code), T);
-make_obj(T = {user_by_facebook_id, _User, FB}, user_by_facebook_id) -> riak_object:new(<<"user_by_facebook_id">>, list_to_binary(FB), T);
-make_obj(T, forget_password) -> riak_object:new(<<"forget_password">>, list_to_binary(T#forget_password.token), T);
-make_obj(T, entry) -> [Key] = io_lib:format("~p", [T#entry.id]), riak_object:new(<<"entry">>, list_to_binary(Key), T);
-make_obj(T, comment) -> [Key] = io_lib:format("~p", [T#comment.id]), riak_object:new(<<"comment">>, list_to_binary(Key), T);
-make_obj(T = {_,Key,_}, id_seq) -> riak_object:new(<<"id_seq">>, key_to_bin(Key), T);
-make_obj(T, group) -> riak_object:new(<<"group">>, list_to_binary(T#group.username), T);
-make_obj(T, tournament) -> riak_object:new(<<"tournament">>, list_to_binary(integer_to_list(T#tournament.id)), T);
-make_obj(T, team) -> riak_object:new(<<"team">>, list_to_binary(integer_to_list(T#team.id)), T);
-make_obj(T, acl) -> [Key] = io_lib:format("~p", [T#acl.id]), riak_object:new(<<"acl">>, list_to_binary(Key), T);
-make_obj(T, acl_entry) -> [Key] = io_lib:format("~p", [T#acl_entry.id]), riak_object:new(<<"acl_entry">>, list_to_binary(Key), T);
-make_obj(T, group_member) -> riak_object:new(<<"group_member">>, list_to_binary(T#group_member.who), T);
-make_obj(T, group_member_rev) -> riak_object:new(<<"group_member_rev">>, list_to_binary(T#group_member_rev.group), T);
-make_obj(T, subscription) -> riak_object:new(<<"subscription">>, list_to_binary(T#subscription.who), T);
-make_obj(T, subscription_rev) -> riak_object:new(<<"subscription_rev">>, list_to_binary(T#subscription_rev.whom), T);
-make_obj(T, user_ignores) -> riak_object:new(<<"user_ignores">>, list_to_binary(T#user_ignores.who), T);
-make_obj(T, user_ignores_rev) -> riak_object:new(<<"user_ignores_rev">>, list_to_binary(T#user_ignores_rev.whom), T);
-make_obj(T, ut_word) -> riak_object:new(<<"ut_word">>, list_to_binary(T#ut_word.english), T);
-make_obj(T, ut_translation) -> {Lang, English} = T#ut_translation.source, riak_object:new(<<"ut_translation">>, list_to_binary(Lang ++ "_" ++ English), T);
-make_obj(T, membership_package) -> riak_object:new(<<"membership_package">>, list_to_binary(T#membership_package.id), T);
-make_obj(T, membership_purchase) -> riak_object:new(<<"membership_purchase">>, list_to_binary(T#membership_purchase.id), T);
-make_obj(T, user_purchase) -> riak_object:new(<<"user_purchase">>, list_to_binary(T#user_purchase.user), T);
-make_obj(T, pointing_rule) -> [Key] = io_lib:format("~p", [T#pointing_rule.id]), riak_object:new(<<"pointing_rule">>, list_to_binary(Key), T);
-make_obj(T, transaction) -> riak_object:new(<<"transaction">>, list_to_binary(T#transaction.id), T);
-make_obj(T, user_transaction) -> riak_object:new(<<"user_transaction">>, key_to_bin(T#user_transaction.user), T);
-make_obj(T = {feed_blocked_users, UserId, _BlockedUsers}, feed_blocked_users) -> riak_object:new(<<"feed_blocked_users">>, list_to_binary(UserId), T);
-make_obj(T, uploads) -> [Key] = io_lib:format("~p", [T#uploads.key]), riak_object:new(<<"uploads">>, list_to_binary(Key), T);
-make_obj(T, invite_code) -> riak_object:new(<<"invite_code">>, list_to_binary(T#invite_code.code), T);
-make_obj(T = {_,User,_}, invite_code_by_user) -> riak_object:new(<<"invite_code_by_user">>, list_to_binary(User), T);
-make_obj(T, invite_by_issuer) -> riak_object:new(<<"invite_by_issuer">>, list_to_binary(T#invite_by_issuer.user), T);
-make_obj(T, entry_likes) -> riak_object:new(<<"entry_likes">>, list_to_binary(T#entry_likes.entry_id), T);
-make_obj(T, user_likes) -> riak_object:new(<<"user_likes">>, list_to_binary(T#user_likes.user_id), T);
-make_obj(T, one_like) -> riak_object:new(<<"one_like">>, list_to_binary(integer_to_list(T#one_like.id)), T);
-make_obj(T, active_users_top) -> riak_object:new(<<"active_users_top">>, list_to_binary(integer_to_list(T#active_users_top.no)), T);
-make_obj(T, user_count) -> riak_object:new(<<"user_count">>, <<"user_count">>, T);
-make_obj(T, twitter_oauth) -> riak_object:new(<<"twitter_oauth">>, list_to_binary(T#twitter_oauth.user_id), T);
-make_obj(T, facebook_oauth) -> riak_object:new(<<"facebook_oauth">>, list_to_binary(T#facebook_oauth.user_id), T);
-make_obj(T, hidden_feed) -> riak_object:new(<<"hidden_feed">>, list_to_binary(integer_to_list(T#hidden_feed.id)), T);
-make_obj(T, user_etries_count) -> riak_object:new(<<"user_etries_count">>, list_to_binary(T#user_etries_count.user_id), T);
-make_obj(T, invitation_tree) ->
-    Key = case T#invitation_tree.user of
-        ?INVITATION_TREE_ROOT -> [K] = io_lib:format("~p", [T#invitation_tree.user]), K;
-        String -> String
-    end,
-    riak_object:new(<<"invitation_tree">>, list_to_binary(Key), T);
-make_obj(T, Unsupported) -> riak_object:new(<<"unsuported">>, term_to_binary(Unsupported), T).
-
-
 riak_client() -> [{_,_,{_,C}}] = ets:lookup(config, "riak_client"), C.
 
--spec put(tuple() | [tuple()]) -> ok.
-put(Records) when is_list(Records) ->
-    lists:foreach(fun riak_put/1, Records);
-put(Record) ->
-    put([Record]).
+put(Records) when is_list(Records) -> lists:foreach(fun riak_put/1, Records);
+put(Record) -> store_riak:put([Record]).
 
 riak_put(Record) ->
-    Class = element(1,Record),
-    Object = make_object(Record, Class),
+    Object = make_object(Record),
     Riak = riak_client(),
     Result = Riak:put(Object, [{allow_mult,false},{last_write_wins,true}]),
-    post_write_hooks(Class, Record, Riak),
+    post_write_hooks(Record, Riak),
     Result.
 
 put_if_none_match(Record) ->
-    Class = element(1,Record),
-    Object = make_object(Record, Class),
+    Object = make_object(Record),
     Riak = riak_client(),
     case Riak:put(Object, [if_none_match]) of
         ok ->
-            post_write_hooks(Class, Record, Riak),
+            post_write_hooks(Record, Riak),
             ok;
         Error ->
             Error
@@ -245,9 +93,7 @@ put_if_none_match(Record) ->
 
 %% update(Record, Meta) -> ok | {error, Reason}
 update(Record, Object) ->
-    Class = element(1,Record),
-    %% Create pseudo new object and take its metadata to store in the updated object
-    NewObject = make_object(Record, Class),
+    NewObject = make_object(Record),
     NewKey = riak_object:key(NewObject),
     case riak_object:key(Object) of
         NewKey ->
@@ -256,54 +102,28 @@ update(Record, Object) ->
             UpdObject3 = riak_object:update_metadata(UpdObject2, MetaInfo),
             Riak = riak_client(),
             case Riak:put(UpdObject3, [if_not_modified]) of
-                ok ->
-                    post_write_hooks(Class, Record, Riak),
-                    ok;
-                Error ->
-                    Error
+                ok -> post_write_hooks(Record, Riak), ok;
+                Error -> Error
             end;
-        _ ->
-            {error, keys_not_equal}
+        _ -> {error, keys_not_equal}
     end.
 
-
-post_write_hooks(Class,R,C) ->
-    case Class of
+post_write_hooks(R,C) ->
+    case element(1,R) of
         user -> case R#user.email of
                     undefined -> nothing;
-                    _ -> C:put(make_object({user_by_email, R#user.username, R#user.email}, user_by_email))
-                end,
+                    _ -> C:put(make_object({email, R#user.username, R#user.email})) end,
                 case R#user.verification_code of
                     undefined -> nothing;
-                    _ -> C:put(make_object({user_by_verification_code, R#user.username, R#user.verification_code}, user_by_verification_code))
-                end,
+                    _ -> C:put(make_object({code, R#user.username, R#user.verification_code})) end,
                 case R#user.facebook_id of
                   undefined -> nothing;
-                  _ -> C:put(make_object({user_by_facebook_id, R#user.username, R#user.facebook_id}, user_by_facebook_id))
-                end;
-
-        invite_code ->
-            #invite_code{created_user=User, issuer = Issuer} = R,
-
-            if Issuer =/= undefined,
-               User =/= undefined ->
-                   nsm_affiliates:invitation_hook(Issuer, User);
-               true -> do_nothing
-            end,
-
-            case R#invite_code.created_user of
-                undefined -> nothing;
-                User -> C:put(make_object({invite_code_by_user, User, R#invite_code.code}, invite_code_by_user))
-            end;
-
+                  _ -> C:put(make_object({facebook, R#user.username, R#user.facebook_id})) end;
         _ -> continue
     end.
 
-% get
-
--spec get(atom(), term()) -> {ok, tuple()} | {error, not_found | duplicated}.
 get(Tab, Key) ->
-    Bucket = t_to_b(Tab),
+    Bucket = key_to_bin(Tab),
     IntKey = key_to_bin(Key),
     riak_get(Bucket, IntKey).
 
@@ -315,42 +135,31 @@ riak_get(Bucket,Key) -> %% TODO: add state monad here for conflict resolution wh
         X -> X
     end.
 
-%% get_for_update(Tab, Key) -> {ok, Record, Meta} | {error, Reason}
 get_for_update(Tab, Key) ->
     C = riak_client(),
-    case C:get(t_to_b(Tab), key_to_bin(Key), [{last_write_wins,true},{allow_mult,false}]) of
+    case C:get(key_to_bin(Tab), key_to_bin(Key), [{last_write_wins,true},{allow_mult,false}]) of
         {ok, O} -> {ok, riak_object:get_value(O), O};
         Error -> Error
     end.
 
-% translations
-
-get_word(Word) ->
-    get(ut_word,Word).
-
-get_translation({Lang, Word}) ->
-    get(ut_translation, Lang ++ "_" ++ Word).
+get_word(Word) -> store_riak:get(ut_word,Word).
+get_translation({Lang, Word}) -> store_riak:get(ut_translation, Lang ++ "_" ++ Word).
 
 % delete
 
--spec delete(tuple() | [tuple()]) -> ok.
-delete(Keys) when is_list(Keys) ->
-    lists:foreach(fun mnesia:delete_object/1, Keys); % TODO
-delete(Keys) ->
-    delete([Keys]).
+delete(Keys) when is_list(Keys) -> lists:foreach(fun mnesia:delete_object/1, Keys); % TODO
+delete(Keys) -> delete([Keys]).
 
--spec delete(atom(), term()) -> ok.
 delete(Tab, Key) ->
     C = riak_client(),
-    Bucket = t_to_b(Tab),
+    Bucket = key_to_bin(Tab),
     IntKey = key_to_bin(Key),
     C:delete(Bucket, IntKey),
     ok.
 
--spec delete_by_index(atom(), binary(), term()) -> ok.
 delete_by_index(Tab, IndexId, IndexVal) ->
     Riak = riak_client(),
-    Bucket = t_to_b(Tab),
+    Bucket = key_to_bin(Tab),
     {ok, Keys} = Riak:get_index(Bucket, {eq, IndexId, key_to_bin(IndexVal)}),
     [Riak:delete(Bucket, Key) || Key <- Keys],
     ok.
@@ -358,18 +167,11 @@ delete_by_index(Tab, IndexId, IndexVal) ->
 key_to_bin(Key) ->
     if is_integer(Key) -> erlang:list_to_binary(integer_to_list(Key));
        is_list(Key) -> erlang:list_to_binary(Key);
-       is_tuple(Key) -> [ListKey] = io_lib:format("~p", [Key]), erlang:list_to_binary(ListKey);
        is_atom(Key) -> erlang:list_to_binary(erlang:atom_to_list(Key));
        is_binary(Key) -> Key;
        true ->  [ListKey] = io_lib:format("~p", [Key]), erlang:list_to_binary(ListKey)
     end.
 
-% search
-
--spec multi_select(atom(), [term()]) -> [tuple()].
-multi_select(_RecordName, _Keys) when is_list(_Keys) -> erlang:error(notimpl).
-%    [mnesia:read({RecordName, Key}) || Key <- Keys].
-
 select(RecordName, Pred) when is_function(Pred) ->
 	%% FIXME: bruteforce select
 	All = all(RecordName),
@@ -393,13 +195,8 @@ select(RecordName, Select) when is_list(Select) ->
 	end.
 
 
--spec count(atom()) -> non_neg_integer().
-count(_RecordName) ->
-    erlang:length(all(_RecordName)).
-%   erlang:error(notimpl).
-%   mnesia:table_info(RecordName, size). % TODO
+count(_RecordName) -> erlang:length(all(_RecordName)).
 
--spec all(atom()) -> [tuple()].
 all(RecordName) ->
     Riak = riak_client(),
     [RecordStr] = io_lib:format("~p",[RecordName]),
@@ -408,10 +205,11 @@ all(RecordName) ->
     Results = [ get_record_from_table({RecordBin, Key, Riak}) || Key <- Keys ],
     [ Object || Object <- Results, Object =/= failure ].
 
-%% all_by_index(Tab, IndexId, IndexVal) -> RecordsList
+%% get by index
+
 all_by_index(Tab, IndexId, IndexVal) ->
     Riak = riak_client(),
-    Bucket = t_to_b(Tab),
+    Bucket = key_to_bin(Tab),
     {ok, Keys} = Riak:get_index(Bucket, {eq, IndexId, key_to_bin(IndexVal)}),
     F = fun(Key, Acc) ->
                 case Riak:get(Bucket, Key, []) of
@@ -429,21 +227,13 @@ get_record_from_table({RecordBin, Key, Riak}) ->
 
 % id generator
 
--spec next_id(list()) -> pos_integer().
-next_id(CounterId) ->
-    next_id(CounterId, 1).
-
--spec next_id(term(), integer()) -> pos_integer().
-next_id(CounterId, Incr) ->
-    next_id(CounterId, 0, Incr).
-
--spec next_id(term(), integer(), integer()) -> pos_integer().
-%% Safe implementation of counters
+next_id(CounterId) -> next_id(CounterId, 1).
+next_id(CounterId, Incr) -> next_id(CounterId, 0, Incr).
 next_id(CounterId, Default, Incr) ->
     Riak = riak_client(),
     CounterBin = key_to_bin(CounterId),
     {Object, Value, Options} =
-        case Riak:get(?COUNTERS_BUCKET_ID_SEQ, CounterBin, []) of
+        case Riak:get(key_to_bin(id_seq), CounterBin, []) of
             {ok, CurObj} ->
                 R = #id_seq{id = CurVal} = riak_object:get_value(CurObj),
                 NewVal = CurVal + Incr,
@@ -451,263 +241,33 @@ next_id(CounterId, Default, Incr) ->
                 {Obj, NewVal, [if_not_modified]};
             {error, notfound} ->
                 NewVal = Default + Incr,
-                Obj = riak_object:new(?COUNTERS_BUCKET_ID_SEQ, CounterBin, #id_seq{thing = CounterId, id = NewVal}),
-                {Obj, NewVal, [if_none_match]}
-        end,
+                Obj = riak_object:new(key_to_bin(id_seq), CounterBin, #id_seq{thing = CounterId, id = NewVal}),
+                {Obj, NewVal, [if_none_match]} end,
     case Riak:put(Object, Options) of
-        ok ->
-            Value;
-        {error, _} -> %% FIXME: Right reason(s) should be specified here
-            next_id(CounterId, Incr)
-    end.
+        ok -> Value;
+        {error, _} -> next_id(CounterId, Incr) end.
 
-% browser counters
-
--spec delete_browser_counter_older_than(pos_integer()) -> ok.
-delete_browser_counter_older_than(_MinTS) -> % TODO
-    [].
-%    MatchHead = #browser_counter{minute='$1', _ = '_'},
-%    Guard = {'<', '$1', MinTS},
-%    Result = '$_',
-%    List = mnesia:select(browser_counter, [{MatchHead, [Guard], [Result]}]),
-%          lists:foreach(fun(X) ->
-%                    mnesia:delete_object(X)
-%                end, List),
-%    List.
-
-unused_invites() -> % TODO
-    List = store:all(invite_code),
-    length([ #invite_code{created_user=undefined} || _Code <- List]).
+% user backlinks
 
 user_by_verification_code(Code) ->
-    R = case store:get(user_by_verification_code,Code) of
-	{ok,{_,User,_}} -> store:get(user,User);
-	Else -> Else
-	end,
-    R.
+    case kvs:get(code,Code) of
+        {ok,{_,User,_}} -> kvs:get(user,User);
+        Else -> Else end.
 
 user_by_facebook_id(FBId) ->
-    R = case store:get(user_by_facebook_id,FBId) of
-	{ok,{_,User,_}} -> store:get(user,User);
-	Else -> Else
-	end,
-    R.
-
-user_by_email(FB) ->
-    R = case store:get(user_by_email,FB) of
-	{ok,{_,User,_}} -> store:get(user,User);
-	Else -> Else
-	end,
-    R.
-
-user_by_username(Name) ->
-    case X = store:get(user,Name) of
-	{ok,_Res} -> X;
-	Else -> Else
-    end.
-
-%invite_code_by_issuer(User) ->
-%    case store:get(invite_code_by_issuer, User) of
-%        {ok, {invite_code_by_user, _, Code}} ->
-%            case store:get(invite_code, Code) of
-%                {ok, #invite_code{} = C} ->
-%                    [C];
-%                _ ->
-%                    []
-%            end;
-%        _ ->
-%            []
-%    end.
-
-invite_code_by_user(User) ->
-    case store:get(invite_code_by_user, User) of
-        {ok, {invite_code_by_user, _, Code}} ->
-            case store:get(invite_code, Code) of
-                {ok, #invite_code{} = C} ->
-                    [C];
-                _ ->
-                    []
-            end;
-        _ ->
-            []
-    end.
-
-
-% Todo: run in background
-update_user_name(UId,UName,Surname) ->
-    Name = case {UName,Surname} of
-        {undefined,undefined} -> UId;
-        _ -> io_lib:format("~s ~s", [UName, Surname])
-    end,
-    case store:get(group_member, UId) of
-    {error, notfound} -> ok;
-    {ok, #group_member{group=List}} ->
-        UpdateUserName = fun(#group_member{group=GId,type=Type}, _) ->
-            case store:get(group_member_rev, GId) of
-            {error, notfound} ->
-                store:put(#group_member_rev{group=GId,
-                                                who=[#group_member_rev{who=UId,who_name=Name,group=GId,type=Type}],
-                                                type=list});
-            {ok,#group_member_rev{who=Whos}} ->
-                NewWhos = lists:map(fun(#group_member_rev{who=U}=M) when U==UId->
-                                           M#group_member_rev{who_name=Name};(M)->M end, Whos),
-                store:put(#group_member_rev{group=GId, who=NewWhos, type=list})
-            end
-        end,
-        lists:foldl(UpdateUserName, undefined, List)
-    end.
-
-% game info
-
-get_save_tables(Id) ->
-    case store:get(save_game_table, Id) of
-	{error,notfound} -> [];
-	{ok,R} -> R
-    end.
+    case kvs:get(facebook,FBId) of
+        {ok,{_,User,_}} -> kvs:get(user,User);
+        Else -> Else end.
 
-save_game_table_by_id(Id) -> store:get(save_game_table, Id).
-
-% subscriptions
-
-subscribe_user(MeId, FrId) ->
-    MeShow = case store:get(user, MeId) of
-        {ok, #user{name=MeName,surname=MeSur}} ->
-            io_lib:format("~s ~s", [MeName,MeSur]);
-        _Z ->
-            io:format("Get ~s: ~p~n", [MeId, _Z]),
-            undefined
-    end,
-    FrShow = case store:get(user, FrId) of
-        {ok, #user{name=FrName,surname=FrSur}} ->
-            io_lib:format("~s ~s", [FrName,FrSur]);
-        _ ->
-            undefined
-    end,
-    Rec = #subscription{who = MeId, whom = FrId, whom_name = FrShow},
-    case store:get(subscription, MeId) of
-        {error, notfound} ->
-            store:put(#subscription{who = MeId, whom = [Rec]});
-        {ok, #subscription{whom = List}} ->
-            case lists:member(Rec, List) of
-                false ->
-                    NewList =
-                        lists:keystore(FrId, #subscription.whom, List, Rec),
-                    store:put(#subscription{who = MeId, whom = NewList});
-                true ->
-                    do_nothing
-            end
-    end,
-    RevRec = #subscription_rev{whom=FrId, who=MeId, who_name=MeShow},
-    case store:get(subscription_rev, FrId) of
-        {error,notfound} ->
-            store:put(#subscription_rev{whom=FrId, who=[RevRec]});
-        {ok,#subscription_rev{who=RevList}} ->
-            case lists:member(RevRec, RevList) of
-                false ->
-                    NewRevList =
-                        lists:keystore(MeId, #subscription_rev.who, RevList, RevRec),
-                    store:put(#subscription_rev{whom=FrId, who=NewRevList});
-                true ->
-                    do_nothing
-            end
-    end,
-    ok.
-
-remove_subscription(MeId, FrId) ->
-    List = nsm_users:list_subscription(MeId),
-    Subs = [ Sub || Sub <- List, not(Sub#subscription.who==MeId andalso Sub#subscription.whom==FrId) ],
-    store:put(#subscription{who = MeId, whom = Subs}),
-    List2 = nsm_users:list_subscription_me(FrId),
-    Revs = [ Rev || Rev <- List2, not(Rev#subscription_rev.who==MeId andalso Rev#subscription_rev.whom==FrId) ],
-    store:put(#subscription_rev{who = Revs, whom = FrId}).
-
-list_subscriptions(#user{username = UId}) -> list_subscriptions(UId);
-list_subscriptions(UId) when is_list(UId) ->
-    case store:get(subscription, UId) of
-	{ok,#subscription{whom = C}} -> C;
-	_ -> []
-    end.
+user_by_email(Email) ->
+    case kvs:get(email,Email) of
+        {ok,{_,User,_}} -> kvs:get(user,User);
+        Else -> Else end.
 
-list_subscription_me(UId) ->
-    case store:get(subscription_rev, UId) of
-	{ok,#subscription_rev{who = C}} -> C;
-	_ -> []
-    end.
-
-is_user_subscribed(Who,Whom) ->
-    case store:get(subscription, Who) of
-    {ok,#subscription{whom = W}} ->
-        lists:any(fun(#subscription{who=Who1, whom=Whom1}) -> Who1==Who andalso Whom1==Whom; (_)->false end, W);
-    _ -> false
-    end.
-
-
-% blocking user
-
-block_user(Who, Whom) ->
-    case store:get(user_ignores, Who) of
-        {error, notfound} ->
-            store:put(#user_ignores{who = Who, whom = [Whom]});
-        {ok, #user_ignores{whom = List}} ->
-            case lists:member(Whom, List) of
-                false ->
-                    NewList = [Whom | List],
-                    store:put(#user_ignores{who = Who, whom = NewList});
-                true ->
-                    do_nothing
-            end
-    end,
-    case store:get(user_ignores_rev, Whom) of
-        {error,notfound} ->
-            store:put(#user_ignores_rev{whom=Whom, who=[Who]});
-        {ok,#user_ignores_rev{who=RevList}} ->
-            case lists:member(Who, RevList) of
-                false ->
-                    NewRevList = [Who | RevList],
-                    store:put(#user_ignores_rev{whom=Whom, who=NewRevList});
-                true ->
-                    do_nothing
-            end
-    end,
-    ok.
-
-unblock_user(Who, Whom) ->
-    List = list_blocks(Who),
-    case lists:member(Whom, List) of
-        true ->
-            NewList = [ UID || UID <- List, UID =/= Whom ],
-            store:put(#user_ignores{who = Who, whom = NewList});
-        false ->
-            do_nothing
-    end,
-    List2 = list_blocked_me(Whom),
-    case lists:member(Who, List2) of
-        true ->
-            NewRevList = [ UID || UID <- List2, UID =/= Who ],
-            store:put(#user_ignores_rev{whom = Whom, who = NewRevList});
-        false ->
-            do_nothing
-    end.
-
-list_blocks(#user{username = UId}) -> list_blocks(UId);
-list_blocks(UId) when is_list(UId) ->
-    case store:get(user_ignores, UId) of
-        {ok,#user_ignores{whom = C}} -> C;
-        _ -> []
-    end.
-
-list_blocked_me(UId) ->
-    case store:get(user_ignores_rev, UId) of
-        {ok,#user_ignores_rev{who = C}} -> C;
-        _ -> []
-    end.
-
-is_user_blocked(Who, Whom) ->
-    case store:get(user_ignores, Who) of
-        {ok,#user_ignores{whom = List}} ->
-            lists:member(Whom, List);
-        _ -> false
-    end.
+user_by_username(Name) ->
+    case X = kvs:get(user,Name) of
+        {ok,_Res} -> X;
+        Else -> Else end.
 
 % feeds
 
@@ -715,31 +275,31 @@ feed_add_direct_message(FId,User,To,EntryId,Desc,Medias) -> feed_add_entry(FId,U
 feed_add_entry(FId,From,EntryId,Desc,Medias) -> feed_add_entry(FId,From,undefined,EntryId,Desc,Medias,{user,normal},"").
 feed_add_entry(FId, User, To, EntryId,Desc,Medias,Type,SharedBy) ->
     %% prevent adding of duplicate records to feed
-    case store:entry_by_id({EntryId, FId}) of
+    case kvs:entry_by_id({EntryId, FId}) of
         {ok, _} -> ok;
         _ -> do_feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy)
     end.
 
 do_feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy) ->
-    {ok,Feed} = store:get(feed,erlang:integer_to_list(FId)),
+    {ok,Feed} = kvs:get(feed,erlang:integer_to_list(FId)),
     Id = {EntryId, FId},
     Next = undefined,
     Prev = case Feed#feed.top of
                undefined ->
                    undefined;
                X ->
-                   case store:get(entry, X) of
+                   case kvs:get(entry, X) of
                        {ok, TopEntry} ->
                            EditedEntry = TopEntry#entry{next = Id},
                            % update prev entry
-                           store:put(EditedEntry),
+                           kvs:put(EditedEntry),
                            TopEntry#entry.id;
                        {error,notfound} ->
                            undefined
                    end
            end,
 
-    store:put(#feed{id = FId, top = {EntryId, FId}}), % update feed top with current
+    kvs:put(#feed{id = FId, top = {EntryId, FId}}), % update feed top with current
 
     Entry  = #entry{id = {EntryId, FId},
                     entry_id = EntryId,
@@ -763,7 +323,7 @@ do_feed_add_entry(FId, User, To, EntryId, Desc, Medias, Type, SharedBy) ->
                        ME
                end,
 
-    store:put(ModEntry),
+    kvs:put(ModEntry),
     {ok, ModEntry}.
 
 feed_add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias) ->
@@ -771,30 +331,30 @@ feed_add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias)
 
     Prev = case ParentComment of
         undefined ->
-            {ok, Entry} = store:entry_by_id({EntryId, FId}),
+            {ok, Entry} = kvs:entry_by_id({EntryId, FId}),
             {PrevC, E} = case Entry#entry.comments of
                         undefined ->
                             {undefined, Entry#entry{comments_rear = FullId}};
                         Id ->
-                            {ok, PrevTop} = store:get(comment, Id),
-                            store:put(PrevTop#comment{next = FullId}),
+                            {ok, PrevTop} = kvs:get(comment, Id),
+                            kvs:put(PrevTop#comment{next = FullId}),
                             {Id, Entry}
                    end,
 
-            store:put(E#entry{comments=FullId}),
+            kvs:put(E#entry{comments=FullId}),
             PrevC;
 
         _ ->
-            {ok, Parent} = store:get(comment, {{EntryId, FId}, ParentComment}),
+            {ok, Parent} = kvs:get(comment, {{EntryId, FId}, ParentComment}),
             {PrevC, CC} = case Parent#comment.comments of
                         undefined ->
                             {undefined, Parent#comment{comments_rear = FullId}};
                         Id ->
-                            {ok, PrevTop} = store:get(comment, Id),
-                            store:put(PrevTop#comment{next = FullId}),
+                            {ok, PrevTop} = kvs:get(comment, Id),
+                            kvs:put(PrevTop#comment{next = FullId}),
                             {Id, Parent}
                     end,
-            store:put(CC#comment{comments = FullId}),
+            kvs:put(CC#comment{comments = FullId}),
             PrevC
     end,
     Comment = #comment{id = FullId,
@@ -808,22 +368,22 @@ feed_add_comment(FId, User, EntryId, ParentComment, CommentId, Content, Medias)
                        prev = Prev,
                        next = undefined
                       },
-    store:put(Comment),
+    kvs:put(Comment),
     {ok, Comment}.
 
 add_transaction_to_user(UserId,Purchase) ->
-    {ok,Team} = case store:get(user_transaction, UserId) of
+    {ok,Team} = case kvs:get(user_transaction, UserId) of
                      {ok,T} -> {ok,T};
                      _ -> ?INFO("user_transaction not found"),
                           Head = #user_transaction{ user = UserId, top = undefined},
-                          {store:put(Head),Head}
+                          {kvs:put(Head),Head}
                 end,
 
-    EntryId = Purchase#transaction.id, %store:next_id("membership_purchase",1),
+    EntryId = Purchase#transaction.id, %kvs:next_id("membership_purchase",1),
     Prev = undefined,
     case Team#user_transaction.top of
         undefined -> Next = undefined;
-        X -> case store:get(transaction, X) of
+        X -> case kvs:get(transaction, X) of
                  {ok, TopEntry} ->
                      Next = TopEntry#transaction.id,
                      EditedEntry = #transaction {
@@ -836,7 +396,7 @@ add_transaction_to_user(UserId,Purchase) ->
                            id = TopEntry#transaction.id,
                            next = TopEntry#transaction.next,
                            prev = EntryId },
-                    store:put(EditedEntry); % update prev entry
+                    kvs:put(EditedEntry); % update prev entry
                  {error,notfound} -> Next = undefined
              end
     end,
@@ -851,22 +411,22 @@ add_transaction_to_user(UserId,Purchase) ->
                            next = Next,
                            prev = Prev},
 
-    case store:put(Entry) of ok -> store:put(#user_transaction{ user = UserId, top = EntryId}), {ok, EntryId};
+    case kvs:put(Entry) of ok -> kvs:put(#user_transaction{ user = UserId, top = EntryId}), {ok, EntryId};
                               Error -> ?INFO("Cant write transaction"), {failure,Error} end.
 
 add_purchase_to_user(UserId,Purchase) ->
-    {ok,Team} = case store:get(user_purchase, UserId) of
+    {ok,Team} = case kvs:get(user_purchase, UserId) of
                      {ok,T} -> ?INFO("user_purchase found"), {ok,T};
                      _ -> ?INFO("user_purchase not found"),
                           Head = #user_purchase{ user = UserId, top = undefined},
-                          {store:put(Head),Head}
+                          {kvs:put(Head),Head}
                 end,
 
-    EntryId = Purchase#membership_purchase.id, %store:next_id("membership_purchase",1),
+    EntryId = Purchase#membership_purchase.id, %kvs:next_id("membership_purchase",1),
     Prev = undefined,
     case Team#user_purchase.top of
         undefined -> Next = undefined;
-        X -> case store:get(membership_purchase, X) of
+        X -> case kvs:get(membership_purchase, X) of
                  {ok, TopEntry} ->
                      Next = TopEntry#membership_purchase.id,
                      EditedEntry = #membership_purchase{
@@ -881,12 +441,12 @@ add_purchase_to_user(UserId,Purchase) ->
                            id = TopEntry#membership_purchase.id,
                            next = TopEntry#membership_purchase.next,
                            prev = EntryId},
-                    store:put(EditedEntry); % update prev entry
+                    kvs:put(EditedEntry); % update prev entry
                  {error,notfound} -> Next = undefined
              end
     end,
 
-    store:put(#user_purchase{ user = UserId, top = EntryId}), % update team top with current
+    kvs:put(#user_purchase{ user = UserId, top = EntryId}), % update team top with current
 
     Entry  = #membership_purchase{id = EntryId,
                                   user_id = UserId,
@@ -900,78 +460,23 @@ add_purchase_to_user(UserId,Purchase) ->
                                   next = Next,
                                   prev = Prev},
 
-    case store:put(Entry) of ok -> {ok, EntryId};
+    case kvs:put(Entry) of ok -> {ok, EntryId};
                            Error -> ?INFO("Cant write purchase"), {failure,Error} end.
 
-invite_code_by_issuer(UserId) -> invite_code_by_issuer(UserId, undefined, 1000).
-
-invite_code_by_issuer(UserId, undefined, PageAmount) ->
-    case store:get(invite_by_issuer, UserId) of
-        {ok, O} when O#invite_by_issuer.top =/= undefined -> 
-                                invite_code_by_issuer(UserId, O#invite_by_issuer.top, PageAmount);
-        {error, notfound} -> []
-    end;
-invite_code_by_issuer(UserId, StartFrom, Limit) ->
-    case store:get(invite_code,StartFrom) of
-        {ok, #invite_code{next = N}=P} -> [ P | riak_traversal(invite_code, #invite_code.next, N, Limit)];
-        X -> []
-    end.
-
-add_invite_to_issuer(UserId,O) ->
-    {ok,Team} = case store:get(invite_by_issuer, UserId) of
-                     {ok,T} -> ?INFO("user inviters root found"), {ok,T};
-                     _ -> ?INFO("user invites root not found"),
-                          Head = #invite_by_issuer{ user = UserId, top = undefined},
-                          {store:put(Head),Head}
-                end,
-
-    EntryId = O#invite_code.code, 
-    Prev = undefined,
-    case Team#invite_by_issuer.top of
-        undefined -> Next = undefined;
-        X -> case store:get(invite_code, X) of
-                 {ok, TopEntry} ->
-                     Next = TopEntry#invite_code.code,
-                     EditedEntry = #invite_code{
-                           code = TopEntry#invite_code.code,
-                           create_date = TopEntry#invite_code.create_date,
-                           issuer = TopEntry#invite_code.issuer,
-                           recipient = TopEntry#invite_code.recipient,
-                           created_user = TopEntry#invite_code.created_user,
-                           next = TopEntry#invite_code.next,
-                           prev = EntryId},
-                    store:put(EditedEntry); % update prev entry
-                 {error,notfound} -> Next = undefined
-             end
-    end,
-
-    store:put(#invite_by_issuer{ user = UserId, top = EntryId}), % update team top with current
-
-    Entry  = #invite_code{ code = EntryId,
-                           create_date = O#invite_code.create_date,
-                           issuer = O#invite_code.issuer,
-                           recipient = O#invite_code.recipient,
-                           created_user = O#invite_code.created_user,
-                     next = Next,
-                     prev = Prev},
-
-    case store:put(Entry) of ok -> {ok, EntryId};
-                           Error -> ?INFO("Cant write invite_by_issuer"), {failure,Error} end.
-
 acl_add_entry(Resource, Accessor, Action) ->
-    Acl = case store:get(acl, Resource) of
+    Acl = case kvs:get(acl, Resource) of
               {ok, A} ->
                   A;
               %% if acl record wasn't created already
               {error, notfound} ->
                   A = #acl{id = Resource, resource=Resource},
-                  store:put(A),
+                  kvs:put(A),
                   A
           end,
 
     EntryId = {Accessor, Resource},
 
-    case store:get(acl_entry, EntryId) of
+    case kvs:get(acl_entry, EntryId) of
         %% there is no entries for specified Acl and Accessor, we have to add it
         {error, notfound} ->
             Next = undefined,
@@ -980,10 +485,10 @@ acl_add_entry(Resource, Accessor, Action) ->
                            undefined;
 
                        Top ->
-                           case store:get(acl_entry, Top) of
+                           case kvs:get(acl_entry, Top) of
                                {ok, TopEntry} ->
                                    EditedEntry = TopEntry#acl_entry{next = EntryId},
-                                   store:put(EditedEntry), % update prev entry
+                                   kvs:put(EditedEntry), % update prev entry
                                    TopEntry#acl_entry.id;
 
                                {error, notfound} ->
@@ -992,7 +497,7 @@ acl_add_entry(Resource, Accessor, Action) ->
                    end,
 
             %% update acl with top of acl entries list
-            store:put(Acl#acl{top = EntryId}),
+            kvs:put(Acl#acl{top = EntryId}),
 
             Entry  = #acl_entry{id = EntryId,
                                 entry_id = EntryId,
@@ -1001,71 +506,63 @@ acl_add_entry(Resource, Accessor, Action) ->
                                 next = Next,
                                 prev = Prev},
 
-            ok = store:put(Entry),
+            ok = kvs:put(Entry),
             Entry;
 
         %% if acl entry for Accessor and Acl is defined - just change action
         {ok, AclEntry} ->
-            store:put(AclEntry#acl_entry{action = Action}),
+            kvs:put(AclEntry#acl_entry{action = Action}),
             AclEntry
     end.
 
 
 join_tournament(UserId, TournamentId) ->
-    case store:get(user, UserId) of
+    case kvs:get(user, UserId) of
         {ok, User} ->
-            GP = case nsm_accounts:balance(UserId, ?CURRENCY_GAME_POINTS) of
+            GP = case accounts:balance(UserId, points) of
                      {ok, AS1} -> AS1;
                      {error, _} -> 0 end,
-            K = case nsm_accounts:balance(UserId,  ?CURRENCY_KAKUSH) of
-                     {ok, AS2} -> AS2;
-                     {error, _} -> 0 end,
-            KC = case nsm_accounts:balance(UserId,  ?CURRENCY_KAKUSH_CURRENCY) of
-                     {ok, AS3} -> AS3;
-                     {error, _} -> 0 end,
-            Q = case nsm_accounts:balance(UserId,  ?CURRENCY_QUOTA) of
+            Q = case accounts:balance(UserId,  quota) of
                      {ok, AS4} -> AS4;
                      {error, _} -> 0 end,
-            RN = nsm_users:user_realname(UserId),
-            store:put(#play_record{
+            RN = users:user_realname(UserId),
+            kvs:put(#play_record{
                  who = UserId,
                  tournament = TournamentId,
                  team = User#user.team,
                  game_id = undefined, 
 		 other = now(),
                  realname = RN,
-                 game_points = GP,
-                 kakush = K,
-                 kakush_currency = KC,
+                 points = GP,
                  quota = Q});
         _ ->
             ?INFO(" User ~p not found for joining tournament ~p", [UserId, TournamentId])
     end.
 
 leave_tournament(UserId, TournamentId) ->
-    case store:get(play_record, {UserId, TournamentId}) of
+    case kvs:get(play_record, {UserId, TournamentId}) of
         {ok, _} -> 
-            store:delete(play_record, {UserId, TournamentId}),
+            kvs:delete(play_record, {UserId, TournamentId}),
             leave_tournament(UserId, TournamentId); % due to WTF error with old records
         _ -> ok
     end.
 
 user_tournaments(UId) -> 
-    store:all_by_index(play_record, <<"play_record_who_bin">>, list_to_binary(UId)).
+    kvs:all_by_index(play_record, <<"play_record_who_bin">>, list_to_binary(UId)).
 
 tournament_waiting_queue(TId) ->
-    store:all_by_index(play_record, <<"play_record_tournament_bin">>, list_to_binary(integer_to_list(TId))).
+    kvs:all_by_index(play_record, <<"play_record_tournament_bin">>, list_to_binary(integer_to_list(TId))).
 
 
 -spec entry_by_id(term()) -> {ok, #entry{}} | {error, not_found}.
-entry_by_id(EntryId) -> store:get(entry, EntryId).
+entry_by_id(EntryId) -> kvs:get(entry, EntryId).
 
 -spec comment_by_id({{EntryId::term(), FeedId::term()}, CommentId::term()}) -> {ok, #comment{}}.
-comment_by_id(CommentId) -> store:get(CommentId).
+comment_by_id(CommentId) -> kvs:get(CommentId).
 
 -spec comments_by_entry(EId::{string(), term()}) -> [#comment{}].
 comments_by_entry({EId, FId}) ->
-    case store:entry_by_id({EId, FId}) of
+    case kvs:entry_by_id({EId, FId}) of
         {ok, #entry{comments_rear = undefined}} ->
             [];
         {ok, #entry{comments_rear = First}} ->
@@ -1085,13 +582,13 @@ get_purchases_by_user(UserId, Start, Count, States) ->
     end.
 
 purchases_in_basket(UserId, undefined, PageAmount) ->
-    case store:get(user_purchase, UserId) of
+    case kvs:get(user_purchase, UserId) of
         {ok, O} when O#user_purchase.top =/= undefined -> 
                                      purchases_in_basket(UserId, O#user_purchase.top, PageAmount);
         {error, notfound} -> []
     end;
 purchases_in_basket(UserId, StartFrom, Limit) ->
-    case store:get(membership_purchase,StartFrom) of
+    case kvs:get(membership_purchase,StartFrom) of
         {ok, #membership_purchase{next = N}=P} -> [ P | riak_traversal(membership_purchase, #membership_purchase.next, N, Limit)];
         X -> []
     end.
@@ -1099,12 +596,12 @@ purchases_in_basket(UserId, StartFrom, Limit) ->
 transactions(UserId) -> tx_list(UserId, undefined, 10000).
 
 tx_list(UserId, undefined, PageAmount) ->
-    case store:get(user_transaction, UserId) of
+    case kvs:get(user_transaction, UserId) of
         {ok, O} when O#user_transaction.top =/= undefined -> tx_list(UserId, O#user_transaction.top, PageAmount);
         {error, notfound} -> []
     end;
 tx_list(UserId, StartFrom, Limit) ->
-    case store:get(transaction,StartFrom) of
+    case kvs:get(transaction,StartFrom) of
         {ok, #transaction{next = N}=P} -> [ P | riak_traversal(transaction, #transaction.next, N, Limit)];
         X -> []
     end.
@@ -1120,7 +617,7 @@ read_comments_rev(C) -> riak_traversal(comment, #comment.next, C, all).
 riak_traversal( _, _, undefined, _) -> [];
 riak_traversal(_, _, _, 0) -> [];
 riak_traversal(RecordType, PrevPos, Next, Count)->
-    case nsm_riak:get(RecordType, Next) of
+    case srore_riak:get(RecordType, Next) of
         {error,notfound} -> [];
         {ok, R} ->
             Prev = element(PrevPos, R),
@@ -1138,51 +635,18 @@ riak_read_acl_entries(C, Next, Result) ->
     end.
 
 purge_feed(FeedId) ->
-    {ok,Feed} = store:get(feed,FeedId),
+    {ok,Feed} = kvs:get(feed,FeedId),
     Removal = riak_entry_traversal(Feed#feed.top, -1),
-    [store:delete(entry,Id)||#entry{id=Id}<-Removal],
-    store:put(Feed#feed{top=undefined}).
+    [kvs:delete(entry,Id)||#entry{id=Id}<-Removal],
+    kvs:put(Feed#feed{top=undefined}).
 
 purge_unverified_feeds() ->
-    [purge_feed(FeedId) || #user{feed=FeedId,status=S,email=E} <- store:all(user),E==undefined].
-
-purge_system_messages() ->
-    [delete_system_messages(U,FeedId) || U=#user{feed=FeedId} <- store:all(user)].
-
-delete_system_messages(U,FeedId) ->
-    ?INFO("Cleaning ~p user feed from system messages",[U]),
-    {ok,Feed} = store:get(feed,FeedId),
-    Entries = riak_entry_traversal(Feed#feed.top, -1),
-    {Removal,Relink} = lists:partition(fun(#entry{type={_,Type}}) -> Type == system orelse Type == system_note end,Entries),
-    [store:delete(entry,Id)||#entry{id=Id}<-Removal],
-    Len = length(Relink),
-    case Len of
-         0 -> skip;
-         _ ->  Relinked = [begin E = lists:nth(N,Relink),
-                               {Next,Prev} = case N of 
-                                   1 -> case Len of
-                                             1 -> {undefined,undefined};
-                                             _ -> NextEntry = lists:nth(N+1,Relink),
-                                                 {undefined,NextEntry#entry.id}
-                                        end;
-                                 Len -> PrevEntry = lists:nth(N-1,Relink),
-                                       {PrevEntry#entry.id,undefined};
-                                   _ -> PrevEntry = lists:nth(N-1,Relink),
-                                        NextEntry = lists:nth(N+1,Relink),
-                                       {PrevEntry#entry.id,NextEntry#entry.id}
-                                end,
-                                E#entry{next = Next, prev = Prev}
-               end || N <- lists:seq(1,Len)],
-               Link = hd(Relinked),
-               store:put(Feed#feed{top=Link#entry.id}),
-               [store:put(X) || X <- Relinked] 
-    end,
-    Len.
+    [purge_feed(FeedId) || #user{feed=FeedId,status=S,email=E} <- kvs:all(user),E==undefined].
 
 riak_entry_traversal(undefined, _) -> [];
 riak_entry_traversal(_, 0) -> [];
 riak_entry_traversal(Next, Count)->
-    case nsm_riak:get(entry, Next) of
+    case store_riak:get(entry, Next) of
         {error,notfound} -> [];
         {ok, R} ->
             Prev = element(#entry.prev, R),
@@ -1198,13 +662,13 @@ riak_entry_traversal(Next, Count)->
     end.
 
 entries_in_feed(FeedId, undefined, PageAmount) ->
-    case store:get(feed, FeedId) of
+    case kvs:get(feed, FeedId) of
         {ok, O} -> riak_entry_traversal(O#feed.top, PageAmount);
         {error, notfound} -> []
     end;
 entries_in_feed(FeedId, StartFrom, PageAmount) ->
     %% construct entry unic id
-    case store:get(entry,{StartFrom, FeedId}) of
+    case kvs:get(entry,{StartFrom, FeedId}) of
         {ok, #entry{prev = Prev}} -> riak_entry_traversal(Prev, PageAmount);
         _ -> []
     end.
@@ -1225,74 +689,3 @@ feed_direct_messages(_FId, Page, PageAmount, CurrentUser, CurrentFId) ->
     Page, PageAmount, CurrentUser, CurrentFId,
     [].
 
--spec put_into_invitation_tree(Parent::string()|{root}, User::string(), InviteCode::string()) -> #invitation_tree{}.
-put_into_invitation_tree(Parent, User, InviteCode) ->
-    URecord =  #invitation_tree{user = User,
-                                invite_code = InviteCode,
-                                parent = Parent},
-
-    case store:get(invitation_tree, Parent) of
-        {ok, #invitation_tree{first_child = TopChild} = P} ->
-            store:put(P#invitation_tree{first_child = User}),
-            URecord1 = URecord#invitation_tree{next_sibling = TopChild},
-            store:put(URecord1),
-            URecord1;
-        _ ->
-            R = case Parent of
-                    ?INVITATION_TREE_ROOT ->
-                        #invitation_tree{user = ?INVITATION_TREE_ROOT};
-                    _ ->
-                        put_into_invitation_tree(?INVITATION_TREE_ROOT,
-                                                 Parent, undefined)
-                end,
-            store:put(R#invitation_tree{first_child = User}),
-            store:put(URecord),
-            URecord
-    end.
-
-
--spec invitation_tree(StartFrom::string()|{root}, Depth::integer()|all) -> [#invitation_tree{}].
-invitation_tree(_, -1) -> [];
-invitation_tree(none, _) -> [];
-invitation_tree(UserId, Depth) ->
-    case store:get(invitation_tree, UserId) of
-        {ok, #invitation_tree{} = ITreeU} ->
-            FirstChild = ITreeU#invitation_tree.first_child,
-            SiblingId = ITreeU#invitation_tree.next_sibling,
-            Depth1 = case Depth of
-                         all -> Depth;
-                         _ -> Depth - 1
-                     end,
-            [ITreeU#invitation_tree{children=invitation_tree(FirstChild, Depth1)}|
-                                       invitation_tree(SiblingId, Depth)];
-        {error, _} -> []
-    end.
-
-%% @doc delete link to child from children list
-invitation_tree_delete_child_link(RootUser, User) ->
-    case invitation_tree(RootUser, 1) of
-        [#invitation_tree{first_child = User} = Root] ->
-            Root1 = Root#invitation_tree{children = []},
-            case store:get(invitation_tree, User) of
-                {ok, #invitation_tree{next_sibling = none}} ->
-                    store:put(Root1#invitation_tree{first_child = none});
-                {ok, #invitation_tree{next_sibling = Next}} ->
-                    store:put(Root1#invitation_tree{first_child = Next});
-                _ -> ok
-            end;
-
-        [#invitation_tree{children = Children}] ->
-            case
-                [E || #invitation_tree{next_sibling = NS, user = U} = E <- Children,
-                      NS == User orelse U == User] of
-
-                [Before, Exactly] ->
-                    NextSibling =  Exactly#invitation_tree.next_sibling,
-                    store:put(Before#invitation_tree{next_sibling = NextSibling,
-                                                         children = []});
-                _ -> ok
-            end;
-        _ -> ok
-    end.
-
-

+ 113 - 272
src/users.erl

@@ -1,293 +1,157 @@
 -module(users).
--include("user.hrl").
--include("accounts.hrl").
--include("log.hrl").
--include_lib("white_rabbit/include/nsm_mq.hrl").
+-include_lib("kvs/include/users.hrl").
+-include_lib("kvs/include/groups.hrl").
+-include_lib("kvs/include/accounts.hrl").
+-include_lib("kvs/include/log.hrl").
+-include_lib("mqs/include/mqs.hrl").
 -compile(export_all).
 
-do_register(#user{username=U} = RegisterData0) ->
-  case check_register_data(RegisterData0) of
-    ok ->
-      HashedPassword = case RegisterData0#user.password of
-        undefined -> undefined;
-        PlainPassword -> utils:sha(PlainPassword)
-      end,
-      RegisterData = RegisterData0#user{
-        feed     = store:feed_create(),
-        direct   = store:feed_create(),
-        pinned   = store:feed_create(),
-        starred  = store:feed_create(),
-        password = HashedPassword},
-
-      store:put(RegisterData),
-      %nsx_msg:notify(["system", "put"], RegisterData),
-      nsm_accounts:create_account(U),
-      % assign quota
-      {ok, DefaultQuota} = store:get(config, "accounts/default_quota",  300),
-      nsm_accounts:transaction(U, ?CURRENCY_QUOTA, DefaultQuota, #ti_default_assignment{}),
-      %% init message queues infrastructure
-      init_mq(U, []),
-      login_posthook(U),
-      {ok, U};
-    {error, Error} -> {error, Error}
-  end.
-
 register(#user{username=U, email=Email, facebook_id = FbId} = RegisterData0) ->
-  FindUser = case check_username(U, FbId) of
-    {error, E} -> {error, E};
-    {ok, NewName} ->
-      case get_user({email, Email}) of
-        {error, _NotFound} -> {ok, NewName};
-        {ok, _} -> {error, email_taken}
-      end
-  end,
-
-  FindUser2 = case FindUser of
-    {ok, UserName} ->
-      case nsm_groups:get_group(UserName) of
-        {error, notfound} -> {ok, UserName}; % it means username is free
-        _ -> {error, username_taken}
-      end;
-    SomethingElse -> SomethingElse
-  end,
-
-  case FindUser2 of
-    {ok, Name} -> do_register(RegisterData0#user{username=Name});
-    {error, username_taken} -> {error, user_exist};
-    {error, email_taken} ->    {error, email_taken}
-  end.
+    FindUser = case check_username(U, FbId) of
+        {error, E} -> {error, E};
+        {ok, NewName} -> case users:get({email, Email}) of
+            {error, _} -> {ok, NewName};
+            {ok, _} -> {error, email_taken} end end,
+
+    FindUser2 = case FindUser of
+        {ok, UserName} -> case groups:get(UserName) of
+            {error, _} -> {ok, UserName};
+            _ -> {error, username_taken} end;
+        A -> A end,
+
+    case FindUser2 of
+        {ok, Name} -> process_register(RegisterData0#user{username=Name});
+        {error, username_taken} -> {error, user_exist};
+        {error, email_taken} ->    {error, email_taken} end.
+
+process_register(#user{username=U} = RegisterData0) ->
+    HashedPassword = case RegisterData0#user.password of
+        undefined -> undefined;
+        PlainPassword -> utils:sha(PlainPassword) end,
+    RegisterData = RegisterData0#user {
+        feed     = kvs:feed_create(),
+        direct   = kvs:feed_create(),
+        pinned   = kvs:feed_create(),
+        starred  = kvs:feed_create(),
+        password = HashedPassword },
+
+    kvs:put(RegisterData),
+    accounts:create_account(U),
+    {ok, DefaultQuota} = kvs:get(config, "accounts/default_quota",  300),
+    accounts:transaction(U, quota, DefaultQuota, #tx_default_assignment{}),
+    init_mq(U, []),
+    {ok, U}.
 
 check_username(Name, FbId) ->
-  case get_user(Name) of
-    {error, notfound} -> {ok, Name};
-    {ok, User} when FbId =/= undefined ->
-      check_username(User#user.username  ++ integer_to_list(crypto:rand_uniform(0,10)), FbId);
-    {ok, _User}-> {error, username_taken}
-  end.
-
-% @doc
-% Removes user with all tigth connected entries relying on user_id
-delete_user(UserName) ->
-   % get User record
-   case get_user(UserName) of
-	{ok, User} ->
-	   %% remove from all groups
-       GIds = nsm_groups:list_groups_per_user(UserName),
-       [nsx_msg:notify(["subscription", "user", UserName, "remove_from_group"], {GId}) || GId <- GIds],
-	   %% remove from subcribtions
-	   S = list_subscr(User),
-	   F2U = [ {MeId, FrId} || #subscription{who = MeId, whom = FrId} <- S ],
-	   [ unsubscr_user(MeId, FrId) || {MeId, FrId} <- F2U ],
-	   [ unsubscr_user(FrId, MeId) || {MeId, FrId} <- F2U ],
-	   store:delete(user_status, UserName),
-	   store:delete(user, UserName),
-	   {ok, User};
-	E -> E
-   end.
-
-get_user({username, UserName}) -> store:user_by_username(UserName);
-get_user({facebook, FBId}) -> store:user_by_facebook_id(FBId);
-get_user({email, Email}) -> store:user_by_email(Email);
-get_user(UId) -> store:get(user, UId).
-
-get_all_users() -> store:all(user).
+    case users:get(Name) of
+        {error, notfound} -> {ok, Name};
+        {ok, User} when FbId =/= undefined -> check_username(User#user.username  ++ integer_to_list(crypto:rand_uniform(0,10)), FbId);
+        {ok, _}-> {error, username_taken} end.
+
+delete(UserName) ->
+    case users:get(UserName) of
+        {ok, User} -> GIds = groups:list_groups_per_user(UserName),
+                      [nsx_msg:notify(["subscription", "user", UserName, "remove_from_group"], {GId}) || GId <- GIds],
+                      F2U = [ {MeId, FrId} || #subscription{who = MeId, whom = FrId} <- subscriptions(User) ],
+                      [ unsubscribe(MeId, FrId) || {MeId, FrId} <- F2U ],
+                      [ unsubscribe(FrId, MeId) || {MeId, FrId} <- F2U ],
+                      kvs:delete(user_status, UserName),
+                      kvs:delete(user, UserName),
+                      {ok, User};
+                 E -> E end.
+
+get({username, UserName}) -> kvs:user_by_username(UserName);
+get({facebook, FBId}) -> kvs:user_by_facebook_id(FBId);
+get({email, Email}) -> kvs:user_by_email(Email);
+get(UId) -> kvs:get(user, UId).
 
 subscribe(Who, Whom) ->
     case is_user_blocked(Who, Whom) of
-        false ->
-            Record = #subs{who = Who, whom = Whom},
-            ok = store:put(Record),
-            subscribe_user_mq(user, Who, Whom);
-        true -> do_nothing
+        false -> Record = #subscription{key={Who,Whom}, who = Who, whom = Whom},
+                 kvs:put(Record),
+                 subscribe_user_mq(user, Who, Whom);
+        true  -> do_nothing
     end.
 
 unsubscribe(Who, Whom) ->
-    case is_user_subscr(Who, Whom) of
-        true ->
-            ok = store:delete(subs, {Who, Whom}),
-            remove_subscription_mq(user, Who, Whom);
-        false ->
-            do_nothing
-    end.
-
-list_subscr(undefined)-> [];
-list_subscr(#user{username = UId}) -> list_subscr(UId);
-list_subscr(UId) when is_list(UId) -> lists:sort( store:all_by_index(subs, <<"subs_who_bin">>, list_to_binary(UId)) ).
-list_subscr(UId, PageNumber, PageAmount) when is_list(UId) -> 
-    Offset = case (PageNumber-1)*PageAmount of
-        I when is_integer(I), I>0 -> I+1;
-        _ -> 1
-	 end,
-	lists:sublist(list_subscr(UId), Offset, PageAmount).
-list_subscr_usernames(UId) -> [UserId || #subs{whom = UserId} <- list_subscr(UId)].
-
-list_subscr_me(#user{username = UId}) -> list_subscr_me(UId);
-list_subscr_me(UId) when is_list(UId) -> lists:sort( store:all_by_index(subs, <<"subs_whom_bin">>, list_to_binary(UId)) ).
+    case subscribed(Who, Whom) of
+        true  -> kvs:delete(subscription, {Who, Whom}),
+                 remove_subscription_mq(user, Who, Whom);
+        false -> skip end.
 
-is_user_subscr(Who, Whom) ->
-    case store:get(subs, {Who, Whom}) of
-        {ok, _} -> ?INFO("User ~p is a friend of user ~p", [Whom, Who]), true;
-        _Response -> ?INFO("User ~p is not a friend of user ~p. Response: ~p", [Whom, Who, _Response]), false
-    end.
-
-update_after_login(User) -> %RPC to cleanup
-    Update =
-        case user_status(User) of
-            {error, status_info_not_found} ->
-                #user_status{username = User,
-                             last_login = erlang:now()};
-            {ok, UserStatus} ->
-                UserStatus#user_status{last_login = erlang:now()}
-        end,
-    store:put(Update).
-
-user_status(User) ->
-    case store:get(user_status, User) of
-        {ok, Status} ->
-            {ok, Status};
-        {error, notfound} ->
-            {error, status_info_not_found}
-    end.
-
-
-user_status(User, Key) ->
-    case user_status(User) of
-        {ok, Status0} ->
-            Fields = record_info(fields, user_status),
-            [user_status | List] = tuple_to_list(Status0),
-            Status = lists:zip(Fields, List),
-            {_, V} = lists:keyfind(Key, 1, Status),
-            {ok, V};
-        _ ->
-            {error, status_info_not_found}
-    end.
-
-user_status(User, Key, Value) ->
-    case user_status(User) of
-        {ok, Status0} ->
-            Fields = record_info(fields, user_status),
-            [user_status | List] = tuple_to_list(Status0),
-            Status = lists:zip(Fields, List),
-            NewStatus0 = lists:keyreplace(Key, 1, Status, {Key, Value}),
-            NewStatus = [user_status | element(2, lists:unzip(NewStatus0))],
-            store:put(list_to_tuple(NewStatus));
-        _ ->
-            {error, status_info_not_found}
-    end.
+subscriptions(undefined)-> [];
+subscriptions(#user{username = UId}) -> subscriptions(UId);
+subscriptions(UId) when is_list(UId) -> lists:sort( kvs:all_by_index(subs, <<"subs_who_bin">>, list_to_binary(UId)) ).
 
-get_user_by_feed_id(Fid) ->
-    store:select(user, fun(#user{feed=F}) when F=:=Fid-> true;(_)->false end).
-
-search_user("") ->
-	store:all(user);
-search_user(Str) ->
-    store:select(user,
-        fun(#user{email=E}) when E=:=Str-> true;
-        (#user{username=N}) when N=:=Str-> true;
-        (#user{name=N})     when N=:=Str-> true;
-        (#user{surname=S})  when S=:=Str-> true;
-        (#user{surname=S, name=N})      ->
-            case S ++ " " ++ N of
-                Sum when Sum=:=Str -> true;
-                _                  -> false
-            end;
-        (_)                             ->false
-        end).
-
-get_user_game_status(User) ->
-    case store:get(user_game_status, User) of
-        {ok, #user_game_status{status=Status}} -> Status
-        ;_                                     -> "offline"
-    end.
-
-set_user_game_status(User, Status) -> store:put(#user_game_status{user=User, status=Status}).
-
-% TODO: game_session:525 move real DB operation from here behind rabbit
-%       two level: first message received by session pid
-%                   then it goes to change db bg worker
+subscribed(Who, Whom) ->
+    case kvs:get(subscription, {Who, Whom}) of
+        {ok, _} -> true;
+        _ -> false end.
 
 block(Who, Whom) ->
     ?INFO("~w:block_user/2 Who=~p Whom=~p", [?MODULE, Who, Whom]),
-    unsubscr_user(Who, Whom),
-    store:block_user(Who, Whom),
+    unsubscribe(Who, Whom),
+    kvs:block_user(Who, Whom),
     nsx_msg:notify_user_block(Who, Whom).
 
 unblock(Who, Whom) ->
     ?INFO("~w:unblock_user/2 Who=~p Whom=~p", [?MODULE, Who, Whom]),
-    store:unblock_user(Who, Whom),
+    kvs:unblock_user(Who, Whom),
     nsx_msg:notify_user_unblock(Who, Whom).
 
-blocked_users(UserId) -> store:list_blocks(UserId).
+blocked_users(UserId) -> kvs:list_blocks(UserId).
 
 get_blocked_users_feed_id(UserId) ->
-    UsersId = store:list_blocks(UserId),
-    Users = store:select(user, fun(#user{username=U})-> lists:member(U, UsersId) end),
+    UsersId = kvs:list_blocks(UserId),
+    Users = kvs:select(user, fun(#user{username=U})-> lists:member(U, UsersId) end),
     {UsersId, [Fid || #user{feed=Fid} <- Users]}.
 
-
-is_user_blocked(Who, Whom) -> store:is_user_blocked(Who,Whom).
+is_user_blocked(Who, Whom) -> kvs:is_user_blocked(Who,Whom).
 
 update_user(#user{username=UId,name=Name,surname=Surname} = NewUser) ->
-    OldUser = case store:get(user,UId) of
+    OldUser = case kvs:get(user,UId) of
         {error,notfound} -> NewUser;
         {ok,#user{}=User} -> User
     end,
-    store:put(NewUser),
+    kvs:put(NewUser),
     case Name==OldUser#user.name andalso Surname==OldUser#user.surname of
         true -> ok;
-        false -> store:update_user_name(UId,Name,Surname)
+        false -> kvs:update_user_name(UId,Name,Surname)
     end.
 
 subscribe_user_mq(Type, MeId, ToId) -> process_subscription_mq(Type, add, MeId, ToId).
 remove_subscription_mq(Type, MeId, ToId) -> process_subscription_mq(Type, delete, MeId, ToId).
 process_subscription_mq(Type, Action, MeId, ToId) ->
-    {ok, Channel} = nsm_mq:open([]),
+    {ok, Channel} = mqs:open([]),
     Routes = case Type of
-                 user ->
-                     rk_user_feed(ToId);
-                 group ->
-                     rk_group_feed(ToId)
+                 user -> rk_user_feed(ToId);
+                 group -> rk_group_feed(ToId)
              end,
     case Action of
-        add ->
-            bind_user_exchange(Channel, MeId, Routes);
-        delete ->
-            catch(unbind_user_exchange(Channel, MeId, Routes))
+        add -> bind_user_exchange(Channel, MeId, Routes);
+        delete -> catch(unbind_user_exchange(Channel, MeId, Routes))
     end,
-    nsm_mq_channel:close(Channel),
-    ok.
+    mqs_channel:close(Channel).
 
 init_mq(User, Groups) ->
-    ?INFO("~p init mq. nsm_users: ~p", [User, Groups]),
+    ?INFO("~p init mq. users: ~p", [User, Groups]),
     UserExchange = ?USER_EXCHANGE(User),
-    %% we need fanout exchange to give all information to all users queues
-    ExchangeOptions = [{type, <<"fanout">>},
-                       durable,
-                       {auto_delete, false}],
-    {ok, Channel} = nsm_mq:open([]),
+    ExchangeOptions = [{type, <<"fanout">>}, durable, {auto_delete, false}],
+    {ok, Channel} = mqs:open([]),
     ?INFO("Cration Exchange: ~p,",[{Channel,UserExchange,ExchangeOptions}]),
-    ok = nsm_mq_channel:create_exchange(Channel, UserExchange,
-                                        ExchangeOptions),
-                                          ?INFO("Created OK"),
-    %% build routing keys for user's relations
+    mqs_channel:create_exchange(Channel, UserExchange, ExchangeOptions), ?INFO("Created OK"),
     Relations = build_user_relations(User, Groups),
-
-    %% RK = Routing Key. Bind exchange to all user related keys.
-    [bind_user_exchange(Channel, User, RK)
-       || RK <- [rk([feed, delete, User])|Relations]],
-
-    nsm_mq_channel:close(Channel),
+    [bind_user_exchange(Channel, User, RK) || RK <- [rk([feed, delete, User])|Relations]],
+    mqs_channel:close(Channel),
     ok.
 
-init_mq_for_user(User) ->
-    init_mq(User, nsm_groups:list_groups_per_user(User) ).
+init_mq_for_user(User) -> init_mq(User, groups:list_groups_per_user(User) ).
 
 build_user_relations(User, Groups) ->
     %% Feed Keys. Subscribe for self events, system and groups events
     %% feed.FeedOwnerType.FeedOwnerId.ElementType.ElementId.Action
     %% feed.system.ElementType.Action
     [rk_user_feed(User),
-     %% API
      rk( [db, user, User, put] ),
      rk( [subscription, user, User, add_to_group]),
      rk( [subscription, user, User, remove_from_group]),
@@ -295,66 +159,48 @@ build_user_relations(User, Groups) ->
      rk( [login, user, User, update_after_login]),
      rk( [likes, user, User, add_like]),
      rk( [personal_score, user, User, add]),
-
      rk( [feed, user, User, count_entry_in_statistics] ),
      rk( [feed, user, User, count_comment_in_statistics] ),
-
      rk( [feed, user, User, post_note] ),
-
      rk( [subscription, user, User, subscribe_user]),
      rk( [subscription, user, User, remove_subscribe]),
      rk( [subscription, user, User, set_user_game_status]),
      rk( [subscription, user, User, update_user]),
      rk( [subscription, user, User, block_user]),
      rk( [subscription, user, User, unblock_user]),
-
      rk( [affiliates, user, User, create_affiliate]),
      rk( [affiliates, user, User, delete_affiliate]),
      rk( [affiliates, user, User, enable_to_look_details]),
      rk( [affiliates, user, User, disable_to_look_details]),
-
      rk( [purchase, user, User, set_purchase_external_id]),
      rk( [purchase, user, User, set_purchase_state]),
      rk( [purchase, user, User, set_purchase_info]),
      rk( [purchase, user, User, add_purchase]),
-
      rk( [transaction, user, User, add_transaction]),
-
      rk( [invite, user, User, add_invite_to_issuer]),
-
      rk( [tournaments, user, User, create]),
      rk( [tournaments, user, User, create_and_join]),
-
      rk( [gifts, user, User, buy_gift]),
      rk( [gifts, user, User, give_gift]),
      rk( [gifts, user, User, mark_gift_as_deliving]),
-
-     %% system message format: feed.system.ElementType.Action
      rk( [feed, system, '*', '*']) |
      [rk_group_feed(G) || G <- Groups]].
 
-bind_user_exchange(Channel, User, RoutingKey) ->
-    {bind, RoutingKey, nsm_mq_channel:bind_exchange(Channel, ?USER_EXCHANGE(User), ?NOTIFICATIONS_EX, RoutingKey)}.
-
-unbind_user_exchange(Channel, User, RoutingKey) ->
-    {unbind, RoutingKey, nsm_mq_channel:unbind_exchange(Channel, ?USER_EXCHANGE(User), ?NOTIFICATIONS_EX, RoutingKey)}.
-
-bind_group_exchange(Channel, Group, RoutingKey) ->
-    {bind, RoutingKey, nsm_mq_channel:bind_exchange(Channel, ?GROUP_EXCHANGE(Group), ?NOTIFICATIONS_EX, RoutingKey)}.
-
-unbind_group_exchange(Channel, Group, RoutingKey) ->
-    {unbind, RoutingKey, nsm_mq_channel:unbind_exchange(Channel, ?GROUP_EXCHANGE(Group), ?NOTIFICATIONS_EX, RoutingKey)}.
+bind_user_exchange(Channel, User, RoutingKey) -> {bind, RoutingKey, mqs_channel:bind_exchange(Channel, ?USER_EXCHANGE(User), ?NOTIFICATIONS_EX, RoutingKey)}.
+unbind_user_exchange(Channel, User, RoutingKey) -> {unbind, RoutingKey, mqs_channel:unbind_exchange(Channel, ?USER_EXCHANGE(User), ?NOTIFICATIONS_EX, RoutingKey)}.
+bind_group_exchange(Channel, Group, RoutingKey) -> {bind, RoutingKey, mqs_channel:bind_exchange(Channel, ?GROUP_EXCHANGE(Group), ?NOTIFICATIONS_EX, RoutingKey)}.
+unbind_group_exchange(Channel, Group, RoutingKey) -> {unbind, RoutingKey, mqs_channel:unbind_exchange(Channel, ?GROUP_EXCHANGE(Group), ?NOTIFICATIONS_EX, RoutingKey)}.
 
 init_mq_for_group(Group) ->
     GroupExchange = ?GROUP_EXCHANGE(Group),
     ExchangeOptions = [{type, <<"fanout">>},
                        durable,
                        {auto_delete, false}],   
-    {ok, Channel} = nsm_mq:open([]),
-    ok = nsm_mq_channel:create_exchange(Channel, GroupExchange, ExchangeOptions),
+    {ok, Channel} = mqs:open([]),
+    ok = mqs_channel:create_exchange(Channel, GroupExchange, ExchangeOptions),
     Relations = build_group_relations(Group),
     [bind_group_exchange(Channel, Group, RK) || RK <- Relations],
-    nsm_mq_channel:close(Channel),
+    mqs_channel:close(Channel),
     ok.
 
 build_group_relations(Group) ->
@@ -368,27 +214,22 @@ build_group_relations(Group) ->
     ].
 
 
-rk(List) ->
-    nsm_mq_lib:list_to_key(List).
-
-rk_user_feed(User) ->
-    rk([feed, user, User, '*', '*', '*']).
-
-rk_group_feed(Group) ->
-    rk([feed, group, Group, '*', '*', '*']).
+rk(List) -> mqs_lib:list_to_key(List).
+rk_user_feed(User) -> rk([feed, user, User, '*', '*', '*']).
+rk_group_feed(Group) -> rk([feed, group, Group, '*', '*', '*']).
 
 retrieve_connections(Id,Type) ->
     Friends = case Type of 
-                  user -> nsm_users:list_subscr_usernames(Id);
-                     _ -> nsm_groups:list_group_members(Id) end,
+                  user -> users:list_subscr_usernames(Id);
+                     _ -> groups:list_group_members(Id) end,
     case Friends of
 	[] -> [];
 	Full -> Sub = lists:sublist(Full, 10),
                 case Sub of
                      [] -> [];
-                      _ -> Data = [begin case store:get(user,Who) of
-                                       {ok,User} -> RealName = nsm_users:user_realname_user(User),
-                                                    Paid = nsm_accounts:user_paid(Who),
+                      _ -> Data = [begin case kvs:get(user,Who) of
+                                       {ok,User} -> RealName = users:user_realname_user(User),
+                                                    Paid = accounts:user_paid(Who),
                                                     {Who,Paid,RealName};
 				               _ -> undefined end end || Who <- Sub],
 			   [X||X<-Data, X/=undefined] end end.