From c7900a01ff8028be4ae1b73cd4c1fe3dfef13200 Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Wed, 12 Dec 2018 21:06:12 +0100 Subject: ... --- src/ataxia_client.erl | 100 ++++++++++++++++++++++++------------------- src/ataxia_server.erl | 40 ++++++++--------- src/ataxic.erl | 116 +++++++++++++++++++++++++++++++++----------------- 3 files changed, 154 insertions(+), 102 deletions(-) diff --git a/src/ataxia_client.erl b/src/ataxia_client.erl index f1b96e1..95b544f 100644 --- a/src/ataxia_client.erl +++ b/src/ataxia_client.erl @@ -13,9 +13,9 @@ insert_at/5, insert/4, remove/3, - fetch/3, + fetch/4, reserve/3, - commit/1 + commit/4 ] ). @@ -44,26 +44,26 @@ get_db_node_for (_ObjectID) -> ataxia_security:permission(), any() ) - -> 'ok'. -insert_at (DB, ObjectID, ReadPerm, WritePerm, Value) -> - DBNode = get_db_node_for(ObjectID), + -> ({'aborted', any()} | 'ok'). +insert_at (DB, ID, ReadPerm, WritePerm, Value) -> + DBNode = get_db_node_for(ID), - {atomic, _} = + Reply = rpc:call ( DBNode, - db_access, + atexia_server, insert_at, - [DB, ObjectID, ReadPerm, WritePerm, Value] + [DB, ID, ReadPerm, WritePerm, Value] ), io:format ( - "~nshr_database:insert_at(~p) ! ~p -> ok.~n", - [{DB, ObjectID, ReadPerm, WritePerm, Value}, DBNode] + "~nshr_database:insert_at(~p) ! ~p -> ~p.~n", + [{DB, ID, ReadPerm, WritePerm, Value}, DBNode, Reply] ), - ok. + Reply. -spec insert ( @@ -72,12 +72,12 @@ insert_at (DB, ObjectID, ReadPerm, WritePerm, Value) -> ataxia_security:permission(), any() ) - -> {'ok', binary()}. + -> ({'ok', ataxia_id:type()} | {'aborted', any()}). insert (DB, ReadPerm, WritePerm, Value) -> DBNode = get_random_db_node(), - {atomic, {ok, ID}} = - rpc:call(DBNode, db_access, insert, [DB, ReadPerm, WritePerm, Value]), + Reply = + rpc:call(DBNode, atexia_server, insert, [DB, ReadPerm, WritePerm, Value]), io:format ( @@ -85,74 +85,86 @@ insert (DB, ReadPerm, WritePerm, Value) -> [{DB, ReadPerm, WritePerm, Value}, DBNode] ), - {ok, ID}. + Reply. -spec fetch ( atom(), - binary(), - ataxia_security:user() + ataxia_security:user(), + ataxic:type(), + ataxia_id:type() ) -> ({'ok', any()} | 'not_found'). -fetch (DB, ObjectID, Cred) -> - DBNode = get_db_node_for(ObjectID), +fetch (DB, User, Selector, ID) -> + DBNode = get_db_node_for(ID), - {atomic, Reply} = rpc:call(DBNode, db_access, read, [DB, ObjectID, Cred]), + Reply = rpc:call(DBNode, atexia_server, read, [DB, User, Selector, ID]), io:format ( "~nshr_database:fetch(~p) ! ~p -> ~p.~n", - [{DB, ObjectID, Cred}, DBNode, Reply] + [{DB, User, Selector, ID}, DBNode, Reply] ), Reply. --spec commit (shr_db_query:type()) -> 'ok'. -commit (Query) -> - DBNode = get_db_node_for(shr_db_query:get_entry_id(Query)), +-spec commit + ( + atom(), + ataxia_security:user(), + ataxiac:meta(), + ataxia_id:type() + ) + -> ('ok' | 'not_found'). +commit (DB, User, Op, ID) -> + DBNode = get_db_node_for(ID), - {atomic, ok} = rpc:call(DBNode, db_access, query, [Query]), + Reply = rpc:call(DBNode, atexia_server, query, [DB, User, Op, ID]), - io:format("~nshr_database:commit(~p) ! ~p -> ok.~n", [Query, DBNode]), + io:format + ( + "~nataxia_client:commit(~p) ! ~p -> ~p.~n", + [{DB, User, Op, ID}, DBNode, Reply] + ), - ok. + Reply. -spec remove ( atom(), - binary(), - ataxia_security:user() + ataxia_security:user(), + ataxia_id:type() ) -> ('ok' | 'not_found'). -remove (DB, ObjectID, Cred) -> - DBNode = get_db_node_for(ObjectID), +remove (DB, User, ID) -> + DBNode = get_db_node_for(ID), - {atomic, _} = rpc:call(DBNode, db_access, remove, [DB, ObjectID, Cred]), + Reply = rpc:call(DBNode, atexia_server, remove, [DB, User, ID]), io:format ( - "~nshr_database:remove(~p) ! ~p -> ok.~n", - [{DB, ObjectID, Cred}, DBNode] + "~nataxia_client:remove(~p) ! ~p -> ~p.~n", + [{DB, User, ID}, DBNode, Reply] ), - ok. + Reply. -spec reserve ( atom(), - binary(), - ataxia_security:user() + ataxia_security:user(), + ataxia_id:type() ) - -> ('ok' | 'not_found'). -reserve (DB, ObjectID, Cred) -> - DBNode = get_db_node_for(ObjectID), + -> ('ok' | 'unavailable'). +reserve (DB, User, ID) -> + DBNode = get_db_node_for(ID), - {atomic, _} = rpc:call(DBNode, db_access, reserve, [DB, ObjectID, Cred]), + Reply = rpc:call(DBNode, atexia_server, reserve, [DB, User, ID]), io:format ( - "~nshr_database:reserve(~p) ! ~p -> ok.~n", - [{DB, ObjectID, Cred}, DBNode] + "~nataxia_client:reserve(~p) ! ~p -> ~p.~n", + [{DB, User, ID}, DBNode, Reply] ), - ok. + Reply. diff --git a/src/ataxia_server.erl b/src/ataxia_server.erl index 206a6d9..eabcd8b 100644 --- a/src/ataxia_server.erl +++ b/src/ataxia_server.erl @@ -18,6 +18,7 @@ query/1 ] ). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -49,33 +50,34 @@ add_new_item (DB, Item) -> -spec read ( atom(), + ataxia_security:user(), ataxic:type(), - binary(), - ataxia_security:user() + ataxia_id:type() ) -> ({'aborted', any()} | {'ok', any()} | 'not_found'). -read (ID, Selector, User, DB) -> +read (DB, User, Selector, ID) -> case mnesia:transaction(fun mnesia:read/2, [DB, ID]) of {'atomic', []} -> 'not_found'; - {'atomic', [Item]} -> + {'atomic', [Entry]} -> true = ataxia_security:can_access ( User, - ataxia_entry:get_read_permission(Item) + ataxia_entry:get_read_permission(Entry) ), - {ok, ataxic:apply_to(Selector, ataxia_entry:get_value(Item))}; + {ok, ataxic:apply_to(Selector, ataxia_entry:get_value(Entry))}; Other -> {'aborted', Other} end. -spec insert_at ( - atom(), - binary(), + ataxia_id:type(), ataxia_security:permission(), ataxia_security:permission(), - any()) + any(), + atom() + ) -> ({'aborted', any()} | 'ok'). insert_at (DB, ID, ReadPerm, WritePerm, Value) -> Item = ataxia_entry:new(ID, ReadPerm, WritePerm, Value), @@ -90,7 +92,7 @@ insert_at (DB, ID, ReadPerm, WritePerm, Value) -> ataxia_security:permission(), ataxia_security:permission(), any()) - -> ({'aborted', any()} | {'ok', binary()}). + -> ({'aborted', any()} | {'ok', ataxia_id:type()}). insert (DB, ReadPerm, WritePerm, Value) -> ID = db_item_ids_manager:allocate(DB), case insert_at(DB, ID, ReadPerm, WritePerm, Value) of @@ -105,17 +107,17 @@ query (Query) -> -spec reserve ( atom(), - binary(), - ataxia_security:user() + ataxia_security:user(), + ataxia_id:type() ) - -> ({'aborted', any()} | {'atomic', 'ok'}). -reserve (DB, ID, Cred) -> + -> ({'aborted', any()} | 'ok'). +reserve (DB, User, ID) -> insert_at ( DB, ID, - [Cred], - [Cred], + [User], + [User], { reserved, <<"?">> %% TODO [FUNCTION: db][LOW]: timestamp @@ -125,11 +127,11 @@ reserve (DB, ID, Cred) -> -spec remove ( atom(), - binary(), - ataxia_security:user() + ataxia_security:user(), + ataxia_id:type() ) -> ({'aborted', any()} | 'ok' | 'not_found'). -remove (_DB, _ID, _Cred) -> +remove (_DB, _User, _ID) -> %% TODO [FUNCTION: db][MEDIUM]: unimplemented %% Don't forget to checkt that Cred has write access before removing the %% value. diff --git a/src/ataxic.erl b/src/ataxic.erl index a1a2a1a..8f8465f 100644 --- a/src/ataxic.erl +++ b/src/ataxic.erl @@ -67,11 +67,50 @@ ] ). --export([apply_to/2]). +-export([apply_to/2, matches/2]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec basic_apply_to (basic(), any()) -> any(). +basic_apply_to (#field{ ix = IX, op = OP}, Val) -> + setelement(IX, Val, basic_apply_to(OP, element(IX, Val))); +basic_apply_to (#array_cell{ ix = IX, op = OP }, Val) -> + array:set(IX, basic_apply_to(OP, array:get(IX, Val)), Val); + +basic_apply_to (#seq{ ops = List }, Val) -> + lists:foldl(fun basic_apply_to/2, Val, List); + +basic_apply_to (#list_append { values = List, head = Head }, Val) -> + case Head of + true -> (List ++ Val); + _ -> (Val ++ List) + end; + +basic_apply_to (#const{ value = Val }, _Val) -> + Val; +basic_apply_to (#current{}, Val) -> + Val; + +basic_apply_to (#ge{ p0 = P0, p1 = P1 }, _Val) -> + P0 >= P1; +basic_apply_to (#gt{ p0 = P0, p1 = P1 }, _Val) -> + P0 > P1; +basic_apply_to (#le{ p0 = P0, p1 = P1 }, _Val) -> + P0 =< P1; +basic_apply_to (#lt{ p0 = P0, p1 = P1 }, _Val) -> + P0 < P1; +basic_apply_to (#eq{ p0 = P0, p1 = P1 }, _Val) -> + P0 == P1; + +basic_apply_to (#land{ params = List }, _Val) -> + lists:all(fun (E) -> E end, List); + +basic_apply_to (#lor{ params = List }, _Val) -> + lists:any(fun (E) -> E end, List); + +basic_apply_to (#neg{ param = V }, _Val) -> + not V. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -120,42 +159,41 @@ neg (V) -> #neg{ param = V }. %%%%% APPLY TO %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec apply_to (basic(), any()) -> any(). -apply_to (#field{ ix = IX, op = OP}, Val) -> - setelement(IX, Val, apply_to(OP, element(IX, Val))); -apply_to (#array_cell{ ix = IX, op = OP }, Val) -> - array:set(IX, apply_to(OP, array:get(IX, Val)), Val); - -apply_to (#seq{ ops = List }, Val) -> - lists:foldl(fun apply_to/2, Val, List); - -apply_to (#list_append { values = List, head = Head }, Val) -> - case Head of - true -> (List ++ Val); - _ -> (Val ++ List) +-spec apply_to (meta(), ataxia_entry:type()) -> ataxia_entry:type(). +apply_to (#read_perm{ op = OP }, Entry) -> + ataxia_entry:set_read_permission + ( + basic_apply_to(OP, ataxia_entry:get_read_permission(Entry)), + Entry + ); +apply_to (#write_perm{ op = OP }, Entry) -> + ataxia_entry:set_write_permission + ( + basic_apply_to(OP, ataxia_entry:get_write_permission(Entry)), + Entry + ); +apply_to (#value{ op = OP }, Entry) -> + ataxia_entry:set_value + ( + basic_apply_to(OP, ataxia_entry:get_value(Entry)), + Entry + ); +apply_to (#mseq { ops = List }, Entry) -> + lists:foldl(fun apply_to/2, Entry, List). + +-spec matches (meta(), ataxia_entry:type()) -> boolean(). +matches (#read_perm{ op = OP }, Entry) -> + case basic_apply_to(OP, ataxia_entry:get_read_permission(Entry)) of + true -> true; + _ -> false end; - -apply_to (#const{ value = Val }, _Val) -> - Val; -apply_to (#current{}, Val) -> - Val; - -apply_to (#ge{ p0 = P0, p1 = P1 }, _Val) -> - P0 >= P1; -apply_to (#gt{ p0 = P0, p1 = P1 }, _Val) -> - P0 > P1; -apply_to (#le{ p0 = P0, p1 = P1 }, _Val) -> - P0 =< P1; -apply_to (#lt{ p0 = P0, p1 = P1 }, _Val) -> - P0 < P1; -apply_to (#eq{ p0 = P0, p1 = P1 }, _Val) -> - P0 == P1; - -apply_to (#land{ params = List }, _Val) -> - lists:all(fun (E) -> E end, List); - -apply_to (#lor{ params = List }, _Val) -> - lists:any(fun (E) -> E end, List); - -apply_to (#neg{ param = V }, _Val) -> - not V. +matches (#write_perm{ op = OP }, Entry) -> + case basic_apply_to(OP, ataxia_entry:get_write_permission(Entry)) of + true -> true; + _ -> false + end; +matches (#value{ op = OP }, Entry) -> + case basic_apply_to(OP, ataxia_entry:get_value(Entry)) of + true -> true; + _ -> false + end. -- cgit v1.2.3-70-g09d2