all repos — honk @ f91f3ffe7e2384ba1f52f9784bf181d3f4021354

my fork of honk

backupdb.go (view raw)

  1package main
  2
  3import (
  4	"database/sql"
  5	"fmt"
  6	"os"
  7	"time"
  8
  9	"strings"
 10)
 11
 12func qordie(db *sql.DB, s string, args ...interface{}) *sql.Rows {
 13	rows, err := db.Query(s, args...)
 14	if err != nil {
 15		elog.Fatalf("can't query %s: %s", s, err)
 16	}
 17	return rows
 18}
 19
 20func scanordie(rows *sql.Rows, args ...interface{}) {
 21	err := rows.Scan(args...)
 22	if err != nil {
 23		elog.Fatalf("can't scan: %s", err)
 24	}
 25}
 26
 27func svalbard(dirname string) {
 28	err := os.Mkdir(dirname, 0700)
 29	if err != nil && !os.IsExist(err) {
 30		elog.Fatalf("can't create directory: %s", dirname)
 31	}
 32	now := time.Now().Unix()
 33	backupdbname := fmt.Sprintf("%s/honk-%d.db", dirname, now)
 34	backup, err := sql.Open("sqlite3", backupdbname)
 35	if err != nil {
 36		elog.Fatalf("can't open backup database")
 37	}
 38	_, err = backup.Exec("PRAGMA journal_mode=WAL")
 39	for _, line := range strings.Split(sqlSchema, ";") {
 40		_, err = backup.Exec(line)
 41		if err != nil {
 42			elog.Fatal(err)
 43			return
 44		}
 45	}
 46	tx, err := backup.Begin()
 47	if err != nil {
 48		elog.Fatal(err)
 49	}
 50	orig := opendatabase()
 51	rows := qordie(orig, "select userid, username, hash, displayname, about, pubkey, seckey, options from users")
 52	for rows.Next() {
 53		var userid int64
 54		var username, hash, displayname, about, pubkey, seckey, options string
 55		scanordie(rows, &userid, &username, &hash, &displayname, &about, &pubkey, &seckey, &options)
 56		doordie(tx, "insert into users (userid, username, hash, displayname, about, pubkey, seckey, options) values (?, ?, ?, ?, ?, ?, ?, ?)", userid, username, hash, displayname, about, pubkey, seckey, options)
 57	}
 58	rows.Close()
 59
 60	rows = qordie(orig, "select honkerid, userid, name, xid, flavor, combos, owner, meta, folxid from honkers")
 61	for rows.Next() {
 62		var honkerid, userid int64
 63		var name, xid, flavor, combos, owner, meta, folxid string
 64		scanordie(rows, &honkerid, &userid, &name, &xid, &flavor, &combos, &owner, &meta, &folxid)
 65		doordie(tx, "insert into honkers (honkerid, userid, name, xid, flavor, combos, owner, meta, folxid) values (?, ?, ?, ?, ?, ?, ?, ?, ?)", honkerid, userid, name, xid, flavor, combos, owner, meta, folxid)
 66	}
 67	rows.Close()
 68
 69	rows = qordie(orig, "select convoy from honks where flags & 4 or whofore = 2 or whofore = 3")
 70	convoys := make(map[string]bool)
 71	for rows.Next() {
 72		var convoy string
 73		scanordie(rows, &convoy)
 74		convoys[convoy] = true
 75	}
 76	rows.Close()
 77
 78	honkids := make(map[int64]bool)
 79	for c := range convoys {
 80		rows = qordie(orig, "select honkid, userid, what, honker, xid, rid, dt, url, audience, noise, convoy, whofore, format, precis, oonker, flags, plain from honks where convoy = ?", c)
 81		for rows.Next() {
 82			var honkid, userid int64
 83			var what, honker, xid, rid, dt, url, audience, noise, convoy, plain string
 84			var whofore int64
 85			var format, precis, oonker string
 86			var flags int64
 87			scanordie(rows, &honkid, &userid, &what, &honker, &xid, &rid, &dt, &url, &audience, &noise, &convoy, &whofore, &format, &precis, &oonker, &flags, &plain)
 88			honkids[honkid] = true
 89			doordie(tx, "insert into honks (honkid, userid, what, honker, xid, rid, dt, url, audience, noise, convoy, whofore, format, precis, oonker, flags, plain) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", honkid, userid, what, honker, xid, rid, dt, url, audience, noise, convoy, whofore, format, precis, oonker, flags, plain)
 90		}
 91		rows.Close()
 92	}
 93	fileids := make(map[int64]bool)
 94	for h := range honkids {
 95		rows = qordie(orig, "select honkid, chonkid, fileid from donks where honkid = ?", h)
 96		for rows.Next() {
 97			var honkid, chonkid, fileid int64
 98			scanordie(rows, &honkid, &chonkid, &fileid)
 99			fileids[fileid] = true
100			doordie(tx, "insert into donks (honkid, chonkid, fileid) values (?, ?, ?)", honkid, chonkid, fileid)
101		}
102		rows.Close()
103		rows = qordie(orig, "select ontology, honkid from onts where honkid = ?", h)
104		for rows.Next() {
105			var ontology string
106			var honkid int64
107			scanordie(rows, &ontology, &honkid)
108			doordie(tx, "insert into onts (ontology, honkid) values (?, ?)", ontology, honkid)
109		}
110		rows.Close()
111		rows = qordie(orig, "select honkid, genus, json from honkmeta where honkid = ?", h)
112		for rows.Next() {
113			var honkid int64
114			var genus, json string
115			scanordie(rows, &honkid, &genus, &json)
116			doordie(tx, "insert into honkmeta (honkid, genus, json) values (?, ?, ?)", honkid, genus, json)
117		}
118		rows.Close()
119	}
120	chonkids := make(map[int64]bool)
121	rows = qordie(orig, "select chonkid, userid, xid, who, target, dt, noise, format from chonks")
122	for rows.Next() {
123		var chonkid, userid int64
124		var xid, who, target, dt, noise, format string
125		scanordie(rows, &chonkid, &userid, &xid, &who, &target, &dt, &noise, &format)
126		chonkids[chonkid] = true
127		doordie(tx, "insert into chonks (chonkid, userid, xid, who, target, dt, noise, format) values (?, ?, ?, ?, ?, ?, ?, ?)", chonkid, userid, xid, who, target, dt, noise, format)
128	}
129	rows.Close()
130	for c := range chonkids {
131		rows = qordie(orig, "select honkid, chonkid, fileid from donks where chonkid = ?", c)
132		for rows.Next() {
133			var honkid, chonkid, fileid int64
134			scanordie(rows, &honkid, &chonkid, &fileid)
135			fileids[fileid] = true
136			doordie(tx, "insert into donks (honkid, chonkid, fileid) values (?, ?, ?)", honkid, chonkid, fileid)
137		}
138		rows.Close()
139	}
140	filexids := make(map[string]bool)
141	for f := range fileids {
142		rows = qordie(orig, "select fileid, xid, name, description, url, media, local from filemeta where fileid = ?", f)
143		for rows.Next() {
144			var fileid int64
145			var xid, name, description, url, media string
146			var local int64
147			scanordie(rows, &fileid, &xid, &name, &description, &url, &media, &local)
148			filexids[xid] = true
149			doordie(tx, "insert into filemeta (fileid, xid, name, description, url, media, local) values (?, ?, ?, ?, ?, ?, ?)", fileid, xid, name, description, url, media, local)
150		}
151		rows.Close()
152	}
153
154	rows = qordie(orig, "select key, value from config")
155	for rows.Next() {
156		var key string
157		var value interface{}
158		scanordie(rows, &key, &value)
159		doordie(tx, "insert into config (key, value) values (?, ?)", key, value)
160	}
161
162	err = tx.Commit()
163	if err != nil {
164		elog.Fatalf("can't commit backp: %s", err)
165	}
166	backup.Close()
167
168	backupblobname := fmt.Sprintf("%s/blob-%d.db", dirname, now)
169	blob, err := sql.Open("sqlite3", backupblobname)
170	if err != nil {
171		elog.Fatalf("can't open backup blob database")
172	}
173	_, err = blob.Exec("PRAGMA journal_mode=WAL")
174	doordie(blob, "create table filedata (xid text, media text, hash text, content blob)")
175	doordie(blob, "create index idx_filexid on filedata(xid)")
176	doordie(blob, "create index idx_filehash on filedata(hash)")
177	tx, err = blob.Begin()
178	if err != nil {
179		elog.Fatalf("can't start transaction: %s", err)
180	}
181	origblob := openblobdb()
182	for x := range filexids {
183		rows = qordie(origblob, "select xid, media, hash, content from filedata where xid = ?", x)
184		for rows.Next() {
185			var xid, media, hash string
186			var content sql.RawBytes
187			scanordie(rows, &xid, &media, &hash, &content)
188			doordie(tx, "insert into filedata (xid, media, hash, content) values (?, ?, ?, ?)", xid, media, hash, content)
189		}
190		rows.Close()
191	}
192
193	err = tx.Commit()
194	if err != nil {
195		elog.Fatalf("can't commit blobs: %s", err)
196	}
197	blob.Close()
198}