new framework
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
create table if not exists tv_show (
|
||||
id serial unique primary key,
|
||||
"name" varchar not null,
|
||||
tt_imdb varchar not null,
|
||||
popularity int not null default 0,
|
||||
|
||||
created_at timestamp not null default (now()),
|
||||
updated_at timestamp not null default (now())
|
||||
);
|
||||
|
||||
create index if not exists idx_tv_show_name on "tv_show" ("name");
|
||||
create index if not exists idx_tv_show_tt_imdb on "tv_show" ("tt_imdb");
|
||||
create index if not exists idx_tv_show_updated_at on "tv_show" ("updated_at");
|
||||
|
||||
create table if not exists episodes (
|
||||
id serial unique primary key,
|
||||
tv_show_id integer not null,
|
||||
|
||||
season integer not null,
|
||||
episode integer not null,
|
||||
released date,
|
||||
"name" varchar not null,
|
||||
plot text not null default '',
|
||||
avg_rating real not null default 0,
|
||||
vote_count int not null default 0,
|
||||
|
||||
foreign key (tv_show_id) references tv_show (id)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
-- name: CreateTVShow :one
|
||||
insert into "tv_show" (name, tt_imdb)
|
||||
values ($1, $2)
|
||||
returning *;
|
||||
|
||||
-- name: CreateEpisodes :one
|
||||
insert into "episodes" (tv_show_id, season, episode, released, name, plot, avg_rating, vote_count)
|
||||
values ($1, $2, $3, $4, $5, $6, $7, $8)
|
||||
returning *;
|
||||
|
||||
-- name: CheckTVShowExists :one
|
||||
select * from "tv_show"
|
||||
where tt_imdb = $1;
|
||||
|
||||
-- name: GetEpisodes :many
|
||||
select * from "episodes"
|
||||
where tv_show_id = $1
|
||||
order by season, episode asc;
|
||||
|
||||
-- name: IncreasePopularity :exec
|
||||
update "tv_show" set popularity = popularity + 1
|
||||
where tt_imdb = $1;
|
||||
|
||||
-- name: TvShowAverageRating :one
|
||||
select avg(avg_rating) from "episodes"
|
||||
where tv_show_id = $1;
|
||||
|
||||
-- name: TvShowMedianRating :one
|
||||
select percentile_cont(0.5) within group (order by avg_rating) from "episodes"
|
||||
where tv_show_id = $1;
|
||||
|
||||
-- name: SeasonAverageRating :one
|
||||
select avg(avg_rating) from "episodes"
|
||||
where tv_show_id = $1 and season = $2;
|
||||
|
||||
-- name: SeasonMedianRating :one
|
||||
select percentile_cont(0.5) within group (order by avg_rating) from "episodes"
|
||||
where tv_show_id = $1 and season = $2;
|
||||
+16
-54
@@ -1,79 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"encoding/gob"
|
||||
"errors"
|
||||
"gopher-toolbox/config"
|
||||
"gopher-toolbox/app"
|
||||
"gopher-toolbox/db"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"ron"
|
||||
|
||||
"gopher-toolbox/db"
|
||||
"gopher-toolbox/utils"
|
||||
|
||||
"github.com/golang-migrate/migrate/v4"
|
||||
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/zepyrshut/rating-orama/internal/handlers"
|
||||
"github.com/zepyrshut/rating-orama/internal/repository"
|
||||
)
|
||||
|
||||
const version = "0.2.0-beta.20241116-4"
|
||||
//go:embed database/migrations
|
||||
var database embed.FS
|
||||
|
||||
var app *config.App
|
||||
const version = "0.2.0-beta.20241116-4"
|
||||
|
||||
func init() {
|
||||
gob.Register(map[string]string{})
|
||||
|
||||
err := godotenv.Load()
|
||||
if err != nil {
|
||||
slog.Error("cannot load .env file", "error", err)
|
||||
}
|
||||
config.NewLogger(config.LogLevel(os.Getenv("LOG_LEVEL")))
|
||||
slog.Info("starting server")
|
||||
|
||||
if os.Getenv("MIGRATE") == "true" {
|
||||
migrateDB()
|
||||
}
|
||||
}
|
||||
|
||||
func migrateDB() {
|
||||
slog.Info("migrating database")
|
||||
m, err := migrate.New("file://database/migrations", os.Getenv("DATASOURCE"))
|
||||
if err != nil {
|
||||
slog.Error("cannot create migration", "error", err)
|
||||
}
|
||||
|
||||
err = m.Up()
|
||||
if err != nil && !errors.Is(err, migrate.ErrNoChange) {
|
||||
slog.Error("cannot migrate", "error", err)
|
||||
panic(err)
|
||||
}
|
||||
if errors.Is(err, migrate.ErrNoChange) {
|
||||
slog.Info("migration has no changes")
|
||||
}
|
||||
|
||||
slog.Info("migration done")
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := app.New(version)
|
||||
app.Migrate(database)
|
||||
r := ron.New(func(e *ron.Engine) {
|
||||
e.Render = ron.NewHTMLRender()
|
||||
e.Config.LogLevel = slog.LevelDebug
|
||||
})
|
||||
|
||||
app = &config.App{
|
||||
DataSource: os.Getenv("DATASOURCE"),
|
||||
UseCache: utils.GetBool(os.Getenv("USE_CACHE")),
|
||||
AppInfo: config.AppInfo{
|
||||
GinMode: os.Getenv("GIN_MODE"),
|
||||
Version: version,
|
||||
},
|
||||
}
|
||||
|
||||
dbPool := db.NewPostgresPool(app.DataSource)
|
||||
dbPool := db.NewPGXPool(app.Database.DataSource)
|
||||
defer dbPool.Close()
|
||||
|
||||
q := repository.NewPGXRepo(dbPool)
|
||||
h := handlers.New(q, app)
|
||||
r := Router(h, app)
|
||||
h := handlers.New(app, q)
|
||||
router(h, r)
|
||||
|
||||
slog.Info("server started", "port", "8080", "version", version)
|
||||
err := http.ListenAndServe(":8080", r)
|
||||
|
||||
+3
-7
@@ -1,18 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/zepyrshut/rating-orama/internal/handlers"
|
||||
"ron"
|
||||
|
||||
"gopher-toolbox/config"
|
||||
"github.com/zepyrshut/rating-orama/internal/handlers"
|
||||
)
|
||||
|
||||
func Router(h *handlers.Handlers, app *config.App) *gin.Engine {
|
||||
gin.SetMode(app.AppInfo.GinMode)
|
||||
r := gin.New()
|
||||
func router(h *handlers.Handlers, r *ron.Engine) {
|
||||
|
||||
r.GET("/ping", h.Ping)
|
||||
r.GET("/tvshow", h.GetTVShow)
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user