summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2018-06-04 14:51:51 +0200
committernsensfel <SpamShield0@noot-noot.org>2018-06-04 14:51:51 +0200
commitbdb3ee493c5b5ad03b7ce189011422a1c6798dd1 (patch)
tree0ce3576ba29c7f936f10c186acfd0da669b0285b
parent09bdaed7100ac97392e152a488d21db016952213 (diff)
Starting to work on the DB implementation.
-rw-r--r--Makefile2
-rw-r--r--src/db/Makefile63
-rw-r--r--src/db/include/db_query.hrl34
-rw-r--r--src/db/mk/debug.mk40
-rw-r--r--src/db/mk/erlang.mk28
-rw-r--r--src/db/mk/preprocessor.mk34
-rw-r--r--src/db/module.conf6
-rw-r--r--src/db/src/storage_access.erl42
-rw-r--r--src/db/src/storage_update.erl36
9 files changed, 284 insertions, 1 deletions
diff --git a/Makefile b/Makefile
index f7f311c..1ac3973 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
################################################################################
## CONFIG ######################################################################
################################################################################
-MODULES ?= battlemap
+MODULES ?= battlemap db
MODULES_DIR ?= ${CURDIR}/src
YAWS_CONFIG_TEMPLATE ?= ${CURDIR}/conf/yaws.conf.m4
diff --git a/src/db/Makefile b/src/db/Makefile
new file mode 100644
index 0000000..d7b6eed
--- /dev/null
+++ b/src/db/Makefile
@@ -0,0 +1,63 @@
+################################################################################
+## CONFIG ######################################################################
+################################################################################
+MODULE_NAME ?= $ $(shell basename ${CURDIR})
+MODULE_PORT ?= 8002
+
+DIALYZER_PLT_FILE ?= tacticians-server.plt
+
+## Main Directories
+SRC_DIR ?= ${CURDIR}/src
+CONF_DIR ?= ${CURDIR}/conf
+
+#### Optional Dirs
+BIN_DIR ?= ${CURDIR}/ebin
+INCLUDE_DIR ?= ${CURDIR}/include
+
+## Binaries
+ERLC ?= erlc
+ERLC_OPTS ?=
+DIALYZER ?= dialyzer
+
+################################################################################
+## MAKEFILE MAGIC ##############################################################
+################################################################################
+OPTIONAL_DIRS = $(BIN_DIR) $(INCLUDE_DIR)
+
+################################################################################
+## SANITY CHECKS ###############################################################
+################################################################################
+DIALYZER_PLT_FILE ?= tacticians-server.plt
+
+## Main Directories
+SRC_DIR ?= src
+CONF_DIR ?= conf
+
+################################################################################
+## INCLUDES ####################################################################
+################################################################################
+main_target: all
+
+include ${CURDIR}/mk/debug.mk
+include ${CURDIR}/mk/erlang.mk
+include ${CURDIR}/mk/preprocessor.mk
+
+################################################################################
+## TARGET RULES ################################################################
+################################################################################
+all: build
+
+debug: debug_run
+
+build: $(REQUIRED_HEADERS) $(PREPROCESSOR_RESULT) $(ERLANG_RESULT)
+
+run:
+
+clean:
+ rm -rf $(PREPROCESSOR_RESULT) $(ERLANG_RESULT)
+
+################################################################################
+## INTERNAL RULES ##############################################################
+################################################################################
+$(OPTIONAL_DIRS): %:
+ mkdir -p $@
diff --git a/src/db/include/db_query.hrl b/src/db/include/db_query.hrl
new file mode 100644
index 0000000..bdd9dc1
--- /dev/null
+++ b/src/db/include/db_query.hrl
@@ -0,0 +1,34 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-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(),
+ update :: list(db_query())
+ }
+).
+
+-type db_query() :: (#set_field{} | #add_to_field{} | #update_indexed{}).
+
diff --git a/src/db/mk/debug.mk b/src/db/mk/debug.mk
new file mode 100644
index 0000000..bd93669
--- /dev/null
+++ b/src/db/mk/debug.mk
@@ -0,0 +1,40 @@
+################################################################################
+## CONFIG ######################################################################
+################################################################################
+DIALYZER_PLT_FILE ?= tacticians-server.plt
+DIALYZER ?= dialyzer
+
+################################################################################
+## MAKEFILE MAGIC ##############################################################
+################################################################################
+SRC_FILES ?= $(wildcard $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl)
+
+################################################################################
+## SANITY CHECKS ###############################################################
+################################################################################
+
+################################################################################
+## TARGET RULES ################################################################
+################################################################################
+DEBUG_RESULT = $(DIALYZER_PLT_FILE)
+
+debug_rebuild:
+ $(MAKE) clean
+ $(MAKE) ERLC_OPTS=+debug_info
+
+################################################################################
+## INTERNAL RULES ##############################################################
+################################################################################
+ifeq ($(wildcard $(DIALYZER_PLT_FILE)),)
+debug_run:
+ $(DIALYZER) --build_plt --apps erts kernel stdlib --output_plt \
+ $(DIALYZER_PLT_FILE)
+ $(MAKE) debug_rebuild
+ $(DIALYZER) --add_to_plt --plt $(DIALYZER_PLT_FILE) -r $(BIN_DIR)
+else
+debug_run:
+ $(MAKE) debug_rebuild
+ $(DIALYZER) --check_plt --plt $(DIALYZER_PLT_FILE)
+ $(DIALYZER) --get_warnings $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl \
+ --src --plt $(DIALYZER_PLT_FILE)
+endif
diff --git a/src/db/mk/erlang.mk b/src/db/mk/erlang.mk
new file mode 100644
index 0000000..9150f63
--- /dev/null
+++ b/src/db/mk/erlang.mk
@@ -0,0 +1,28 @@
+################################################################################
+## CONFIG ######################################################################
+################################################################################
+ERLC ?= erlc
+ERLC_OPTS ?=
+
+################################################################################
+## MAKEFILE MAGIC ##############################################################
+################################################################################
+SRC_FILES ?= $(wildcard $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl)
+BIN_FILES = \
+ $(patsubst %.erl,$(BIN_DIR)/%.beam,$(notdir $(SRC_FILES)))
+
+################################################################################
+## SANITY CHECKS ###############################################################
+################################################################################
+
+################################################################################
+## TARGET RULES ################################################################
+################################################################################
+ERLANG_RESULT = $(BIN_DIR) $(BIN_FILES)
+
+################################################################################
+## INTERNAL RULES ##############################################################
+################################################################################
+.SECONDEXPANSION:
+$(BIN_FILES): $(BIN_DIR)/%.beam : $$(wildcard $(SRC_DIR)/*/%.erl $(SRC_DIR)/%.erl)
+ $(ERLC) $(ERLC_OPTS) -o $(BIN_DIR) $<
diff --git a/src/db/mk/preprocessor.mk b/src/db/mk/preprocessor.mk
new file mode 100644
index 0000000..74f66ba
--- /dev/null
+++ b/src/db/mk/preprocessor.mk
@@ -0,0 +1,34 @@
+################################################################################
+## CONFIG ######################################################################
+################################################################################
+CONFIG_FILE ?= ${CURDIR}/module.conf
+
+################################################################################
+## MAKEFILE MAGIC ##############################################################
+################################################################################
+PREPROCESSOR_FILES = $(shell find ${CURDIR} -name "*.m4")
+PREPROCESSED_FILES = $(patsubst %.m4,%,$(PREPROCESSOR_FILES))
+
+MAKEFILE_TO_M4 = \
+ --define=__MAKEFILE_MODULE_NAME=$(MODULE_NAME) \
+ --define=__MAKEFILE_MODULE_PORT=$(MODULE_PORT) \
+ --define=__MAKEFILE_BIN_DIR=$(BIN_DIR) \
+ --define=__MAKEFILE_INCLUDE_DIR=$(INCLUDE_DIR)
+
+################################################################################
+## SANITY CHECKS ###############################################################
+################################################################################
+ifeq ($(wildcard $(CONFIG_FILE)),)
+$(error "Missing CONFIG_FILE ($(CONFIG_FILE)).")
+endif
+
+################################################################################
+## TARGET RULES ################################################################
+################################################################################
+PREPROCESSOR_RESULT = $(PREPROCESSED_FILES)
+
+################################################################################
+## INTERNAL RULES ##############################################################
+################################################################################
+$(PREPROCESSED_FILES): %: $(CONFIG_FILE) %.m4
+ m4 -P $^ > $@
diff --git a/src/db/module.conf b/src/db/module.conf
new file mode 100644
index 0000000..08714a1
--- /dev/null
+++ b/src/db/module.conf
@@ -0,0 +1,6 @@
+m4_define(`__MODULE_NAME', `__MAKEFILE_MODULE_NAME')m4_dnl
+m4_define(`__MODULE_PORT', `__MAKEFILE_MODULE_PORT')m4_dnl
+m4_dnl
+m4_define(`__MODULE_BIN_DIR', `__MAKEFILE_BIN_DIR')m4_dnl
+m4_define(`__MODULE_INCLUDE_DIR', `__MAKEFILE_INCLUDE_DIR')m4_dnl
+m4_dnl
diff --git a/src/db/src/storage_access.erl b/src/db/src/storage_access.erl
new file mode 100644
index 0000000..be481ee
--- /dev/null
+++ b/src/db/src/storage_access.erl
@@ -0,0 +1,42 @@
+-module(storage_access).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-record(regval, {id, owner, val}).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export
+(
+ [
+ read/2,
+ insert/4,
+ update/3
+ ]
+).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+get_value([]) -> [];
+get_value([#regval{ val = Val }]) -> [Val].
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+read (DB, ID) ->
+ get_value(mnesia:read(DB, ID)).
+
+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).
+
+update (DB, ID, Update) ->
+ % FIXME: handle return value, mnesia:write -> (transaction abort | ok).
+ case mnesia:read(DB, ID) of
+ [] -> error;
+ _ -> unimplemented
+ end.
diff --git a/src/db/src/storage_update.erl b/src/db/src/storage_update.erl
new file mode 100644
index 0000000..c3a53e4
--- /dev/null
+++ b/src/db/src/storage_update.erl
@@ -0,0 +1,36 @@
+-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).