From 0973d33cbd0140cf23722620c3dcd0b76e5c4968 Mon Sep 17 00:00:00 2001 From: cspark Date: Sun, 15 Jun 2025 19:04:30 +0100 Subject: [PATCH] Seperate all into new files, setup models --- main.go | 56 ++++++++--------------------------------------- models/models.go | 32 +++++++++++++++++++++++++++ routes/README.org | 3 +++ routes/routes.go | 8 +++++++ routes/users.go | 36 ++++++++++++++++++++++++++++++ run.sh | 4 ++++ tubson/tubson.go | 27 +++++++++++++++++++---- tubsql/tubsql.go | 20 ++++++++++------- 8 files changed, 127 insertions(+), 59 deletions(-) create mode 100644 models/models.go create mode 100644 routes/README.org create mode 100644 routes/routes.go create mode 100644 routes/users.go create mode 100755 run.sh diff --git a/main.go b/main.go index 88040d8..9ab1ab7 100644 --- a/main.go +++ b/main.go @@ -1,67 +1,29 @@ package main import ( - "fmt" - "log" "net/http" - "os" - "os/signal" - "syscall" "time" + "timefu.li/backend/models" + "timefu.li/backend/routes" "timefu.li/backend/tubson" "timefu.li/backend/tubsql" ) func main() { - type foo_request_body struct { - Arg1 int - Arg2 int - } - type foo_response_body struct { - Field1 string - Field2 int - } - foo_route_handler := func(body foo_request_body, raw_request *http.Request) (foo_response_body, tubson.Http_status_code) { - return foo_response_body { - Field1: "hi there on foo!", - Field2: body.Arg1 + body.Arg2, - }, tubson.OK - } - tubson.New_route(tubson.GET, "foo", foo_route_handler) - - type bar_response_body struct { - Response int - Message string - } - bar_route_handler := func(body tubson.Empty_request_body, raw_request *http.Request) (bar_response_body, tubson.Http_status_code) { - return bar_response_body { - Response: 400, - Message: "hi there on bar!", - }, tubson.INTERNAL_SERVER_ERROR - } - tubson.New_route(tubson.GET, "bar", bar_route_handler) - db := tubsql.Connect_database() - tubsql.Test_commit(db) - db.Close() + models.Init_tables(db) - http_server := &http.Server{ + routes.Register_routes() + + tubson.Start_server(&http.Server{ Addr: ":8080", Handler: nil, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, - } - go func() { - log.Fatal(http_server.ListenAndServe()) - }() - fmt.Println("Server started! Listening in on ", http_server.Addr) - - sigs := make(chan os.Signal, 1) - signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) - <-sigs - fmt.Println("Server stopped!") - os.Exit(1) + }, func() { + db.Close() + }) } diff --git a/models/models.go b/models/models.go new file mode 100644 index 0000000..eb0a855 --- /dev/null +++ b/models/models.go @@ -0,0 +1,32 @@ +package models + +import ( + "database/sql" + + "timefu.li/backend/tubsql" +) + +func Init_tables(db *sql.DB) { + tubsql.Init_table(db, "users", []string{ + "id int not null PRIMARY KEY", + "name varchar(255)", + }) + tubsql.Init_table(db, "tasks", []string{ + "id int not null PRIMARY KEY", + "name varchar(255)", + + "user_id int", + "FOREIGN KEY(user_id) REFERENCES users(id)", + }) + tubsql.Init_table(db, "completed_tasks", []string{ + "id int not null PRIMARY KEY", + "completed_date int", + "started_date int", + + "task_id int", + "FOREIGN KEY(task_id) REFERENCES tasks(id)", + + "user_id int", + "FOREIGN KEY(user_id) REFERENCES users(id)", + }) +} diff --git a/routes/README.org b/routes/README.org new file mode 100644 index 0000000..674017a --- /dev/null +++ b/routes/README.org @@ -0,0 +1,3 @@ +* Routes + +All endpoint logic and route registration happens here. diff --git a/routes/routes.go b/routes/routes.go new file mode 100644 index 0000000..4e9a8d7 --- /dev/null +++ b/routes/routes.go @@ -0,0 +1,8 @@ +package routes + +import ( +) + +func Register_routes() { + register_user_routes("users/") +} diff --git a/routes/users.go b/routes/users.go new file mode 100644 index 0000000..a829783 --- /dev/null +++ b/routes/users.go @@ -0,0 +1,36 @@ +package routes + +import ( + "net/http" + "timefu.li/backend/tubson" +) + +func register_user_routes(endpoint string) { + type foo_request_body struct { + Arg1 int + Arg2 int + } + type foo_response_body struct { + Field1 string + Field2 int + } + foo_endpoint_handler := func(body foo_request_body, raw_request *http.Request) (foo_response_body, tubson.Http_status_code) { + return foo_response_body { + Field1: "hi there on foo!", + Field2: body.Arg1 + body.Arg2, + }, tubson.OK + } + tubson.New_endpoint(tubson.GET, endpoint, "foo", foo_endpoint_handler) + + type bar_response_body struct { + Response int + Message string + } + bar_endpoint_handler := func(body tubson.Empty_request_body, raw_request *http.Request) (bar_response_body, tubson.Http_status_code) { + return bar_response_body { + Response: 400, + Message: "hi there on bar!", + }, tubson.INTERNAL_SERVER_ERROR + } + tubson.New_endpoint(tubson.GET, endpoint, "bar", bar_endpoint_handler) +} diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..64c7d11 --- /dev/null +++ b/run.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +rm test.db +go run . diff --git a/tubson/tubson.go b/tubson/tubson.go index 1f02321..ca48dc0 100644 --- a/tubson/tubson.go +++ b/tubson/tubson.go @@ -1,13 +1,16 @@ package tubson import ( + "context" "encoding/json" "fmt" "io" "log" "net/http" - "reflect" + "os" + "os/signal" "strings" + "syscall" ) type Http_method uint8; const ( @@ -44,8 +47,8 @@ type Http_status_code int; const ( type Empty_request_body struct {} /* T Representing any request body struct S Representing any response body struct */ -func New_route[T any, S any](method Http_method, route string, handle_func func(body T, raw_request *http.Request) (S, Http_status_code)) { - http.HandleFunc(method.to_string() + " /" + route, func(response http.ResponseWriter, request *http.Request) { +func New_endpoint[T any, S any](method Http_method, route string, endpoint string, handle_func func(body T, raw_request *http.Request) (S, Http_status_code)) { + http.HandleFunc(method.to_string() + " /" + route + endpoint, func(response http.ResponseWriter, request *http.Request) { request_body_bytes, err := io.ReadAll(request.Body) if err != nil { response.WriteHeader(int(INTERNAL_SERVER_ERROR)) @@ -72,9 +75,25 @@ func New_route[T any, S any](method Http_method, route string, handle_func func( log.Panicln(err) return } - fmt.Println(reflect.VisibleFields(reflect.TypeOf(body))) response.WriteHeader(int(status_code)) response.Write(encode_result) }) } + +func Start_server(http_server *http.Server, cleanup func()) { + go func() { + log.Fatal(http_server.ListenAndServe()) + }() + fmt.Println("Timefu.li server started! Listening in on ", http_server.Addr) + + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, os.Interrupt, syscall.SIGTERM) + <-sigs + + fmt.Println("Exit called, attempting to stop server!") + ctx := context.Background() + http_server.Shutdown(ctx) + cleanup() + os.Exit(1) +} diff --git a/tubsql/tubsql.go b/tubsql/tubsql.go index 2ff802d..6098018 100644 --- a/tubsql/tubsql.go +++ b/tubsql/tubsql.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "log" + "strings" _ "github.com/mattn/go-sqlite3" ) @@ -17,24 +18,27 @@ func Connect_database() *sql.DB { return db } -func Test_commit(db *sql.DB) { +func Init_table(db *sql.DB, table_name string, table_data []string) { tx, err := db.Begin() if err != nil { log.Fatal(err) } ctx := context.Background() - _, err = tx.Exec("CREATE TABLE IF NOT EXISTS users ( name varchar(255), age int )") _, err = tx.ExecContext( - ctx, - "INSERT INTO users (name, age) VALUES ($1, $2)", - "testing", - 42, + ctx, + `CREATE TABLE IF NOT EXISTS ` + table_name + ` ( + ` + strings.Join(table_data, ", ") + ` + )`, ) - if err != nil { tx.Rollback() log.Fatal(err) } - tx.Commit() + + err = tx.Commit() + if err != nil { + tx.Rollback() + log.Fatal(err) + } }