mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 18:51:03 +01:00
187 lines
3.9 KiB
Go
187 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/kataras/iris/v12"
|
|
"github.com/kataras/iris/v12/x/errors"
|
|
"github.com/kataras/iris/v12/x/sqlx"
|
|
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
const (
|
|
host = "localhost"
|
|
port = 5432
|
|
user = "postgres"
|
|
password = "admin!123"
|
|
dbname = "test"
|
|
)
|
|
|
|
func main() {
|
|
app := iris.New()
|
|
|
|
db := mustConnectDB()
|
|
mustCreateExtensions(context.Background(), db)
|
|
mustCreateTables(context.Background(), db)
|
|
|
|
app.Post("/", insert(db))
|
|
app.Get("/", list(db))
|
|
app.Get("/{event_id:uuid}", getByID(db))
|
|
|
|
/*
|
|
curl --location --request POST 'http://localhost:8080' \
|
|
--header 'Content-Type: application/json' \
|
|
--data-raw '{
|
|
"name": "second_test_event",
|
|
"data": {
|
|
"key": "value",
|
|
"year": 2022
|
|
}
|
|
}'
|
|
|
|
curl --location --request GET 'http://localhost:8080'
|
|
|
|
curl --location --request GET 'http://localhost:8080/4fc0363f-1d1f-4a43-8608-5ed266485645'
|
|
*/
|
|
app.Listen(":8080")
|
|
}
|
|
|
|
func mustConnectDB() *sql.DB {
|
|
connString := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
|
|
host, port, user, password, dbname)
|
|
db, err := sql.Open("postgres", connString)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = db.Ping()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return db
|
|
}
|
|
|
|
func mustCreateExtensions(ctx context.Context, db *sql.DB) {
|
|
query := `CREATE EXTENSION IF NOT EXISTS pgcrypto;`
|
|
_, err := db.ExecContext(ctx, query)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func mustCreateTables(ctx context.Context, db *sql.DB) {
|
|
query := `CREATE TABLE IF NOT EXISTS "events" (
|
|
"id" uuid PRIMARY KEY NOT NULL DEFAULT gen_random_uuid(),
|
|
"created_at" timestamp(6) DEFAULT now(),
|
|
"name" text COLLATE "pg_catalog"."default",
|
|
"data" jsonb
|
|
);`
|
|
|
|
_, err := db.ExecContext(ctx, query)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
sqlx.Register("events", Event{})
|
|
}
|
|
|
|
type Event struct {
|
|
ID string `json:"id"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
Name string `json:"name"`
|
|
Data json.RawMessage `json:"data"`
|
|
|
|
Presenter string `db:"-" json:"-"`
|
|
}
|
|
|
|
func insertEvent(ctx context.Context, db *sql.DB, evt Event) (id string, err error) {
|
|
query := `INSERT INTO events(name,data) VALUES($1,$2) RETURNING id;`
|
|
err = db.QueryRowContext(ctx, query, evt.Name, evt.Data).Scan(&id)
|
|
return
|
|
}
|
|
|
|
func listEvents(ctx context.Context, db *sql.DB) ([]Event, error) {
|
|
list := make([]Event, 0)
|
|
query := `SELECT * FROM events ORDER BY created_at;`
|
|
rows, err := db.QueryContext(ctx, query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Not required. See sqlx.DefaultSchema.AutoCloseRows field.
|
|
// defer rows.Close()
|
|
|
|
if err = sqlx.Bind(&list, rows); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return list, nil
|
|
}
|
|
|
|
func getEvent(ctx context.Context, db *sql.DB, id string) (evt Event, err error) {
|
|
query := `SELECT * FROM events WHERE id = $1 LIMIT 1;`
|
|
err = sqlx.Query(ctx, db, &evt, query, id)
|
|
return
|
|
//
|
|
// Same as:
|
|
//
|
|
// rows, err := db.QueryContext(ctx, query, id)
|
|
// if err != nil {
|
|
// return Event{}, err
|
|
// }
|
|
//
|
|
// var evt Event
|
|
// err = sqlx.Bind(&evt, rows)
|
|
//
|
|
// return evt, err
|
|
}
|
|
|
|
func insert(db *sql.DB) iris.Handler {
|
|
return func(ctx iris.Context) {
|
|
var evt Event
|
|
if err := ctx.ReadJSON(&evt); err != nil {
|
|
errors.InvalidArgument.Details(ctx, "unable to read body", err.Error())
|
|
return
|
|
}
|
|
|
|
id, err := insertEvent(ctx, db, evt)
|
|
if err != nil {
|
|
errors.Internal.LogErr(ctx, err)
|
|
return
|
|
}
|
|
|
|
ctx.JSON(iris.Map{"id": id})
|
|
}
|
|
}
|
|
|
|
func list(db *sql.DB) iris.Handler {
|
|
return func(ctx iris.Context) {
|
|
events, err := listEvents(ctx, db)
|
|
if err != nil {
|
|
errors.Internal.LogErr(ctx, err)
|
|
return
|
|
}
|
|
|
|
ctx.JSON(events)
|
|
}
|
|
}
|
|
|
|
func getByID(db *sql.DB) iris.Handler {
|
|
return func(ctx iris.Context) {
|
|
eventID := ctx.Params().Get("event_id")
|
|
|
|
evt, err := getEvent(ctx, db, eventID)
|
|
if err != nil {
|
|
errors.Internal.LogErr(ctx, err)
|
|
return
|
|
}
|
|
|
|
ctx.JSON(evt)
|
|
}
|
|
}
|