creating chirps!
This commit is contained in:
36
internal/database/CreateChirp.sql.go
Normal file
36
internal/database/CreateChirp.sql.go
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.28.0
|
||||||
|
// source: CreateChirp.sql
|
||||||
|
|
||||||
|
package database
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
)
|
||||||
|
|
||||||
|
const createChirp = `-- name: CreateChirp :one
|
||||||
|
INSERT INTO chirps (id, created_at, updated_at, body, user_id)
|
||||||
|
VALUES (gen_random_uuid(), NOW(), NOW(), $1, $2)
|
||||||
|
RETURNING id, created_at, updated_at, body, user_id
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreateChirpParams struct {
|
||||||
|
Body string
|
||||||
|
UserID uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateChirp(ctx context.Context, arg CreateChirpParams) (Chirp, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, createChirp, arg.Body, arg.UserID)
|
||||||
|
var i Chirp
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CreatedAt,
|
||||||
|
&i.UpdatedAt,
|
||||||
|
&i.Body,
|
||||||
|
&i.UserID,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
@@ -10,6 +10,14 @@ import (
|
|||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Chirp struct {
|
||||||
|
ID uuid.UUID
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
|
Body string
|
||||||
|
UserID uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
|
|||||||
68
main.go
68
main.go
@@ -5,6 +5,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"github.com/rdarius/go-http-server/internal/database"
|
"github.com/rdarius/go-http-server/internal/database"
|
||||||
@@ -74,6 +75,46 @@ func fileServerHandler() http.Handler {
|
|||||||
return http.StripPrefix("/app", fileServer)
|
return http.StripPrefix("/app", fileServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func postChirpsHandler(cfg *apiConfig) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
type parameters struct {
|
||||||
|
Body string `json:"body"`
|
||||||
|
UserID uuid.UUID `json:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
params := parameters{}
|
||||||
|
err := json.NewDecoder(r.Body).Decode(¶ms)
|
||||||
|
if err != nil {
|
||||||
|
httpResponse.JSONHandler(w, http.StatusBadRequest, `{"error": "Failed to parse request body"}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chirp, err := validateChirp(params.Body)
|
||||||
|
if err != nil {
|
||||||
|
httpResponse.JSONHandler(w, http.StatusBadRequest, fmt.Sprintf(`{"error": "%s"}`, err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
newChirp, err := cfg.db.CreateChirp(context.Background(), database.CreateChirpParams{
|
||||||
|
Body: chirp,
|
||||||
|
UserID: params.UserID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
httpResponse.JSONHandler(w, http.StatusInternalServerError, fmt.Sprintf(`{"error": "%s"}`, err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData := fmt.Sprintf(`{
|
||||||
|
"id": "%s",
|
||||||
|
"created_at": "%s",
|
||||||
|
"updated_at": "%s",
|
||||||
|
"body": "%s",
|
||||||
|
"user_id": "%s"
|
||||||
|
}`, newChirp.ID, newChirp.CreatedAt, newChirp.UpdatedAt, newChirp.Body, newChirp.UserID)
|
||||||
|
httpResponse.JSONHandler(w, http.StatusCreated, jsonData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func postUsersHandler(cfg *apiConfig) http.HandlerFunc {
|
func postUsersHandler(cfg *apiConfig) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
type parameters struct {
|
type parameters struct {
|
||||||
@@ -103,36 +144,19 @@ func postUsersHandler(cfg *apiConfig) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateChirpHandler(w http.ResponseWriter, r *http.Request) {
|
func validateChirp(chirp string) (string, error) {
|
||||||
type parameters struct {
|
|
||||||
Body string `json:"body"`
|
|
||||||
}
|
|
||||||
|
|
||||||
profaneWords := []string{"kerfuffle", "sharbert", "fornax"}
|
profaneWords := []string{"kerfuffle", "sharbert", "fornax"}
|
||||||
|
|
||||||
decoder := json.NewDecoder(r.Body)
|
if len(chirp) > 140 {
|
||||||
params := parameters{}
|
return "", fmt.Errorf("chirp is too long")
|
||||||
err := decoder.Decode(¶ms)
|
|
||||||
if err != nil {
|
|
||||||
httpResponse.SomethingWentWrong(w)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(params.Body) > 140 {
|
|
||||||
httpResponse.JSONHandler(w, http.StatusBadRequest, `{"error": "Chirp is too long"}`)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
chirp := params.Body
|
|
||||||
|
|
||||||
for _, word := range profaneWords {
|
for _, word := range profaneWords {
|
||||||
// Use word boundaries (\b) to match whole words and ignore punctuation
|
|
||||||
re := regexp.MustCompile(`(?i)\b` + regexp.QuoteMeta(word) + `\b`)
|
re := regexp.MustCompile(`(?i)\b` + regexp.QuoteMeta(word) + `\b`)
|
||||||
chirp = re.ReplaceAllString(chirp, "****")
|
chirp = re.ReplaceAllString(chirp, "****")
|
||||||
}
|
}
|
||||||
|
|
||||||
httpResponse.JSONHandler(w, http.StatusOK, fmt.Sprintf(`{"cleaned_body": "%s"}`, chirp))
|
return chirp, nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -159,8 +183,8 @@ func main() {
|
|||||||
mux.HandleFunc("GET /api/healthz", readinessHandler)
|
mux.HandleFunc("GET /api/healthz", readinessHandler)
|
||||||
mux.HandleFunc("GET /api/metrics", metricsHandler(apiCfg))
|
mux.HandleFunc("GET /api/metrics", metricsHandler(apiCfg))
|
||||||
mux.HandleFunc("POST /api/reset", resetMetricsHandler(apiCfg))
|
mux.HandleFunc("POST /api/reset", resetMetricsHandler(apiCfg))
|
||||||
mux.HandleFunc("POST /api/validate_chirp", validateChirpHandler)
|
|
||||||
mux.HandleFunc("POST /api/users", postUsersHandler(apiCfg))
|
mux.HandleFunc("POST /api/users", postUsersHandler(apiCfg))
|
||||||
|
mux.HandleFunc("POST /api/chirps", postChirpsHandler(apiCfg))
|
||||||
|
|
||||||
mux.HandleFunc("GET /admin/metrics", adminMetricsHandler(apiCfg))
|
mux.HandleFunc("GET /admin/metrics", adminMetricsHandler(apiCfg))
|
||||||
mux.HandleFunc("POST /admin/reset", resetMetricsHandler(apiCfg))
|
mux.HandleFunc("POST /admin/reset", resetMetricsHandler(apiCfg))
|
||||||
|
|||||||
4
sql/queries/CreateChirp.sql
Normal file
4
sql/queries/CreateChirp.sql
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
-- name: CreateChirp :one
|
||||||
|
INSERT INTO chirps (id, created_at, updated_at, body, user_id)
|
||||||
|
VALUES (gen_random_uuid(), NOW(), NOW(), $1, $2)
|
||||||
|
RETURNING *;
|
||||||
11
sql/schema/002_chirps.sql
Normal file
11
sql/schema/002_chirps.sql
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
-- +goose Up
|
||||||
|
CREATE TABLE chirps(
|
||||||
|
id UUID PRIMARY KEY,
|
||||||
|
created_at TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
body TEXT not null UNIQUE,
|
||||||
|
user_id UUID not null REFERENCES users(id) ON DELETE CASCADE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- +goose Down
|
||||||
|
DROP TABLE chirps;
|
||||||
Reference in New Issue
Block a user