From ca5fccb809ee07a656639b334c7e5ff1112b069d Mon Sep 17 00:00:00 2001 From: dylan Date: Fri, 27 Dec 2024 11:09:53 +0100 Subject: [PATCH] Small fixes in init.sql and create drop.sql --- cmd/web/main.go | 7 ++++++ main.go | 21 ---------------- sql/drop.sql | 7 ++++++ sql/init.sql | 66 +++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 67 insertions(+), 34 deletions(-) create mode 100644 cmd/web/main.go delete mode 100644 main.go create mode 100644 sql/drop.sql diff --git a/cmd/web/main.go b/cmd/web/main.go new file mode 100644 index 0000000..f7b60bd --- /dev/null +++ b/cmd/web/main.go @@ -0,0 +1,7 @@ +package main + +import "fmt" + +func main() { + fmt.Println("Hello, world!") +} diff --git a/main.go b/main.go deleted file mode 100644 index 19e1dbd..0000000 --- a/main.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "fmt" -) - -//TIP

To run your code, right-click the code and select Run.

Alternatively, click -// the icon in the gutter and select the Run menu item from here.

- -func main() { - //TIP

Press when your caret is at the underlined text - // to see how GoLand suggests fixing the warning.

Alternatively, if available, click the lightbulb to view possible fixes.

- s := "gopher" - fmt.Println("Hello and welcome, %s!", s) - - for i := 1; i <= 5; i++ { - //TIP

To start your debugging session, right-click your code in the editor and select the Debug option.

We have set one breakpoint - // for you, but you can always add more by pressing .

- fmt.Println("i =", 100/i) - } -} diff --git a/sql/drop.sql b/sql/drop.sql new file mode 100644 index 0000000..9f9ede7 --- /dev/null +++ b/sql/drop.sql @@ -0,0 +1,7 @@ +DROP TABLE IF EXISTS votes; +DROP TABLE IF EXISTS voters; +DROP TABLE IF EXISTS choices; +DROP TABLE IF EXISTS elections; +DROP TRIGGER IF EXISTS prevent_created_at_update_election; +DROP TRIGGER IF EXISTS prevent_created_at_update_votes; +DROP TRIGGER IF EXISTS enforce_max_voters; \ No newline at end of file diff --git a/sql/init.sql b/sql/init.sql index 1bcc306..4311f08 100644 --- a/sql/init.sql +++ b/sql/init.sql @@ -1,34 +1,74 @@ -CREATE TABLE election ( +CREATE TABLE elections ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, tokens INTEGER NOT NULL, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP + is_anonymous INTEGER NOT NULL, + max_voters INTEGER, -- mandatory when election is anonymous + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + expires_at DATETIME NOT NULL, + CHECK (is_anonymous = 0 OR (is_anonymous = 1 AND max_voters IS NOT NULL AND max_voters >= 1)) ); +CREATE TRIGGER prevent_created_at_update_election + BEFORE UPDATE OF created_at ON elections +BEGIN + SELECT RAISE(FAIL, 'created_at column is read-only'); +END; + CREATE TABLE choices ( text TEXT NOT NULL, election_id INTEGER NOT NULL, PRIMARY KEY (text, election_id), - FOREIGN KEY (election_id) REFERENCES election (id) + FOREIGN KEY (election_id) REFERENCES elections (id) ); CREATE TABLE voters ( - passcode TEXT NOT NULL, + identity TEXT NOT NULL, -- when election is anonymous, passcodes will be pre-generated election_id INTEGER NOT NULL, - PRIMARY KEY (passcode, election_id), - FOREIGN KEY (election_id) REFERENCES election (id) + PRIMARY KEY (identity, election_id), + FOREIGN KEY (election_id) REFERENCES elections (id) ); +CREATE TRIGGER enforce_max_voters + BEFORE INSERT ON voters + WHEN EXISTS ( + SELECT 1 + FROM elections e + WHERE e.id = NEW.election_id + AND e.max_voters IS NOT NULL + ) +BEGIN + SELECT CASE + WHEN ( + SELECT COUNT(*) + FROM voters v + WHERE v.election_id = NEW.election_id + ) >= ( + SELECT max_voters + FROM elections + WHERE id = NEW.election_id + ) + THEN RAISE(FAIL, 'Maximum number of voters reached for this election') + END; +END; + CREATE TABLE votes ( - voter_passcode TEXT NOT NULL, + voter_identity TEXT NOT NULL, election_id INTEGER NOT NULL, - choice_text TEXT NOT NULL, - tokens INTEGER NOT NULL, - calculated_vote_count GENERATED ALWAYS AS (sqrt(tokens)) VIRTUAL, + choice_text TEXT, + tokens INTEGER, + calculated_vote_count GENERATED ALWAYS AS (floor(sqrt(tokens))) VIRTUAL, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - PRIMARY KEY (voter_passcode, choice_text), - FOREIGN KEY (voter_passcode, election_id) REFERENCES voters (passcode, election_id), - FOREIGN KEY (choice_text, election_id) REFERENCES choices (text, election_id) + PRIMARY KEY (voter_identity, choice_text), + FOREIGN KEY (voter_identity, election_id) REFERENCES voters (identity, election_id), + FOREIGN KEY (choice_text, election_id) REFERENCES choices (text, election_id), + CHECK (tokens IS NULL OR tokens >= 0) ); +CREATE TRIGGER prevent_created_at_update_votes + BEFORE UPDATE OF created_at ON votes +BEGIN + SELECT RAISE(FAIL, 'created_at column is read-only'); +END; + PRAGMA foreign_keys = ON; -- run after opening the connection so foreign key constraints are checked \ No newline at end of file