source: code/trunk/db.go@ 93

Last change on this file since 93 was 93, checked in by contact, 5 years ago

Add support for upstream PASS command

File size: 4.0 KB
RevLine 
[77]1package jounce
2
3import (
4 "database/sql"
5 "sync"
6
7 _ "github.com/mattn/go-sqlite3"
8)
9
10type User struct {
11 Username string
[85]12 Password string // hashed
[77]13}
14
15type Network struct {
16 ID int64
17 Addr string
18 Nick string
19 Username string
20 Realname string
[93]21 Pass string
[77]22}
23
24type Channel struct {
25 ID int64
26 Name string
27}
28
29type DB struct {
[81]30 lock sync.RWMutex
[77]31 db *sql.DB
32}
33
34func OpenSQLDB(driver, source string) (*DB, error) {
35 db, err := sql.Open(driver, source)
36 if err != nil {
37 return nil, err
38 }
39 return &DB{db: db}, nil
40}
41
42func (db *DB) Close() error {
43 db.lock.Lock()
44 defer db.lock.Unlock()
45 return db.Close()
46}
47
48func (db *DB) ListUsers() ([]User, error) {
[81]49 db.lock.RLock()
50 defer db.lock.RUnlock()
[77]51
52 rows, err := db.db.Query("SELECT username, password FROM User")
53 if err != nil {
54 return nil, err
55 }
56 defer rows.Close()
57
58 var users []User
59 for rows.Next() {
60 var user User
61 var password *string
62 if err := rows.Scan(&user.Username, &password); err != nil {
63 return nil, err
64 }
65 if password != nil {
66 user.Password = *password
67 }
68 users = append(users, user)
69 }
70 if err := rows.Err(); err != nil {
71 return nil, err
72 }
73
74 return users, nil
75}
76
[84]77func (db *DB) CreateUser(user *User) error {
78 db.lock.Lock()
79 defer db.lock.Unlock()
80
81 var password *string
82 if user.Password != "" {
83 password = &user.Password
84 }
[89]85 _, err := db.db.Exec("INSERT INTO User(username, password) VALUES (?, ?)", user.Username, password)
86 return err
[84]87}
88
[77]89func (db *DB) ListNetworks(username string) ([]Network, error) {
[81]90 db.lock.RLock()
91 defer db.lock.RUnlock()
[77]92
[93]93 rows, err := db.db.Query("SELECT id, addr, nick, username, realname, pass FROM Network WHERE user = ?", username)
[77]94 if err != nil {
95 return nil, err
96 }
97 defer rows.Close()
98
99 var networks []Network
100 for rows.Next() {
101 var net Network
[93]102 var username, realname, pass *string
103 if err := rows.Scan(&net.ID, &net.Addr, &net.Nick, &username, &realname, &pass); err != nil {
[77]104 return nil, err
105 }
106 if username != nil {
107 net.Username = *username
108 }
109 if realname != nil {
110 net.Realname = *realname
111 }
[93]112 if pass != nil {
113 net.Pass = *pass
114 }
[77]115 networks = append(networks, net)
116 }
117 if err := rows.Err(); err != nil {
118 return nil, err
119 }
120
121 return networks, nil
122}
123
[90]124func (db *DB) StoreNetwork(username string, network *Network) error {
125 db.lock.Lock()
126 defer db.lock.Unlock()
127
[93]128 var netUsername, realname, pass *string
[90]129 if network.Username != "" {
130 netUsername = &network.Username
131 }
132 if network.Realname != "" {
[93]133 realname = &network.Realname
[90]134 }
[93]135 if network.Pass != "" {
136 pass = &network.Pass
137 }
[90]138
139 var err error
140 if network.ID != 0 {
[93]141 _, err = db.db.Exec(`UPDATE Network
142 SET addr = ?, nick = ?, username = ?, realname = ?, pass = ?
143 WHERE id = ?`,
144 network.Addr, network.Nick, netUsername, realname, pass, network.ID)
[90]145 } else {
146 var res sql.Result
[93]147 res, err = db.db.Exec(`INSERT INTO Network(user, addr, nick, username,
148 realname, pass)
149 VALUES (?, ?, ?, ?, ?, ?)`,
150 username, network.Addr, network.Nick, netUsername, realname, pass)
[90]151 if err != nil {
152 return err
153 }
154 network.ID, err = res.LastInsertId()
155 }
156 return err
157}
158
[77]159func (db *DB) ListChannels(networkID int64) ([]Channel, error) {
[81]160 db.lock.RLock()
161 defer db.lock.RUnlock()
[77]162
163 rows, err := db.db.Query("SELECT id, name FROM Channel WHERE network = ?", networkID)
164 if err != nil {
165 return nil, err
166 }
167 defer rows.Close()
168
169 var channels []Channel
170 for rows.Next() {
171 var ch Channel
172 if err := rows.Scan(&ch.ID, &ch.Name); err != nil {
173 return nil, err
174 }
175 channels = append(channels, ch)
176 }
177 if err := rows.Err(); err != nil {
178 return nil, err
179 }
180
181 return channels, nil
182}
[89]183
184func (db *DB) StoreChannel(networkID int64, ch *Channel) error {
185 db.lock.Lock()
186 defer db.lock.Unlock()
187
188 _, err := db.db.Exec("INSERT OR REPLACE INTO Channel(network, name) VALUES (?, ?)", networkID, ch.Name)
189 return err
190}
191
192func (db *DB) DeleteChannel(networkID int64, name string) error {
193 db.lock.Lock()
194 defer db.lock.Unlock()
195
196 _, err := db.db.Exec("DELETE FROM Channel WHERE network = ? AND name = ?", networkID, name)
197 return err
198}
Note: See TracBrowser for help on using the repository browser.