Initial insert in handler

drew/lets-go
Drew Bednar 3 months ago
parent 8e42f69a70
commit 0a978da3ac

@ -45,7 +45,7 @@ func main() {
// Propagate build information to root package to share globally
// ratchet.Version = strings.TrimPrefix(version, "")
// ratchet.Commit = commit
server := server.NewRatchetServer(logger)
server := server.NewRatchetServer(logger, db)
// START SERVING REQUESTS
slog.Debug("Herp dirp!")

@ -0,0 +1,66 @@
package model
import (
"database/sql"
"fmt"
"log/slog"
"time"
)
type Snippet struct {
ID int
Title string
Content string
CreatedAt time.Time
UpdatedAt time.Time
ExpiresAt time.Time
}
type SnippetService struct {
DB *sql.DB
}
// Insert inserts a new SnippetModel into the database
func (s *SnippetService) Insert(title, content string, expiresAt int) (int, error) {
slog.Debug(fmt.Sprintf("Inserting new snippet. Title: %s", title))
stmt, err := s.DB.Prepare("INSERT INTO snippets (title, content, expires_at) VALUES ($1, $2, DATETIME(CURRENT_TIMESTAMP, '+' || $3 || ' DAY'))")
if err != nil {
slog.Debug("The prepared statement has an error")
return 0, err
}
defer stmt.Close()
// stmt.Exec returns a sql.Result. That also has access to the statement metadata
// use _ if you don't care about the result and only want to check the err.
// Exec will NOT reserve a connection. unlike db.Query which returns a sql.Rows that
// will hold on to a connection until .Close() is called.
res, err := stmt.Exec(title, content, expiresAt)
if err != nil {
slog.Debug("SQL DDL returned an error.")
return 0, err
}
// Use the LastInsertId() method on the result to get the ID of our
// newly inserted record in the snippets table.
lastId, err := res.LastInsertId()
if err != nil {
slog.Debug("An error occured when retrieving insert result id.")
return 0, err
}
// The ID returned has the type int64, so we convert it to an int type
// before returning.
slog.Debug(fmt.Sprintf("Inserted new snippet. Snippet pk: %d", int(lastId)))
return int(lastId), nil
}
// Get retrieves a specific Snippet by ID
func (s *SnippetService) Get(id int) (Snippet, error) {
return Snippet{}, nil
}
// Latest retrieves up to latest 10 Snippets from the database.
func (s *SnippetService) Lastest() (Snippet, error) {
return Snippet{}, nil
}

@ -1,6 +1,7 @@
package server
import (
"database/sql"
"fmt"
"html/template"
"log/slog"
@ -8,6 +9,7 @@ import (
"strconv"
"git.runcible.io/learning/ratchet/internal/domain/user"
"git.runcible.io/learning/ratchet/internal/model"
)
type RatchetServer struct {
@ -15,12 +17,14 @@ type RatchetServer struct {
logger *slog.Logger
//Services used by HTTP routes
UserService user.UserService
snippetService *model.SnippetService
UserService user.UserService
}
func NewRatchetServer(logger *slog.Logger) *RatchetServer {
func NewRatchetServer(logger *slog.Logger, db *sql.DB) *RatchetServer {
rs := new(RatchetServer)
rs.logger = logger
rs.snippetService = &model.SnippetService{DB: db}
// TODO implement middleware that disables directory listings
fileServer := http.FileServer(http.Dir("./ui/static/"))
router := http.NewServeMux()
@ -101,15 +105,27 @@ func (rs *RatchetServer) snippetView(w http.ResponseWriter, r *http.Request) {
// snippetCreate handles display of the form used to create snippets
func (rs *RatchetServer) snippetCreate(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Displaying snippetCreate form..."))
w.Write([]byte("Create snippet form..."))
}
// snippetCreate handles display of the form used to create snippets
//
// curl -iL -d "" http://localhost:5000/snippet/create
func (rs *RatchetServer) snippetCreatePost(w http.ResponseWriter, r *http.Request) {
// example of a custom header. Must be done before calling WriteHeader
// or they will fail to take effect.
w.Header().Add("Server", "Dirp")
w.WriteHeader(http.StatusCreated)
// Create some variables holding dummy data. We'll remove these later on
// during the build.
title := "O snail"
content := "O snail\nClimb Mount Fuji,\nBut slowly, slowly!\n\n Kobayashi Issa"
expires := 7
w.Write([]byte("Created snippet..."))
id, err := rs.snippetService.Insert(title, content, expires)
if err != nil {
rs.serverError(w, r, err)
}
http.Redirect(w, r, fmt.Sprintf("/snippet/view/%d", id), http.StatusSeeOther)
}

Loading…
Cancel
Save