A vibe coded tangled fork which supports pijul.
1package db
2
3import (
4 "database/sql"
5 "errors"
6 "fmt"
7 "strings"
8 "time"
9
10 "tangled.org/core/appview/models"
11 "tangled.org/core/orm"
12)
13
14func UpsertString(e Execer, s models.String) error {
15 panic("unimplemented")
16}
17
18func AddString(e Execer, s models.String) error {
19 _, err := e.Exec(
20 `insert into strings (
21 did,
22 rkey,
23 filename,
24 description,
25 content,
26 created,
27 edited
28 )
29 values (?, ?, ?, ?, ?, ?, null)
30 on conflict(did, rkey) do update set
31 filename = excluded.filename,
32 description = excluded.description,
33 content = excluded.content,
34 edited = case
35 when
36 strings.content != excluded.content
37 or strings.filename != excluded.filename
38 or strings.description != excluded.description then ?
39 else strings.edited
40 end`,
41 s.Did,
42 s.Rkey,
43 s.Filename,
44 s.Description,
45 s.Contents,
46 s.Created.Format(time.RFC3339),
47 time.Now().Format(time.RFC3339),
48 )
49 return err
50}
51
52func GetStrings(e Execer, limit int, filters ...orm.Filter) ([]models.String, error) {
53 var all []models.String
54
55 var conditions []string
56 var args []any
57 for _, filter := range filters {
58 conditions = append(conditions, filter.Condition())
59 args = append(args, filter.Arg()...)
60 }
61
62 whereClause := ""
63 if conditions != nil {
64 whereClause = " where " + strings.Join(conditions, " and ")
65 }
66
67 limitClause := ""
68 if limit != 0 {
69 limitClause = fmt.Sprintf(" limit %d ", limit)
70 }
71
72 query := fmt.Sprintf(`select
73 did,
74 rkey,
75 filename,
76 description,
77 content,
78 created,
79 edited
80 from strings
81 %s
82 order by created desc
83 %s`,
84 whereClause,
85 limitClause,
86 )
87
88 rows, err := e.Query(query, args...)
89
90 if err != nil {
91 return nil, err
92 }
93 defer rows.Close()
94
95 for rows.Next() {
96 var s models.String
97 var createdAt string
98 var editedAt sql.NullString
99
100 if err := rows.Scan(
101 &s.Did,
102 &s.Rkey,
103 &s.Filename,
104 &s.Description,
105 &s.Contents,
106 &createdAt,
107 &editedAt,
108 ); err != nil {
109 return nil, err
110 }
111
112 s.Created, err = time.Parse(time.RFC3339, createdAt)
113 if err != nil {
114 s.Created = time.Now()
115 }
116
117 if editedAt.Valid {
118 e, err := time.Parse(time.RFC3339, editedAt.String)
119 if err != nil {
120 e = time.Now()
121 }
122 s.Edited = &e
123 }
124
125 all = append(all, s)
126 }
127
128 if err := rows.Err(); err != nil {
129 return nil, err
130 }
131
132 return all, nil
133}
134
135func CountStrings(e Execer, filters ...orm.Filter) (int64, error) {
136 var conditions []string
137 var args []any
138 for _, filter := range filters {
139 conditions = append(conditions, filter.Condition())
140 args = append(args, filter.Arg()...)
141 }
142
143 whereClause := ""
144 if conditions != nil {
145 whereClause = " where " + strings.Join(conditions, " and ")
146 }
147
148 repoQuery := fmt.Sprintf(`select count(1) from strings %s`, whereClause)
149 var count int64
150 err := e.QueryRow(repoQuery, args...).Scan(&count)
151
152 if !errors.Is(err, sql.ErrNoRows) && err != nil {
153 return 0, err
154 }
155
156 return count, nil
157}
158
159func DeleteString(e Execer, filters ...orm.Filter) error {
160 var conditions []string
161 var args []any
162 for _, filter := range filters {
163 conditions = append(conditions, filter.Condition())
164 args = append(args, filter.Arg()...)
165 }
166
167 whereClause := ""
168 if conditions != nil {
169 whereClause = " where " + strings.Join(conditions, " and ")
170 }
171
172 query := fmt.Sprintf(`delete from strings %s`, whereClause)
173
174 _, err := e.Exec(query, args...)
175 return err
176}