105 lines
2.1 KiB
Go
105 lines
2.1 KiB
Go
// Path: Backend/internal/posixproj/projector.go
|
|
|
|
package posixproj
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"moku-backend/internal/database"
|
|
)
|
|
|
|
func NewProjector(db *database.DB, root string) *Projector {
|
|
return &Projector{db: db, root: strings.TrimSpace(root)}
|
|
}
|
|
|
|
func (projector *Projector) Rebuild(ctx context.Context) error {
|
|
_, err := projector.RebuildWithSummary(ctx)
|
|
return err
|
|
}
|
|
|
|
func (projector *Projector) RebuildWithSummary(ctx context.Context) (RebuildSummary, error) {
|
|
if projector == nil || projector.db == nil || projector.db.Pool == nil {
|
|
return RebuildSummary{}, nil
|
|
}
|
|
|
|
nodes, err := ScanRoot(projector.root)
|
|
if err != nil {
|
|
return RebuildSummary{}, err
|
|
}
|
|
|
|
summary := summarizeNodes(nodes)
|
|
|
|
tx, err := projector.db.Pool.Begin(ctx)
|
|
if err != nil {
|
|
return RebuildSummary{}, err
|
|
}
|
|
defer func() {
|
|
_ = tx.Rollback(ctx)
|
|
}()
|
|
|
|
if _, err := tx.Exec(ctx, `DELETE FROM posix_nodes;`); err != nil {
|
|
return RebuildSummary{}, fmt.Errorf("clear posix_nodes: %w", err)
|
|
}
|
|
|
|
for _, node := range nodes {
|
|
if _, err := tx.Exec(ctx, `
|
|
INSERT INTO posix_nodes (
|
|
path,
|
|
parent_path,
|
|
name,
|
|
depth,
|
|
node_kind,
|
|
logical_type,
|
|
file_role,
|
|
resource_id,
|
|
resource_name,
|
|
resource_slug,
|
|
installation_id,
|
|
organization_id,
|
|
organization_slug,
|
|
department_slug,
|
|
team_slug,
|
|
project_slug,
|
|
personal_slug,
|
|
content_json,
|
|
size_bytes,
|
|
checksum
|
|
) VALUES (
|
|
$1, $2, $3, $4, $5::posix_node_kind, $6, $7, $8, $9, $10,
|
|
$11, $12, $13, $14, $15, $16, $17, $18::jsonb, $19, $20
|
|
);
|
|
`,
|
|
node.Path,
|
|
node.ParentPath,
|
|
node.Name,
|
|
node.Depth,
|
|
string(node.NodeKind),
|
|
node.LogicalType,
|
|
node.FileRole,
|
|
node.ResourceID,
|
|
node.ResourceName,
|
|
node.ResourceSlug,
|
|
node.InstallationID,
|
|
node.OrganizationID,
|
|
node.OrganizationSlug,
|
|
node.DepartmentSlug,
|
|
node.TeamSlug,
|
|
node.ProjectSlug,
|
|
node.PersonalSlug,
|
|
node.ContentJSON,
|
|
node.SizeBytes,
|
|
node.Checksum,
|
|
); err != nil {
|
|
return RebuildSummary{}, fmt.Errorf("insert posix node %s: %w", node.Path, err)
|
|
}
|
|
}
|
|
|
|
if err := tx.Commit(ctx); err != nil {
|
|
return RebuildSummary{}, err
|
|
}
|
|
|
|
return summary, nil
|
|
}
|