summaryrefslogtreecommitdiff
path: root/src/db
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2018-06-04 16:53:17 +0200
committernsensfel <SpamShield0@noot-noot.org>2018-06-04 16:53:17 +0200
commit4aa208ada20eaa3795740424d3519083fef1df65 (patch)
tree6a15cec7e1d565b24cddc18bcb46b2d4f7d26b21 /src/db
parentbdb3ee493c5b5ad03b7ce189011422a1c6798dd1 (diff)
Still working on it...
Diffstat (limited to 'src/db')
-rw-r--r--src/db/include/db_query.hrl27
-rw-r--r--src/db/src/storage_access.erl20
-rw-r--r--src/db/src/storage_query.erl90
-rw-r--r--src/db/src/storage_update.erl36
4 files changed, 127 insertions, 46 deletions
diff --git a/src/db/include/db_query.hrl b/src/db/include/db_query.hrl
index bdd9dc1..45c040b 100644
--- a/src/db/include/db_query.hrl
+++ b/src/db/include/db_query.hrl
@@ -1,6 +1,8 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-type db_user() :: ({'user', any()} | 'admin' | 'any').
+
-record
(
set_field,
@@ -26,9 +28,30 @@
{
field :: non_neg_integer(),
ix :: non_neg_integer(),
- update :: list(db_query())
+ ops :: list(db_query_op())
+ }
+).
+
+-record
+(
+ set_user,
+ {
+ user :: db_user()
+ }
+).
+
+-record
+(
+ db_query,
+ {
+ db :: atom(),
+ id :: any(),
+ user :: db_user(),
+ ops :: list(db_query_master_op())
}
).
--type db_query() :: (#set_field{} | #add_to_field{} | #update_indexed{}).
+-type db_query_op() :: (#set_field{} | #add_to_field{} | #update_indexed{}).
+-type db_query_master_op() :: (db_query_op() | #set_user{}).
+-type db_query() :: #db_query{}.
diff --git a/src/db/src/storage_access.erl b/src/db/src/storage_access.erl
index be481ee..c58f26d 100644
--- a/src/db/src/storage_access.erl
+++ b/src/db/src/storage_access.erl
@@ -19,8 +19,10 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-get_value([]) -> [];
-get_value([#regval{ val = Val }]) -> [Val].
+get_value ([]) -> not_found;
+get_value ([Regval]) -> {ok, Regval}.
+
+get_value(DB, ID) -> get_value(mnesia:read(DB, ID)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -32,11 +34,13 @@ insert (DB, ID, Owner, Value) ->
StoredItem = #regval{ id = ID, owner = Owner, val = Value },
% FIXME: handle return value, mnesia:write -> (transaction abort | ok).
% FIXME: is this an atomic OP? Is the lock freed afterwards?
- mnesia:write(DB, StoredItem, sticky_write).
+ mnesia:write(DB, StoredItem, sticky_write),
+ ok.
-update (DB, ID, Update) ->
+update (DB, ID, Query) ->
+ {ok, Item} = get_value(DB, ID),
+ {ok, UpdatedItem} = db_query:apply_to(Query, Item),
% FIXME: handle return value, mnesia:write -> (transaction abort | ok).
- case mnesia:read(DB, ID) of
- [] -> error;
- _ -> unimplemented
- end.
+ % FIXME: is this an atomic OP? Is the lock freed afterwards?
+ mnesia:write(DB, UpdatedItem, sticky_write),
+ ok.
diff --git a/src/db/src/storage_query.erl b/src/db/src/storage_query.erl
new file mode 100644
index 0000000..5b37f2d
--- /dev/null
+++ b/src/db/src/storage_query.erl
@@ -0,0 +1,90 @@
+-module(storage_query).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-include("../include/db_query.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export([apply_to/2]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec get_user (db_query()) -> db_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),
+
+ 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(Elem, set_field) ->
+ apply_set_field(Op, Elem);
+apply_op_to (Op, Elem) when is_record(Elem, add_to_field) ->
+ apply_add_to_field(Op, Elem);
+apply_op_to (Op, Elem) when is_record(Elem, update_indexed) ->
+ apply_update_indexed(Op, Elem).
+
+-spec apply_master_op_to
+ (
+ db_query_master_op(),
+ db_item:type()
+ )
+ -> db_item:type().
+apply_master_op_to (MOp, Elem) when is_record(MOp, set_user) ->
+ NewUser = MOp#set_user.user,
+
+ db_item:set_user(NewUser, Elem);
+apply_master_op_to (MOp, Elem) ->
+ OldValue = db_item:get_value(Elem),
+ NewValue = apply_op_to(MOp, OldValue),
+
+ db_item:set_value(NewValue, Elem).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec apply_to
+ (
+ db_query(),
+ db_item:type()
+ )
+ -> ({'ok', db_item:type()} | 'error').
+apply_to (DBQuery, DBItem) ->
+ true = db_user:has_permission(db_item:get_user(DBItem), get_user(DBQuery)),
+ {ok, apply_master_op_to(DBQuery, DBItem)}.
+
diff --git a/src/db/src/storage_update.erl b/src/db/src/storage_update.erl
deleted file mode 100644
index c3a53e4..0000000
--- a/src/db/src/storage_update.erl
+++ /dev/null
@@ -1,36 +0,0 @@
--module(storage_update).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--include("../include/db_query.hrl").
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
--export([apply_to/2]).
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-apply_to (#set_field{ field = Field, value = Value }, Elem) ->
- setelement(Field, Elem, Value);
-apply_to (#add_to_field{ field = Field, values = Values, head = Head }, Elem) ->
- CurrentValues = element(Field, Elem),
- UpdatedValues =
- case Head of
- true -> (Values ++ CurrentValues);
- _ -> (CurrentValues ++ Values)
- end,
- setelement(Field, Elem, UpdatedValues);
-apply_to (#update_indexed{ field = Field, ix = IX, update = Update}, Elem) ->
- IndexedFieldValue = element(Field, Elem),
- ArrayValue = array:get(IX, IndexedFieldValue),
- UpdatedArrayValue = lists:foldl(fun apply_to/2, ArrayValue, Update),
- UpdatedIndexedFieldValue = array:set(IX, UpdatedArrayValue),
- setelement(Field, Elem, UpdatedIndexedFieldValue).