Implement complete collection persistence with database-backed survival across server restarts
• Add full multi-table schema for collections with normalized design (collections, collection_templates, collection_items, collection_item_versions) • Implement collection detection and processing in enhancement pipeline for .insertr-add elements • Add template extraction and storage from existing HTML children with multi-variant support • Enable collection reconstruction from database on server restart with proper DOM rebuilding • Extend ContentClient interface with collection operations and full database integration • Update enhance command to use engine.DatabaseClient for collection persistence support
This commit is contained in:
327
internal/db/postgresql/collection_items.sql.go
Normal file
327
internal/db/postgresql/collection_items.sql.go
Normal file
@@ -0,0 +1,327 @@
|
||||
// Code generated by sqlc. DO NOT EDIT.
|
||||
// versions:
|
||||
// sqlc v1.30.0
|
||||
// source: collection_items.sql
|
||||
|
||||
package postgresql
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
const createCollectionItem = `-- name: CreateCollectionItem :one
|
||||
INSERT INTO collection_items (item_id, collection_id, site_id, template_id, html_content, position, last_edited_by)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING item_id, collection_id, site_id, template_id, html_content, position, created_at, updated_at, last_edited_by
|
||||
`
|
||||
|
||||
type CreateCollectionItemParams struct {
|
||||
ItemID string `json:"item_id"`
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
TemplateID int32 `json:"template_id"`
|
||||
HtmlContent string `json:"html_content"`
|
||||
Position int32 `json:"position"`
|
||||
LastEditedBy string `json:"last_edited_by"`
|
||||
}
|
||||
|
||||
func (q *Queries) CreateCollectionItem(ctx context.Context, arg CreateCollectionItemParams) (CollectionItem, error) {
|
||||
row := q.db.QueryRowContext(ctx, createCollectionItem,
|
||||
arg.ItemID,
|
||||
arg.CollectionID,
|
||||
arg.SiteID,
|
||||
arg.TemplateID,
|
||||
arg.HtmlContent,
|
||||
arg.Position,
|
||||
arg.LastEditedBy,
|
||||
)
|
||||
var i CollectionItem
|
||||
err := row.Scan(
|
||||
&i.ItemID,
|
||||
&i.CollectionID,
|
||||
&i.SiteID,
|
||||
&i.TemplateID,
|
||||
&i.HtmlContent,
|
||||
&i.Position,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.LastEditedBy,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteCollectionItem = `-- name: DeleteCollectionItem :exec
|
||||
DELETE FROM collection_items
|
||||
WHERE item_id = $1 AND collection_id = $2 AND site_id = $3
|
||||
`
|
||||
|
||||
type DeleteCollectionItemParams struct {
|
||||
ItemID string `json:"item_id"`
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteCollectionItem(ctx context.Context, arg DeleteCollectionItemParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteCollectionItem, arg.ItemID, arg.CollectionID, arg.SiteID)
|
||||
return err
|
||||
}
|
||||
|
||||
const deleteCollectionItems = `-- name: DeleteCollectionItems :exec
|
||||
DELETE FROM collection_items
|
||||
WHERE collection_id = $1 AND site_id = $2
|
||||
`
|
||||
|
||||
type DeleteCollectionItemsParams struct {
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) DeleteCollectionItems(ctx context.Context, arg DeleteCollectionItemsParams) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteCollectionItems, arg.CollectionID, arg.SiteID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getCollectionItem = `-- name: GetCollectionItem :one
|
||||
|
||||
SELECT item_id, collection_id, site_id, template_id, html_content, position, created_at, updated_at, last_edited_by
|
||||
FROM collection_items
|
||||
WHERE item_id = $1 AND collection_id = $2 AND site_id = $3
|
||||
`
|
||||
|
||||
type GetCollectionItemParams struct {
|
||||
ItemID string `json:"item_id"`
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
// Collection items table queries
|
||||
func (q *Queries) GetCollectionItem(ctx context.Context, arg GetCollectionItemParams) (CollectionItem, error) {
|
||||
row := q.db.QueryRowContext(ctx, getCollectionItem, arg.ItemID, arg.CollectionID, arg.SiteID)
|
||||
var i CollectionItem
|
||||
err := row.Scan(
|
||||
&i.ItemID,
|
||||
&i.CollectionID,
|
||||
&i.SiteID,
|
||||
&i.TemplateID,
|
||||
&i.HtmlContent,
|
||||
&i.Position,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.LastEditedBy,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getCollectionItems = `-- name: GetCollectionItems :many
|
||||
SELECT item_id, collection_id, site_id, template_id, html_content, position, created_at, updated_at, last_edited_by
|
||||
FROM collection_items
|
||||
WHERE collection_id = $1 AND site_id = $2
|
||||
ORDER BY position ASC
|
||||
`
|
||||
|
||||
type GetCollectionItemsParams struct {
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetCollectionItems(ctx context.Context, arg GetCollectionItemsParams) ([]CollectionItem, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getCollectionItems, arg.CollectionID, arg.SiteID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []CollectionItem
|
||||
for rows.Next() {
|
||||
var i CollectionItem
|
||||
if err := rows.Scan(
|
||||
&i.ItemID,
|
||||
&i.CollectionID,
|
||||
&i.SiteID,
|
||||
&i.TemplateID,
|
||||
&i.HtmlContent,
|
||||
&i.Position,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.LastEditedBy,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getCollectionItemsWithTemplate = `-- name: GetCollectionItemsWithTemplate :many
|
||||
SELECT
|
||||
ci.item_id, ci.collection_id, ci.site_id, ci.template_id, ci.html_content, ci.position, ci.created_at, ci.updated_at, ci.last_edited_by,
|
||||
ct.name as template_name, ct.html_template, ct.is_default
|
||||
FROM collection_items ci
|
||||
JOIN collection_templates ct ON ci.template_id = ct.template_id
|
||||
WHERE ci.collection_id = $1 AND ci.site_id = $2
|
||||
ORDER BY ci.position ASC
|
||||
`
|
||||
|
||||
type GetCollectionItemsWithTemplateParams struct {
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
type GetCollectionItemsWithTemplateRow struct {
|
||||
ItemID string `json:"item_id"`
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
TemplateID int32 `json:"template_id"`
|
||||
HtmlContent string `json:"html_content"`
|
||||
Position int32 `json:"position"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
LastEditedBy string `json:"last_edited_by"`
|
||||
TemplateName string `json:"template_name"`
|
||||
HtmlTemplate string `json:"html_template"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetCollectionItemsWithTemplate(ctx context.Context, arg GetCollectionItemsWithTemplateParams) ([]GetCollectionItemsWithTemplateRow, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getCollectionItemsWithTemplate, arg.CollectionID, arg.SiteID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []GetCollectionItemsWithTemplateRow
|
||||
for rows.Next() {
|
||||
var i GetCollectionItemsWithTemplateRow
|
||||
if err := rows.Scan(
|
||||
&i.ItemID,
|
||||
&i.CollectionID,
|
||||
&i.SiteID,
|
||||
&i.TemplateID,
|
||||
&i.HtmlContent,
|
||||
&i.Position,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.LastEditedBy,
|
||||
&i.TemplateName,
|
||||
&i.HtmlTemplate,
|
||||
&i.IsDefault,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getMaxPosition = `-- name: GetMaxPosition :one
|
||||
SELECT COALESCE(MAX(position), 0) as max_position
|
||||
FROM collection_items
|
||||
WHERE collection_id = $1 AND site_id = $2
|
||||
`
|
||||
|
||||
type GetMaxPositionParams struct {
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetMaxPosition(ctx context.Context, arg GetMaxPositionParams) (interface{}, error) {
|
||||
row := q.db.QueryRowContext(ctx, getMaxPosition, arg.CollectionID, arg.SiteID)
|
||||
var max_position interface{}
|
||||
err := row.Scan(&max_position)
|
||||
return max_position, err
|
||||
}
|
||||
|
||||
const reorderCollectionItems = `-- name: ReorderCollectionItems :exec
|
||||
UPDATE collection_items
|
||||
SET position = position + $1
|
||||
WHERE collection_id = $2 AND site_id = $3
|
||||
AND position >= $4
|
||||
`
|
||||
|
||||
type ReorderCollectionItemsParams struct {
|
||||
PositionDelta int32 `json:"position_delta"`
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
StartPosition int32 `json:"start_position"`
|
||||
}
|
||||
|
||||
func (q *Queries) ReorderCollectionItems(ctx context.Context, arg ReorderCollectionItemsParams) error {
|
||||
_, err := q.db.ExecContext(ctx, reorderCollectionItems,
|
||||
arg.PositionDelta,
|
||||
arg.CollectionID,
|
||||
arg.SiteID,
|
||||
arg.StartPosition,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const updateCollectionItem = `-- name: UpdateCollectionItem :one
|
||||
UPDATE collection_items
|
||||
SET html_content = $1, last_edited_by = $2
|
||||
WHERE item_id = $3 AND collection_id = $4 AND site_id = $5
|
||||
RETURNING item_id, collection_id, site_id, template_id, html_content, position, created_at, updated_at, last_edited_by
|
||||
`
|
||||
|
||||
type UpdateCollectionItemParams struct {
|
||||
HtmlContent string `json:"html_content"`
|
||||
LastEditedBy string `json:"last_edited_by"`
|
||||
ItemID string `json:"item_id"`
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateCollectionItem(ctx context.Context, arg UpdateCollectionItemParams) (CollectionItem, error) {
|
||||
row := q.db.QueryRowContext(ctx, updateCollectionItem,
|
||||
arg.HtmlContent,
|
||||
arg.LastEditedBy,
|
||||
arg.ItemID,
|
||||
arg.CollectionID,
|
||||
arg.SiteID,
|
||||
)
|
||||
var i CollectionItem
|
||||
err := row.Scan(
|
||||
&i.ItemID,
|
||||
&i.CollectionID,
|
||||
&i.SiteID,
|
||||
&i.TemplateID,
|
||||
&i.HtmlContent,
|
||||
&i.Position,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.LastEditedBy,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateCollectionItemPosition = `-- name: UpdateCollectionItemPosition :exec
|
||||
UPDATE collection_items
|
||||
SET position = $1
|
||||
WHERE item_id = $2 AND collection_id = $3 AND site_id = $4
|
||||
`
|
||||
|
||||
type UpdateCollectionItemPositionParams struct {
|
||||
Position int32 `json:"position"`
|
||||
ItemID string `json:"item_id"`
|
||||
CollectionID string `json:"collection_id"`
|
||||
SiteID string `json:"site_id"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateCollectionItemPosition(ctx context.Context, arg UpdateCollectionItemPositionParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateCollectionItemPosition,
|
||||
arg.Position,
|
||||
arg.ItemID,
|
||||
arg.CollectionID,
|
||||
arg.SiteID,
|
||||
)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user