From bfef2fe7f9e86128ddd7d3c9c61c80e0709f9114 Mon Sep 17 00:00:00 2001 From: Michael Li Date: Sat, 4 Feb 2023 18:00:44 +0800 Subject: [PATCH] sqlc: prepare implement topics data logic --- internal/dao/slonik/ce/postgres/city.sql.go | 90 ----- internal/dao/slonik/ce/postgres/models.go | 81 +--- internal/dao/slonik/ce/postgres/querier.go | 25 +- .../dao/slonik/ce/postgres/query/city.sql | 26 -- .../dao/slonik/ce/postgres/query/topic.sql | 58 +++ .../dao/slonik/ce/postgres/query/venue.sql | 49 --- .../slonik/ce/postgres/schema/0001_city.sql | 4 - .../schema/0001_initialize_schema.down.sql | 2 + .../schema/0001_initialize_schema.up.sql | 17 + .../slonik/ce/postgres/schema/0002_venue.sql | 18 - .../ce/postgres/schema/0003_add_column.sql | 3 - internal/dao/slonik/ce/postgres/topic.sql.go | 348 ++++++++++++++++++ internal/dao/slonik/ce/postgres/venue.sql.go | 189 ---------- internal/dao/slonik/ce/sqlc.yaml | 2 + internal/dao/slonik/pgx.go | 8 +- internal/dao/slonik/topics.go | 92 ++++- 16 files changed, 535 insertions(+), 477 deletions(-) delete mode 100644 internal/dao/slonik/ce/postgres/city.sql.go delete mode 100644 internal/dao/slonik/ce/postgres/query/city.sql create mode 100644 internal/dao/slonik/ce/postgres/query/topic.sql delete mode 100644 internal/dao/slonik/ce/postgres/query/venue.sql delete mode 100644 internal/dao/slonik/ce/postgres/schema/0001_city.sql create mode 100644 internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.down.sql create mode 100644 internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.up.sql delete mode 100644 internal/dao/slonik/ce/postgres/schema/0002_venue.sql delete mode 100644 internal/dao/slonik/ce/postgres/schema/0003_add_column.sql create mode 100644 internal/dao/slonik/ce/postgres/topic.sql.go delete mode 100644 internal/dao/slonik/ce/postgres/venue.sql.go diff --git a/internal/dao/slonik/ce/postgres/city.sql.go b/internal/dao/slonik/ce/postgres/city.sql.go deleted file mode 100644 index d16ffab9..00000000 --- a/internal/dao/slonik/ce/postgres/city.sql.go +++ /dev/null @@ -1,90 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.16.0 -// source: city.sql - -package dbr - -import ( - "context" -) - -const createCity = `-- name: CreateCity :one -INSERT INTO city ( - name, - slug -) VALUES ( - $1, - $2 -) RETURNING slug, name -` - -type CreateCityParams struct { - Name string - Slug string -} - -// Create a new city. The slug must be unique. -// This is the second line of the comment -// This is the third line -func (q *Queries) CreateCity(ctx context.Context, arg CreateCityParams) (City, error) { - row := q.db.QueryRow(ctx, createCity, arg.Name, arg.Slug) - var i City - err := row.Scan(&i.Slug, &i.Name) - return i, err -} - -const getCity = `-- name: GetCity :one -SELECT slug, name -FROM city -WHERE slug = $1 -` - -func (q *Queries) GetCity(ctx context.Context, slug string) (City, error) { - row := q.db.QueryRow(ctx, getCity, slug) - var i City - err := row.Scan(&i.Slug, &i.Name) - return i, err -} - -const listCities = `-- name: ListCities :many -SELECT slug, name -FROM city -ORDER BY name -` - -func (q *Queries) ListCities(ctx context.Context) ([]City, error) { - rows, err := q.db.Query(ctx, listCities) - if err != nil { - return nil, err - } - defer rows.Close() - var items []City - for rows.Next() { - var i City - if err := rows.Scan(&i.Slug, &i.Name); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const updateCityName = `-- name: UpdateCityName :exec -UPDATE city -SET name = $2 -WHERE slug = $1 -` - -type UpdateCityNameParams struct { - Slug string - Name string -} - -func (q *Queries) UpdateCityName(ctx context.Context, arg UpdateCityNameParams) error { - _, err := q.db.Exec(ctx, updateCityName, arg.Slug, arg.Name) - return err -} diff --git a/internal/dao/slonik/ce/postgres/models.go b/internal/dao/slonik/ce/postgres/models.go index 2a099189..d50ca7ad 100644 --- a/internal/dao/slonik/ce/postgres/models.go +++ b/internal/dao/slonik/ce/postgres/models.go @@ -4,72 +4,17 @@ package dbr -import ( - "database/sql/driver" - "fmt" - - "github.com/jackc/pgx/v5/pgtype" -) - -// Venues can be either open or closed -type Status string - -const ( - StatusOpen Status = "op!en" - StatusClosed Status = "clo@sed" -) - -func (e *Status) Scan(src interface{}) error { - switch s := src.(type) { - case []byte: - *e = Status(s) - case string: - *e = Status(s) - default: - return fmt.Errorf("unsupported scan type for Status: %T", src) - } - return nil -} - -type NullStatus struct { - Status Status - Valid bool // Valid is true if Status is not NULL -} - -// Scan implements the Scanner interface. -func (ns *NullStatus) Scan(value interface{}) error { - if value == nil { - ns.Status, ns.Valid = "", false - return nil - } - ns.Valid = true - return ns.Status.Scan(value) -} - -// Value implements the driver Valuer interface. -func (ns NullStatus) Value() (driver.Value, error) { - if !ns.Valid { - return nil, nil - } - return string(ns.Status), nil -} - -type City struct { - Slug string - Name string -} - -// Venues are places where muisc happens -type Venue struct { - ID int32 - Status Status - Statuses pgtype.Array[Status] - // This value appears in public URLs - Slug string - Name string - City string - SpotifyPlaylist string - SongkickID pgtype.Text - Tags pgtype.Array[string] - CreatedAt pgtype.Timestamp +import () + +// 主题标签 +type PTag struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 + CreatedOn int32 + ModifiedOn int32 + DeletedOn int32 + // 是否删除 + IsDel bool } diff --git a/internal/dao/slonik/ce/postgres/querier.go b/internal/dao/slonik/ce/postgres/querier.go index 5d494697..7ba9ef07 100644 --- a/internal/dao/slonik/ce/postgres/querier.go +++ b/internal/dao/slonik/ce/postgres/querier.go @@ -6,22 +6,21 @@ package dbr import ( "context" + + "github.com/jackc/pgx/v5/pgtype" ) type Querier interface { - // Create a new city. The slug must be unique. - // This is the second line of the comment - // This is the third line - CreateCity(ctx context.Context, arg CreateCityParams) (City, error) - CreateVenue(ctx context.Context, arg CreateVenueParams) (int32, error) - DeleteVenue(ctx context.Context, slug string) error - GetCity(ctx context.Context, slug string) (City, error) - GetVenue(ctx context.Context, arg GetVenueParams) (Venue, error) - ListCities(ctx context.Context) ([]City, error) - ListVenues(ctx context.Context, city string) ([]Venue, error) - UpdateCityName(ctx context.Context, arg UpdateCityNameParams) error - UpdateVenueName(ctx context.Context, arg UpdateVenueNameParams) (int32, error) - VenueCountByCity(ctx context.Context) ([]VenueCountByCityRow, error) + DecrTagsById(ctx context.Context, arg *DecrTagsByIdParams) error + HotTags(ctx context.Context, arg *HotTagsParams) ([]*HotTagsRow, error) + IncrTagsById(ctx context.Context, arg *IncrTagsByIdParams) error + InsertTags(ctx context.Context, arg *InsertTagsParams) (*InsertTagsRow, error) + NewestTags(ctx context.Context, arg *NewestTagsParams) ([]*NewestTagsRow, error) + TagsByIdA(ctx context.Context, ids pgtype.Array[int64]) ([]int64, error) + TagsByIdB(ctx context.Context, ids pgtype.Array[int64]) ([]*TagsByIdBRow, error) + TagsByKeywordA(ctx context.Context) ([]*TagsByKeywordARow, error) + TagsByKeywordB(ctx context.Context, tag string) ([]*TagsByKeywordBRow, error) + TagsByName(ctx context.Context, tags pgtype.Array[string]) ([]*TagsByNameRow, error) } var _ Querier = (*Queries)(nil) diff --git a/internal/dao/slonik/ce/postgres/query/city.sql b/internal/dao/slonik/ce/postgres/query/city.sql deleted file mode 100644 index f34dc996..00000000 --- a/internal/dao/slonik/ce/postgres/query/city.sql +++ /dev/null @@ -1,26 +0,0 @@ --- name: ListCities :many -SELECT * -FROM city -ORDER BY name; - --- name: GetCity :one -SELECT * -FROM city -WHERE slug = $1; - --- name: CreateCity :one --- Create a new city. The slug must be unique. --- This is the second line of the comment --- This is the third line -INSERT INTO city ( - name, - slug -) VALUES ( - $1, - $2 -) RETURNING *; - --- name: UpdateCityName :exec -UPDATE city -SET name = $2 -WHERE slug = $1; diff --git a/internal/dao/slonik/ce/postgres/query/topic.sql b/internal/dao/slonik/ce/postgres/query/topic.sql new file mode 100644 index 00000000..febcdeb6 --- /dev/null +++ b/internal/dao/slonik/ce/postgres/query/topic.sql @@ -0,0 +1,58 @@ +-- name: NewestTags :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del = false AND quote_num > 0 +ORDER BY id DESC +OFFSET $1 LIMIT $2; + +-- name: HotTags :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del = false AND quote_num > 0 +ORDER BY quote_num DESC +OFFSET $1 LIMIT $2; + +-- name: TagsByKeywordA :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del AND quote_num > 0 +ORDER BY quote_num DESC +OFFSET 0 LIMIT 6; + +-- name: TagsByKeywordB :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del = false AND tag LIKE $1 +ORDER BY quote_num DESC +OFFSET 0 LIMIT 6; + +-- name: InsertTags :one +INSERT INTO p_tag (user_id, tag, created_on, modified_on, quote_num) +VALUES ($1, $2, $3, $3, 1) +RETURNING id, user_id, tag, quote_num; + +-- name: TagsByIdA :many +SELECT id +FROM p_tag +WHERE id = ANY(@ids::bigserial[]) AND is_del = false AND quote_num >= 0; + +-- name: TagsByIdB :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE id = ANY(@ids::bigserial[]); + +-- name: DecrTagsById :exec +UPDATE p_tag +SET quote_num = quote_num-1, + modified_on=$1 +WHERE id = ANY(@ids::bigserial[]); + +-- name: TagsByName :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE tag = ANY(@tags::varchar[]) AND is_del = false AND quote_num >= 0; + +-- name: IncrTagsById :exec +UPDATE p_tag +SET quote_num = quote_num+1, modified_on = $1 +WHERE id = ANY(@ids::bigserial[]); diff --git a/internal/dao/slonik/ce/postgres/query/venue.sql b/internal/dao/slonik/ce/postgres/query/venue.sql deleted file mode 100644 index 8c6bd026..00000000 --- a/internal/dao/slonik/ce/postgres/query/venue.sql +++ /dev/null @@ -1,49 +0,0 @@ --- name: ListVenues :many -SELECT * -FROM venue -WHERE city = $1 -ORDER BY name; - --- name: DeleteVenue :exec -DELETE FROM venue -WHERE slug = $1 AND slug = $1; - --- name: GetVenue :one -SELECT * -FROM venue -WHERE slug = $1 AND city = $2; - --- name: CreateVenue :one -INSERT INTO venue ( - slug, - name, - city, - created_at, - spotify_playlist, - status, - statuses, - tags -) VALUES ( - $1, - $2, - $3, - NOW(), - $4, - $5, - $6, - $7 -) RETURNING id; - --- name: UpdateVenueName :one -UPDATE venue -SET name = $2 -WHERE slug = $1 -RETURNING id; - --- name: VenueCountByCity :many -SELECT - city, - count(*) -FROM venue -GROUP BY 1 -ORDER BY 1; diff --git a/internal/dao/slonik/ce/postgres/schema/0001_city.sql b/internal/dao/slonik/ce/postgres/schema/0001_city.sql deleted file mode 100644 index af38f16b..00000000 --- a/internal/dao/slonik/ce/postgres/schema/0001_city.sql +++ /dev/null @@ -1,4 +0,0 @@ -CREATE TABLE city ( - slug text PRIMARY KEY, - name text NOT NULL -) diff --git a/internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.down.sql b/internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.down.sql new file mode 100644 index 00000000..f447ca66 --- /dev/null +++ b/internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.down.sql @@ -0,0 +1,2 @@ +DROP TABLE IF EXISTS p_tag; +DROP INDEX IF EXISTS p_tag_tag_idx, p_tag_user_idx, p_tag_quote_num_idx; diff --git a/internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.up.sql b/internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.up.sql new file mode 100644 index 00000000..aa7900ac --- /dev/null +++ b/internal/dao/slonik/ce/postgres/schema/0001_initialize_schema.up.sql @@ -0,0 +1,17 @@ +CREATE TABLE p_tag ( + id bigserial PRIMARY KEY, + user_id bigserial NOT NULL DEFAULT 0, + tag varchar(255) NOT NULL, + quote_num bigint NOT NULL DEFAULT 0, + created_on int NOT NULL DEFAULT 0, + modified_on int NOT NULL DEFAULT 0, + deleted_on int NOT NULL DEFAULT 0, + is_del boolean NOT NULL DEFAULT false, + UNIQUE (tag) +); +COMMENT ON TABLE p_tag IS '主题标签'; +COMMENT ON COLUMN p_tag.is_del IS '是否删除'; +CREATE UNIQUE INDEX p_tag_tag_idx ON p_tag (tag); +CREATE INDEX p_tag_user_idx ON p_tag (user_id); +CREATE INDEX p_tag_quote_num_idx On p_tag (quote_num); + diff --git a/internal/dao/slonik/ce/postgres/schema/0002_venue.sql b/internal/dao/slonik/ce/postgres/schema/0002_venue.sql deleted file mode 100644 index 940de7a5..00000000 --- a/internal/dao/slonik/ce/postgres/schema/0002_venue.sql +++ /dev/null @@ -1,18 +0,0 @@ -CREATE TYPE status AS ENUM ('op!en', 'clo@sed'); -COMMENT ON TYPE status IS 'Venues can be either open or closed'; - -CREATE TABLE venues ( - id SERIAL primary key, - dropped text, - status status not null, - statuses status[], - slug text not null, - name varchar(255) not null, - city text not null references city(slug), - spotify_playlist varchar not null, - songkick_id text, - tags text[] -); -COMMENT ON TABLE venues IS 'Venues are places where muisc happens'; -COMMENT ON COLUMN venues.slug IS 'This value appears in public URLs'; - diff --git a/internal/dao/slonik/ce/postgres/schema/0003_add_column.sql b/internal/dao/slonik/ce/postgres/schema/0003_add_column.sql deleted file mode 100644 index 9b334bcc..00000000 --- a/internal/dao/slonik/ce/postgres/schema/0003_add_column.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE venues RENAME TO venue; -ALTER TABLE venue ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT NOW(); -ALTER TABLE venue DROP COLUMN dropped; diff --git a/internal/dao/slonik/ce/postgres/topic.sql.go b/internal/dao/slonik/ce/postgres/topic.sql.go new file mode 100644 index 00000000..b3c726c0 --- /dev/null +++ b/internal/dao/slonik/ce/postgres/topic.sql.go @@ -0,0 +1,348 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.16.0 +// source: topic.sql + +package dbr + +import ( + "context" + + "github.com/jackc/pgx/v5/pgtype" +) + +const decrTagsById = `-- name: DecrTagsById :exec +UPDATE p_tag +SET quote_num = quote_num-1, + modified_on=$1 +WHERE id = ANY($2::bigserial[]) +` + +type DecrTagsByIdParams struct { + ModifiedOn int32 + Ids pgtype.Array[int64] +} + +func (q *Queries) DecrTagsById(ctx context.Context, arg *DecrTagsByIdParams) error { + _, err := q.db.Exec(ctx, decrTagsById, arg.ModifiedOn, arg.Ids) + return err +} + +const hotTags = `-- name: HotTags :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del = false AND quote_num > 0 +ORDER BY quote_num DESC +OFFSET $1 LIMIT $2 +` + +type HotTagsParams struct { + Offset int32 + Limit int32 +} + +type HotTagsRow struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 +} + +func (q *Queries) HotTags(ctx context.Context, arg *HotTagsParams) ([]*HotTagsRow, error) { + rows, err := q.db.Query(ctx, hotTags, arg.Offset, arg.Limit) + if err != nil { + return nil, err + } + defer rows.Close() + var items []*HotTagsRow + for rows.Next() { + var i HotTagsRow + if err := rows.Scan( + &i.ID, + &i.UserID, + &i.Tag, + &i.QuoteNum, + ); err != nil { + return nil, err + } + items = append(items, &i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const incrTagsById = `-- name: IncrTagsById :exec +UPDATE p_tag +SET quote_num = quote_num+1, modified_on = $1 +WHERE id = ANY($2::bigserial[]) +` + +type IncrTagsByIdParams struct { + ModifiedOn int32 + Ids pgtype.Array[int64] +} + +func (q *Queries) IncrTagsById(ctx context.Context, arg *IncrTagsByIdParams) error { + _, err := q.db.Exec(ctx, incrTagsById, arg.ModifiedOn, arg.Ids) + return err +} + +const insertTags = `-- name: InsertTags :one +INSERT INTO p_tag (user_id, tag, created_on, modified_on, quote_num) +VALUES ($1, $2, $3, $3, 1) +RETURNING id, user_id, tag, quote_num +` + +type InsertTagsParams struct { + UserID int64 + Tag string + CreatedOn int32 +} + +type InsertTagsRow struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 +} + +func (q *Queries) InsertTags(ctx context.Context, arg *InsertTagsParams) (*InsertTagsRow, error) { + row := q.db.QueryRow(ctx, insertTags, arg.UserID, arg.Tag, arg.CreatedOn) + var i InsertTagsRow + err := row.Scan( + &i.ID, + &i.UserID, + &i.Tag, + &i.QuoteNum, + ) + return &i, err +} + +const newestTags = `-- name: NewestTags :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del = false AND quote_num > 0 +ORDER BY id DESC +OFFSET $1 LIMIT $2 +` + +type NewestTagsParams struct { + Offset int32 + Limit int32 +} + +type NewestTagsRow struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 +} + +func (q *Queries) NewestTags(ctx context.Context, arg *NewestTagsParams) ([]*NewestTagsRow, error) { + rows, err := q.db.Query(ctx, newestTags, arg.Offset, arg.Limit) + if err != nil { + return nil, err + } + defer rows.Close() + var items []*NewestTagsRow + for rows.Next() { + var i NewestTagsRow + if err := rows.Scan( + &i.ID, + &i.UserID, + &i.Tag, + &i.QuoteNum, + ); err != nil { + return nil, err + } + items = append(items, &i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const tagsByIdA = `-- name: TagsByIdA :many +SELECT id +FROM p_tag +WHERE id = ANY($1::bigserial[]) AND is_del = false AND quote_num >= 0 +` + +func (q *Queries) TagsByIdA(ctx context.Context, ids pgtype.Array[int64]) ([]int64, error) { + rows, err := q.db.Query(ctx, tagsByIdA, ids) + if err != nil { + return nil, err + } + defer rows.Close() + var items []int64 + for rows.Next() { + var id int64 + if err := rows.Scan(&id); err != nil { + return nil, err + } + items = append(items, id) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const tagsByIdB = `-- name: TagsByIdB :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE id = ANY($1::bigserial[]) +` + +type TagsByIdBRow struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 +} + +func (q *Queries) TagsByIdB(ctx context.Context, ids pgtype.Array[int64]) ([]*TagsByIdBRow, error) { + rows, err := q.db.Query(ctx, tagsByIdB, ids) + if err != nil { + return nil, err + } + defer rows.Close() + var items []*TagsByIdBRow + for rows.Next() { + var i TagsByIdBRow + if err := rows.Scan( + &i.ID, + &i.UserID, + &i.Tag, + &i.QuoteNum, + ); err != nil { + return nil, err + } + items = append(items, &i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const tagsByKeywordA = `-- name: TagsByKeywordA :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del AND quote_num > 0 +ORDER BY quote_num DESC +OFFSET 0 LIMIT 6 +` + +type TagsByKeywordARow struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 +} + +func (q *Queries) TagsByKeywordA(ctx context.Context) ([]*TagsByKeywordARow, error) { + rows, err := q.db.Query(ctx, tagsByKeywordA) + if err != nil { + return nil, err + } + defer rows.Close() + var items []*TagsByKeywordARow + for rows.Next() { + var i TagsByKeywordARow + if err := rows.Scan( + &i.ID, + &i.UserID, + &i.Tag, + &i.QuoteNum, + ); err != nil { + return nil, err + } + items = append(items, &i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const tagsByKeywordB = `-- name: TagsByKeywordB :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE is_del = false AND tag LIKE $1 +ORDER BY quote_num DESC +OFFSET 0 LIMIT 6 +` + +type TagsByKeywordBRow struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 +} + +func (q *Queries) TagsByKeywordB(ctx context.Context, tag string) ([]*TagsByKeywordBRow, error) { + rows, err := q.db.Query(ctx, tagsByKeywordB, tag) + if err != nil { + return nil, err + } + defer rows.Close() + var items []*TagsByKeywordBRow + for rows.Next() { + var i TagsByKeywordBRow + if err := rows.Scan( + &i.ID, + &i.UserID, + &i.Tag, + &i.QuoteNum, + ); err != nil { + return nil, err + } + items = append(items, &i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const tagsByName = `-- name: TagsByName :many +SELECT id, user_id, tag, quote_num +FROM p_tag +WHERE tag = ANY($1::varchar[]) AND is_del = false AND quote_num >= 0 +` + +type TagsByNameRow struct { + ID int64 + UserID int64 + Tag string + QuoteNum int64 +} + +func (q *Queries) TagsByName(ctx context.Context, tags pgtype.Array[string]) ([]*TagsByNameRow, error) { + rows, err := q.db.Query(ctx, tagsByName, tags) + if err != nil { + return nil, err + } + defer rows.Close() + var items []*TagsByNameRow + for rows.Next() { + var i TagsByNameRow + if err := rows.Scan( + &i.ID, + &i.UserID, + &i.Tag, + &i.QuoteNum, + ); err != nil { + return nil, err + } + items = append(items, &i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/internal/dao/slonik/ce/postgres/venue.sql.go b/internal/dao/slonik/ce/postgres/venue.sql.go deleted file mode 100644 index 384701a2..00000000 --- a/internal/dao/slonik/ce/postgres/venue.sql.go +++ /dev/null @@ -1,189 +0,0 @@ -// Code generated by sqlc. DO NOT EDIT. -// versions: -// sqlc v1.16.0 -// source: venue.sql - -package dbr - -import ( - "context" - - "github.com/jackc/pgx/v5/pgtype" -) - -const createVenue = `-- name: CreateVenue :one -INSERT INTO venue ( - slug, - name, - city, - created_at, - spotify_playlist, - status, - statuses, - tags -) VALUES ( - $1, - $2, - $3, - NOW(), - $4, - $5, - $6, - $7 -) RETURNING id -` - -type CreateVenueParams struct { - Slug string - Name string - City string - SpotifyPlaylist string - Status Status - Statuses pgtype.Array[Status] - Tags pgtype.Array[string] -} - -func (q *Queries) CreateVenue(ctx context.Context, arg CreateVenueParams) (int32, error) { - row := q.db.QueryRow(ctx, createVenue, - arg.Slug, - arg.Name, - arg.City, - arg.SpotifyPlaylist, - arg.Status, - arg.Statuses, - arg.Tags, - ) - var id int32 - err := row.Scan(&id) - return id, err -} - -const deleteVenue = `-- name: DeleteVenue :exec -DELETE FROM venue -WHERE slug = $1 AND slug = $1 -` - -func (q *Queries) DeleteVenue(ctx context.Context, slug string) error { - _, err := q.db.Exec(ctx, deleteVenue, slug) - return err -} - -const getVenue = `-- name: GetVenue :one -SELECT id, status, statuses, slug, name, city, spotify_playlist, songkick_id, tags, created_at -FROM venue -WHERE slug = $1 AND city = $2 -` - -type GetVenueParams struct { - Slug string - City string -} - -func (q *Queries) GetVenue(ctx context.Context, arg GetVenueParams) (Venue, error) { - row := q.db.QueryRow(ctx, getVenue, arg.Slug, arg.City) - var i Venue - err := row.Scan( - &i.ID, - &i.Status, - &i.Statuses, - &i.Slug, - &i.Name, - &i.City, - &i.SpotifyPlaylist, - &i.SongkickID, - &i.Tags, - &i.CreatedAt, - ) - return i, err -} - -const listVenues = `-- name: ListVenues :many -SELECT id, status, statuses, slug, name, city, spotify_playlist, songkick_id, tags, created_at -FROM venue -WHERE city = $1 -ORDER BY name -` - -func (q *Queries) ListVenues(ctx context.Context, city string) ([]Venue, error) { - rows, err := q.db.Query(ctx, listVenues, city) - if err != nil { - return nil, err - } - defer rows.Close() - var items []Venue - for rows.Next() { - var i Venue - if err := rows.Scan( - &i.ID, - &i.Status, - &i.Statuses, - &i.Slug, - &i.Name, - &i.City, - &i.SpotifyPlaylist, - &i.SongkickID, - &i.Tags, - &i.CreatedAt, - ); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} - -const updateVenueName = `-- name: UpdateVenueName :one -UPDATE venue -SET name = $2 -WHERE slug = $1 -RETURNING id -` - -type UpdateVenueNameParams struct { - Slug string - Name string -} - -func (q *Queries) UpdateVenueName(ctx context.Context, arg UpdateVenueNameParams) (int32, error) { - row := q.db.QueryRow(ctx, updateVenueName, arg.Slug, arg.Name) - var id int32 - err := row.Scan(&id) - return id, err -} - -const venueCountByCity = `-- name: VenueCountByCity :many -SELECT - city, - count(*) -FROM venue -GROUP BY 1 -ORDER BY 1 -` - -type VenueCountByCityRow struct { - City string - Count int64 -} - -func (q *Queries) VenueCountByCity(ctx context.Context) ([]VenueCountByCityRow, error) { - rows, err := q.db.Query(ctx, venueCountByCity) - if err != nil { - return nil, err - } - defer rows.Close() - var items []VenueCountByCityRow - for rows.Next() { - var i VenueCountByCityRow - if err := rows.Scan(&i.City, &i.Count); err != nil { - return nil, err - } - items = append(items, i) - } - if err := rows.Err(); err != nil { - return nil, err - } - return items, nil -} diff --git a/internal/dao/slonik/ce/sqlc.yaml b/internal/dao/slonik/ce/sqlc.yaml index 230f8cb4..87c7a4fc 100644 --- a/internal/dao/slonik/ce/sqlc.yaml +++ b/internal/dao/slonik/ce/sqlc.yaml @@ -10,3 +10,5 @@ sql: sql_package: 'pgx/v5' emit_prepared_queries: true emit_interface: true + emit_result_struct_pointers: true + emit_params_struct_pointers: true diff --git a/internal/dao/slonik/pgx.go b/internal/dao/slonik/pgx.go index 60a52cf2..54ece04a 100644 --- a/internal/dao/slonik/pgx.go +++ b/internal/dao/slonik/pgx.go @@ -39,27 +39,27 @@ func (s *pgxServant) beingTx(ctx context.Context, txOptions pgx.TxOptions) (pgx. return tx, dbr.New(tx), nil } -func (s *pgxServant) with(handle func(dbr.Querier) error) error { +func (s *pgxServant) with(handle func(c context.Context, q dbr.Querier) error) error { ctx := context.Background() tx, err := s.db.Begin(ctx) if err != nil { return err } defer tx.Rollback(ctx) - if err = handle(dbr.New(tx)); err != nil { + if err = handle(ctx, dbr.New(tx)); err != nil { return err } return tx.Commit(ctx) } -func (s *pgxServant) withTx(txOptions pgx.TxOptions, handle func(dbr.Querier) error) error { +func (s *pgxServant) withTx(txOptions pgx.TxOptions, handle func(ctx context.Context, q dbr.Querier) error) error { ctx := context.Background() tx, err := s.db.BeginTx(ctx, txOptions) if err != nil { return err } defer tx.Rollback(ctx) - if err = handle(dbr.New(tx)); err != nil { + if err = handle(ctx, dbr.New(tx)); err != nil { return err } return tx.Commit(ctx) diff --git a/internal/dao/slonik/topics.go b/internal/dao/slonik/topics.go index 55a1cc31..28249f91 100644 --- a/internal/dao/slonik/topics.go +++ b/internal/dao/slonik/topics.go @@ -5,8 +5,12 @@ package slonik import ( + "context" + "strings" + "github.com/jackc/pgx/v5" "github.com/rocboss/paopao-ce/internal/core" + dbr "github.com/rocboss/paopao-ce/internal/dao/slonik/ce/postgres" "github.com/rocboss/paopao-ce/pkg/debug" ) @@ -20,26 +24,88 @@ type topicServant struct { func (s *topicServant) UpsertTags(userId int64, tags []string) ([]*core.Tag, error) { // TODO - debug.NotImplemented() - return nil, nil + return nil, debug.ErrNotImplemented } func (s *topicServant) DecrTagsById(ids []int64) error { - // TODO - debug.NotImplemented() - return nil + // return s.with(func(c context.Context, q dbr.Querier) error { + // tagIds, err := q.TagsByIdA(c, pgtype.Array[int64](ids)) + // if err != nil { + // return err + // } + // err := q.DecrTagsById(c, &dbr.DecrTagsByIdParams{ModifiedOn: time.Now().Unix(), Ids: tagIds}) + // if err != nil { + // return err + // } + // return nil + // }) + return debug.ErrNotImplemented } -func (s *topicServant) GetTags(category core.TagCategory, offset int, limit int) ([]*core.Tag, error) { - // TODO - debug.NotImplemented() - return nil, nil +func (s *topicServant) GetTags(category core.TagCategory, offset int, limit int) (res []*core.Tag, _ error) { + ctx := context.Background() + switch category { + case core.TagCategoryHot: + tags, err := s.q.HotTags(ctx, &dbr.HotTagsParams{Offset: int32(offset), Limit: int32(limit)}) + if err != nil { + return nil, err + } + for _, tag := range tags { + res = append(res, &core.Tag{ + ID: tag.ID, + UserID: tag.UserID, + Tag: tag.Tag, + QuoteNum: tag.QuoteNum, + }) + } + case core.TagCategoryNew: + tags, err := s.q.NewestTags(ctx, &dbr.NewestTagsParams{Offset: int32(offset), Limit: int32(limit)}) + if err != nil { + return nil, err + } + for _, tag := range tags { + res = append(res, &core.Tag{ + ID: tag.ID, + UserID: tag.UserID, + Tag: tag.Tag, + QuoteNum: tag.QuoteNum, + }) + } + } + return } -func (s *topicServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) { - // TODO - debug.NotImplemented() - return nil, nil +func (s *topicServant) GetTagsByKeyword(keyword string) (res []*core.Tag, _ error) { + ctx := context.Background() + keyword = "%" + strings.Trim(keyword, " ") + "%" + if keyword == "%%" { + tags, err := s.q.TagsByKeywordA(ctx) + if err != nil { + return nil, err + } + for _, tag := range tags { + res = append(res, &core.Tag{ + ID: tag.ID, + UserID: tag.UserID, + Tag: tag.Tag, + QuoteNum: tag.QuoteNum, + }) + } + } else { + tags, err := s.q.TagsByKeywordB(ctx, keyword) + if err != nil { + return nil, err + } + for _, tag := range tags { + res = append(res, &core.Tag{ + ID: tag.ID, + UserID: tag.UserID, + Tag: tag.Tag, + QuoteNum: tag.QuoteNum, + }) + } + } + return } func newTopicService(db *pgx.Conn) core.TopicService {