feat(db): backfill prefix snapshots and switch read path
Backfill миграция; чтение префиксов через snapshot; запись без дублирования rows. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -800,6 +800,9 @@ func (p *Postgres) ListRevisionPrefixes(tenantID, revisionID string, cursor stri
|
||||
}
|
||||
return nil, "", false
|
||||
}
|
||||
if snapID, ok := p.revisionPrefixSnapshotID(ctx, revisionID); ok {
|
||||
return p.listSnapshotPrefixes(ctx, snapID, cursor, limit)
|
||||
}
|
||||
var rows pgx.Rows
|
||||
var err error
|
||||
if useOffset {
|
||||
@@ -884,11 +887,7 @@ func (p *Postgres) CreateRollbackRevision(tenantID, sourceRevisionID string) (st
|
||||
if err := copyRevisionPreview(ctx, tx, newID, sourceRevisionID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
_, err = tx.Exec(ctx, `
|
||||
INSERT INTO revision_materialized_prefix (revision_id, prefix, community_id, source, meta_json)
|
||||
SELECT $1::uuid, prefix, community_id, source, meta_json FROM revision_materialized_prefix WHERE revision_id=$2::uuid`,
|
||||
newID, sourceRevisionID)
|
||||
if err != nil {
|
||||
if err := p.copyRevisionPrefixSnapshotRef(ctx, tx, newID, sourceRevisionID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
@@ -909,19 +908,17 @@ func (p *Postgres) RevisionDiff(tenantID, aID, bID string) (map[string]any, erro
|
||||
ctx := context.Background()
|
||||
var unchanged int
|
||||
err := p.pool.QueryRow(ctx, `
|
||||
SELECT COUNT(*)::int FROM revision_materialized_prefix b
|
||||
INNER JOIN revision_materialized_prefix a
|
||||
ON a.revision_id = $1::uuid AND a.prefix = b.prefix
|
||||
WHERE b.revision_id = $2::uuid`, aID, bID).Scan(&unchanged)
|
||||
SELECT COUNT(*)::int FROM (
|
||||
SELECT b.prefix FROM (`+sqlRevisionPrefixes("$2")+`) b
|
||||
INNER JOIN (`+sqlRevisionPrefixes("$1")+`) a ON a.prefix = b.prefix
|
||||
) t`, aID, bID).Scan(&unchanged)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rowsAdded, err := p.pool.Query(ctx, `
|
||||
SELECT b.prefix::text
|
||||
FROM revision_materialized_prefix b
|
||||
LEFT JOIN revision_materialized_prefix a
|
||||
ON a.revision_id = $1::uuid AND a.prefix = b.prefix
|
||||
WHERE b.revision_id = $2::uuid AND a.prefix IS NULL
|
||||
SELECT b.prefix::text FROM (`+sqlRevisionPrefixes("$2")+`) b
|
||||
LEFT JOIN (`+sqlRevisionPrefixes("$1")+`) a ON a.prefix = b.prefix
|
||||
WHERE a.prefix IS NULL
|
||||
ORDER BY b.prefix
|
||||
LIMIT $3`, aID, bID, maxRevisionDiffRows+1)
|
||||
if err != nil {
|
||||
@@ -942,11 +939,9 @@ func (p *Postgres) RevisionDiff(tenantID, aID, bID string) (map[string]any, erro
|
||||
}
|
||||
addedTruncated := len(added) >= maxRevisionDiffRows
|
||||
rowsRem, err := p.pool.Query(ctx, `
|
||||
SELECT a.prefix::text
|
||||
FROM revision_materialized_prefix a
|
||||
LEFT JOIN revision_materialized_prefix b
|
||||
ON b.revision_id = $2::uuid AND b.prefix = a.prefix
|
||||
WHERE a.revision_id = $1::uuid AND b.prefix IS NULL
|
||||
SELECT a.prefix::text FROM (`+sqlRevisionPrefixes("$1")+`) a
|
||||
LEFT JOIN (`+sqlRevisionPrefixes("$2")+`) b ON b.prefix = a.prefix
|
||||
WHERE b.prefix IS NULL
|
||||
ORDER BY a.prefix
|
||||
LIMIT $3`, aID, bID, maxRevisionDiffRows+1)
|
||||
if err != nil {
|
||||
@@ -1109,25 +1104,12 @@ func (p *Postgres) CreateRenderRevision(revisionID, tenantID, moduleID string, p
|
||||
if err := insertRevisionPreview(ctx, tx, revID, previewFragments); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(prefixes) > 0 {
|
||||
_, err = tx.CopyFrom(ctx,
|
||||
pgx.Identifier{"revision_materialized_prefix"},
|
||||
[]string{"revision_id", "prefix", "community_id", "source"},
|
||||
pgx.CopyFromSlice(len(prefixes), func(i int) ([]any, error) {
|
||||
pr := prefixes[i]
|
||||
var comm any
|
||||
if pr.CommunityID != nil && strings.TrimSpace(*pr.CommunityID) != "" {
|
||||
comm = strings.TrimSpace(*pr.CommunityID)
|
||||
}
|
||||
src := pr.Source
|
||||
if strings.TrimSpace(src) == "" {
|
||||
src = "render"
|
||||
}
|
||||
return []any{revID, strings.TrimSpace(pr.Prefix), comm, src}, nil
|
||||
}))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
snapID, err := p.ensurePrefixSnapshot(ctx, tx, contentHash, prefixes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.linkRevisionPrefixSnapshot(ctx, tx, revID, snapID); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := tx.Commit(ctx); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user