Seperate all into new files, setup models

This commit is contained in:
Curt Spark 2025-06-15 19:04:30 +01:00
parent d42ac510d3
commit 0973d33cbd
8 changed files with 127 additions and 59 deletions

56
main.go
View File

@ -1,67 +1,29 @@
package main package main
import ( import (
"fmt"
"log"
"net/http" "net/http"
"os"
"os/signal"
"syscall"
"time" "time"
"timefu.li/backend/models"
"timefu.li/backend/routes"
"timefu.li/backend/tubson" "timefu.li/backend/tubson"
"timefu.li/backend/tubsql" "timefu.li/backend/tubsql"
) )
func main() { 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() db := tubsql.Connect_database()
tubsql.Test_commit(db) models.Init_tables(db)
db.Close()
http_server := &http.Server{ routes.Register_routes()
tubson.Start_server(&http.Server{
Addr: ":8080", Addr: ":8080",
Handler: nil, Handler: nil,
ReadTimeout: 10 * time.Second, ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20, MaxHeaderBytes: 1 << 20,
} }, func() {
go func() { db.Close()
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)
} }

32
models/models.go Normal file
View File

@ -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)",
})
}

3
routes/README.org Normal file
View File

@ -0,0 +1,3 @@
* Routes
All endpoint logic and route registration happens here.

8
routes/routes.go Normal file
View File

@ -0,0 +1,8 @@
package routes
import (
)
func Register_routes() {
register_user_routes("users/")
}

36
routes/users.go Normal file
View File

@ -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)
}

4
run.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh
rm test.db
go run .

View File

@ -1,13 +1,16 @@
package tubson package tubson
import ( import (
"context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
"log" "log"
"net/http" "net/http"
"reflect" "os"
"os/signal"
"strings" "strings"
"syscall"
) )
type Http_method uint8; const ( type Http_method uint8; const (
@ -44,8 +47,8 @@ type Http_status_code int; const (
type Empty_request_body struct {} type Empty_request_body struct {}
/* T Representing any request body struct /* T Representing any request body struct
S Representing any response 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)) { 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, func(response http.ResponseWriter, request *http.Request) { http.HandleFunc(method.to_string() + " /" + route + endpoint, func(response http.ResponseWriter, request *http.Request) {
request_body_bytes, err := io.ReadAll(request.Body) request_body_bytes, err := io.ReadAll(request.Body)
if err != nil { if err != nil {
response.WriteHeader(int(INTERNAL_SERVER_ERROR)) 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) log.Panicln(err)
return return
} }
fmt.Println(reflect.VisibleFields(reflect.TypeOf(body)))
response.WriteHeader(int(status_code)) response.WriteHeader(int(status_code))
response.Write(encode_result) 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)
}

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"database/sql" "database/sql"
"log" "log"
"strings"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
) )
@ -17,24 +18,27 @@ func Connect_database() *sql.DB {
return 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() tx, err := db.Begin()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
ctx := context.Background() ctx := context.Background()
_, err = tx.Exec("CREATE TABLE IF NOT EXISTS users ( name varchar(255), age int )")
_, err = tx.ExecContext( _, err = tx.ExecContext(
ctx, ctx,
"INSERT INTO users (name, age) VALUES ($1, $2)", `CREATE TABLE IF NOT EXISTS ` + table_name + ` (
"testing", ` + strings.Join(table_data, ", ") + `
42, )`,
) )
if err != nil { if err != nil {
tx.Rollback() tx.Rollback()
log.Fatal(err) log.Fatal(err)
} }
tx.Commit()
err = tx.Commit()
if err != nil {
tx.Rollback()
log.Fatal(err)
}
} }