initial commit
This commit is contained in:
commit
858174b9d2
22
.devcontainer/devcontainer.json
Normal file
22
.devcontainer/devcontainer.json
Normal 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
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
notes.sqlite
|
||||
NoteServer
|
5
go.mod
Normal file
5
go.mod
Normal 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
2
go.sum
Normal 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
140
main.go
Normal 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(¬e.Id, ¬e.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, ¬e)
|
||||
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(¬e.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
|
||||
}
|
Loading…
Reference in New Issue
Block a user