summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndinus <andinus@nand.sh>2020-03-26 22:22:57 +0530
committerAndinus <andinus@nand.sh>2020-03-26 22:22:57 +0530
commit288d04779e881cb4738ea469e4c93b841a5b42e2 (patch)
treee69a2111dcabea4f1699a58d8194930129e630da
parentb89fcdbe3d9f5083090bd07753cb04de2c5ef6c2 (diff)
downloadperseus-288d04779e881cb4738ea469e4c93b841a5b42e2.tar.gz
Update database schema, add registration table
-rw-r--r--storage/sqlite3/init.go70
1 files changed, 50 insertions, 20 deletions
diff --git a/storage/sqlite3/init.go b/storage/sqlite3/init.go
index 337d15b..cb573a2 100644
--- a/storage/sqlite3/init.go
+++ b/storage/sqlite3/init.go
@@ -31,7 +31,10 @@ func Init(db *DB) {
 
 	// We set the database path, first the environment variable
 	// PERSEUS_DBPATH is checked. If it doesn't exist then use set
-	// it to the default (perseus.db).
+	// it to the default (perseus.db). Note that this is LookupEnv
+	// so if the user has set PERSEUS_DBPATH="" then it'll return
+	// true for exists as it should because techincally user has
+	// set the env var, the sql.Open statement will fail though.
 	envDBPath, exists := os.LookupEnv("PERSEUS_DBPATH")
 	if !exists {
 		envDBPath = "perseus.db"
@@ -45,29 +48,56 @@ func Init(db *DB) {
 		initErr(db, err)
 	}
 
-	// Create account table, this will hold information on account
-	// like id, type & other user specific information. We are
-	// using id because later we may want to add username change
-	// or account delete functionality. If we add user delete
-	// function then we'll just have to change the username here.
-	stmt, err := db.Conn.Prepare(`
-CREATE TABLE IF NOT EXISTS account (
+	sqlstmt := []string{
+		// Create users table, this will hold information on
+		// account like id, type & other user specific
+		// information. We are using id because later we may
+		// want to add username change or account delete
+		// functionality. username here is not unique because
+		// if user deletes account then we'll change it to
+		// "ghost" or something. This doesn't mean usernames
+		// shouldn't be unique, registration table requires
+		// them to be unique so it'll fail if they aren't
+		// unique.
+		`CREATE TABLE IF NOT EXISTS users (
        id       TEXT PRIMARY KEY,
-       type     TEXT NOT NULL DEFAULT user,
+       type     TEXT NOT NULL DEFAULT notadmin,
        username TEXT NOT NULL,
-       password TEXT NOT NULL);`)
+       password TEXT NOT NULL);`,
 
-	if err != nil {
-		log.Printf("sqlite3/init.go: %s\n",
-			"Failed to prepare statement")
-		initErr(db, err)
+		// Create registration table, this will hold user
+		// account details like registration time, ip &
+		// similar details. This is the only place that will
+		// relate the username to id even after deletion.
+		// usernames must be unique in this table.
+		`CREATE TABLE IF NOT EXISTS registration (
+       id       TEXT PRIMARY KEY,
+       username TEXT NOT NULL UNIQUE,
+       reg_time TEXT NOT NULL,
+       reg_ip   TEXT NOT NULL);`,
 	}
 
-	_, err = stmt.Exec()
-	stmt.Close()
-	if err != nil {
-		log.Printf("sqlite3/init.go: %s\n",
-			"Failed to execute statement")
-		initErr(db, err)
+	// We range over statements and execute them one by one, this
+	// is during initialization so it doesn't matter if it takes
+	// few more ms. This way we know which statement caused the
+	// program to fail.
+	for _, s := range sqlstmt {
+		stmt, err := db.Conn.Prepare(s)
+
+		if err != nil {
+			log.Printf("sqlite3/init.go: %s\n",
+				"Failed to prepare statement")
+			log.Println(s)
+			initErr(db, err)
+		}
+
+		_, err = stmt.Exec()
+		stmt.Close()
+		if err != nil {
+			log.Printf("sqlite3/init.go: %s\n",
+				"Failed to execute statement")
+			log.Println(s)
+			initErr(db, err)
+		}
 	}
 }