upgradedb.go (view raw)
1//
2// Copyright (c) 2019 Ted Unangst <tedu@tedunangst.com>
3//
4// Permission to use, copy, modify, and distribute this software for any
5// purpose with or without fee is hereby granted, provided that the above
6// copyright notice and this permission notice appear in all copies.
7//
8// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16package main
17
18import (
19 "database/sql"
20 "log"
21 "os"
22 "strings"
23 "time"
24)
25
26var myVersion = 40
27
28type dbexecer interface {
29 Exec(query string, args ...interface{}) (sql.Result, error)
30}
31
32func doordie(db dbexecer, s string, args ...interface{}) {
33 _, err := db.Exec(s, args...)
34 if err != nil {
35 log.Fatalf("can't run %s: %s", s, err)
36 }
37}
38
39func upgradedb() {
40 db := opendatabase()
41 dbversion := 0
42 getconfig("dbversion", &dbversion)
43 getconfig("servername", &serverName)
44
45 if dbversion < 13 {
46 log.Fatal("database is too old to upgrade")
47 }
48 switch dbversion {
49 case 25:
50 doordie(db, "delete from auth")
51 doordie(db, "alter table auth add column expiry text")
52 doordie(db, "update config set value = 26 where key = 'dbversion'")
53 fallthrough
54 case 26:
55 s := ""
56 getconfig("servermsg", &s)
57 if s == "" {
58 setconfig("servermsg", "<h2>Things happen.</h2>")
59 }
60 s = ""
61 getconfig("aboutmsg", &s)
62 if s == "" {
63 setconfig("aboutmsg", "<h3>What is honk?</h3><p>Honk is amazing!")
64 }
65 s = ""
66 getconfig("loginmsg", &s)
67 if s == "" {
68 setconfig("loginmsg", "<h2>login</h2>")
69 }
70 d := -1
71 getconfig("debug", &d)
72 if d == -1 {
73 setconfig("debug", 0)
74 }
75 doordie(db, "update config set value = 27 where key = 'dbversion'")
76 fallthrough
77 case 27:
78 createserveruser(db)
79 doordie(db, "update config set value = 28 where key = 'dbversion'")
80 fallthrough
81 case 28:
82 doordie(db, "drop table doovers")
83 doordie(db, "create table doovers(dooverid integer primary key, dt text, tries integer, userid integer, rcpt text, msg blob)")
84 doordie(db, "update config set value = 29 where key = 'dbversion'")
85 fallthrough
86 case 29:
87 doordie(db, "alter table honkers add column owner text")
88 doordie(db, "update honkers set owner = xid")
89 doordie(db, "update config set value = 30 where key = 'dbversion'")
90 fallthrough
91 case 30:
92 tx, err := db.Begin()
93 if err != nil {
94 log.Fatal(err)
95 }
96 rows, err := tx.Query("select userid, options from users")
97 if err != nil {
98 log.Fatal(err)
99 }
100 m := make(map[int64]string)
101 for rows.Next() {
102 var userid int64
103 var options string
104 err = rows.Scan(&userid, &options)
105 if err != nil {
106 log.Fatal(err)
107 }
108 var uo UserOptions
109 uo.SkinnyCSS = strings.Contains(options, " skinny ")
110 m[userid], err = jsonify(uo)
111 if err != nil {
112 log.Fatal(err)
113 }
114 }
115 rows.Close()
116 for u, o := range m {
117 _, err = tx.Exec("update users set options = ? where userid = ?", o, u)
118 if err != nil {
119 log.Fatal(err)
120 }
121 }
122 err = tx.Commit()
123 if err != nil {
124 log.Fatal(err)
125 }
126 doordie(db, "update config set value = 31 where key = 'dbversion'")
127 fallthrough
128 case 31:
129 doordie(db, "create table tracks (xid text, fetches text)")
130 doordie(db, "create index idx_trackhonkid on tracks(xid)")
131 doordie(db, "update config set value = 32 where key = 'dbversion'")
132 fallthrough
133 case 32:
134 doordie(db, "alter table xonkers add column dt text")
135 doordie(db, "update xonkers set dt = ?", time.Now().UTC().Format(dbtimeformat))
136 doordie(db, "update config set value = 33 where key = 'dbversion'")
137 fallthrough
138 case 33:
139 doordie(db, "alter table honkers add column meta text")
140 doordie(db, "update honkers set meta = '{}'")
141 doordie(db, "update config set value = 34 where key = 'dbversion'")
142 fallthrough
143 case 34:
144 doordie(db, "create table chonks (chonkid integer primary key, userid integer, xid text, who txt, target text, dt text, noise text, format text)")
145 doordie(db, "update config set value = 35 where key = 'dbversion'")
146 fallthrough
147 case 35:
148 doordie(db, "alter table donks add column chonkid integer")
149 doordie(db, "update donks set chonkid = -1")
150 doordie(db, "create index idx_donkshonk on donks(honkid)")
151 doordie(db, "create index idx_donkschonk on donks(chonkid)")
152 doordie(db, "update config set value = 36 where key = 'dbversion'")
153 fallthrough
154 case 36:
155 doordie(db, "alter table honkers add column folxid text")
156 doordie(db, "update honkers set folxid = 'lostdata'")
157 doordie(db, "update config set value = 37 where key = 'dbversion'")
158 fallthrough
159 case 37:
160 doordie(db, "update honkers set combos = '' where combos is null")
161 doordie(db, "update honkers set owner = '' where owner is null")
162 doordie(db, "update honkers set meta = '' where meta is null")
163 doordie(db, "update honkers set folxid = '' where folxid is null")
164 doordie(db, "update config set value = 38 where key = 'dbversion'")
165 fallthrough
166 case 38:
167 doordie(db, "update honkers set folxid = abs(random())")
168 doordie(db, "update config set value = 39 where key = 'dbversion'")
169 fallthrough
170 case 39:
171 blobdb := openblobdb()
172 doordie(blobdb, "alter table filedata add column hash text")
173 doordie(blobdb, "create index idx_filehash on filedata(hash)")
174 rows, err := blobdb.Query("select xid, content from filedata")
175 if err != nil {
176 log.Fatal(err)
177 }
178 m := make(map[string]string)
179 for rows.Next() {
180 var xid string
181 var data sql.RawBytes
182 err := rows.Scan(&xid, &data)
183 if err != nil {
184 log.Fatal(err)
185 }
186 hash := hashfiledata(data)
187 m[xid] = hash
188 }
189 rows.Close()
190 tx, err := blobdb.Begin()
191 if err != nil {
192 log.Fatal(err)
193 }
194 for xid, hash := range m {
195 doordie(tx, "update filedata set hash = ? where xid = ?", hash, xid)
196 }
197 err = tx.Commit()
198 if err != nil {
199 log.Fatal(err)
200 }
201 doordie(db, "update config set value = 40 where key = 'dbversion'")
202 fallthrough
203 case 40:
204
205 default:
206 log.Fatalf("can't upgrade unknown version %d", dbversion)
207 }
208 os.Exit(0)
209}