sqlc: impement topic data logic

r/paopao-ce-pro
Michael Li 2 years ago
parent bfef2fe7f9
commit 3f3cebed70
No known key found for this signature in database

@ -12,9 +12,9 @@ type PTag struct {
UserID int64
Tag string
QuoteNum int64
CreatedOn int32
ModifiedOn int32
DeletedOn int32
CreatedOn int64
ModifiedOn int64
DeletedOn int64
// 是否删除
IsDel bool
}

@ -6,21 +6,16 @@ package dbr
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
type Querier interface {
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)
IncrTags(ctx context.Context, arg *IncrTagsParams) ([]*IncrTagsRow, error)
InsertTags(ctx context.Context, arg *InsertTagsParams) (int64, 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)

@ -29,30 +29,26 @@ 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[]);
RETURNING id;
-- name: DecrTagsById :exec
UPDATE p_tag
SET quote_num = quote_num-1,
modified_on=$1
WHERE id = ANY(@ids::bigserial[]);
WHERE id IN (
SELECT id
FROM p_tag
WHERE id = ANY(@ids::bigserial[]) AND is_del = false AND quote_num >= 1
);
-- 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
-- name: IncrTags :many
UPDATE p_tag
SET quote_num = quote_num+1, modified_on = $1
WHERE id = ANY(@ids::bigserial[]);
SET quote_num = quote_num+1,
modified_on = $1,
id_del = false
WHERE id IN (
SELECT id
FROM p_tag
WHERE tag = ANY(@tags::varchar[])
)
RETURNING id, user_id, tag, quote_num;

@ -3,9 +3,9 @@ CREATE TABLE p_tag (
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,
created_on bigint NOT NULL DEFAULT 0,
modified_on bigint NOT NULL DEFAULT 0,
deleted_on bigint NOT NULL DEFAULT 0,
is_del boolean NOT NULL DEFAULT false,
UNIQUE (tag)
);

@ -15,11 +15,15 @@ const decrTagsById = `-- name: DecrTagsById :exec
UPDATE p_tag
SET quote_num = quote_num-1,
modified_on=$1
WHERE id = ANY($2::bigserial[])
WHERE id IN (
SELECT id
FROM p_tag
WHERE id = ANY($2::bigserial[]) AND is_del = false AND quote_num >= 1
)
`
type DecrTagsByIdParams struct {
ModifiedOn int32
ModifiedOn int64
Ids pgtype.Array[int64]
}
@ -73,82 +77,40 @@ func (q *Queries) HotTags(ctx context.Context, arg *HotTagsParams) ([]*HotTagsRo
return items, nil
}
const incrTagsById = `-- name: IncrTagsById :exec
const incrTags = `-- name: IncrTags :many
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)
SET quote_num = quote_num+1,
modified_on = $1,
id_del = false
WHERE id IN (
SELECT id
FROM p_tag
WHERE tag = ANY($2::varchar[])
)
RETURNING id, user_id, tag, quote_num
`
type InsertTagsParams struct {
UserID int64
Tag string
CreatedOn int32
type IncrTagsParams struct {
ModifiedOn int64
Tags pgtype.Array[string]
}
type InsertTagsRow struct {
type IncrTagsRow 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)
func (q *Queries) IncrTags(ctx context.Context, arg *IncrTagsParams) ([]*IncrTagsRow, error) {
rows, err := q.db.Query(ctx, incrTags, arg.ModifiedOn, arg.Tags)
if err != nil {
return nil, err
}
defer rows.Close()
var items []*NewestTagsRow
var items []*IncrTagsRow
for rows.Next() {
var i NewestTagsRow
var i IncrTagsRow
if err := rows.Scan(
&i.ID,
&i.UserID,
@ -165,54 +127,54 @@ func (q *Queries) NewestTags(ctx context.Context, arg *NewestTagsParams) ([]*New
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
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
`
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
type InsertTagsParams struct {
UserID int64
Tag string
CreatedOn int64
}
const tagsByIdB = `-- name: TagsByIdB :many
func (q *Queries) InsertTags(ctx context.Context, arg *InsertTagsParams) (int64, error) {
row := q.db.QueryRow(ctx, insertTags, arg.UserID, arg.Tag, arg.CreatedOn)
var id int64
err := row.Scan(&id)
return id, err
}
const newestTags = `-- name: NewestTags :many
SELECT id, user_id, tag, quote_num
FROM p_tag
WHERE id = ANY($1::bigserial[])
WHERE is_del = false AND quote_num > 0
ORDER BY id DESC
OFFSET $1 LIMIT $2
`
type TagsByIdBRow struct {
type NewestTagsParams struct {
Offset int32
Limit int32
}
type NewestTagsRow 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)
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 []*TagsByIdBRow
var items []*NewestTagsRow
for rows.Next() {
var i TagsByIdBRow
var i NewestTagsRow
if err := rows.Scan(
&i.ID,
&i.UserID,
@ -308,41 +270,3 @@ func (q *Queries) TagsByKeywordB(ctx context.Context, tag string) ([]*TagsByKeyw
}
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
}

@ -7,11 +7,12 @@ package slonik
import (
"context"
"strings"
"time"
"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"
"github.com/rocboss/paopao-ce/pkg/types"
)
var (
@ -22,24 +23,62 @@ type topicServant struct {
*pgxServant
}
func (s *topicServant) UpsertTags(userId int64, tags []string) ([]*core.Tag, error) {
// TODO
return nil, debug.ErrNotImplemented
// UpsertTags update/insert tags info.
// Assume tags slice is distinct elements.
func (s *topicServant) UpsertTags(userId int64, tags []string) (res []*core.Tag, err error) {
err = s.with(func(c context.Context, q dbr.Querier) error {
now := time.Now().Unix()
upTags, err := q.IncrTags(c, &dbr.IncrTagsParams{
Tags: types.PgxArray(tags),
ModifiedOn: now,
})
if err != nil {
return err
}
if len(upTags) > 0 {
for _, t := range upTags {
for i := 0; i < len(tags); {
if tags[i] == t.Tag {
latestIdx := len(tags) - 1
tags[i] = tags[latestIdx]
tags = tags[:latestIdx]
break
}
}
res = append(res, &core.Tag{
ID: t.ID,
UserID: t.UserID,
Tag: t.Tag,
QuoteNum: t.QuoteNum,
})
}
}
for _, tag := range tags {
id, err := q.InsertTags(c, &dbr.InsertTagsParams{
UserID: userId,
Tag: tag,
CreatedOn: now,
})
if err != nil {
return err
}
res = append(res, &core.Tag{
ID: id,
UserID: userId,
Tag: tag,
QuoteNum: 1,
})
}
return nil
})
return
}
func (s *topicServant) DecrTagsById(ids []int64) error {
// 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
return s.q.DecrTagsById(context.Background(), &dbr.DecrTagsByIdParams{
Ids: types.PgxArray(ids),
ModifiedOn: time.Now().Unix(),
})
}
func (s *topicServant) GetTags(category core.TagCategory, offset int, limit int) (res []*core.Tag, _ error) {

@ -4,8 +4,21 @@
package types
import (
"github.com/jackc/pgx/v5/pgtype"
)
// Empty empty alias type
type Empty = struct{}
// Fn empty argument func alias type
type Fn = func()
// PgxArray returns an object usable by pg drivers for passing a []T slice
// into a database as type T[].
func PgxArray[T any](elements []T) pgtype.Array[T] {
return pgtype.Array[T]{
Elements: elements,
Dims: []pgtype.ArrayDimension{{Length: int32(len(elements)), LowerBound: 1}},
}
}

Loading…
Cancel
Save