initial commit

This commit is contained in:
MrLetsplay 2023-08-17 20:32:43 +00:00 committed by MrLetsplay
commit 858174b9d2
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
5 changed files with 171 additions and 0 deletions

View File

@ -0,0 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/go
{
"name": "Go",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/go:0-1-bullseye"
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "go version",
// Configure tool-specific properties.
// "customizations": {},
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
notes.sqlite
NoteServer

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.cringe-studios.com/NoteServer
go 1.20
require github.com/mattn/go-sqlite3 v1.14.17

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=

140
main.go Normal file
View File

@ -0,0 +1,140 @@
package main
import (
"database/sql"
"encoding/json"
"io"
"log"
"net/http"
_ "github.com/mattn/go-sqlite3"
)
var db *sql.DB
type Note struct {
Id int64 `json:"id"`
Content string `json:"content"`
}
func httpError(err error, statusCode int, message string, w http.ResponseWriter) bool {
if err != nil {
w.WriteHeader(statusCode)
io.WriteString(w, message)
return true
}
return false
}
func getNotes(w http.ResponseWriter, req *http.Request) {
res, err := db.Query(`SELECT Id, Content FROM Notes`)
if httpError(err, http.StatusInternalServerError, "Failed to load notes", w) {
return
}
defer res.Close()
var notes []Note = []Note{}
for res.Next() {
if httpError(res.Err(), http.StatusInternalServerError, "Failed to load notes", w) {
return
}
var note Note
res.Scan(&note.Id, &note.Content)
notes = append(notes, note)
}
json, err := json.Marshal(notes)
if httpError(err, http.StatusInternalServerError, "Failed to create JSON", w) {
return
}
w.Write(json)
}
func postNotes(w http.ResponseWriter, req *http.Request) {
data, err := io.ReadAll(req.Body)
if httpError(err, http.StatusBadRequest, "Failed to read data", w) {
return
}
var note Note
err = json.Unmarshal(data, &note)
if httpError(err, http.StatusBadRequest, "Invalid request", w) {
return
}
if len(note.Content) == 0 {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Missing note content")
return
}
stmt, err := db.Prepare(`INSERT INTO Notes(Content) VALUES(?) RETURNING Id`)
if httpError(err, http.StatusInternalServerError, "Failed to store note", w) {
return
}
defer stmt.Close()
res := stmt.QueryRow(note.Content)
err = res.Scan(&note.Id)
if httpError(err, http.StatusInternalServerError, "Failed to store note", w) {
return
}
json, err := json.Marshal(note)
if httpError(err, http.StatusInternalServerError, "Failed to create JSON", w) {
return
}
w.WriteHeader(http.StatusCreated)
w.Write(json)
}
func putNote(w http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPut {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Invalid method")
return
}
}
func handleNotes(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case http.MethodGet:
getNotes(w, req)
case http.MethodPost:
postNotes(w, req)
default:
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Invalid method")
}
}
func main() {
log.Println("Starting NoteServer")
log.Println("Loading database")
var err error
db, err = sql.Open("sqlite3", "./notes.sqlite")
if err != nil {
log.Fatalln("Failed to load db:", err)
}
log.Println("Creating missing tables")
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS Notes(Id INTEGER PRIMARY KEY AUTOINCREMENT, Content TEXT)`)
if err != nil {
log.Fatalln("Failed to create table:", err)
}
log.Println("Listening")
http.HandleFunc("/api/notes", handleNotes)
http.HandleFunc("/api/note/", putNote)
http.ListenAndServe(":8080", nil) // TODO: configure host, port, TLS
}