summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2018-06-06 16:42:42 +0200
committernsensfel <SpamShield0@noot-noot.org>2018-06-06 16:42:42 +0200
commit82081d45fd64294f4bc417085e06284f3487b32f (patch)
tree1da77dd39829f8bfdcbf200df6a12a0a53edf661 /src/shared/struct/sh_db_query.erl
parentee9c2ac044cc77b80f30420c8f0788cad4281084 (diff)
...
Diffstat (limited to 'src/shared/struct/sh_db_query.erl')
-rw-r--r--src/shared/struct/sh_db_query.erl157
1 files changed, 156 insertions, 1 deletions
diff --git a/src/shared/struct/sh_db_query.erl b/src/shared/struct/sh_db_query.erl
index 998568e..4eb50ba 100644
--- a/src/shared/struct/sh_db_query.erl
+++ b/src/shared/struct/sh_db_query.erl
@@ -3,7 +3,65 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--include("../include/db_query.hrl").
+-record
+(
+ set_field,
+ {
+ field :: non_neg_integer(),
+ value :: any()
+ }
+).
+
+-record
+(
+ add_to_field,
+ {
+ field :: non_neg_integer(),
+ values :: list(any()),
+ head :: boolean()
+ }
+).
+
+-record
+(
+ update_indexed,
+ {
+ field :: non_neg_integer(),
+ ix :: non_neg_integer(),
+ ops :: list(db_query_op())
+ }
+).
+
+-record
+(
+ set_perm,
+ {
+ perm :: sh_db_user:permission()
+ }
+).
+
+-record
+(
+ set_val,
+ {
+ val :: any()
+ }
+).
+
+-record
+(
+ db_query,
+ {
+ db :: atom(),
+ id :: any(),
+ user :: db_user:user(),
+ ops :: list(db_query_master_op())
+ }
+).
+
+-type db_query_op() :: (#set_field{} | #add_to_field{} | #update_indexed{}).
+-type db_query_master_op() :: (db_query_op() | #set_perm{} | #set_val{}).
+-type db_query() :: #db_query{}.
-opaque op() :: db_query_op().
-opaque type() :: db_query().
@@ -22,10 +80,84 @@
update_indexed/3
]
).
+-export
+(
+ [
+ get_database/1,
+ get_entry_id/1
+ ]
+).
+-export([apply_to/2]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec get_user (db_query()) -> sh_db_user:user().
+get_user (#db_query{ user = Result }) -> Result.
+
+-spec apply_update_indexed (#update_indexed{}, any()) -> any().
+apply_update_indexed (Op, Elem) ->
+ FieldNumber = Op#update_indexed.field,
+ IX = Op#update_indexed.ix,
+ Ops = Op#update_indexed.ops,
+
+ IndexedFieldValue = element(FieldNumber, Elem),
+ ArrayValue = array:get(IX, IndexedFieldValue),
+ UpdatedArrayValue = lists:foldl(fun apply_op_to/2, ArrayValue, Ops),
+ UpdatedIndexedFieldValue =
+ array:set(IX, UpdatedArrayValue, IndexedFieldValue),
+
+ setelement(FieldNumber, Elem, UpdatedIndexedFieldValue).
+
+-spec apply_add_to_field (#add_to_field{}, any()) -> any().
+apply_add_to_field (Op, Elem) ->
+ FieldNumber = Op#add_to_field.field,
+ NewValues = Op#add_to_field.values,
+ AddToHead = Op#add_to_field.head,
+
+ CurrentValues = element(FieldNumber, Elem),
+ UpdatedValues =
+ case AddToHead of
+ true -> (NewValues ++ CurrentValues);
+ _ -> (CurrentValues ++ NewValues)
+ end,
+
+ setelement(FieldNumber, Elem, UpdatedValues).
+
+-spec apply_set_field (#set_field{}, any()) -> any().
+apply_set_field (Op, Elem) ->
+ FieldNumber = Op#set_field.field,
+ NewValue = Op#set_field.value,
+
+ setelement(FieldNumber, Elem, NewValue).
+
+-spec apply_op_to (db_query_op(), any()) -> any().
+apply_op_to (Op, Elem) when is_record(Op, set_field) ->
+ apply_set_field(Op, Elem);
+apply_op_to (Op, Elem) when is_record(Op, add_to_field) ->
+ apply_add_to_field(Op, Elem);
+apply_op_to (Op, Elem) when is_record(Op, update_indexed) ->
+ apply_update_indexed(Op, Elem).
+
+-spec apply_master_op_to
+ (
+ db_query_master_op(),
+ sh_db_item:type()
+ )
+ -> sh_db_item:type().
+apply_master_op_to (MOp, Elem) when is_record(MOp, set_perm) ->
+ NewPerm = MOp#set_perm.perm,
+
+ sh_db_item:set_perm(NewPerm, Elem);
+apply_master_op_to (MOp, Elem) when is_record(MOp, set_val) ->
+ NewVal = MOp#set_val.val,
+
+ sh_db_item:set_value(NewVal, Elem);
+apply_master_op_to (MOp, Elem) ->
+ OldValue = sh_db_item:get_value(Elem),
+ NewValue = apply_op_to(MOp, OldValue),
+
+ sh_db_item:set_value(NewValue, Elem).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -57,3 +189,26 @@ add_to_field (Field, Values) ->
-> op().
update_indexed (Field, IX, Updates) ->
#update_indexed { field = Field, ix = IX, ops = Updates}.
+
+-spec get_database (db_query()) -> atom().
+get_database (#db_query{ db = Result }) -> Result.
+
+-spec get_entry_id (db_query()) -> any().
+get_entry_id (#db_query{ id = Result }) -> Result.
+
+-spec apply_to
+ (
+ db_query(),
+ sh_db_item:type()
+ )
+ -> ({'ok', sh_db_item:type()} | 'error').
+apply_to (DBQuery, DBItem) ->
+ true =
+ sh_db_user:can_access
+ (
+ sh_db_item:get_permission(DBItem),
+ get_user(DBQuery)
+ ),
+ MOps = DBQuery#db_query.ops,
+ {ok, lists:foldl(fun apply_master_op_to/2, DBItem, MOps)}.
+