forked from
tangled.org/core
Monorepo for Tangled — https://tangled.org
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.RepoPullNSID, 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
60type filter struct {
61 key string
62 arg any
63}
64
65func Filter(key string, arg any) filter {
66 return filter{
67 key: key,
68 arg: arg,
69 }
70}
71
72func (f filter) Condition() string {
73 return fmt.Sprintf("%s = ?", f.key)
74}
75
76func GetArtifact(e Execer, filters ...filter) ([]Artifact, error) {
77 var artifacts []Artifact
78
79 var conditions []string
80 var args []any
81 for _, filter := range filters {
82 conditions = append(conditions, filter.Condition())
83 args = append(args, filter.arg)
84 }
85
86 whereClause := ""
87 if conditions != nil {
88 whereClause = " where " + strings.Join(conditions, " and ")
89 }
90
91 query := fmt.Sprintf(`select
92 did,
93 rkey,
94 repo_at,
95 tag,
96 created,
97 blob_cid,
98 name,
99 size,
100 mimetype
101 from artifacts %s`,
102 whereClause,
103 )
104
105 rows, err := e.Query(query, args...)
106
107 if err != nil {
108 return nil, err
109 }
110 defer rows.Close()
111
112 for rows.Next() {
113 var artifact Artifact
114 var createdAt string
115 var tag []byte
116 var blobCid string
117
118 if err := rows.Scan(
119 &artifact.Did,
120 &artifact.Rkey,
121 &artifact.RepoAt,
122 &tag,
123 &createdAt,
124 &blobCid,
125 &artifact.Name,
126 &artifact.Size,
127 &artifact.MimeType,
128 ); err != nil {
129 return nil, err
130 }
131
132 artifact.CreatedAt, err = time.Parse(time.RFC3339, createdAt)
133 if err != nil {
134 artifact.CreatedAt = time.Now()
135 }
136 artifact.Tag = plumbing.Hash(tag)
137 artifact.BlobCid = cid.MustParse(blobCid)
138
139 artifacts = append(artifacts, artifact)
140 }
141
142 if err := rows.Err(); err != nil {
143 return nil, err
144 }
145
146 return artifacts, nil
147}
148
149func DeleteArtifact(e Execer, filters ...filter) error {
150 var conditions []string
151 var args []any
152 for _, filter := range filters {
153 conditions = append(conditions, filter.Condition())
154 args = append(args, filter.arg)
155 }
156
157 whereClause := ""
158 if conditions != nil {
159 whereClause = " where " + strings.Join(conditions, " and ")
160 }
161
162 query := fmt.Sprintf(`delete from artifacts %s`, whereClause)
163
164 _, err := e.Exec(query, args...)
165 return err
166}