feat: implement core backend architecture and project management services for the History API
Build and Release / release (push) Successful in 1m33s
Build and Release / release (push) Successful in 1m33s
This commit is contained in:
@@ -2,8 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -66,14 +65,14 @@ func (r *battleReplayRepository) getByIDsWithFallback(ctx context.Context, ids [
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("battle_replay:id:%s", id)
|
||||
keys[i] = cache.Key("battle_replay:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var items []*models.BattleReplayEntity
|
||||
missingToCache := make(map[string]any)
|
||||
items := make([]*models.BattleReplayEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -84,7 +83,7 @@ func (r *battleReplayRepository) getByIDsWithFallback(ctx context.Context, ids [
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.BattleReplayEntity)
|
||||
dbMap := make(map[string]*models.BattleReplayEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetBattleReplaysByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -121,7 +120,7 @@ func (r *battleReplayRepository) GetByIDs(ctx context.Context, ids []string) ([]
|
||||
}
|
||||
|
||||
func (r *battleReplayRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.BattleReplayEntity, error) {
|
||||
cacheId := fmt.Sprintf("battle_replay:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("battle_replay:id", convert.UUIDToString(id))
|
||||
var item models.BattleReplayEntity
|
||||
err := r.c.Get(ctx, cacheId, &item)
|
||||
if err == nil {
|
||||
@@ -141,7 +140,7 @@ func (r *battleReplayRepository) GetByID(ctx context.Context, id pgtype.UUID) (*
|
||||
}
|
||||
|
||||
func (r *battleReplayRepository) GetByGeometryID(ctx context.Context, geometryID pgtype.UUID) ([]*models.BattleReplayEntity, error) {
|
||||
cacheKey := fmt.Sprintf("battle_replay:geometry:%s", convert.UUIDToString(geometryID))
|
||||
cacheKey := cache.Key("battle_replay:geometry", convert.UUIDToString(geometryID))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, cacheKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -156,15 +155,15 @@ func (r *battleReplayRepository) GetByGeometryID(ctx context.Context, geometryID
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var items []*models.BattleReplayEntity
|
||||
var ids []string
|
||||
itemToCache := make(map[string]any)
|
||||
items := make([]*models.BattleReplayEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
itemToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
item := r.rowToEntity(row)
|
||||
ids = append(ids, item.ID)
|
||||
items = append(items, item)
|
||||
itemToCache[fmt.Sprintf("battle_replay:id:%s", item.ID)] = item
|
||||
itemToCache[cache.Key("battle_replay:id", item.ID)] = item
|
||||
}
|
||||
|
||||
if len(itemToCache) > 0 {
|
||||
@@ -180,7 +179,7 @@ func (r *battleReplayRepository) GetByGeometryIDs(ctx context.Context, geometryI
|
||||
return []*models.BattleReplayEntity{}, nil
|
||||
}
|
||||
|
||||
var pgIds []pgtype.UUID
|
||||
pgIds := make([]pgtype.UUID, 0, len(geometryIDs))
|
||||
for _, id := range geometryIDs {
|
||||
pgId := pgtype.UUID{}
|
||||
if err := pgId.Scan(id); err == nil {
|
||||
@@ -193,13 +192,13 @@ func (r *battleReplayRepository) GetByGeometryIDs(ctx context.Context, geometryI
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var items []*models.BattleReplayEntity
|
||||
itemToCache := make(map[string]any)
|
||||
items := make([]*models.BattleReplayEntity, 0, len(rows))
|
||||
itemToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
item := r.rowToEntity(row)
|
||||
items = append(items, item)
|
||||
itemToCache[fmt.Sprintf("battle_replay:id:%s", item.ID)] = item
|
||||
itemToCache[cache.Key("battle_replay:id", item.ID)] = item
|
||||
}
|
||||
|
||||
if len(itemToCache) > 0 {
|
||||
@@ -210,7 +209,7 @@ func (r *battleReplayRepository) GetByGeometryIDs(ctx context.Context, geometryI
|
||||
}
|
||||
|
||||
func (r *battleReplayRepository) GetByProjectID(ctx context.Context, projectID pgtype.UUID) ([]*models.BattleReplayEntity, error) {
|
||||
cacheKey := fmt.Sprintf("battle_replay:project:%s", convert.UUIDToString(projectID))
|
||||
cacheKey := cache.Key("battle_replay:project", convert.UUIDToString(projectID))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, cacheKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -225,15 +224,15 @@ func (r *battleReplayRepository) GetByProjectID(ctx context.Context, projectID p
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var items []*models.BattleReplayEntity
|
||||
var ids []string
|
||||
itemToCache := make(map[string]any)
|
||||
items := make([]*models.BattleReplayEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
itemToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
item := r.rowToEntity(row)
|
||||
ids = append(ids, item.ID)
|
||||
items = append(items, item)
|
||||
itemToCache[fmt.Sprintf("battle_replay:id:%s", item.ID)] = item
|
||||
itemToCache[cache.Key("battle_replay:id", item.ID)] = item
|
||||
}
|
||||
|
||||
if len(itemToCache) > 0 {
|
||||
@@ -252,8 +251,8 @@ func (r *battleReplayRepository) Create(ctx context.Context, params sqlc.CreateB
|
||||
|
||||
entity := r.rowToEntity(row)
|
||||
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("battle_replay:project:%s", entity.ProjectID))
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("battle_replay:geometry:%s", entity.GeometryID))
|
||||
_ = r.c.Del(ctx, cache.Key("battle_replay:project", entity.ProjectID))
|
||||
_ = r.c.Del(ctx, cache.Key("battle_replay:geometry", entity.GeometryID))
|
||||
|
||||
return entity, nil
|
||||
}
|
||||
@@ -265,7 +264,7 @@ func (r *battleReplayRepository) Update(ctx context.Context, params sqlc.UpdateB
|
||||
}
|
||||
|
||||
entity := r.rowToEntity(row)
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("battle_replay:id:%s", entity.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("battle_replay:id", entity.ID))
|
||||
return entity, nil
|
||||
}
|
||||
|
||||
@@ -274,7 +273,7 @@ func (r *battleReplayRepository) Delete(ctx context.Context, id pgtype.UUID) err
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("battle_replay:id:%s", convert.UUIDToString(id)))
|
||||
_ = r.c.Del(ctx, cache.Key("battle_replay:id", convert.UUIDToString(id)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -286,7 +285,7 @@ func (r *battleReplayRepository) DeleteByIDs(ctx context.Context, ids []pgtype.U
|
||||
if len(ids) > 0 {
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("battle_replay:id:%s", convert.UUIDToString(id))
|
||||
keys[i] = cache.Key("battle_replay:id", convert.UUIDToString(id))
|
||||
}
|
||||
_ = r.c.Del(ctx, keys...)
|
||||
}
|
||||
|
||||
@@ -2,14 +2,13 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"history-api/internal/gen/sqlc"
|
||||
"history-api/internal/models"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"history-api/pkg/convert"
|
||||
json "history-api/pkg/jsonx"
|
||||
"strconv"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
@@ -39,9 +38,7 @@ func NewChatRepository(db *pgxpool.Pool, c cache.Cache) ChatRepository {
|
||||
}
|
||||
|
||||
func (r *chatRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:query:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *chatRepository) getConversationsByIDsWithFallback(ctx context.Context, ids []string) ([]*models.ConversationEntity, error) {
|
||||
@@ -50,14 +47,14 @@ func (r *chatRepository) getConversationsByIDsWithFallback(ctx context.Context,
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("conversation:id:%s", id)
|
||||
keys[i] = cache.Key("conversation:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var results []*models.ConversationEntity
|
||||
missingToCache := make(map[string]any)
|
||||
results := make([]*models.ConversationEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -68,7 +65,7 @@ func (r *chatRepository) getConversationsByIDsWithFallback(ctx context.Context,
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.ConversationEntity)
|
||||
dbMap := make(map[string]*models.ConversationEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetConversationsByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -114,14 +111,14 @@ func (r *chatRepository) getMessagesByIDsWithFallback(ctx context.Context, ids [
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("message:id:%s", id)
|
||||
keys[i] = cache.Key("message:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var results []*models.MessageEntity
|
||||
missingToCache := make(map[string]any)
|
||||
results := make([]*models.MessageEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -132,7 +129,7 @@ func (r *chatRepository) getMessagesByIDsWithFallback(ctx context.Context, ids [
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.MessageEntity)
|
||||
dbMap := make(map[string]*models.MessageEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetMessagesByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -176,14 +173,14 @@ func (r *chatRepository) getChatbotHistoriesByIDsWithFallback(ctx context.Contex
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("chatbot_history:id:%s", id)
|
||||
keys[i] = cache.Key("chatbot_history:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var results []*models.ChatbotHistoryEntity
|
||||
missingToCache := make(map[string]any)
|
||||
results := make([]*models.ChatbotHistoryEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -194,7 +191,7 @@ func (r *chatRepository) getChatbotHistoriesByIDsWithFallback(ctx context.Contex
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.ChatbotHistoryEntity)
|
||||
dbMap := make(map[string]*models.ChatbotHistoryEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetChatbotHistoriesByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -263,7 +260,7 @@ func (r *chatRepository) UpdateConversationStatus(ctx context.Context, params sq
|
||||
CreatedAt: convert.TimeToPtr(row.CreatedAt),
|
||||
UpdatedAt: convert.TimeToPtr(row.UpdatedAt),
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("conversation:id:%s", entity.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("conversation:id", entity.ID))
|
||||
return entity, nil
|
||||
}
|
||||
|
||||
@@ -299,9 +296,9 @@ func (r *chatRepository) GetMessagesByConversation(ctx context.Context, params s
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var results []*models.MessageEntity
|
||||
var ids []string
|
||||
toCache := make(map[string]any)
|
||||
results := make([]*models.MessageEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
toCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
item := &models.MessageEntity{
|
||||
@@ -313,7 +310,7 @@ func (r *chatRepository) GetMessagesByConversation(ctx context.Context, params s
|
||||
}
|
||||
ids = append(ids, item.ID)
|
||||
results = append(results, item)
|
||||
toCache[fmt.Sprintf("message:id:%s", item.ID)] = item
|
||||
toCache[cache.Key("message:id", item.ID)] = item
|
||||
}
|
||||
|
||||
if len(toCache) > 0 {
|
||||
@@ -341,7 +338,7 @@ func (r *chatRepository) CreateChatbotHistory(ctx context.Context, params sqlc.C
|
||||
go func() {
|
||||
userId := convert.UUIDToString(params.UserID)
|
||||
if userId != "" {
|
||||
_ = r.c.DelByPattern(context.Background(), fmt.Sprintf("chatbot_history:userId:%s:*", userId))
|
||||
_ = r.c.DelByPattern(context.Background(), "chatbot_history:userId:"+userId+":*")
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -349,12 +346,9 @@ func (r *chatRepository) CreateChatbotHistory(ctx context.Context, params sqlc.C
|
||||
}
|
||||
|
||||
func (r *chatRepository) GetChatbotHistory(ctx context.Context, params sqlc.GetChatbotHistoryParams) ([]*models.ChatbotHistoryEntity, error) {
|
||||
queryKey := fmt.Sprintf(
|
||||
"chatbot_history:userId:%s:limit:%d:cursor:%s",
|
||||
convert.UUIDToString(params.UserID),
|
||||
params.Limit,
|
||||
convert.UUIDToString(params.CursorID),
|
||||
)
|
||||
queryKey := "chatbot_history:userId:" + convert.UUIDToString(params.UserID) +
|
||||
":limit:" + strconv.Itoa(int(params.Limit)) +
|
||||
":cursor:" + convert.UUIDToString(params.CursorID)
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, queryKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -369,9 +363,9 @@ func (r *chatRepository) GetChatbotHistory(ctx context.Context, params sqlc.GetC
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var results []*models.ChatbotHistoryEntity
|
||||
var ids []string
|
||||
toCache := make(map[string]any)
|
||||
results := make([]*models.ChatbotHistoryEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
toCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
item := &models.ChatbotHistoryEntity{
|
||||
@@ -383,7 +377,7 @@ func (r *chatRepository) GetChatbotHistory(ctx context.Context, params sqlc.GetC
|
||||
}
|
||||
ids = append(ids, item.ID)
|
||||
results = append(results, item)
|
||||
toCache[fmt.Sprintf("chatbot_history:id:%s", item.ID)] = item
|
||||
toCache[cache.Key("chatbot_history:id", item.ID)] = item
|
||||
}
|
||||
|
||||
if len(toCache) > 0 {
|
||||
|
||||
@@ -2,14 +2,13 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"history-api/internal/gen/sqlc"
|
||||
"history-api/internal/models"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"history-api/pkg/convert"
|
||||
"history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -62,7 +61,7 @@ func (r *commitRepository) Create(ctx context.Context, params sqlc.CreateCommitP
|
||||
}
|
||||
|
||||
func (r *commitRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.CommitEntity, error) {
|
||||
cacheId := fmt.Sprintf("commit:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("commit:id", convert.UUIDToString(id))
|
||||
var commit models.CommitEntity
|
||||
err := r.c.Get(ctx, cacheId, &commit)
|
||||
if err == nil {
|
||||
@@ -92,9 +91,7 @@ func (r *commitRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models
|
||||
}
|
||||
|
||||
func (r *commitRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:query:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *commitRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.CommitEntity, error) {
|
||||
@@ -103,14 +100,14 @@ func (r *commitRepository) getByIDsWithFallback(ctx context.Context, ids []strin
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("commit:id:%s", id)
|
||||
keys[i] = cache.Key("commit:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var commits []*models.CommitEntity
|
||||
missingToCache := make(map[string]any)
|
||||
commits := make([]*models.CommitEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -121,7 +118,7 @@ func (r *commitRepository) getByIDsWithFallback(ctx context.Context, ids []strin
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.CommitEntity)
|
||||
dbMap := make(map[string]*models.CommitEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetCommitsByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -144,7 +141,7 @@ func (r *commitRepository) getByIDsWithFallback(ctx context.Context, ids []strin
|
||||
for i, b := range raws {
|
||||
if len(b) > 0 {
|
||||
var c models.CommitEntity
|
||||
if err := json.Unmarshal(b, &c); err == nil {
|
||||
if err := jsonx.Unmarshal(b, &c); err == nil {
|
||||
commits = append(commits, &c)
|
||||
}
|
||||
} else {
|
||||
@@ -163,7 +160,7 @@ func (r *commitRepository) getByIDsWithFallback(ctx context.Context, ids []strin
|
||||
}
|
||||
|
||||
func (r *commitRepository) GetByProjectID(ctx context.Context, projectID pgtype.UUID) ([]*models.CommitEntity, error) {
|
||||
queryKey := fmt.Sprintf("commit:project:%s", convert.UUIDToString(projectID))
|
||||
queryKey := cache.Key("commit:project", convert.UUIDToString(projectID))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, queryKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -180,7 +177,7 @@ func (r *commitRepository) GetByProjectID(ctx context.Context, projectID pgtype.
|
||||
|
||||
entities := make([]*models.CommitEntity, 0, len(rows))
|
||||
ids := make([]string, len(rows))
|
||||
commitToCache := make(map[string]any)
|
||||
commitToCache := make(map[string]any, len(rows))
|
||||
for i, row := range rows {
|
||||
item := &models.CommitEntity{
|
||||
ID: convert.UUIDToString(row.ID),
|
||||
@@ -194,7 +191,7 @@ func (r *commitRepository) GetByProjectID(ctx context.Context, projectID pgtype.
|
||||
}
|
||||
entities = append(entities, item)
|
||||
ids[i] = item.ID
|
||||
commitToCache[fmt.Sprintf("commit:id:%s", item.ID)] = item
|
||||
commitToCache[cache.Key("commit:id", item.ID)] = item
|
||||
}
|
||||
if len(commitToCache) > 0 {
|
||||
_ = r.c.MSet(ctx, commitToCache, constants.NormalCacheDuration)
|
||||
@@ -217,9 +214,9 @@ func (r *commitRepository) Search(ctx context.Context, params sqlc.SearchCommits
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var commits []*models.CommitEntity
|
||||
var ids []string
|
||||
commitToCache := make(map[string]any)
|
||||
commits := make([]*models.CommitEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
commitToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
commit := &models.CommitEntity{
|
||||
@@ -234,7 +231,7 @@ func (r *commitRepository) Search(ctx context.Context, params sqlc.SearchCommits
|
||||
}
|
||||
ids = append(ids, commit.ID)
|
||||
commits = append(commits, commit)
|
||||
commitToCache[fmt.Sprintf("commit:id:%s", commit.ID)] = commit
|
||||
commitToCache[cache.Key("commit:id", commit.ID)] = commit
|
||||
}
|
||||
|
||||
if len(commitToCache) > 0 {
|
||||
@@ -253,7 +250,7 @@ func (r *commitRepository) UpdateSnapshot(ctx context.Context, id pgtype.UUID, s
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r.c.Del(ctx, fmt.Sprintf("commit:id:%s", convert.UUIDToString(id)))
|
||||
r.c.Del(ctx, cache.Key("commit:id", convert.UUIDToString(id)))
|
||||
|
||||
return &models.CommitEntity{
|
||||
ID: convert.UUIDToString(row.ID),
|
||||
|
||||
@@ -2,9 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -51,9 +49,7 @@ func (r *entityRepository) WithTx(tx pgx.Tx) EntityRepository {
|
||||
}
|
||||
|
||||
func (r *entityRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *entityRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.EntityEntity, error) {
|
||||
@@ -62,14 +58,14 @@ func (r *entityRepository) getByIDsWithFallback(ctx context.Context, ids []strin
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("entity:id:%s", id)
|
||||
keys[i] = cache.Key("entity:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var entities []*models.EntityEntity
|
||||
missingToCache := make(map[string]any)
|
||||
entities := make([]*models.EntityEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -80,7 +76,7 @@ func (r *entityRepository) getByIDsWithFallback(ctx context.Context, ids []strin
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.EntityEntity)
|
||||
dbMap := make(map[string]*models.EntityEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetEntitiesByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -129,7 +125,7 @@ func (r *entityRepository) GetByIDs(ctx context.Context, ids []string) ([]*model
|
||||
}
|
||||
|
||||
func (r *entityRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.EntityEntity, error) {
|
||||
cacheId := fmt.Sprintf("entity:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("entity:id", convert.UUIDToString(id))
|
||||
var entity models.EntityEntity
|
||||
err := r.c.Get(ctx, cacheId, &entity)
|
||||
if err == nil {
|
||||
@@ -175,9 +171,9 @@ func (r *entityRepository) Search(ctx context.Context, params sqlc.SearchEntitie
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var entities []*models.EntityEntity
|
||||
var ids []string
|
||||
entityToCache := make(map[string]any)
|
||||
entities := make([]*models.EntityEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
entityToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
entity := &models.EntityEntity{
|
||||
@@ -195,7 +191,7 @@ func (r *entityRepository) Search(ctx context.Context, params sqlc.SearchEntitie
|
||||
}
|
||||
ids = append(ids, entity.ID)
|
||||
entities = append(entities, entity)
|
||||
entityToCache[fmt.Sprintf("entity:id:%s", entity.ID)] = entity
|
||||
entityToCache[cache.Key("entity:id", entity.ID)] = entity
|
||||
}
|
||||
|
||||
if len(entityToCache) > 0 {
|
||||
@@ -248,8 +244,7 @@ func (r *entityRepository) Update(ctx context.Context, params sqlc.UpdateEntityP
|
||||
CreatedAt: convert.TimeToPtr(row.CreatedAt),
|
||||
UpdatedAt: convert.TimeToPtr(row.UpdatedAt),
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("entity:id:%s", entity.ID))
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("entity:slug:%s", entity.Slug))
|
||||
_ = r.c.Del(ctx, cache.Key("entity:id", entity.ID), cache.Key("entity:slug", entity.Slug))
|
||||
return &entity, nil
|
||||
}
|
||||
|
||||
@@ -258,12 +253,12 @@ func (r *entityRepository) Delete(ctx context.Context, id pgtype.UUID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("entity:id:%s", convert.UUIDToString(id)))
|
||||
_ = r.c.Del(ctx, cache.Key("entity:id", convert.UUIDToString(id)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *entityRepository) GetByProjectID(ctx context.Context, projectID pgtype.UUID) ([]*models.EntityEntity, error) {
|
||||
cacheKey := fmt.Sprintf("entity:project:%s", convert.UUIDToString(projectID))
|
||||
cacheKey := cache.Key("entity:project", convert.UUIDToString(projectID))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, cacheKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -278,9 +273,9 @@ func (r *entityRepository) GetByProjectID(ctx context.Context, projectID pgtype.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var entities []*models.EntityEntity
|
||||
var ids []string
|
||||
entityToCache := make(map[string]any)
|
||||
entities := make([]*models.EntityEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
entityToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
entity := &models.EntityEntity{
|
||||
@@ -298,7 +293,7 @@ func (r *entityRepository) GetByProjectID(ctx context.Context, projectID pgtype.
|
||||
}
|
||||
ids = append(ids, entity.ID)
|
||||
entities = append(entities, entity)
|
||||
entityToCache[fmt.Sprintf("entity:id:%s", entity.ID)] = entity
|
||||
entityToCache[cache.Key("entity:id", entity.ID)] = entity
|
||||
}
|
||||
|
||||
if len(entityToCache) > 0 {
|
||||
@@ -317,7 +312,7 @@ func (r *entityRepository) DeleteByIDs(ctx context.Context, ids []pgtype.UUID) e
|
||||
if len(ids) > 0 {
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("entity:id:%s", convert.UUIDToString(id))
|
||||
keys[i] = cache.Key("entity:id", convert.UUIDToString(id))
|
||||
}
|
||||
_ = r.c.Del(ctx, keys...)
|
||||
}
|
||||
@@ -325,7 +320,7 @@ func (r *entityRepository) DeleteByIDs(ctx context.Context, ids []pgtype.UUID) e
|
||||
}
|
||||
|
||||
func (r *entityRepository) GetBySlug(ctx context.Context, slug string) (*models.EntityEntity, error) {
|
||||
cacheKey := fmt.Sprintf("entity:slug:%s", slug)
|
||||
cacheKey := cache.Key("entity:slug", slug)
|
||||
var entity models.EntityEntity
|
||||
err := r.c.Get(ctx, cacheKey, &entity)
|
||||
if err == nil {
|
||||
@@ -362,13 +357,13 @@ func (r *entityRepository) GetBySlugs(ctx context.Context, slugs []string) ([]*m
|
||||
}
|
||||
keys := make([]string, len(slugs))
|
||||
for i, slug := range slugs {
|
||||
keys[i] = fmt.Sprintf("entity:slug:%s", slug)
|
||||
keys[i] = cache.Key("entity:slug", slug)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var entities []*models.EntityEntity
|
||||
missingToCache := make(map[string]any)
|
||||
var missingSlugs []string
|
||||
entities := make([]*models.EntityEntity, 0, len(slugs))
|
||||
missingToCache := make(map[string]any, len(slugs))
|
||||
missingSlugs := make([]string, 0, len(slugs))
|
||||
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
@@ -376,7 +371,7 @@ func (r *entityRepository) GetBySlugs(ctx context.Context, slugs []string) ([]*m
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.EntityEntity)
|
||||
dbMap := make(map[string]*models.EntityEntity, len(missingSlugs))
|
||||
if len(missingSlugs) > 0 {
|
||||
dbRows, err := r.q.GetEntitiesBySlugs(ctx, missingSlugs)
|
||||
if err == nil {
|
||||
@@ -427,13 +422,13 @@ func (r *entityRepository) GetEntityIDsByGeometryIDs(ctx context.Context, geomet
|
||||
|
||||
keys := make([]string, len(geometryIDs))
|
||||
for i, id := range geometryIDs {
|
||||
keys[i] = fmt.Sprintf("entity_geometries:geometry:%s", id)
|
||||
keys[i] = cache.Key("entity_geometries:geometry", id)
|
||||
}
|
||||
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
result := make(map[string][]string)
|
||||
var missingGeometryIDs []string
|
||||
var missingPgIDs []pgtype.UUID
|
||||
result := make(map[string][]string, len(geometryIDs))
|
||||
missingGeometryIDs := make([]string, 0, len(geometryIDs))
|
||||
missingPgIDs := make([]pgtype.UUID, 0, len(geometryIDs))
|
||||
|
||||
for i, b := range raws {
|
||||
if len(b) > 0 {
|
||||
@@ -456,7 +451,7 @@ func (r *entityRepository) GetEntityIDsByGeometryIDs(ctx context.Context, geomet
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbMap := make(map[string][]string)
|
||||
dbMap := make(map[string][]string, len(missingGeometryIDs))
|
||||
for _, id := range missingGeometryIDs {
|
||||
dbMap[id] = []string{}
|
||||
}
|
||||
@@ -466,10 +461,10 @@ func (r *entityRepository) GetEntityIDsByGeometryIDs(ctx context.Context, geomet
|
||||
dbMap[gID] = append(dbMap[gID], eID)
|
||||
}
|
||||
|
||||
missingToCache := make(map[string]any)
|
||||
missingToCache := make(map[string]any, len(dbMap))
|
||||
for gID, eIDs := range dbMap {
|
||||
result[gID] = eIDs
|
||||
missingToCache[fmt.Sprintf("entity_geometries:geometry:%s", gID)] = eIDs
|
||||
missingToCache[cache.Key("entity_geometries:geometry", gID)] = eIDs
|
||||
}
|
||||
if len(missingToCache) > 0 {
|
||||
_ = r.c.MSet(ctx, missingToCache, constants.NormalCacheDuration)
|
||||
|
||||
@@ -2,9 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
json "history-api/pkg/jsonx"
|
||||
"strings"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -60,9 +58,7 @@ func (r *geometryRepository) WithTx(tx pgx.Tx) GeometryRepository {
|
||||
}
|
||||
|
||||
func (r *geometryRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *geometryRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.GeometryEntity, error) {
|
||||
@@ -71,14 +67,14 @@ func (r *geometryRepository) getByIDsWithFallback(ctx context.Context, ids []str
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("geometry:id:%s", id)
|
||||
keys[i] = cache.Key("geometry:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var geometries []*models.GeometryEntity
|
||||
missingToCache := make(map[string]any)
|
||||
geometries := make([]*models.GeometryEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -89,7 +85,7 @@ func (r *geometryRepository) getByIDsWithFallback(ctx context.Context, ids []str
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.GeometryEntity)
|
||||
dbMap := make(map[string]*models.GeometryEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetGeometriesByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -143,7 +139,7 @@ func (r *geometryRepository) GetByIDs(ctx context.Context, ids []string) ([]*mod
|
||||
}
|
||||
|
||||
func (r *geometryRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.GeometryEntity, error) {
|
||||
cacheId := fmt.Sprintf("geometry:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("geometry:id", convert.UUIDToString(id))
|
||||
var geometry models.GeometryEntity
|
||||
err := r.c.Get(ctx, cacheId, &geometry)
|
||||
if err == nil {
|
||||
@@ -194,9 +190,9 @@ func (r *geometryRepository) Search(ctx context.Context, params sqlc.SearchGeome
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var geometries []*models.GeometryEntity
|
||||
var ids []string
|
||||
geometryToCache := make(map[string]any)
|
||||
geometries := make([]*models.GeometryEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
geometryToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
geometry := &models.GeometryEntity{
|
||||
@@ -219,7 +215,7 @@ func (r *geometryRepository) Search(ctx context.Context, params sqlc.SearchGeome
|
||||
}
|
||||
ids = append(ids, geometry.ID)
|
||||
geometries = append(geometries, geometry)
|
||||
geometryToCache[fmt.Sprintf("geometry:id:%s", geometry.ID)] = geometry
|
||||
geometryToCache[cache.Key("geometry:id", geometry.ID)] = geometry
|
||||
}
|
||||
|
||||
if len(geometryToCache) > 0 {
|
||||
@@ -281,7 +277,7 @@ func (r *geometryRepository) Update(ctx context.Context, params sqlc.UpdateGeome
|
||||
CreatedAt: convert.TimeToPtr(row.CreatedAt),
|
||||
UpdatedAt: convert.TimeToPtr(row.UpdatedAt),
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("geometry:id:%s", geometry.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("geometry:id", geometry.ID))
|
||||
return &geometry, nil
|
||||
}
|
||||
|
||||
@@ -290,7 +286,7 @@ func (r *geometryRepository) Delete(ctx context.Context, id pgtype.UUID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("geometry:id:%s", convert.UUIDToString(id)))
|
||||
_ = r.c.Del(ctx, cache.Key("geometry:id", convert.UUIDToString(id)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -311,7 +307,7 @@ func (r *geometryRepository) BulkDeleteEntityGeometriesByEntityId(ctx context.Co
|
||||
}
|
||||
|
||||
func (r *geometryRepository) GetByProjectID(ctx context.Context, projectID pgtype.UUID) ([]*models.GeometryEntity, error) {
|
||||
cacheKey := fmt.Sprintf("geometry:project:%s", convert.UUIDToString(projectID))
|
||||
cacheKey := cache.Key("geometry:project", convert.UUIDToString(projectID))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, cacheKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -326,9 +322,9 @@ func (r *geometryRepository) GetByProjectID(ctx context.Context, projectID pgtyp
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var geometries []*models.GeometryEntity
|
||||
var ids []string
|
||||
geometryToCache := make(map[string]any)
|
||||
geometries := make([]*models.GeometryEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
geometryToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
geometry := &models.GeometryEntity{
|
||||
@@ -351,7 +347,7 @@ func (r *geometryRepository) GetByProjectID(ctx context.Context, projectID pgtyp
|
||||
}
|
||||
ids = append(ids, geometry.ID)
|
||||
geometries = append(geometries, geometry)
|
||||
geometryToCache[fmt.Sprintf("geometry:id:%s", geometry.ID)] = geometry
|
||||
geometryToCache[cache.Key("geometry:id", geometry.ID)] = geometry
|
||||
}
|
||||
|
||||
if len(geometryToCache) > 0 {
|
||||
@@ -363,7 +359,7 @@ func (r *geometryRepository) GetByProjectID(ctx context.Context, projectID pgtyp
|
||||
}
|
||||
|
||||
func (r *geometryRepository) GetGeometriesByBoundWith(ctx context.Context, boundWith pgtype.UUID) ([]*models.GeometryEntity, error) {
|
||||
cacheKey := fmt.Sprintf("geometry:bound_with:%s", convert.UUIDToString(boundWith))
|
||||
cacheKey := cache.Key("geometry:bound_with", convert.UUIDToString(boundWith))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, cacheKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -378,9 +374,9 @@ func (r *geometryRepository) GetGeometriesByBoundWith(ctx context.Context, bound
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var geometries []*models.GeometryEntity
|
||||
var ids []string
|
||||
geometryToCache := make(map[string]any)
|
||||
geometries := make([]*models.GeometryEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
geometryToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
geometry := &models.GeometryEntity{
|
||||
@@ -403,7 +399,7 @@ func (r *geometryRepository) GetGeometriesByBoundWith(ctx context.Context, bound
|
||||
}
|
||||
ids = append(ids, geometry.ID)
|
||||
geometries = append(geometries, geometry)
|
||||
geometryToCache[fmt.Sprintf("geometry:id:%s", geometry.ID)] = geometry
|
||||
geometryToCache[cache.Key("geometry:id", geometry.ID)] = geometry
|
||||
}
|
||||
|
||||
if len(geometryToCache) > 0 {
|
||||
@@ -421,7 +417,7 @@ func (r *geometryRepository) DeleteByIDs(ctx context.Context, ids []pgtype.UUID)
|
||||
if len(ids) > 0 {
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("geometry:id:%s", convert.UUIDToString(id))
|
||||
keys[i] = cache.Key("geometry:id", convert.UUIDToString(id))
|
||||
}
|
||||
_ = r.c.Del(ctx, keys...)
|
||||
}
|
||||
@@ -445,15 +441,15 @@ func (r *geometryRepository) getSearchByIDsWithFallback(ctx context.Context, pai
|
||||
}
|
||||
keys := make([]string, len(pairs))
|
||||
for i, pair := range pairs {
|
||||
keys[i] = fmt.Sprintf("geometry:search:item:%s", pair)
|
||||
keys[i] = cache.Key("geometry:search:item", pair)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var results []*models.EntityGeometriesSearchEntity
|
||||
missingToCache := make(map[string]any)
|
||||
results := make([]*models.EntityGeometriesSearchEntity, 0, len(pairs))
|
||||
missingToCache := make(map[string]any, len(pairs))
|
||||
|
||||
var missingEntityIds []pgtype.UUID
|
||||
var missingGeometryIds []pgtype.UUID
|
||||
missingEntityIds := make([]pgtype.UUID, 0, len(pairs))
|
||||
missingGeometryIds := make([]pgtype.UUID, 0, len(pairs))
|
||||
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
@@ -471,7 +467,7 @@ func (r *geometryRepository) getSearchByIDsWithFallback(ctx context.Context, pai
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.EntityGeometriesSearchEntity)
|
||||
dbMap := make(map[string]*models.EntityGeometriesSearchEntity, len(missingEntityIds))
|
||||
if len(missingEntityIds) > 0 {
|
||||
dbRows, err := r.q.GetEntityGeometriesByPairs(ctx, sqlc.GetEntityGeometriesByPairsParams{
|
||||
EntityIds: missingEntityIds,
|
||||
@@ -490,7 +486,7 @@ func (r *geometryRepository) getSearchByIDsWithFallback(ctx context.Context, pai
|
||||
TimeStart: convert.Int4ToPtr(row.TimeStart),
|
||||
TimeEnd: convert.Int4ToPtr(row.TimeEnd),
|
||||
}
|
||||
key := fmt.Sprintf("%s:%s", item.EntityID, item.GeometryID)
|
||||
key := cache.Key(item.EntityID, item.GeometryID)
|
||||
dbMap[key] = item
|
||||
}
|
||||
}
|
||||
@@ -533,9 +529,9 @@ func (r *geometryRepository) SearchByEntityName(ctx context.Context, params sqlc
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var geometries []*models.EntityGeometriesSearchEntity
|
||||
var pairs []string
|
||||
geometryToCache := make(map[string]any)
|
||||
geometries := make([]*models.EntityGeometriesSearchEntity, 0, len(rows))
|
||||
pairs := make([]string, 0, len(rows))
|
||||
geometryToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
item := &models.EntityGeometriesSearchEntity{
|
||||
@@ -549,10 +545,10 @@ func (r *geometryRepository) SearchByEntityName(ctx context.Context, params sqlc
|
||||
TimeStart: convert.Int4ToPtr(row.TimeStart),
|
||||
TimeEnd: convert.Int4ToPtr(row.TimeEnd),
|
||||
}
|
||||
pair := fmt.Sprintf("%s:%s", item.EntityID, item.GeometryID)
|
||||
pair := cache.Key(item.EntityID, item.GeometryID)
|
||||
geometries = append(geometries, item)
|
||||
pairs = append(pairs, pair)
|
||||
geometryToCache[fmt.Sprintf("geometry:search:item:%s", pair)] = item
|
||||
geometryToCache[cache.Key("geometry:search:item", pair)] = item
|
||||
}
|
||||
|
||||
if len(geometryToCache) > 0 {
|
||||
|
||||
@@ -2,14 +2,12 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"history-api/internal/gen/sqlc"
|
||||
"history-api/internal/models"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"history-api/pkg/convert"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -47,9 +45,7 @@ func (r *mediaRepository) WithTx(tx pgx.Tx) MediaRepository {
|
||||
}
|
||||
|
||||
func (r *mediaRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *mediaRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.MediaEntity, error) {
|
||||
@@ -58,14 +54,14 @@ func (r *mediaRepository) getByIDsWithFallback(ctx context.Context, ids []string
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("media:id:%s", id)
|
||||
keys[i] = cache.Key("media:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var medias []*models.MediaEntity
|
||||
missingMediasToCache := make(map[string]any)
|
||||
medias := make([]*models.MediaEntity, 0, len(ids))
|
||||
missingMediasToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -76,7 +72,7 @@ func (r *mediaRepository) getByIDsWithFallback(ctx context.Context, ids []string
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.MediaEntity)
|
||||
dbMap := make(map[string]*models.MediaEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetMediaByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -123,7 +119,7 @@ func (r *mediaRepository) GetByIDs(ctx context.Context, ids []string) ([]*models
|
||||
}
|
||||
|
||||
func (r *mediaRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.MediaEntity, error) {
|
||||
cacheId := fmt.Sprintf("media:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("media:id", convert.UUIDToString(id))
|
||||
var media models.MediaEntity
|
||||
err := r.c.Get(ctx, cacheId, &media)
|
||||
if err == nil {
|
||||
@@ -165,7 +161,7 @@ func (r *mediaRepository) Create(ctx context.Context, params sqlc.CreateMediaPar
|
||||
_ = r.c.DelByPattern(bgCtx, "media:count*")
|
||||
}()
|
||||
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("media:userId:%s", convert.UUIDToString(params.UserID)))
|
||||
_ = r.c.Del(ctx, cache.Key("media:userId", convert.UUIDToString(params.UserID)))
|
||||
|
||||
media := models.MediaEntity{
|
||||
ID: convert.UUIDToString(row.ID),
|
||||
@@ -188,7 +184,7 @@ func (r *mediaRepository) Delete(ctx context.Context, id pgtype.UUID) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cacheId := fmt.Sprintf("media:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("media:id", convert.UUIDToString(id))
|
||||
_ = r.c.Del(ctx, cacheId)
|
||||
go func() {
|
||||
_ = r.c.DelByPattern(context.Background(), "media:count*")
|
||||
@@ -206,7 +202,7 @@ func (r *mediaRepository) BulkDelete(ctx context.Context, ids []pgtype.UUID) err
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("media:id:%s", convert.UUIDToString(id))
|
||||
keys[i] = cache.Key("media:id", convert.UUIDToString(id))
|
||||
}
|
||||
_ = r.c.Del(ctx, keys...)
|
||||
|
||||
@@ -237,9 +233,9 @@ func (r *mediaRepository) Search(ctx context.Context, params sqlc.SearchMediasPa
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var medias []*models.MediaEntity
|
||||
var ids []string
|
||||
mediasToCache := make(map[string]any)
|
||||
medias := make([]*models.MediaEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
mediasToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
media := &models.MediaEntity{
|
||||
@@ -256,7 +252,7 @@ func (r *mediaRepository) Search(ctx context.Context, params sqlc.SearchMediasPa
|
||||
ids = append(ids, media.ID)
|
||||
medias = append(medias, media)
|
||||
|
||||
mediasToCache[fmt.Sprintf("media:id:%s", media.ID)] = media
|
||||
mediasToCache[cache.Key("media:id", media.ID)] = media
|
||||
}
|
||||
|
||||
if len(mediasToCache) > 0 {
|
||||
@@ -284,7 +280,7 @@ func (r *mediaRepository) Count(ctx context.Context, params sqlc.CountMediasPara
|
||||
}
|
||||
|
||||
func (r *mediaRepository) GetByUserID(ctx context.Context, userId pgtype.UUID) ([]*models.MediaEntity, error) {
|
||||
queryKey := fmt.Sprintf("media:userId:%s", convert.UUIDToString(userId))
|
||||
queryKey := cache.Key("media:userId", convert.UUIDToString(userId))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, queryKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -307,9 +303,9 @@ func (r *mediaRepository) GetByUserID(ctx context.Context, userId pgtype.UUID) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var medias []*models.MediaEntity
|
||||
var ids []string
|
||||
mediasToCache := make(map[string]any)
|
||||
medias := make([]*models.MediaEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
mediasToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
media := &models.MediaEntity{
|
||||
@@ -326,7 +322,7 @@ func (r *mediaRepository) GetByUserID(ctx context.Context, userId pgtype.UUID) (
|
||||
ids = append(ids, media.ID)
|
||||
medias = append(medias, media)
|
||||
|
||||
mediasToCache[fmt.Sprintf("media:id:%s", media.ID)] = media
|
||||
mediasToCache[cache.Key("media:id", media.ID)] = media
|
||||
}
|
||||
|
||||
if len(mediasToCache) > 0 {
|
||||
|
||||
@@ -2,9 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -53,9 +51,7 @@ func (r *projectRepository) WithTx(tx pgx.Tx) ProjectRepository {
|
||||
}
|
||||
}
|
||||
func (r *projectRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *projectRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.ProjectEntity, error) {
|
||||
@@ -64,14 +60,14 @@ func (r *projectRepository) getByIDsWithFallback(ctx context.Context, ids []stri
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("project:id:%s", id)
|
||||
keys[i] = cache.Key("project:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var projects []*models.ProjectEntity
|
||||
missingToCache := make(map[string]any)
|
||||
projects := make([]*models.ProjectEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -82,7 +78,7 @@ func (r *projectRepository) getByIDsWithFallback(ctx context.Context, ids []stri
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.ProjectEntity)
|
||||
dbMap := make(map[string]*models.ProjectEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetProjectsByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -134,7 +130,7 @@ func (r *projectRepository) GetByIDs(ctx context.Context, ids []string) ([]*mode
|
||||
}
|
||||
|
||||
func (r *projectRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.ProjectEntity, error) {
|
||||
cacheId := fmt.Sprintf("project:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("project:id", convert.UUIDToString(id))
|
||||
var project models.ProjectEntity
|
||||
err := r.c.Get(ctx, cacheId, &project)
|
||||
if err == nil {
|
||||
@@ -185,9 +181,9 @@ func (r *projectRepository) GetByUserID(ctx context.Context, params sqlc.GetProj
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var projects []*models.ProjectEntity
|
||||
var ids []string
|
||||
projectToCache := make(map[string]any)
|
||||
projects := make([]*models.ProjectEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
projectToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
project := &models.ProjectEntity{
|
||||
@@ -209,7 +205,7 @@ func (r *projectRepository) GetByUserID(ctx context.Context, params sqlc.GetProj
|
||||
|
||||
ids = append(ids, project.ID)
|
||||
projects = append(projects, project)
|
||||
projectToCache[fmt.Sprintf("project:id:%s", project.ID)] = project
|
||||
projectToCache[cache.Key("project:id", project.ID)] = project
|
||||
}
|
||||
|
||||
if len(projectToCache) > 0 {
|
||||
@@ -235,9 +231,9 @@ func (r *projectRepository) Search(ctx context.Context, params sqlc.SearchProjec
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var projects []*models.ProjectEntity
|
||||
var ids []string
|
||||
projectToCache := make(map[string]any)
|
||||
projects := make([]*models.ProjectEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
projectToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
project := &models.ProjectEntity{
|
||||
@@ -259,7 +255,7 @@ func (r *projectRepository) Search(ctx context.Context, params sqlc.SearchProjec
|
||||
|
||||
ids = append(ids, project.ID)
|
||||
projects = append(projects, project)
|
||||
projectToCache[fmt.Sprintf("project:id:%s", project.ID)] = project
|
||||
projectToCache[cache.Key("project:id", project.ID)] = project
|
||||
}
|
||||
|
||||
if len(projectToCache) > 0 {
|
||||
@@ -340,7 +336,7 @@ func (r *projectRepository) Update(ctx context.Context, params sqlc.UpdateProjec
|
||||
_ = project.ParseSubmissions(row.Submissions)
|
||||
_ = project.ParseMembers(row.Members)
|
||||
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:id:%s", project.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("project:id", project.ID))
|
||||
return &project, nil
|
||||
}
|
||||
|
||||
@@ -349,7 +345,7 @@ func (r *projectRepository) Delete(ctx context.Context, id pgtype.UUID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:id:%s", convert.UUIDToString(id)))
|
||||
_ = r.c.Del(ctx, cache.Key("project:id", convert.UUIDToString(id)))
|
||||
go func() {
|
||||
bgCtx := context.Background()
|
||||
_ = r.c.DelByPattern(bgCtx, "project:search*")
|
||||
@@ -367,8 +363,8 @@ func (r *projectRepository) AddMember(ctx context.Context, params sqlc.AddProjec
|
||||
go func() {
|
||||
_ = r.c.DelByPattern(context.Background(), "project:user*")
|
||||
}()
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:id:%s", convert.UUIDToString(params.ProjectID)))
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:perm:%s:%s", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID)))
|
||||
_ = r.c.Del(ctx, cache.Key("project:id", convert.UUIDToString(params.ProjectID)))
|
||||
_ = r.c.Del(ctx, cache.Key2("project:perm", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -380,8 +376,8 @@ func (r *projectRepository) UpdateMemberRole(ctx context.Context, params sqlc.Up
|
||||
go func() {
|
||||
_ = r.c.DelByPattern(context.Background(), "project:user*")
|
||||
}()
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:id:%s", convert.UUIDToString(params.ProjectID)))
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:perm:%s:%s", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID)))
|
||||
_ = r.c.Del(ctx, cache.Key("project:id", convert.UUIDToString(params.ProjectID)))
|
||||
_ = r.c.Del(ctx, cache.Key2("project:perm", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -393,13 +389,13 @@ func (r *projectRepository) RemoveMember(ctx context.Context, params sqlc.Remove
|
||||
go func() {
|
||||
_ = r.c.DelByPattern(context.Background(), "project:user*")
|
||||
}()
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:id:%s", convert.UUIDToString(params.ProjectID)))
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:perm:%s:%s", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID)))
|
||||
_ = r.c.Del(ctx, cache.Key("project:id", convert.UUIDToString(params.ProjectID)))
|
||||
_ = r.c.Del(ctx, cache.Key2("project:perm", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID)))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *projectRepository) CheckPermission(ctx context.Context, params sqlc.CheckProjectPermissionParams) (int16, error) {
|
||||
cacheKey := fmt.Sprintf("project:perm:%s:%s", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID))
|
||||
cacheKey := cache.Key2("project:perm", convert.UUIDToString(params.ProjectID), convert.UUIDToString(params.UserID))
|
||||
var role int16
|
||||
if err := r.c.Get(ctx, cacheKey, &role); err == nil {
|
||||
return role, nil
|
||||
@@ -420,9 +416,9 @@ func (r *projectRepository) ChangeOwner(ctx context.Context, params sqlc.ChangeP
|
||||
return err
|
||||
}
|
||||
projectID := convert.UUIDToString(params.ID)
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:id:%s", projectID))
|
||||
_ = r.c.Del(ctx, cache.Key("project:id", projectID))
|
||||
go func() {
|
||||
_ = r.c.DelByPattern(context.Background(), fmt.Sprintf("project:perm:%s:*", projectID))
|
||||
_ = r.c.DelByPattern(context.Background(), "project:perm:"+projectID+":*")
|
||||
}()
|
||||
return nil
|
||||
}
|
||||
@@ -432,6 +428,6 @@ func (r *projectRepository) UpdateLatestCommit(ctx context.Context, params sqlc.
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("project:id:%s", convert.UUIDToString(params.ID)))
|
||||
_ = r.c.Del(ctx, cache.Key("project:id", convert.UUIDToString(params.ID)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,17 +6,23 @@ import (
|
||||
"fmt"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const rasterTileCacheDuration = 5 * time.Minute
|
||||
|
||||
type RasterTileRepository interface {
|
||||
GetMetadata(ctx context.Context) (map[string]string, error)
|
||||
GetTile(ctx context.Context, z, x, y int) ([]byte, string, error)
|
||||
}
|
||||
|
||||
type rasterTileRepository struct {
|
||||
db *sql.DB
|
||||
c cache.Cache
|
||||
db *sql.DB
|
||||
c cache.Cache
|
||||
metadataMu sync.RWMutex
|
||||
metadata map[string]string
|
||||
}
|
||||
|
||||
func NewRasterTileRepository(db *sql.DB, c cache.Cache) RasterTileRepository {
|
||||
@@ -27,11 +33,27 @@ func NewRasterTileRepository(db *sql.DB, c cache.Cache) RasterTileRepository {
|
||||
}
|
||||
|
||||
func (r *rasterTileRepository) GetMetadata(ctx context.Context) (map[string]string, error) {
|
||||
r.metadataMu.RLock()
|
||||
if r.metadata != nil {
|
||||
metadata := r.metadata
|
||||
r.metadataMu.RUnlock()
|
||||
return metadata, nil
|
||||
}
|
||||
r.metadataMu.RUnlock()
|
||||
|
||||
r.metadataMu.Lock()
|
||||
defer r.metadataMu.Unlock()
|
||||
|
||||
if r.metadata != nil {
|
||||
return r.metadata, nil
|
||||
}
|
||||
|
||||
cacheId := "rasterTile:metadata"
|
||||
|
||||
var cached map[string]string
|
||||
err := r.c.Get(ctx, cacheId, &cached)
|
||||
if err == nil {
|
||||
r.metadata = cached
|
||||
return cached, nil
|
||||
}
|
||||
|
||||
@@ -41,7 +63,7 @@ func (r *rasterTileRepository) GetMetadata(ctx context.Context) (map[string]stri
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
metadata := make(map[string]string)
|
||||
metadata := make(map[string]string, 8)
|
||||
|
||||
for rows.Next() {
|
||||
var name, value string
|
||||
@@ -50,8 +72,12 @@ func (r *rasterTileRepository) GetMetadata(ctx context.Context) (map[string]stri
|
||||
}
|
||||
metadata[name] = value
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = r.c.Set(ctx, cacheId, metadata, constants.NormalCacheDuration)
|
||||
r.metadata = metadata
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
@@ -61,12 +87,14 @@ func (r *rasterTileRepository) GetTile(ctx context.Context, z, x, y int) ([]byte
|
||||
return nil, "", fmt.Errorf("invalid tile coordinates")
|
||||
}
|
||||
|
||||
cacheId := fmt.Sprintf("rasterTile:%d:%d:%d", z, x, y)
|
||||
cacheId := "rasterTile:raw:" + strconv.Itoa(z) + ":" + strconv.Itoa(x) + ":" + strconv.Itoa(y)
|
||||
|
||||
var cached []byte
|
||||
err := r.c.Get(ctx, cacheId, &cached)
|
||||
cached, err := r.c.GetRawClient().Get(ctx, cacheId).Bytes()
|
||||
if err == nil {
|
||||
meta, _ := r.GetMetadata(ctx)
|
||||
meta, err := r.GetMetadata(ctx)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
return cached, meta["format"], nil
|
||||
}
|
||||
|
||||
@@ -92,7 +120,7 @@ func (r *rasterTileRepository) GetTile(ctx context.Context, z, x, y int) ([]byte
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
_ = r.c.Set(ctx, cacheId, tileData, 5*time.Minute)
|
||||
_ = r.c.GetRawClient().Set(ctx, cacheId, tileData, rasterTileCacheDuration).Err()
|
||||
|
||||
return tileData, meta["format"], nil
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -52,9 +50,7 @@ func (r *roleRepository) WithTx(tx pgx.Tx) RoleRepository {
|
||||
}
|
||||
|
||||
func (r *roleRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *roleRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.RoleEntity, error) {
|
||||
@@ -63,14 +59,14 @@ func (r *roleRepository) getByIDsWithFallback(ctx context.Context, ids []string)
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("role:id:%s", id)
|
||||
keys[i] = cache.Key("role:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var roles []*models.RoleEntity
|
||||
missingRolesToCache := make(map[string]any)
|
||||
roles := make([]*models.RoleEntity, 0, len(ids))
|
||||
missingRolesToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -81,7 +77,7 @@ func (r *roleRepository) getByIDsWithFallback(ctx context.Context, ids []string)
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.RoleEntity)
|
||||
dbMap := make(map[string]*models.RoleEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetRolesByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -124,7 +120,7 @@ func (r *roleRepository) GetByIDs(ctx context.Context, ids []string) ([]*models.
|
||||
}
|
||||
|
||||
func (r *roleRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.RoleEntity, error) {
|
||||
cacheId := fmt.Sprintf("role:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("role:id", convert.UUIDToString(id))
|
||||
var role models.RoleEntity
|
||||
err := r.c.Get(ctx, cacheId, &role)
|
||||
if err == nil {
|
||||
@@ -150,7 +146,7 @@ func (r *roleRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.R
|
||||
}
|
||||
|
||||
func (r *roleRepository) GetByName(ctx context.Context, name string) (*models.RoleEntity, error) {
|
||||
cacheId := fmt.Sprintf("role:name:%s", name)
|
||||
cacheId := cache.Key("role:name", name)
|
||||
var role models.RoleEntity
|
||||
err := r.c.Get(ctx, cacheId, &role)
|
||||
if err == nil {
|
||||
@@ -208,7 +204,7 @@ func (r *roleRepository) Update(ctx context.Context, params sqlc.UpdateRoleParam
|
||||
UpdatedAt: convert.TimeToPtr(row.UpdatedAt),
|
||||
}
|
||||
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("role:id:%s", convert.UUIDToString(row.ID)), fmt.Sprintf("role:name:%s", row.Name))
|
||||
_ = r.c.Del(ctx, cache.Key("role:id", convert.UUIDToString(row.ID)), cache.Key("role:name", row.Name))
|
||||
return &role, nil
|
||||
}
|
||||
|
||||
@@ -236,9 +232,9 @@ func (r *roleRepository) All(ctx context.Context) ([]*models.RoleEntity, error)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var roles []*models.RoleEntity
|
||||
var ids []string
|
||||
roleToCache := make(map[string]any)
|
||||
roles := make([]*models.RoleEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
roleToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
role := &models.RoleEntity{
|
||||
@@ -251,7 +247,7 @@ func (r *roleRepository) All(ctx context.Context) ([]*models.RoleEntity, error)
|
||||
ids = append(ids, role.ID)
|
||||
roles = append(roles, role)
|
||||
|
||||
roleToCache[fmt.Sprintf("role:id:%s", role.ID)] = role
|
||||
roleToCache[cache.Key("role:id", role.ID)] = role
|
||||
}
|
||||
|
||||
if len(roleToCache) > 0 {
|
||||
@@ -273,7 +269,7 @@ func (r *roleRepository) Delete(ctx context.Context, id pgtype.UUID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("role:id:%s", role.ID), fmt.Sprintf("role:name:%s", role.Name))
|
||||
_ = r.c.Del(ctx, cache.Key("role:id", role.ID), cache.Key("role:name", role.Name))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -282,7 +278,7 @@ func (r *roleRepository) Restore(ctx context.Context, id pgtype.UUID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("role:id:%s", convert.UUIDToString(id)))
|
||||
_ = r.c.Del(ctx, cache.Key("role:id", convert.UUIDToString(id)))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,12 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"history-api/internal/gen/sqlc"
|
||||
"history-api/internal/models"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"history-api/pkg/convert"
|
||||
json "history-api/pkg/jsonx"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
@@ -47,9 +45,7 @@ func (r *statisticRepository) WithTx(tx pgx.Tx) StatisticRepository {
|
||||
}
|
||||
|
||||
func (r *statisticRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func mapToEntity(row sqlc.SystemStatistic) *models.StatisticEntity {
|
||||
@@ -84,14 +80,14 @@ func (r *statisticRepository) getByIDsWithFallback(ctx context.Context, ids []st
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("statistic:id:%s", id)
|
||||
keys[i] = cache.Key("statistic:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var stats []*models.StatisticEntity
|
||||
missingStatsToCache := make(map[string]any)
|
||||
stats := make([]*models.StatisticEntity, 0, len(ids))
|
||||
missingStatsToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -102,7 +98,7 @@ func (r *statisticRepository) getByIDsWithFallback(ctx context.Context, ids []st
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.StatisticEntity)
|
||||
dbMap := make(map[string]*models.StatisticEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetSystemStatisticsByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -151,15 +147,15 @@ func (r *statisticRepository) Search(ctx context.Context, params sqlc.SearchSyst
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ids []string
|
||||
statsToCache := make(map[string]any)
|
||||
var stats []*models.StatisticEntity
|
||||
ids := make([]string, 0, len(rows))
|
||||
statsToCache := make(map[string]any, len(rows))
|
||||
stats := make([]*models.StatisticEntity, 0, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
entity := mapToEntity(row)
|
||||
ids = append(ids, entity.ID)
|
||||
stats = append(stats, entity)
|
||||
statsToCache[fmt.Sprintf("statistic:id:%s", entity.ID)] = entity
|
||||
statsToCache[cache.Key("statistic:id", entity.ID)] = entity
|
||||
}
|
||||
|
||||
if len(statsToCache) > 0 {
|
||||
@@ -171,7 +167,7 @@ func (r *statisticRepository) Search(ctx context.Context, params sqlc.SearchSyst
|
||||
}
|
||||
|
||||
func (r *statisticRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.StatisticEntity, error) {
|
||||
cacheId := fmt.Sprintf("statistic:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("statistic:id", convert.UUIDToString(id))
|
||||
var stat models.StatisticEntity
|
||||
err := r.c.Get(ctx, cacheId, &stat)
|
||||
if err == nil {
|
||||
@@ -194,7 +190,7 @@ func (r *statisticRepository) GetByID(ctx context.Context, id pgtype.UUID) (*mod
|
||||
|
||||
func (r *statisticRepository) GetByDate(ctx context.Context, date time.Time) (*models.StatisticEntity, error) {
|
||||
dateStr := date.Format("2006-01-02")
|
||||
cacheId := fmt.Sprintf("statistic:date:%s", dateStr)
|
||||
cacheId := cache.Key("statistic:date", dateStr)
|
||||
|
||||
var stat models.StatisticEntity
|
||||
err := r.c.Get(ctx, cacheId, &stat)
|
||||
@@ -213,7 +209,7 @@ func (r *statisticRepository) GetByDate(ctx context.Context, date time.Time) (*m
|
||||
entity := mapToEntity(row)
|
||||
|
||||
_ = r.c.Set(ctx, cacheId, entity, constants.NormalCacheDuration)
|
||||
_ = r.c.Set(ctx, fmt.Sprintf("statistic:id:%s", entity.ID), entity, constants.NormalCacheDuration)
|
||||
_ = r.c.Set(ctx, cache.Key("statistic:id", entity.ID), entity, constants.NormalCacheDuration)
|
||||
|
||||
return entity, nil
|
||||
}
|
||||
@@ -231,12 +227,10 @@ func (r *statisticRepository) Upsert(ctx context.Context, date time.Time) (*mode
|
||||
_ = r.c.DelByPattern(bgCtx, "statistic:search*")
|
||||
_ = r.c.Del(
|
||||
bgCtx,
|
||||
fmt.Sprintf("statistic:id:%s", entity.ID),
|
||||
fmt.Sprintf("statistic:date:%s", date.Format("2006-01-02")),
|
||||
cache.Key("statistic:id", entity.ID),
|
||||
cache.Key("statistic:date", date.Format("2006-01-02")),
|
||||
)
|
||||
}()
|
||||
|
||||
return entity, nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,14 +2,12 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"history-api/internal/gen/sqlc"
|
||||
"history-api/internal/models"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"history-api/pkg/convert"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -48,7 +46,7 @@ func (r *submissionRepository) WithTx(tx pgx.Tx) SubmissionRepository {
|
||||
}
|
||||
|
||||
func (r *submissionRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.SubmissionEntity, error) {
|
||||
cacheId := fmt.Sprintf("submission:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("submission:id", convert.UUIDToString(id))
|
||||
var submission models.SubmissionEntity
|
||||
err := r.c.Get(ctx, cacheId, &submission)
|
||||
if err == nil {
|
||||
@@ -82,9 +80,7 @@ func (r *submissionRepository) GetByID(ctx context.Context, id pgtype.UUID) (*mo
|
||||
}
|
||||
|
||||
func (r *submissionRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *submissionRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.SubmissionEntity, error) {
|
||||
@@ -93,14 +89,14 @@ func (r *submissionRepository) getByIDsWithFallback(ctx context.Context, ids []s
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("submission:id:%s", id)
|
||||
keys[i] = cache.Key("submission:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var submission []*models.SubmissionEntity
|
||||
missingSubmisstionToCache := make(map[string]any)
|
||||
submission := make([]*models.SubmissionEntity, 0, len(ids))
|
||||
missingSubmisstionToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -111,7 +107,7 @@ func (r *submissionRepository) getByIDsWithFallback(ctx context.Context, ids []s
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.SubmissionEntity)
|
||||
dbMap := make(map[string]*models.SubmissionEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetSubmissionsByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -164,7 +160,7 @@ func (r *submissionRepository) GetByIDs(ctx context.Context, ids []string) ([]*m
|
||||
}
|
||||
|
||||
func (r *submissionRepository) Search(ctx context.Context, params sqlc.SearchSubmissionsParams) ([]*models.SubmissionEntity, error) {
|
||||
queryKey := r.generateQueryKey("verification:search", params)
|
||||
queryKey := r.generateQueryKey("submission:search", params)
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, queryKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -187,9 +183,9 @@ func (r *submissionRepository) Search(ctx context.Context, params sqlc.SearchSub
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var items []*models.SubmissionEntity
|
||||
var ids []string
|
||||
itemToCache := make(map[string]any)
|
||||
items := make([]*models.SubmissionEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
itemToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
entity := &models.SubmissionEntity{
|
||||
@@ -213,7 +209,7 @@ func (r *submissionRepository) Search(ctx context.Context, params sqlc.SearchSub
|
||||
ids = append(ids, entity.ID)
|
||||
items = append(items, entity)
|
||||
|
||||
itemToCache[fmt.Sprintf("submission:id:%s", entity.ID)] = entity
|
||||
itemToCache[cache.Key("submission:id", entity.ID)] = entity
|
||||
}
|
||||
|
||||
if len(itemToCache) > 0 {
|
||||
@@ -308,7 +304,7 @@ func (r *submissionRepository) Update(ctx context.Context, params sqlc.UpdateSub
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("submission:id:%s", submission.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("submission:id", submission.ID))
|
||||
|
||||
return &submission, nil
|
||||
}
|
||||
@@ -319,7 +315,7 @@ func (r *submissionRepository) Delete(ctx context.Context, id pgtype.UUID) error
|
||||
return err
|
||||
}
|
||||
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("submission:id:%s", convert.UUIDToString(id)))
|
||||
_ = r.c.Del(ctx, cache.Key("submission:id", convert.UUIDToString(id)))
|
||||
go func() {
|
||||
bgCtx := context.Background()
|
||||
_ = r.c.DelByPattern(bgCtx, "submission:search*")
|
||||
|
||||
@@ -6,17 +6,23 @@ import (
|
||||
"fmt"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const tileCacheDuration = 5 * time.Minute
|
||||
|
||||
type TileRepository interface {
|
||||
GetMetadata(ctx context.Context) (map[string]string, error)
|
||||
GetTile(ctx context.Context, z, x, y int) ([]byte, string, bool, error)
|
||||
}
|
||||
|
||||
type tileRepository struct {
|
||||
db *sql.DB
|
||||
c cache.Cache
|
||||
db *sql.DB
|
||||
c cache.Cache
|
||||
metadataMu sync.RWMutex
|
||||
metadata map[string]string
|
||||
}
|
||||
|
||||
func NewTileRepository(db *sql.DB, c cache.Cache) TileRepository {
|
||||
@@ -27,11 +33,27 @@ func NewTileRepository(db *sql.DB, c cache.Cache) TileRepository {
|
||||
}
|
||||
|
||||
func (r *tileRepository) GetMetadata(ctx context.Context) (map[string]string, error) {
|
||||
r.metadataMu.RLock()
|
||||
if r.metadata != nil {
|
||||
metadata := r.metadata
|
||||
r.metadataMu.RUnlock()
|
||||
return metadata, nil
|
||||
}
|
||||
r.metadataMu.RUnlock()
|
||||
|
||||
r.metadataMu.Lock()
|
||||
defer r.metadataMu.Unlock()
|
||||
|
||||
if r.metadata != nil {
|
||||
return r.metadata, nil
|
||||
}
|
||||
|
||||
cacheId := "tile:metadata"
|
||||
|
||||
var cached map[string]string
|
||||
err := r.c.Get(ctx, cacheId, &cached)
|
||||
if err == nil {
|
||||
r.metadata = cached
|
||||
return cached, nil
|
||||
}
|
||||
|
||||
@@ -41,7 +63,7 @@ func (r *tileRepository) GetMetadata(ctx context.Context) (map[string]string, er
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
metadata := make(map[string]string)
|
||||
metadata := make(map[string]string, 8)
|
||||
|
||||
for rows.Next() {
|
||||
var name, value string
|
||||
@@ -50,8 +72,12 @@ func (r *tileRepository) GetMetadata(ctx context.Context) (map[string]string, er
|
||||
}
|
||||
metadata[name] = value
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_ = r.c.Set(ctx, cacheId, metadata, constants.NormalCacheDuration)
|
||||
r.metadata = metadata
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
@@ -61,13 +87,16 @@ func (r *tileRepository) GetTile(ctx context.Context, z, x, y int) ([]byte, stri
|
||||
return nil, "", false, fmt.Errorf("invalid tile coordinates")
|
||||
}
|
||||
|
||||
cacheId := fmt.Sprintf("tile:%d:%d:%d", z, x, y)
|
||||
cacheId := "tile:raw:" + strconv.Itoa(z) + ":" + strconv.Itoa(x) + ":" + strconv.Itoa(y)
|
||||
|
||||
var cached []byte
|
||||
err := r.c.Get(ctx, cacheId, &cached)
|
||||
cached, err := r.c.GetRawClient().Get(ctx, cacheId).Bytes()
|
||||
if err == nil {
|
||||
meta, _ := r.GetMetadata(ctx)
|
||||
return cached, meta["format"], meta["format"] == "pbf", nil
|
||||
meta, err := r.GetMetadata(ctx)
|
||||
if err != nil {
|
||||
return nil, "", false, err
|
||||
}
|
||||
format := meta["format"]
|
||||
return cached, format, format == "pbf", nil
|
||||
}
|
||||
|
||||
// XYZ -> TMS
|
||||
@@ -92,7 +121,7 @@ func (r *tileRepository) GetTile(ctx context.Context, z, x, y int) ([]byte, stri
|
||||
return nil, "", false, err
|
||||
}
|
||||
|
||||
_ = r.c.Set(ctx, cacheId, tileData, 5*time.Minute)
|
||||
_ = r.c.GetRawClient().Set(ctx, cacheId, tileData, tileCacheDuration).Err()
|
||||
|
||||
return tileData, meta["format"], meta["format"] == "pbf", nil
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"history-api/internal/models"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type TokenRepository interface {
|
||||
@@ -33,23 +33,27 @@ func NewTokenRepository(c cache.Cache) TokenRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func tokenTypeValue(t constants.TokenType) string {
|
||||
return strconv.Itoa(int(t.Value()))
|
||||
}
|
||||
|
||||
func (t *tokenRepository) CreateVerified(ctx context.Context, email string, tokenType constants.TokenType, id string) error {
|
||||
cacheKey := fmt.Sprintf("token:verified:%d:%s:%s", tokenType.Value(), email, id)
|
||||
cacheKey := cache.Key2("token:verified:"+tokenTypeValue(tokenType), email, id)
|
||||
return t.c.Set(ctx, cacheKey, true, constants.TokenVerifiedDuration)
|
||||
}
|
||||
|
||||
func (t *tokenRepository) DeleteVerified(ctx context.Context, email string, tokenType constants.TokenType, id string) error {
|
||||
cacheKey := fmt.Sprintf("token:verified:%d:%s:%s", tokenType.Value(), email, id)
|
||||
cacheKey := cache.Key2("token:verified:"+tokenTypeValue(tokenType), email, id)
|
||||
return t.c.Del(ctx, cacheKey)
|
||||
}
|
||||
func (t *tokenRepository) CheckVerified(ctx context.Context, email string, tokenType constants.TokenType, id string) (bool, error) {
|
||||
cacheKey := fmt.Sprintf("token:verified:%d:%s:%s", tokenType.Value(), email, id)
|
||||
cacheKey := cache.Key2("token:verified:"+tokenTypeValue(tokenType), email, id)
|
||||
exists, err := t.c.Exists(ctx, cacheKey)
|
||||
return exists, err
|
||||
}
|
||||
|
||||
func (t *tokenRepository) CreateUploadToken(ctx context.Context, userId string, token *models.TokenUploadEntity) error {
|
||||
cacheKey := fmt.Sprintf("token:%d:%s:%s", constants.TokenTypeUpload.Value(), userId, token.ID)
|
||||
cacheKey := cache.Key2("token:"+tokenTypeValue(constants.TokenTypeUpload), userId, token.ID)
|
||||
err := t.c.Set(ctx, cacheKey, token, constants.TokenUploadDuration)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -58,7 +62,7 @@ func (t *tokenRepository) CreateUploadToken(ctx context.Context, userId string,
|
||||
}
|
||||
|
||||
func (t *tokenRepository) GetUploadToken(ctx context.Context, userId string, id string) (*models.TokenUploadEntity, error) {
|
||||
cacheKey := fmt.Sprintf("token:%d:%s:%s", constants.TokenTypeUpload.Value(), userId, id)
|
||||
cacheKey := cache.Key2("token:"+tokenTypeValue(constants.TokenTypeUpload), userId, id)
|
||||
var token models.TokenUploadEntity
|
||||
err := t.c.Get(ctx, cacheKey, &token)
|
||||
if err != nil {
|
||||
@@ -68,35 +72,35 @@ func (t *tokenRepository) GetUploadToken(ctx context.Context, userId string, id
|
||||
}
|
||||
|
||||
func (t *tokenRepository) DeleteUploadToken(ctx context.Context, userId string, id string) error {
|
||||
cacheKey := fmt.Sprintf("token:%d:%s:%s", constants.TokenTypeUpload.Value(), userId, id)
|
||||
cacheKey := cache.Key2("token:"+tokenTypeValue(constants.TokenTypeUpload), userId, id)
|
||||
return t.c.Del(ctx, cacheKey)
|
||||
}
|
||||
|
||||
func (t *tokenRepository) CheckCooldown(ctx context.Context, email string, tokenType constants.TokenType) (bool, error) {
|
||||
cacheKey := fmt.Sprintf("token:cooldown:%d:%s", tokenType.Value(), email)
|
||||
cacheKey := cache.Key("token:cooldown:"+tokenTypeValue(tokenType), email)
|
||||
exists, err := t.c.Exists(ctx, cacheKey)
|
||||
return exists, err
|
||||
}
|
||||
|
||||
func (t *tokenRepository) Create(ctx context.Context, token *models.TokenEntity) error {
|
||||
cacheKey := fmt.Sprintf("token:%d:%s", token.TokenType.Value(), token.Email)
|
||||
cacheKey := cache.Key("token:"+tokenTypeValue(token.TokenType), token.Email)
|
||||
err := t.c.Set(ctx, cacheKey, token, constants.TokenExpirationDuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cooldownKey := fmt.Sprintf("token:cooldown:%d:%s", token.TokenType.Value(), token.Email)
|
||||
cooldownKey := cache.Key("token:cooldown:"+tokenTypeValue(token.TokenType), token.Email)
|
||||
return t.c.Set(ctx, cooldownKey, true, constants.TokenCooldownDuration)
|
||||
}
|
||||
|
||||
func (t *tokenRepository) Delete(ctx context.Context, email string, tokenType constants.TokenType) error {
|
||||
cacheKey := fmt.Sprintf("token:%d:%s", tokenType.Value(), email)
|
||||
cooldownKey := fmt.Sprintf("token:cooldown:%d:%s", tokenType.Value(), email)
|
||||
cacheKey := cache.Key("token:"+tokenTypeValue(tokenType), email)
|
||||
cooldownKey := cache.Key("token:cooldown:"+tokenTypeValue(tokenType), email)
|
||||
_ = t.c.Del(ctx, cooldownKey)
|
||||
return t.c.Del(ctx, cacheKey)
|
||||
}
|
||||
|
||||
func (t *tokenRepository) Get(ctx context.Context, email string, tokenType constants.TokenType) (*models.TokenEntity, error) {
|
||||
cacheKey := fmt.Sprintf("token:%d:%s", tokenType.Value(), email)
|
||||
cacheKey := cache.Key("token:"+tokenTypeValue(tokenType), email)
|
||||
var token models.TokenEntity
|
||||
err := t.c.Get(ctx, cacheKey, &token)
|
||||
if err != nil {
|
||||
|
||||
@@ -2,7 +2,6 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"time"
|
||||
@@ -25,7 +24,7 @@ func NewUsageRepository(c cache.Cache) UsageRepository {
|
||||
|
||||
func (r *usageRepository) getUsageKey(userID string) string {
|
||||
dateStr := time.Now().Format("20060102")
|
||||
return fmt.Sprintf("usage:ai:%s:%s", userID, dateStr)
|
||||
return cache.Key2("usage:ai", userID, dateStr)
|
||||
}
|
||||
|
||||
func (r *usageRepository) GetAIUsage(ctx context.Context, userID string) (int, error) {
|
||||
|
||||
@@ -2,9 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -54,9 +52,7 @@ func (r *userRepository) WithTx(tx pgx.Tx) UserRepository {
|
||||
}
|
||||
|
||||
func (r *userRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *userRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.UserEntity, error) {
|
||||
@@ -65,14 +61,14 @@ func (r *userRepository) getByIDsWithFallback(ctx context.Context, ids []string)
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("user:id:%s", id)
|
||||
keys[i] = cache.Key("user:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var users []*models.UserEntity
|
||||
missingUsersToCache := make(map[string]any)
|
||||
users := make([]*models.UserEntity, 0, len(ids))
|
||||
missingUsersToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -83,7 +79,7 @@ func (r *userRepository) getByIDsWithFallback(ctx context.Context, ids []string)
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.UserEntity)
|
||||
dbMap := make(map[string]*models.UserEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetUsersByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -126,7 +122,7 @@ func (r *userRepository) getByIDsWithFallback(ctx context.Context, ids []string)
|
||||
}
|
||||
|
||||
func (r *userRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.UserEntity, error) {
|
||||
cacheId := fmt.Sprintf("user:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("user:id", convert.UUIDToString(id))
|
||||
var user models.UserEntity
|
||||
err := r.c.Get(ctx, cacheId, &user)
|
||||
if err == nil {
|
||||
@@ -164,7 +160,7 @@ func (r *userRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.U
|
||||
}
|
||||
|
||||
func (r *userRepository) GetByIDWithoutDeleted(ctx context.Context, id pgtype.UUID) (*models.UserEntity, error) {
|
||||
cacheId := fmt.Sprintf("user:deleted:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("user:deleted:id", convert.UUIDToString(id))
|
||||
var user models.UserEntity
|
||||
err := r.c.Get(ctx, cacheId, &user)
|
||||
if err == nil {
|
||||
@@ -202,7 +198,7 @@ func (r *userRepository) GetByIDWithoutDeleted(ctx context.Context, id pgtype.UU
|
||||
}
|
||||
|
||||
func (r *userRepository) GetByEmail(ctx context.Context, email string) (*models.UserEntity, error) {
|
||||
cacheId := fmt.Sprintf("user:email:%s", email)
|
||||
cacheId := cache.Key("user:email", email)
|
||||
|
||||
var user models.UserEntity
|
||||
err := r.c.Get(ctx, cacheId, &user)
|
||||
@@ -287,7 +283,7 @@ func (r *userRepository) UpdateProfile(ctx context.Context, params sqlc.UpdateUs
|
||||
}
|
||||
|
||||
user.Profile = &profile
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("user:email:%s", user.Email), fmt.Sprintf("user:id:%s", user.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("user:email", user.Email), cache.Key("user:id", user.ID))
|
||||
return user, nil
|
||||
}
|
||||
|
||||
@@ -326,9 +322,9 @@ func (r *userRepository) Search(ctx context.Context, params sqlc.SearchUsersPara
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var users []*models.UserEntity
|
||||
var ids []string
|
||||
usersToCache := make(map[string]any)
|
||||
users := make([]*models.UserEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
usersToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
user := &models.UserEntity{
|
||||
@@ -352,7 +348,7 @@ func (r *userRepository) Search(ctx context.Context, params sqlc.SearchUsersPara
|
||||
|
||||
users = append(users, user)
|
||||
ids = append(ids, user.ID)
|
||||
usersToCache[fmt.Sprintf("user:id:%s", user.ID)] = user
|
||||
usersToCache[cache.Key("user:id", user.ID)] = user
|
||||
}
|
||||
|
||||
if len(usersToCache) > 0 {
|
||||
@@ -392,9 +388,9 @@ func (r *userRepository) Delete(ctx context.Context, id pgtype.UUID) error {
|
||||
|
||||
_ = r.c.Del(
|
||||
ctx,
|
||||
fmt.Sprintf("user:id:%s", user.ID),
|
||||
fmt.Sprintf("user:email:%s", user.Email),
|
||||
fmt.Sprintf("user:token:%s", user.ID),
|
||||
cache.Key("user:id", user.ID),
|
||||
cache.Key("user:email", user.Email),
|
||||
cache.Key("user:token", user.ID),
|
||||
)
|
||||
go func() {
|
||||
bgCtx := context.Background()
|
||||
@@ -411,9 +407,9 @@ func (r *userRepository) Restore(ctx context.Context, id pgtype.UUID) error {
|
||||
}
|
||||
_ = r.c.Del(
|
||||
ctx,
|
||||
fmt.Sprintf("user:deleted:id:%s", convert.UUIDToString(id)),
|
||||
fmt.Sprintf("user:email:%s", convert.UUIDToString(id)),
|
||||
fmt.Sprintf("user:id:%s", convert.UUIDToString(id)),
|
||||
cache.Key("user:deleted:id", convert.UUIDToString(id)),
|
||||
cache.Key("user:email", convert.UUIDToString(id)),
|
||||
cache.Key("user:id", convert.UUIDToString(id)),
|
||||
)
|
||||
go func() {
|
||||
bgCtx := context.Background()
|
||||
@@ -424,7 +420,7 @@ func (r *userRepository) Restore(ctx context.Context, id pgtype.UUID) error {
|
||||
}
|
||||
|
||||
func (r *userRepository) GetTokenVersion(ctx context.Context, id pgtype.UUID) (int32, error) {
|
||||
cacheId := fmt.Sprintf("user:token:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("user:token", convert.UUIDToString(id))
|
||||
var token int32
|
||||
err := r.c.Get(ctx, cacheId, &token)
|
||||
if err == nil {
|
||||
@@ -445,7 +441,7 @@ func (r *userRepository) UpdateTokenVersion(ctx context.Context, params sqlc.Upd
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("user:token:%s", convert.UUIDToString(params.ID)))
|
||||
_ = r.c.Del(ctx, cache.Key("user:token", convert.UUIDToString(params.ID)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -458,7 +454,7 @@ func (r *userRepository) UpdatePassword(ctx context.Context, params sqlc.UpdateU
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("user:email:%s", user.Email), fmt.Sprintf("user:id:%s", user.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("user:email", user.Email), cache.Key("user:id", user.ID))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -474,6 +470,6 @@ func (r *userRepository) UpdateRefreshToken(ctx context.Context, params sqlc.Upd
|
||||
|
||||
user.RefreshToken = convert.TextToString(params.RefreshToken)
|
||||
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("user:email:%s", user.Email), fmt.Sprintf("user:id:%s", user.ID))
|
||||
_ = r.c.Del(ctx, cache.Key("user:email", user.Email), cache.Key("user:id", user.ID))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -2,14 +2,12 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"history-api/internal/gen/sqlc"
|
||||
"history-api/internal/models"
|
||||
"history-api/pkg/cache"
|
||||
"history-api/pkg/constants"
|
||||
"history-api/pkg/convert"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -49,13 +47,11 @@ func (v *verificationRepository) WithTx(tx pgx.Tx) VerificationRepository {
|
||||
}
|
||||
|
||||
func (v *verificationRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (v *verificationRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.UserVerificationEntity, error) {
|
||||
cacheId := fmt.Sprintf("verification:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("verification:id", convert.UUIDToString(id))
|
||||
var verification models.UserVerificationEntity
|
||||
err := v.c.Get(ctx, cacheId, &verification)
|
||||
if err == nil {
|
||||
@@ -101,14 +97,14 @@ func (v *verificationRepository) getByIDsWithFallback(ctx context.Context, ids [
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("verification:id:%s", id)
|
||||
keys[i] = cache.Key("verification:id", id)
|
||||
}
|
||||
raws := v.c.MGet(ctx, keys...)
|
||||
|
||||
var verification []*models.UserVerificationEntity
|
||||
missingVerificationToCache := make(map[string]any)
|
||||
verification := make([]*models.UserVerificationEntity, 0, len(ids))
|
||||
missingVerificationToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -119,7 +115,7 @@ func (v *verificationRepository) getByIDsWithFallback(ctx context.Context, ids [
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.UserVerificationEntity)
|
||||
dbMap := make(map[string]*models.UserVerificationEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := v.q.GetUserVerificationsByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -212,7 +208,7 @@ func (v *verificationRepository) Create(ctx context.Context, params sqlc.CreateU
|
||||
_ = v.c.DelByPattern(bgCtx, "verification:count*")
|
||||
}()
|
||||
|
||||
_ = v.c.Del(ctx, fmt.Sprintf("verification:userId:%s", convert.UUIDToString(params.UserID)))
|
||||
_ = v.c.Del(ctx, cache.Key("verification:userId", convert.UUIDToString(params.UserID)))
|
||||
|
||||
return &verification, nil
|
||||
}
|
||||
@@ -222,7 +218,7 @@ func (v *verificationRepository) UpdateStatus(ctx context.Context, params sqlc.U
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = v.c.Del(ctx, fmt.Sprintf("verification:id:%s", convert.UUIDToString(params.ID)))
|
||||
_ = v.c.Del(ctx, cache.Key("verification:id", convert.UUIDToString(params.ID)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -232,7 +228,7 @@ func (v *verificationRepository) Delete(ctx context.Context, id pgtype.UUID) err
|
||||
return err
|
||||
}
|
||||
|
||||
_ = v.c.Del(ctx, fmt.Sprintf("verification:id:%s", convert.UUIDToString(id)))
|
||||
_ = v.c.Del(ctx, cache.Key("verification:id", convert.UUIDToString(id)))
|
||||
go func() {
|
||||
_ = v.c.DelByPattern(context.Background(), "verification:count*")
|
||||
}()
|
||||
@@ -249,13 +245,13 @@ func (v *verificationRepository) BulkVerificationMediaByMediaId(ctx context.Cont
|
||||
return nil
|
||||
}
|
||||
|
||||
listCacheId := make([]string, 0)
|
||||
listCacheId := make([]string, 0, len(ids))
|
||||
for _, it := range ids {
|
||||
id := convert.UUIDToString(it)
|
||||
if id == "" {
|
||||
continue
|
||||
}
|
||||
listCacheId = append(listCacheId, fmt.Sprintf("verification:id:%s", id))
|
||||
listCacheId = append(listCacheId, cache.Key("verification:id", id))
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -276,7 +272,7 @@ func (v *verificationRepository) DeleteVerificationMedia(ctx context.Context, pa
|
||||
}
|
||||
|
||||
func (v *verificationRepository) GetByUserID(ctx context.Context, userId pgtype.UUID) ([]*models.UserVerificationEntity, error) {
|
||||
queryKey := fmt.Sprintf("verification:userId:%s", convert.UUIDToString(userId))
|
||||
queryKey := cache.Key("verification:userId", convert.UUIDToString(userId))
|
||||
var cachedIDs []string
|
||||
err := v.c.Get(ctx, queryKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -299,9 +295,9 @@ func (v *verificationRepository) GetByUserID(ctx context.Context, userId pgtype.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var items []*models.UserVerificationEntity
|
||||
var ids []string
|
||||
itemToCache := make(map[string]any)
|
||||
items := make([]*models.UserVerificationEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
itemToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
verification := &models.UserVerificationEntity{
|
||||
@@ -329,7 +325,7 @@ func (v *verificationRepository) GetByUserID(ctx context.Context, userId pgtype.
|
||||
ids = append(ids, verification.ID)
|
||||
items = append(items, verification)
|
||||
|
||||
itemToCache[fmt.Sprintf("verification:id:%s", verification.ID)] = verification
|
||||
itemToCache[cache.Key("verification:id", verification.ID)] = verification
|
||||
}
|
||||
|
||||
if len(itemToCache) > 0 {
|
||||
@@ -365,9 +361,9 @@ func (v *verificationRepository) Search(ctx context.Context, params sqlc.SearchU
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var items []*models.UserVerificationEntity
|
||||
var ids []string
|
||||
itemToCache := make(map[string]any)
|
||||
items := make([]*models.UserVerificationEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
itemToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
verification := &models.UserVerificationEntity{
|
||||
@@ -396,7 +392,7 @@ func (v *verificationRepository) Search(ctx context.Context, params sqlc.SearchU
|
||||
ids = append(ids, verification.ID)
|
||||
items = append(items, verification)
|
||||
|
||||
itemToCache[fmt.Sprintf("verification:id:%s", verification.ID)] = verification
|
||||
itemToCache[cache.Key("verification:id", verification.ID)] = verification
|
||||
}
|
||||
|
||||
if len(itemToCache) > 0 {
|
||||
|
||||
@@ -2,9 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
json "history-api/pkg/jsonx"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
@@ -60,9 +58,7 @@ func (r *wikiRepository) WithTx(tx pgx.Tx) WikiRepository {
|
||||
}
|
||||
|
||||
func (r *wikiRepository) generateQueryKey(prefix string, params any) string {
|
||||
b, _ := json.Marshal(params)
|
||||
hash := fmt.Sprintf("%x", md5.Sum(b))
|
||||
return fmt.Sprintf("%s:%s", prefix, hash)
|
||||
return cache.QueryKey(prefix, params)
|
||||
}
|
||||
|
||||
func (r *wikiRepository) getByIDsWithFallback(ctx context.Context, ids []string) ([]*models.WikiEntity, error) {
|
||||
@@ -71,14 +67,14 @@ func (r *wikiRepository) getByIDsWithFallback(ctx context.Context, ids []string)
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("wiki:id:%s", id)
|
||||
keys[i] = cache.Key("wiki:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var wikis []*models.WikiEntity
|
||||
missingToCache := make(map[string]any)
|
||||
wikis := make([]*models.WikiEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -89,7 +85,7 @@ func (r *wikiRepository) getByIDsWithFallback(ctx context.Context, ids []string)
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.WikiEntity)
|
||||
dbMap := make(map[string]*models.WikiEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetWikisByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -148,7 +144,7 @@ func (r *wikiRepository) GetByIDs(ctx context.Context, ids []string) ([]*models.
|
||||
}
|
||||
|
||||
func (r *wikiRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.WikiEntity, error) {
|
||||
cacheId := fmt.Sprintf("wiki:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("wiki:id", convert.UUIDToString(id))
|
||||
var wiki models.WikiEntity
|
||||
err := r.c.Get(ctx, cacheId, &wiki)
|
||||
if err == nil {
|
||||
@@ -173,6 +169,7 @@ func (r *wikiRepository) GetByID(ctx context.Context, id pgtype.UUID) (*models.W
|
||||
|
||||
samples, err := r.q.GetWikiContentByWikiID(ctx, row.ID)
|
||||
if err == nil {
|
||||
wiki.ContentSample = make([]models.WikiContentSample, 0, len(samples))
|
||||
for _, sample := range samples {
|
||||
wiki.ContentSample = append(wiki.ContentSample, models.WikiContentSample{
|
||||
ID: convert.UUIDToString(sample.ID),
|
||||
@@ -202,11 +199,11 @@ func (r *wikiRepository) Search(ctx context.Context, params sqlc.SearchWikisPara
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var wikis []*models.WikiEntity
|
||||
var ids []string
|
||||
var pgIds []pgtype.UUID
|
||||
wikiMap := make(map[string]*models.WikiEntity)
|
||||
wikiToCache := make(map[string]any)
|
||||
wikis := make([]*models.WikiEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
pgIds := make([]pgtype.UUID, 0, len(rows))
|
||||
wikiMap := make(map[string]*models.WikiEntity, len(rows))
|
||||
wikiToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
wiki := &models.WikiEntity{
|
||||
@@ -241,7 +238,7 @@ func (r *wikiRepository) Search(ctx context.Context, params sqlc.SearchWikisPara
|
||||
}
|
||||
|
||||
for _, wiki := range wikis {
|
||||
wikiToCache[fmt.Sprintf("wiki:id:%s", wiki.ID)] = wiki
|
||||
wikiToCache[cache.Key("wiki:id", wiki.ID)] = wiki
|
||||
}
|
||||
if len(wikiToCache) > 0 {
|
||||
_ = r.c.MSet(ctx, wikiToCache, constants.NormalCacheDuration)
|
||||
@@ -284,8 +281,7 @@ func (r *wikiRepository) Update(ctx context.Context, params sqlc.UpdateWikiParam
|
||||
CreatedAt: convert.TimeToPtr(row.CreatedAt),
|
||||
UpdatedAt: convert.TimeToPtr(row.UpdatedAt),
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("wiki:id:%s", wiki.ID))
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("wiki:slug:%s", wiki.Slug))
|
||||
_ = r.c.Del(ctx, cache.Key("wiki:id", wiki.ID), cache.Key("wiki:slug", wiki.Slug))
|
||||
return &wiki, nil
|
||||
}
|
||||
|
||||
@@ -294,7 +290,7 @@ func (r *wikiRepository) Delete(ctx context.Context, id pgtype.UUID) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = r.c.Del(ctx, fmt.Sprintf("wiki:id:%s", convert.UUIDToString(id)))
|
||||
_ = r.c.Del(ctx, cache.Key("wiki:id", convert.UUIDToString(id)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -315,7 +311,7 @@ func (r *wikiRepository) BulkDeleteEntityWikisByEntityId(ctx context.Context, en
|
||||
}
|
||||
|
||||
func (r *wikiRepository) GetByProjectID(ctx context.Context, projectID pgtype.UUID) ([]*models.WikiEntity, error) {
|
||||
cacheKey := fmt.Sprintf("wiki:project:%s", convert.UUIDToString(projectID))
|
||||
cacheKey := cache.Key("wiki:project", convert.UUIDToString(projectID))
|
||||
var cachedIDs []string
|
||||
err := r.c.Get(ctx, cacheKey, &cachedIDs)
|
||||
if err == nil {
|
||||
@@ -330,11 +326,11 @@ func (r *wikiRepository) GetByProjectID(ctx context.Context, projectID pgtype.UU
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var wikis []*models.WikiEntity
|
||||
var ids []string
|
||||
var pgIds []pgtype.UUID
|
||||
wikiMap := make(map[string]*models.WikiEntity)
|
||||
wikiToCache := make(map[string]any)
|
||||
wikis := make([]*models.WikiEntity, 0, len(rows))
|
||||
ids := make([]string, 0, len(rows))
|
||||
pgIds := make([]pgtype.UUID, 0, len(rows))
|
||||
wikiMap := make(map[string]*models.WikiEntity, len(rows))
|
||||
wikiToCache := make(map[string]any, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
wiki := &models.WikiEntity{
|
||||
@@ -369,7 +365,7 @@ func (r *wikiRepository) GetByProjectID(ctx context.Context, projectID pgtype.UU
|
||||
}
|
||||
|
||||
for _, wiki := range wikis {
|
||||
wikiToCache[fmt.Sprintf("wiki:id:%s", wiki.ID)] = wiki
|
||||
wikiToCache[cache.Key("wiki:id", wiki.ID)] = wiki
|
||||
}
|
||||
if len(wikiToCache) > 0 {
|
||||
_ = r.c.MSet(ctx, wikiToCache, constants.NormalCacheDuration)
|
||||
@@ -387,7 +383,7 @@ func (r *wikiRepository) DeleteByIDs(ctx context.Context, ids []pgtype.UUID) err
|
||||
if len(ids) > 0 {
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("wiki:id:%s", convert.UUIDToString(id))
|
||||
keys[i] = cache.Key("wiki:id", convert.UUIDToString(id))
|
||||
}
|
||||
_ = r.c.Del(ctx, keys...)
|
||||
}
|
||||
@@ -406,7 +402,7 @@ func (r *wikiRepository) DeleteEntityWiki(ctx context.Context, entityID pgtype.U
|
||||
}
|
||||
|
||||
func (r *wikiRepository) GetBySlug(ctx context.Context, slug string) (*models.WikiEntity, error) {
|
||||
cacheKey := fmt.Sprintf("wiki:slug:%s", slug)
|
||||
cacheKey := cache.Key("wiki:slug", slug)
|
||||
var wiki models.WikiEntity
|
||||
err := r.c.Get(ctx, cacheKey, &wiki)
|
||||
if err == nil {
|
||||
@@ -431,6 +427,7 @@ func (r *wikiRepository) GetBySlug(ctx context.Context, slug string) (*models.Wi
|
||||
|
||||
samples, err := r.q.GetWikiContentByWikiID(ctx, row.ID)
|
||||
if err == nil {
|
||||
wiki.ContentSample = make([]models.WikiContentSample, 0, len(samples))
|
||||
for _, sample := range samples {
|
||||
wiki.ContentSample = append(wiki.ContentSample, models.WikiContentSample{
|
||||
ID: convert.UUIDToString(sample.ID),
|
||||
@@ -451,13 +448,13 @@ func (r *wikiRepository) GetBySlugs(ctx context.Context, slugs []string) ([]*mod
|
||||
}
|
||||
keys := make([]string, len(slugs))
|
||||
for i, slug := range slugs {
|
||||
keys[i] = fmt.Sprintf("wiki:slug:%s", slug)
|
||||
keys[i] = cache.Key("wiki:slug", slug)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var wikis []*models.WikiEntity
|
||||
missingToCache := make(map[string]any)
|
||||
var missingSlugs []string
|
||||
wikis := make([]*models.WikiEntity, 0, len(slugs))
|
||||
missingToCache := make(map[string]any, len(slugs))
|
||||
missingSlugs := make([]string, 0, len(slugs))
|
||||
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
@@ -465,11 +462,11 @@ func (r *wikiRepository) GetBySlugs(ctx context.Context, slugs []string) ([]*mod
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.WikiEntity)
|
||||
dbMap := make(map[string]*models.WikiEntity, len(missingSlugs))
|
||||
if len(missingSlugs) > 0 {
|
||||
dbRows, err := r.q.GetWikisBySlugs(ctx, missingSlugs)
|
||||
if err == nil {
|
||||
var pgIds []pgtype.UUID
|
||||
pgIds := make([]pgtype.UUID, 0, len(dbRows))
|
||||
for _, row := range dbRows {
|
||||
item := models.WikiEntity{
|
||||
ID: convert.UUIDToString(row.ID),
|
||||
@@ -487,7 +484,7 @@ func (r *wikiRepository) GetBySlugs(ctx context.Context, slugs []string) ([]*mod
|
||||
if len(pgIds) > 0 {
|
||||
samples, sErr := r.q.GetWikiContentByWikiIDs(ctx, pgIds)
|
||||
if sErr == nil {
|
||||
wikiByID := make(map[string]*models.WikiEntity)
|
||||
wikiByID := make(map[string]*models.WikiEntity, len(dbMap))
|
||||
for _, item := range dbMap {
|
||||
wikiByID[item.ID] = item
|
||||
}
|
||||
@@ -554,14 +551,14 @@ func (r *wikiRepository) getContentByIDsWithFallback(ctx context.Context, ids []
|
||||
}
|
||||
keys := make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
keys[i] = fmt.Sprintf("wiki_content:id:%s", id)
|
||||
keys[i] = cache.Key("wiki_content:id", id)
|
||||
}
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
|
||||
var contents []*models.WikiContentEntity
|
||||
missingToCache := make(map[string]any)
|
||||
contents := make([]*models.WikiContentEntity, 0, len(ids))
|
||||
missingToCache := make(map[string]any, len(ids))
|
||||
|
||||
var missingPgIds []pgtype.UUID
|
||||
missingPgIds := make([]pgtype.UUID, 0, len(ids))
|
||||
for i, b := range raws {
|
||||
if len(b) == 0 {
|
||||
pgId := pgtype.UUID{}
|
||||
@@ -572,7 +569,7 @@ func (r *wikiRepository) getContentByIDsWithFallback(ctx context.Context, ids []
|
||||
}
|
||||
}
|
||||
|
||||
dbMap := make(map[string]*models.WikiContentEntity)
|
||||
dbMap := make(map[string]*models.WikiContentEntity, len(missingPgIds))
|
||||
if len(missingPgIds) > 0 {
|
||||
dbRows, err := r.q.GetWikiContentByIDs(ctx, missingPgIds)
|
||||
if err == nil {
|
||||
@@ -613,7 +610,7 @@ func (r *wikiRepository) getContentByIDsWithFallback(ctx context.Context, ids []
|
||||
}
|
||||
|
||||
func (r *wikiRepository) GetContentByID(ctx context.Context, id pgtype.UUID) (*models.WikiContentEntity, error) {
|
||||
cacheId := fmt.Sprintf("wiki_content:id:%s", convert.UUIDToString(id))
|
||||
cacheId := cache.Key("wiki_content:id", convert.UUIDToString(id))
|
||||
var content models.WikiContentEntity
|
||||
err := r.c.Get(ctx, cacheId, &content)
|
||||
if err == nil {
|
||||
@@ -651,13 +648,13 @@ func (r *wikiRepository) GetWikiIDsByEntityIDs(ctx context.Context, entityIDs []
|
||||
|
||||
keys := make([]string, len(entityIDs))
|
||||
for i, id := range entityIDs {
|
||||
keys[i] = fmt.Sprintf("entity_wikis:entity:%s", id)
|
||||
keys[i] = cache.Key("entity_wikis:entity", id)
|
||||
}
|
||||
|
||||
raws := r.c.MGet(ctx, keys...)
|
||||
result := make(map[string][]string)
|
||||
var missingEntityIDs []string
|
||||
var missingPgIDs []pgtype.UUID
|
||||
result := make(map[string][]string, len(entityIDs))
|
||||
missingEntityIDs := make([]string, 0, len(entityIDs))
|
||||
missingPgIDs := make([]pgtype.UUID, 0, len(entityIDs))
|
||||
|
||||
for i, b := range raws {
|
||||
if len(b) > 0 {
|
||||
@@ -680,7 +677,7 @@ func (r *wikiRepository) GetWikiIDsByEntityIDs(ctx context.Context, entityIDs []
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbMap := make(map[string][]string)
|
||||
dbMap := make(map[string][]string, len(missingEntityIDs))
|
||||
for _, id := range missingEntityIDs {
|
||||
dbMap[id] = []string{}
|
||||
}
|
||||
@@ -690,10 +687,10 @@ func (r *wikiRepository) GetWikiIDsByEntityIDs(ctx context.Context, entityIDs []
|
||||
dbMap[eID] = append(dbMap[eID], wID)
|
||||
}
|
||||
|
||||
missingToCache := make(map[string]any)
|
||||
missingToCache := make(map[string]any, len(dbMap))
|
||||
for eID, wIDs := range dbMap {
|
||||
result[eID] = wIDs
|
||||
missingToCache[fmt.Sprintf("entity_wikis:entity:%s", eID)] = wIDs
|
||||
missingToCache[cache.Key("entity_wikis:entity", eID)] = wIDs
|
||||
}
|
||||
if len(missingToCache) > 0 {
|
||||
_ = r.c.MSet(ctx, missingToCache, constants.NormalCacheDuration)
|
||||
|
||||
Reference in New Issue
Block a user