A vibe coded tangled fork which supports pijul.
at sl/tap-appview 176 lines 3.4 kB view raw
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}