base
This commit is contained in:
parent
412ce338f3
commit
ec629baa9a
9 changed files with 168 additions and 26 deletions
5
.env.example
Normal file
5
.env.example
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
PRODUCTION="0"
|
||||||
|
PORT=8080
|
||||||
|
APP_DATA_DIR=./data
|
||||||
|
DB_CONNDVR="sqlite3"
|
||||||
|
DB_CONNSTR="./db.db"
|
19
.gitignore
vendored
19
.gitignore
vendored
|
@ -1,27 +1,14 @@
|
||||||
# ---> Go
|
|
||||||
# If you prefer the allow list template instead of the deny list, see community template:
|
|
||||||
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
|
||||||
#
|
|
||||||
# Binaries for programs and plugins
|
|
||||||
*.exe
|
*.exe
|
||||||
*.exe~
|
*.exe~
|
||||||
*.dll
|
*.dll
|
||||||
*.so
|
*.so
|
||||||
*.dylib
|
*.dylib
|
||||||
|
|
||||||
# Test binary, built with `go test -c`
|
|
||||||
*.test
|
*.test
|
||||||
|
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
|
||||||
*.out
|
*.out
|
||||||
|
vendor/
|
||||||
# Dependency directories (remove the comment below to include it)
|
|
||||||
# vendor/
|
|
||||||
|
|
||||||
# Go workspace file
|
|
||||||
go.work
|
go.work
|
||||||
go.work.sum
|
go.work.sum
|
||||||
|
|
||||||
# env file
|
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
axiom
|
||||||
|
db.db
|
||||||
|
|
20
database/database.go
Normal file
20
database/database.go
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Init(connDvr, connStr string) (*sql.DB, error) {
|
||||||
|
db, err := sql.Open(connDvr, connStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := db.Ping(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return db, nil
|
||||||
|
}
|
4
go.mod
4
go.mod
|
@ -1,3 +1,5 @@
|
||||||
module git.tavo.one/tavo/axiom
|
module git.tavo.one/tavo/axiom
|
||||||
|
|
||||||
go 1.24.4
|
go 1.22.1
|
||||||
|
|
||||||
|
require github.com/mattn/go-sqlite3 v1.14.28 // indirect
|
||||||
|
|
2
go.sum
Normal file
2
go.sum
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
47
handlers/handler.go
Normal file
47
handlers/handler.go
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"git.tavo.one/tavo/axiom/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Handler struct {
|
||||||
|
cfg Config
|
||||||
|
mux *http.ServeMux
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
Production bool
|
||||||
|
Views map[string]*template.Template
|
||||||
|
DB *sql.DB
|
||||||
|
S3 *storage.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(cfg Config) *Handler {
|
||||||
|
return &Handler{
|
||||||
|
cfg: cfg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) Router() *http.ServeMux {
|
||||||
|
return h.mux
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) Production() bool {
|
||||||
|
return h.cfg.Production
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) Views() map[string]*template.Template {
|
||||||
|
return h.cfg.Views
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) DB() *sql.DB {
|
||||||
|
return h.cfg.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) S3() *storage.Client {
|
||||||
|
return h.cfg.S3
|
||||||
|
}
|
9
handlers/sampleIndex.go
Normal file
9
handlers/sampleIndex.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *Handler) SampleIndex(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.Write([]byte("Hello from Index!"))
|
||||||
|
}
|
70
main.go
Normal file
70
main.go
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"git.tavo.one/tavo/axiom/database"
|
||||||
|
"git.tavo.one/tavo/axiom/handlers"
|
||||||
|
"git.tavo.one/tavo/axiom/storage"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
needed := []string{
|
||||||
|
"PRODUCTION",
|
||||||
|
"PORT",
|
||||||
|
"APP_DATA_DIR",
|
||||||
|
"DB_CONNDVR",
|
||||||
|
"DB_CONNSTR",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range needed {
|
||||||
|
if os.Getenv(v) == "" {
|
||||||
|
log.Fatalf("missing environment varialbe: %s", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
db, err := database.Init(os.Getenv("DB_CONNDVR"), os.Getenv("DB_CONNSTR"))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to initialize database: %v", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
s3, err := storage.New(os.Getenv("APP_DATA_DIR"), 4<<20)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed to initialize storage: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
handlerConfig := handlers.Config{
|
||||||
|
Production: os.Getenv("PRODUCTION") == "1",
|
||||||
|
Views: nil,
|
||||||
|
DB: db,
|
||||||
|
S3: s3,
|
||||||
|
}
|
||||||
|
handler := handlers.New(handlerConfig)
|
||||||
|
|
||||||
|
router := http.NewServeMux()
|
||||||
|
router.HandleFunc("GET /", handler.SampleIndex)
|
||||||
|
|
||||||
|
stop := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
|
port := os.Getenv("PORT")
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
log.Printf("starting on :%s...", port)
|
||||||
|
|
||||||
|
if err := http.ListenAndServe(":"+port, router); err != nil {
|
||||||
|
log.Fatalf("fatal: failed to start on port %s: %v", port, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
<-stop
|
||||||
|
|
||||||
|
log.Printf("shutting down...")
|
||||||
|
}
|
|
@ -11,8 +11,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
RootDir string
|
rootDir string
|
||||||
MaxObjectSize int64
|
maxObjectSize int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(root string, maxObjectSize int64) (*Client, error) {
|
func New(root string, maxObjectSize int64) (*Client, error) {
|
||||||
|
@ -40,17 +40,17 @@ func New(root string, maxObjectSize int64) (*Client, error) {
|
||||||
os.Remove(testFile)
|
os.Remove(testFile)
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
RootDir: root,
|
rootDir: root,
|
||||||
MaxObjectSize: maxObjectSize,
|
maxObjectSize: maxObjectSize,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Client) getPath(bucket, key string) string {
|
func (s *Client) getPath(bucket, key string) string {
|
||||||
return filepath.Join(s.RootDir, bucket, key)
|
return filepath.Join(s.rootDir, bucket, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Client) CreateBucket(bucket string) error {
|
func (s *Client) CreateBucket(bucket string) error {
|
||||||
path := filepath.Join(s.RootDir, bucket)
|
path := filepath.Join(s.rootDir, bucket)
|
||||||
return os.MkdirAll(path, 0755)
|
return os.MkdirAll(path, 0755)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,15 +67,15 @@ func (s *Client) PutObject(bucket, key string, reader io.Reader) error {
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
limitedReader := io.LimitReader(reader, s.MaxObjectSize+1)
|
limitedReader := io.LimitReader(reader, s.maxObjectSize+1)
|
||||||
written, err := io.Copy(f, limitedReader)
|
written, err := io.Copy(f, limitedReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if written > s.MaxObjectSize {
|
if written > s.maxObjectSize {
|
||||||
os.Remove(fullPath)
|
os.Remove(fullPath)
|
||||||
return fmt.Errorf("object size exceeds maximum allowed: %d bytes", s.MaxObjectSize)
|
return fmt.Errorf("object size exceeds maximum allowed: %d bytes", s.maxObjectSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in a new issue