all repos — honk @ d96bb9376fe1846298c700baef403a002c1762fb

my fork of honk

backupdb.go (view raw)

  1package main
  2
  3import (
  4	"database/sql"
  5	"fmt"
  6	"log"
  7	"os"
  8	"time"
  9
 10	"strings"
 11)
 12
 13func qordie(db *sql.DB, s string, args ...interface{}) *sql.Rows {
 14	rows, err := db.Query(s, args...)
 15	if err != nil {
 16		log.Fatalf("can't query %s: %s", s, err)
 17	}
 18	return rows
 19}
 20
 21func scanordie(rows *sql.Rows, args ...interface{}) {
 22	err := rows.Scan(args...)
 23	if err != nil {
 24		log.Fatalf("can't scan: %s", err)
 25	}
 26}
 27
 28func svalbard(dirname string) {
 29	err := os.Mkdir(dirname, 0700)
 30	if err != nil && !os.IsExist(err) {
 31		log.Fatalf("can't create directory: %s", dirname)
 32	}
 33	now := time.Now().Unix()
 34	backupdbname := fmt.Sprintf("%s/honk-%d.db", dirname, now)
 35	backup, err := sql.Open("sqlite3", backupdbname)
 36	if err != nil {
 37		log.Fatalf("can't open backup database")
 38	}
 39	for _, line := range strings.Split(sqlSchema, ";") {
 40		_, err = backup.Exec(line)
 41		if err != nil {
 42			log.Fatal(err)
 43			return
 44		}
 45	}
 46	tx, err := backup.Begin()
 47	if err != nil {
 48		log.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 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 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)
 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) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", honkid, userid, what, honker, xid, rid, dt, url, audience, noise, convoy, whofore, format, precis, oonker, flags)
 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		log.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		log.Fatalf("can't open backup blob database")
172	}
173	doordie(blob, "create table filedata (xid text, media text, hash text, content blob)")
174	doordie(blob, "create index idx_filexid on filedata(xid)")
175	doordie(blob, "create index idx_filehash on filedata(hash)")
176	tx, err = blob.Begin()
177	if err != nil {
178		log.Fatalf("can't start transaction: %s", err)
179	}
180	origblob := openblobdb()
181	for x := range filexids {
182		rows = qordie(origblob, "select xid, media, hash, content from filedata where xid = ?", x)
183		for rows.Next() {
184			var xid, media, hash string
185			var content sql.RawBytes
186			scanordie(rows, &xid, &media, &hash, &content)
187			doordie(tx, "insert into filedata (xid, media, hash, content) values (?, ?, ?, ?)", xid, media, hash, content)
188		}
189		rows.Close()
190	}
191
192	err = tx.Commit()
193	if err != nil {
194		log.Fatalf("can't commit blobs: %s", err)
195	}
196	blob.Close()
197}