all repos — honk @ v1.0.0

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