1package db
2
3import (
4 "fmt"
5 "strings"
6 "time"
7
8 "github.com/bluesky-social/indigo/atproto/syntax"
9 "github.com/go-git/go-git/v5/plumbing"
10 "github.com/ipfs/go-cid"
11 "tangled.sh/tangled.sh/core/api/tangled"
12)
13
14type Artifact struct {
15 Id uint64
16 Did string
17 Rkey string
18
19 RepoAt syntax.ATURI
20 Tag plumbing.Hash
21 CreatedAt time.Time
22
23 BlobCid cid.Cid
24 Name string
25 Size uint64
26 MimeType string
27}
28
29func (a *Artifact) ArtifactAt() syntax.ATURI {
30 return syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", a.Did, tangled.RepoArtifactNSID, a.Rkey))
31}
32
33func AddArtifact(e Execer, artifact Artifact) error {
34 _, err := e.Exec(
35 `insert or ignore into artifacts (
36 did,
37 rkey,
38 repo_at,
39 tag,
40 created,
41 blob_cid,
42 name,
43 size,
44 mimetype
45 )
46 values (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
47 artifact.Did,
48 artifact.Rkey,
49 artifact.RepoAt,
50 artifact.Tag[:],
51 artifact.CreatedAt.Format(time.RFC3339),
52 artifact.BlobCid.String(),
53 artifact.Name,
54 artifact.Size,
55 artifact.MimeType,
56 )
57 return err
58}
59
60func GetArtifact(e Execer, filters ...filter) ([]Artifact, error) {
61 var artifacts []Artifact
62
63 var conditions []string
64 var args []any
65 for _, filter := range filters {
66 conditions = append(conditions, filter.Condition())
67 args = append(args, filter.Arg()...)
68 }
69
70 whereClause := ""
71 if conditions != nil {
72 whereClause = " where " + strings.Join(conditions, " and ")
73 }
74
75 query := fmt.Sprintf(`select
76 did,
77 rkey,
78 repo_at,
79 tag,
80 created,
81 blob_cid,
82 name,
83 size,
84 mimetype
85 from artifacts %s`,
86 whereClause,
87 )
88
89 rows, err := e.Query(query, args...)
90
91 if err != nil {
92 return nil, err
93 }
94 defer rows.Close()
95
96 for rows.Next() {
97 var artifact Artifact
98 var createdAt string
99 var tag []byte
100 var blobCid string
101
102 if err := rows.Scan(
103 &artifact.Did,
104 &artifact.Rkey,
105 &artifact.RepoAt,
106 &tag,
107 &createdAt,
108 &blobCid,
109 &artifact.Name,
110 &artifact.Size,
111 &artifact.MimeType,
112 ); err != nil {
113 return nil, err
114 }
115
116 artifact.CreatedAt, err = time.Parse(time.RFC3339, createdAt)
117 if err != nil {
118 artifact.CreatedAt = time.Now()
119 }
120 artifact.Tag = plumbing.Hash(tag)
121 artifact.BlobCid = cid.MustParse(blobCid)
122
123 artifacts = append(artifacts, artifact)
124 }
125
126 if err := rows.Err(); err != nil {
127 return nil, err
128 }
129
130 return artifacts, nil
131}
132
133func DeleteArtifact(e Execer, filters ...filter) error {
134 var conditions []string
135 var args []any
136 for _, filter := range filters {
137 conditions = append(conditions, filter.Condition())
138 args = append(args, filter.Arg()...)
139 }
140
141 whereClause := ""
142 if conditions != nil {
143 whereClause = " where " + strings.Join(conditions, " and ")
144 }
145
146 query := fmt.Sprintf(`delete from artifacts %s`, whereClause)
147
148 _, err := e.Exec(query, args...)
149 return err
150}