Changeset 255 in code
- Timestamp:
- Apr 10, 2020, 8:45:02 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/README.md
r189 r255 11 11 ## Usage 12 12 13 sqlite3 soju.db <schema.sql14 13 go run ./cmd/sojuctl create-user <username> 15 14 go run ./cmd/soju -
trunk/db.go
r251 r255 49 49 var ErrNoSuchChannel = fmt.Errorf("soju: no such channel") 50 50 51 const schema = ` 52 CREATE TABLE User ( 53 username VARCHAR(255) PRIMARY KEY, 54 password VARCHAR(255) NOT NULL 55 ); 56 57 CREATE TABLE Network ( 58 id INTEGER PRIMARY KEY, 59 name VARCHAR(255), 60 user VARCHAR(255) NOT NULL, 61 addr VARCHAR(255) NOT NULL, 62 nick VARCHAR(255) NOT NULL, 63 username VARCHAR(255), 64 realname VARCHAR(255), 65 pass VARCHAR(255), 66 sasl_mechanism VARCHAR(255), 67 sasl_plain_username VARCHAR(255), 68 sasl_plain_password VARCHAR(255), 69 FOREIGN KEY(user) REFERENCES User(username), 70 UNIQUE(user, addr, nick) 71 ); 72 73 CREATE TABLE Channel ( 74 id INTEGER PRIMARY KEY, 75 network INTEGER NOT NULL, 76 name VARCHAR(255) NOT NULL, 77 key VARCHAR(255), 78 FOREIGN KEY(network) REFERENCES Network(id), 79 UNIQUE(network, name) 80 ); 81 ` 82 83 var migrations = []string{ 84 "", // migration #0 is reserved for schema initialization 85 } 86 51 87 type DB struct { 52 88 lock sync.RWMutex … … 55 91 56 92 func OpenSQLDB(driver, source string) (*DB, error) { 57 db, err := sql.Open(driver, source) 58 if err != nil { 59 return nil, err 60 } 61 return &DB{db: db}, nil 93 sqlDB, err := sql.Open(driver, source) 94 if err != nil { 95 return nil, err 96 } 97 98 db := &DB{db: sqlDB} 99 if err := db.upgrade(); err != nil { 100 return nil, err 101 } 102 103 return db, nil 62 104 } 63 105 … … 66 108 defer db.lock.Unlock() 67 109 return db.Close() 110 } 111 112 func (db *DB) upgrade() error { 113 db.lock.Lock() 114 defer db.lock.Unlock() 115 116 var version int 117 if err := db.db.QueryRow("PRAGMA user_version").Scan(&version); err != nil { 118 return fmt.Errorf("failed to query schema version: %v", err) 119 } 120 121 if version == len(migrations) { 122 return nil 123 } else if version > len(migrations) { 124 return fmt.Errorf("soju (version %d) older than schema (version %d)", len(migrations), version) 125 } 126 127 tx, err := db.db.Begin() 128 if err != nil { 129 return err 130 } 131 defer tx.Rollback() 132 133 if version == 0 { 134 if _, err := tx.Exec(schema); err != nil { 135 return fmt.Errorf("failed to initialize schema: %v", err) 136 } 137 } else { 138 for i := version; i < len(migrations); i++ { 139 if _, err := tx.Exec(migrations[i]); err != nil { 140 return fmt.Errorf("failed to execute migration #%v: %v", i, err) 141 } 142 } 143 } 144 145 // For some reason prepared statements don't work here 146 _, err = tx.Exec(fmt.Sprintf("PRAGMA user_version = %d", len(migrations))) 147 if err != nil { 148 return fmt.Errorf("failed to bump schema version: %v", err) 149 } 150 151 return tx.Commit() 68 152 } 69 153
Note:
See TracChangeset
for help on using the changeset viewer.