Skip to content

Instantly share code, notes, and snippets.

@foxcpp
Created May 11, 2020 12:24
Show Gist options
  • Save foxcpp/1be0b627f9d2be6004c3867be186b7fb to your computer and use it in GitHub Desktop.
Save foxcpp/1be0b627f9d2be6004c3867be186b7fb to your computer and use it in GitHub Desktop.
0.2 -> 0.3 imapsql DB migration script
package main
import (
"database/sql"
"fmt"
"os"
"time"
_ "github.com/mattn/go-sqlite3"
)
func main() {
if len(os.Args) != 2 {
fmt.Printf("Usage: %s <DB file path>\n", os.Args[0])
return
}
fmt.Println("Seriously, take a DB backup now. I will give you 5 seconds to abort.")
time.Sleep(5 * time.Second)
/* In go-imap-sql used by maddy 0.2:
id BIGSERIAL NOT NULL PRIMARY KEY AUTOINCREMENT,
username VARCHAR(255) NOT NULL UNIQUE,
msgsizelimit INTEGER DEFAULT NULL,
password VARCHAR(255) DEFAULT NULL,
password_salt VARCHAR(255) DEFAULT NULL,
inboxId BIGINT DEFAULT 0
*/
/* In go-imap-sql used by maddy 0.3:
id BIGSERIAL NOT NULL PRIMARY KEY AUTOINCREMENT,
username VARCHAR(255) NOT NULL UNIQUE,
msgsizelimit INTEGER DEFAULT NULL,
inboxId BIGINT DEFAULT 0
*/
db, err := sql.Open("sqlite3", os.Args[1])
if err != nil {
fmt.Println(err)
return
}
defer db.Close()
if err := db.Ping(); err != nil {
fmt.Println(err)
return
}
db.SetMaxOpenConns(1)
fmt.Println("Disabling foreign keys...")
db.Exec("PRAGMA foreign_keys=OFF")
fmt.Println("Taking exclusive DB lock...")
db.Exec("PRAGMA locking_mode=EXCLUSIVE")
tx, err := db.Begin()
if err != nil {
fmt.Println("Tx begin:", err)
return
}
defer tx.Rollback()
fmt.Println("Creating new users table...")
_, err = tx.Exec(`
CREATE TABLE __new_users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
username VARCHAR(255) NOT NULL UNIQUE,
msgsizelimit INTEGER DEFAULT NULL,
inboxId BIGINT DEFAULT 0
)`)
if err != nil {
fmt.Println("Create new table:", err)
return
}
fmt.Println("Moving data from old table...")
_, err = tx.Exec(`
INSERT INTO __new_users
SELECT id, username, msgsizelimit, inboxId
FROM users`)
if err != nil {
fmt.Println("Data move:", err)
return
}
fmt.Println("Removing old table...")
_, err = tx.Exec(`DROP TABLE users`)
if err != nil {
fmt.Println("Table drop:", err)
return
}
fmt.Println("Renaming new table to the normal name...")
_, err = tx.Exec(`ALTER TABLE __new_users RENAME TO users`)
if err != nil {
fmt.Println("Table rename:", err)
return
}
fmt.Println("Completing transaction...")
if err := tx.Commit(); err != nil {
fmt.Println("Tx commit:", err)
return
}
fmt.Println("Done! Now go back and run maddyctl to readd passwords to DB.")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment