all repos — honk @ 71ca9d93877085777250a670c61d9e70a07b6c5f

my fork of honk

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	"fmt"
 21	"log"
 22	"os"
 23	"regexp"
 24	"strings"
 25)
 26
 27func doordie(db *sql.DB, s string, args ...interface{}) {
 28	_, err := db.Exec(s, args...)
 29	if err != nil {
 30		log.Fatalf("can't run %s: %s", s, err)
 31	}
 32}
 33
 34func upgradedb() {
 35	db := opendatabase()
 36	dbversion := 0
 37	getconfig("dbversion", &dbversion)
 38	getconfig("servername", &serverName)
 39
 40	switch dbversion {
 41	case 0:
 42		doordie(db, "insert into config (key, value) values ('dbversion', 1)")
 43		fallthrough
 44	case 1:
 45		doordie(db, "create table doovers(dooverid integer primary key, dt text, tries integer, username text, rcpt text, msg blob)")
 46		doordie(db, "update config set value = 2 where key = 'dbversion'")
 47		fallthrough
 48	case 2:
 49		doordie(db, "alter table honks add column convoy text")
 50		doordie(db, "update honks set convoy = ''")
 51		doordie(db, "create index idx_honksconvoy on honks(convoy)")
 52		doordie(db, "create table xonkers (xonkerid integer primary key, xid text, ibox text, obox text, sbox text, pubkey text)")
 53		doordie(db, "insert into xonkers (xid, ibox, obox, sbox, pubkey) select xid, '', '', '', pubkey from honkers where flavor = 'key'")
 54		doordie(db, "delete from honkers where flavor = 'key'")
 55		doordie(db, "create index idx_xonkerxid on xonkers(xid)")
 56		doordie(db, "create table zonkers (zonkerid integer primary key, userid integer, name text, wherefore text)")
 57		doordie(db, "create index idx_zonkersname on zonkers(name)")
 58		doordie(db, "update config set value = 3 where key = 'dbversion'")
 59		fallthrough
 60	case 3:
 61		doordie(db, "alter table honks add column whofore integer")
 62		doordie(db, "update honks set whofore = 0")
 63		doordie(db, "update honks set whofore = 1 where honkid in (select honkid from honks join users on honks.userid = users.userid where instr(audience, username) > 0)")
 64		doordie(db, "update config set value = 4 where key = 'dbversion'")
 65		fallthrough
 66	case 4:
 67		doordie(db, "alter table honkers add column combos text")
 68		doordie(db, "update honkers set combos = ''")
 69		doordie(db, "update config set value = 5 where key = 'dbversion'")
 70		fallthrough
 71	case 5:
 72		doordie(db, "delete from donks where honkid in (select honkid from honks where what = 'zonk')")
 73		doordie(db, "delete from honks where what = 'zonk'")
 74		doordie(db, "update config set value = 6 where key = 'dbversion'")
 75		fallthrough
 76	case 6:
 77		doordie(db, "alter table honks add column format")
 78		doordie(db, "update honks set format = 'html'")
 79		doordie(db, "alter table honks add column precis")
 80		doordie(db, "update honks set precis = ''")
 81		doordie(db, "alter table honks add column oonker")
 82		doordie(db, "update honks set oonker = ''")
 83		doordie(db, "update config set value = 7 where key = 'dbversion'")
 84		fallthrough
 85	case 7:
 86		users := allusers()
 87		for _, u := range users {
 88			h := fmt.Sprintf("https://%s/u/%s", serverName, u.Username)
 89			doordie(db, fmt.Sprintf("update honks set xid = '%s/h/' || xid, honker = ?, whofore = 2 where userid = ? and honker = '' and (what = 'honk' or what = 'tonk')", h), h, u.UserID)
 90			doordie(db, "update honks set honker = ?, whofore = 2 where userid = ? and honker = '' and what = 'bonk'", h, u.UserID)
 91		}
 92		doordie(db, "update config set value = 8 where key = 'dbversion'")
 93		fallthrough
 94	case 8:
 95		doordie(db, "alter table files add column local integer")
 96		doordie(db, "update files set local = 1")
 97		doordie(db, "update config set value = 9 where key = 'dbversion'")
 98		fallthrough
 99	case 9:
100		doordie(db, "drop table xonkers")
101		doordie(db, "create table xonkers (xonkerid integer primary key, name text, info text, flavor text)")
102		doordie(db, "create index idx_xonkername on xonkers(name)")
103		doordie(db, "update config set value = 10 where key = 'dbversion'")
104		fallthrough
105	case 10:
106		doordie(db, "update zonkers set wherefore = 'zomain' where wherefore = 'zurl'")
107		doordie(db, "update zonkers set wherefore = 'zord' where wherefore = 'zword'")
108		doordie(db, "update config set value = 11 where key = 'dbversion'")
109		fallthrough
110	case 11:
111		doordie(db, "alter table users add column options text")
112		doordie(db, "update users set options = ''")
113		doordie(db, "update config set value = 12 where key = 'dbversion'")
114		fallthrough
115	case 12:
116		doordie(db, "create index idx_honksoonker on honks(oonker)")
117		doordie(db, "update config set value = 13 where key = 'dbversion'")
118		fallthrough
119	case 13:
120		doordie(db, "alter table honks add column flags integer")
121		doordie(db, "update honks set flags = 0")
122		doordie(db, "update config set value = 14 where key = 'dbversion'")
123		fallthrough
124	case 14:
125		doordie(db, "create table onts (ontology text, honkid integer)")
126		doordie(db, "create index idx_ontology on onts(ontology)")
127		doordie(db, "update config set value = 15 where key = 'dbversion'")
128		fallthrough
129	case 15:
130		doordie(db, "delete from onts")
131		ontmap := make(map[int64][]string)
132		rows, err := db.Query("select honkid, noise from honks")
133		if err != nil {
134			log.Fatalf("can't query honks: %s", err)
135		}
136		re_more := regexp.MustCompile(`#<span>[[:alpha:]][[:alnum:]-]*`)
137		for rows.Next() {
138			var honkid int64
139			var noise string
140			err := rows.Scan(&honkid, &noise)
141			if err != nil {
142				log.Fatalf("can't scan honks: %s", err)
143			}
144			onts := ontologies(noise)
145			mo := re_more.FindAllString(noise, -1)
146			for _, o := range mo {
147				onts = append(onts, "#"+o[7:])
148			}
149			if len(onts) > 0 {
150				ontmap[honkid] = oneofakind(onts)
151			}
152		}
153		rows.Close()
154		tx, err := db.Begin()
155		if err != nil {
156			log.Fatalf("can't begin: %s", err)
157		}
158		stmtOnts, err := tx.Prepare("insert into onts (ontology, honkid) values (?, ?)")
159		if err != nil {
160			log.Fatal(err)
161		}
162		for honkid, onts := range ontmap {
163			for _, o := range onts {
164				_, err = stmtOnts.Exec(strings.ToLower(o), honkid)
165				if err != nil {
166					log.Fatal(err)
167				}
168			}
169		}
170		err = tx.Commit()
171		if err != nil {
172			log.Fatalf("can't commit: %s", err)
173		}
174		doordie(db, "update config set value = 16 where key = 'dbversion'")
175		fallthrough
176	case 16:
177		doordie(db, "alter table files add column description text")
178		doordie(db, "update files set description = name")
179		doordie(db, "update config set value = 17 where key = 'dbversion'")
180		fallthrough
181	case 17:
182		doordie(db, "create table forsaken (honkid integer, precis text, noise text)")
183		doordie(db, "update config set value = 18 where key = 'dbversion'")
184		fallthrough
185	case 18:
186		doordie(db, "create index idx_onthonkid on onts(honkid)")
187		doordie(db, "update config set value = 19 where key = 'dbversion'")
188		fallthrough
189	case 19:
190		doordie(db, "create table places (honkid integer, name text, latitude real, longitude real)")
191		doordie(db, "create index idx_placehonkid on places(honkid)")
192		fallthrough
193	case 20:
194		doordie(db, "alter table places add column url text")
195		doordie(db, "update places set url = ''")
196		doordie(db, "update config set value = 21 where key = 'dbversion'")
197		fallthrough
198	case 21:
199		// here we go...
200		initblobdb()
201		blobdb, err := sql.Open("sqlite3", blobdbname)
202		if err != nil {
203			log.Fatal(err)
204		}
205		tx, err := blobdb.Begin()
206		if err != nil {
207			log.Fatalf("can't begin: %s", err)
208		}
209		doordie(db, "drop index idx_filesxid")
210		doordie(db, "drop index idx_filesurl")
211		doordie(db, "create table filemeta (fileid integer primary key, xid text, name text, description text, url text, media text, local integer)")
212		doordie(db, "insert into filemeta select fileid, xid, name, description, url, media, local from files")
213		doordie(db, "create index idx_filesxid on filemeta(xid)")
214		doordie(db, "create index idx_filesurl on filemeta(url)")
215
216		rows, err := db.Query("select xid, media, content from files where local = 1")
217		if err != nil {
218			log.Fatal(err)
219		}
220		for rows.Next() {
221			var xid, media string
222			var data []byte
223			err = rows.Scan(&xid, &media, &data)
224			if err != nil {
225				log.Fatal(err)
226			}
227			_, err = tx.Exec("insert into filedata (xid, media, content) values (?, ?, ?)", xid, media, data)
228			if err != nil {
229				log.Fatal(err)
230			}
231		}
232		rows.Close()
233		err = tx.Commit()
234		if err != nil {
235			log.Fatalf("can't commit: %s", err)
236		}
237		doordie(db, "drop table files")
238		doordie(db, "vacuum")
239		doordie(db, "update config set value = 22 where key = 'dbversion'")
240		fallthrough
241	case 22:
242		doordie(db, "create table honkmeta (honkid integer, genus text, json text)")
243		doordie(db, "create index idx_honkmetaid on honkmeta(honkid)")
244		doordie(db, "drop table forsaken") // don't bother saving this one
245		rows, err := db.Query("select honkid, name, latitude, longitude, url from places")
246		if err != nil {
247			log.Fatal(err)
248		}
249		places := make(map[int64]*Place)
250		for rows.Next() {
251			var honkid int64
252			p := new(Place)
253			err = rows.Scan(&honkid, &p.Name, &p.Latitude, &p.Longitude, &p.Url)
254			if err != nil {
255				log.Fatal(err)
256			}
257			places[honkid] = p
258		}
259		rows.Close()
260		tx, err := db.Begin()
261		if err != nil {
262			log.Fatalf("can't begin: %s", err)
263		}
264		for honkid, p := range places {
265			j, err := jsonify(p)
266			_, err = tx.Exec("insert into honkmeta (honkid, genus, json) values (?, ?, ?)",
267				honkid, "place", j)
268			if err != nil {
269				log.Fatal(err)
270			}
271		}
272		err = tx.Commit()
273		if err != nil {
274			log.Fatalf("can't commit: %s", err)
275		}
276		doordie(db, "update config set value = 23 where key = 'dbversion'")
277		fallthrough
278	case 23:
279
280	default:
281		log.Fatalf("can't upgrade unknown version %d", dbversion)
282	}
283	os.Exit(0)
284}