feat: string-unpack api

This commit is contained in:
2024-05-08 21:25:02 +03:00
parent 0f8d6b39fb
commit 070934d66a
18 changed files with 572 additions and 4 deletions

View File

@ -0,0 +1,10 @@
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE TABLE unpack_history
(
id uuid default gen_random_uuid() primary key,
input text NOT NULL,
result text NOT NULL,
created_at timestamptz DEFAULT NOW()
)
;

View File

@ -0,0 +1,32 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.26.0
package sql
import (
"context"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
type DBTX interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx pgx.Tx) *Queries {
return &Queries{
db: tx,
}
}

View File

@ -0,0 +1,9 @@
-- name: Insert :one
INSERT INTO unpack_history (input, result)
VALUES (@input, @result)
RETURNING
id,
input,
result,
created_at
;

View File

@ -0,0 +1,37 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.26.0
// source: insert.sql
package sql
import (
"context"
)
const insert = `-- name: Insert :one
INSERT INTO unpack_history (input, result)
VALUES ($1, $2)
RETURNING
id,
input,
result,
created_at
`
type InsertParams struct {
Input string `db:"input" json:"input"`
Result string `db:"result" json:"result"`
}
func (q *Queries) Insert(ctx context.Context, arg InsertParams) (UnpackHistory, error) {
row := q.db.QueryRow(ctx, insert, arg.Input, arg.Result)
var i UnpackHistory
err := row.Scan(
&i.ID,
&i.Input,
&i.Result,
&i.CreatedAt,
)
return i, err
}

View File

@ -0,0 +1,9 @@
-- name: Latest :many
SELECT id,
input,
result,
created_at
FROM unpack_history
ORDER BY created_at DESC
LIMIT 15
;

View File

@ -0,0 +1,45 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.26.0
// source: latest.sql
package sql
import (
"context"
)
const latest = `-- name: Latest :many
SELECT id,
input,
result,
created_at
FROM unpack_history
ORDER BY created_at DESC
LIMIT 15
`
func (q *Queries) Latest(ctx context.Context) ([]UnpackHistory, error) {
rows, err := q.db.Query(ctx, latest)
if err != nil {
return nil, err
}
defer rows.Close()
var items []UnpackHistory
for rows.Next() {
var i UnpackHistory
if err := rows.Scan(
&i.ID,
&i.Input,
&i.Result,
&i.CreatedAt,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}

View File

@ -0,0 +1,16 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.26.0
package sql
import (
"github.com/jackc/pgx/v5/pgtype"
)
type UnpackHistory struct {
ID pgtype.UUID `db:"id" json:"id"`
Input string `db:"input" json:"input"`
Result string `db:"result" json:"result"`
CreatedAt pgtype.Timestamptz `db:"created_at" json:"created_at"`
}

View File

@ -0,0 +1,16 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.26.0
package sql
import (
"context"
)
type Querier interface {
Insert(ctx context.Context, arg InsertParams) (UnpackHistory, error)
Latest(ctx context.Context) ([]UnpackHistory, error)
}
var _ Querier = (*Queries)(nil)

78
string-unpack/server.go Normal file
View File

@ -0,0 +1,78 @@
package stringunpack
import (
"context"
"errors"
"fmt"
"net/http"
"git.grachevko.ru/grachevko/h/string-unpack/internal/sql"
"github.com/gin-gonic/gin"
"github.com/jackc/pgx/v5"
"go.uber.org/zap"
)
var queries sql.Querier
func Setup(ctx context.Context, logger *zap.Logger, r *gin.RouterGroup, conn *pgx.Conn) {
if queries != nil {
panic("Setup must call only once")
}
queries = sql.New(conn)
unpack := func(input string) (r string, err error) {
r, err = Unpack(input)
{ // history
result := r
if err != nil {
result = fmt.Sprintf("err: %s", err.Error())
}
_, err := queries.Insert(ctx, sql.InsertParams{
Input: input,
Result: result,
})
if err != nil {
logger.Error("pg insert", zap.Error(err))
}
} // history
return
}
r.GET("history", func(c *gin.Context) {
latest, err := queries.Latest(ctx)
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"err": err.Error(),
})
return
}
c.JSON(http.StatusOK, latest)
})
r.GET(":s", func(c *gin.Context) {
s := c.Param("s")
result, err := unpack(s)
if errors.Is(err, ErrIncorrectString) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"err": err.Error(),
})
return
}
if err != nil {
logger.Error("unpack", zap.Error(err))
c.AbortWithStatus(http.StatusInternalServerError)
}
c.JSON(http.StatusOK, gin.H{
"result": result,
})
})
}