Files
ai_site/platform/internal/license/mirror.go
2026-07-31 10:31:17 +08:00

88 lines
2.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package license
import (
"context"
"database/sql"
"fmt"
"strings"
)
// ConsumedMirror 第二持久化(如 Postgresleases 目录被删后仍能识别已用过的 id。
type ConsumedMirror interface {
Load(ctx context.Context) (activeID string, ids []string, err error)
Save(ctx context.Context, activeID string, ids []string) error
}
type pgMirror struct {
db *sql.DB
}
func NewPGMirror(db *sql.DB) ConsumedMirror {
if db == nil {
return nil
}
return &pgMirror{db: db}
}
func (p *pgMirror) Load(ctx context.Context) (string, []string, error) {
rows, err := p.db.QueryContext(ctx, `
SELECT lease_id, active FROM platform_meta.license_consumed`)
if err != nil {
return "", nil, err
}
defer rows.Close()
var active string
var ids []string
for rows.Next() {
var id string
var isActive bool
if err := rows.Scan(&id, &isActive); err != nil {
return "", nil, err
}
ids = append(ids, id)
if isActive {
active = id
}
}
return active, ids, rows.Err()
}
func (p *pgMirror) Save(ctx context.Context, activeID string, ids []string) error {
tx, err := p.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer func() { _ = tx.Rollback() }()
if _, err := tx.ExecContext(ctx, `DELETE FROM platform_meta.license_consumed`); err != nil {
return err
}
for _, id := range ids {
id = trimID(id)
if id == "" {
continue
}
_, err := tx.ExecContext(ctx, `
INSERT INTO platform_meta.license_consumed(lease_id, active, updated_at)
VALUES ($1, $2, now())
ON CONFLICT (lease_id) DO UPDATE SET active=EXCLUDED.active, updated_at=now()`,
id, id == activeID)
if err != nil {
return fmt.Errorf("license_consumed upsert: %w", err)
}
}
if activeID != "" {
_, err := tx.ExecContext(ctx, `
INSERT INTO platform_meta.license_consumed(lease_id, active, updated_at)
VALUES ($1, true, now())
ON CONFLICT (lease_id) DO UPDATE SET active=true, updated_at=now()`, activeID)
if err != nil {
return err
}
}
return tx.Commit()
}
func trimID(s string) string {
return strings.TrimSpace(s)
}