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