/{cmd,docs,internal}: support import export for dolt backends
This commit is contained in:
@@ -17,6 +17,12 @@ type doltTransaction struct {
|
||||
store *DoltStore
|
||||
}
|
||||
|
||||
// CreateIssueImport is the import-friendly issue creation hook.
|
||||
// Dolt does not enforce prefix validation at the storage layer, so this delegates to CreateIssue.
|
||||
func (t *doltTransaction) CreateIssueImport(ctx context.Context, issue *types.Issue, actor string, skipPrefixValidation bool) error {
|
||||
return t.CreateIssue(ctx, issue, actor)
|
||||
}
|
||||
|
||||
// RunInTransaction executes a function within a database transaction
|
||||
func (s *DoltStore) RunInTransaction(ctx context.Context, fn func(tx storage.Transaction) error) error {
|
||||
sqlTx, err := s.db.BeginTx(ctx, nil)
|
||||
@@ -169,6 +175,36 @@ func (t *doltTransaction) AddDependency(ctx context.Context, dep *types.Dependen
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *doltTransaction) GetDependencyRecords(ctx context.Context, issueID string) ([]*types.Dependency, error) {
|
||||
rows, err := t.tx.QueryContext(ctx, `
|
||||
SELECT issue_id, depends_on_id, type, created_at, created_by, metadata, thread_id
|
||||
FROM dependencies
|
||||
WHERE issue_id = ?
|
||||
`, issueID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var deps []*types.Dependency
|
||||
for rows.Next() {
|
||||
var d types.Dependency
|
||||
var metadata sql.NullString
|
||||
var threadID sql.NullString
|
||||
if err := rows.Scan(&d.IssueID, &d.DependsOnID, &d.Type, &d.CreatedAt, &d.CreatedBy, &metadata, &threadID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if metadata.Valid {
|
||||
d.Metadata = metadata.String
|
||||
}
|
||||
if threadID.Valid {
|
||||
d.ThreadID = threadID.String
|
||||
}
|
||||
deps = append(deps, &d)
|
||||
}
|
||||
return deps, rows.Err()
|
||||
}
|
||||
|
||||
// RemoveDependency removes a dependency within the transaction
|
||||
func (t *doltTransaction) RemoveDependency(ctx context.Context, issueID, dependsOnID string, actor string) error {
|
||||
_, err := t.tx.ExecContext(ctx, `
|
||||
@@ -185,6 +221,23 @@ func (t *doltTransaction) AddLabel(ctx context.Context, issueID, label, actor st
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *doltTransaction) GetLabels(ctx context.Context, issueID string) ([]string, error) {
|
||||
rows, err := t.tx.QueryContext(ctx, `SELECT label FROM labels WHERE issue_id = ? ORDER BY label`, issueID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var labels []string
|
||||
for rows.Next() {
|
||||
var l string
|
||||
if err := rows.Scan(&l); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
labels = append(labels, l)
|
||||
}
|
||||
return labels, rows.Err()
|
||||
}
|
||||
|
||||
// RemoveLabel removes a label within the transaction
|
||||
func (t *doltTransaction) RemoveLabel(ctx context.Context, issueID, label, actor string) error {
|
||||
_, err := t.tx.ExecContext(ctx, `
|
||||
@@ -231,6 +284,63 @@ func (t *doltTransaction) GetMetadata(ctx context.Context, key string) (string,
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (t *doltTransaction) ImportIssueComment(ctx context.Context, issueID, author, text string, createdAt time.Time) (*types.Comment, error) {
|
||||
// Verify issue exists in tx
|
||||
iss, err := t.GetIssue(ctx, issueID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if iss == nil {
|
||||
return nil, fmt.Errorf("issue %s not found", issueID)
|
||||
}
|
||||
|
||||
createdAt = createdAt.UTC()
|
||||
res, err := t.tx.ExecContext(ctx, `
|
||||
INSERT INTO comments (issue_id, author, text, created_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
`, issueID, author, text, createdAt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add comment: %w", err)
|
||||
}
|
||||
id, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get comment id: %w", err)
|
||||
}
|
||||
|
||||
// mark dirty in tx
|
||||
if _, err := t.tx.ExecContext(ctx, `
|
||||
INSERT INTO dirty_issues (issue_id, marked_at)
|
||||
VALUES (?, ?)
|
||||
ON DUPLICATE KEY UPDATE marked_at = VALUES(marked_at)
|
||||
`, issueID, time.Now().UTC()); err != nil {
|
||||
return nil, fmt.Errorf("failed to mark issue dirty: %w", err)
|
||||
}
|
||||
|
||||
return &types.Comment{ID: id, IssueID: issueID, Author: author, Text: text, CreatedAt: createdAt}, nil
|
||||
}
|
||||
|
||||
func (t *doltTransaction) GetIssueComments(ctx context.Context, issueID string) ([]*types.Comment, error) {
|
||||
rows, err := t.tx.QueryContext(ctx, `
|
||||
SELECT id, issue_id, author, text, created_at
|
||||
FROM comments
|
||||
WHERE issue_id = ?
|
||||
ORDER BY created_at ASC
|
||||
`, issueID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var comments []*types.Comment
|
||||
for rows.Next() {
|
||||
var c types.Comment
|
||||
if err := rows.Scan(&c.ID, &c.IssueID, &c.Author, &c.Text, &c.CreatedAt); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
comments = append(comments, &c)
|
||||
}
|
||||
return comments, rows.Err()
|
||||
}
|
||||
|
||||
// AddComment adds a comment within the transaction
|
||||
func (t *doltTransaction) AddComment(ctx context.Context, issueID, actor, comment string) error {
|
||||
_, err := t.tx.ExecContext(ctx, `
|
||||
|
||||
Reference in New Issue
Block a user