github.com/code-to-go/safepool.lib@v0.0.0-20221205180519-ee25e63c226e/pool/db.go (about) 1 package pool 2 3 import ( 4 "encoding/json" 5 "time" 6 7 "github.com/code-to-go/safepool.lib/core" 8 "github.com/code-to-go/safepool.lib/security" 9 "github.com/code-to-go/safepool.lib/sql" 10 "github.com/code-to-go/safepool.lib/transport" 11 ) 12 13 func sqlGetHeads(pool string, afterId uint64, afterTime time.Time) ([]Head, error) { 14 rows, err := sql.Query("GET_HEADS", sql.Args{"pool": pool, "afterId": afterId, "afterTime": sql.EncodeTime(afterTime)}) 15 if core.IsErr(err, "cannot get pools heads from db: %v") { 16 return nil, err 17 } 18 defer rows.Close() 19 20 var heads []Head 21 for rows.Next() { 22 var h Head 23 var modTime int64 24 var ts int64 25 var hash string 26 err = rows.Scan(&h.Id, &h.Name, &modTime, &h.Size, &hash, &ts) 27 if !core.IsErr(err, "cannot read pool heads from db: %v") { 28 continue 29 } 30 h.ModTime = sql.DecodeTime(modTime) 31 h.TimeStamp = sql.DecodeTime(ts) 32 heads = append(heads, h) 33 } 34 return heads, nil 35 } 36 37 func sqlAddHead(pool string, h Head) error { 38 _, err := sql.Exec("SET_HEAD", sql.Args{ 39 "pool": pool, 40 "id": h.Id, 41 "name": h.Name, 42 "size": h.Size, 43 "modTime": sql.EncodeTime(h.ModTime), 44 "hash": sql.EncodeBase64(h.Hash[:]), 45 "ts": sql.EncodeTime(time.Now()), 46 }) 47 return err 48 } 49 50 func (p *Pool) sqlGetKey(keyId uint64) []byte { 51 rows, err := sql.Query("GET_KEY", sql.Args{"pool": p.Name, "keyId": keyId}) 52 if err != nil { 53 return nil 54 } 55 defer rows.Close() 56 57 for rows.Next() { 58 var key string 59 var err = rows.Scan(&key) 60 if !core.IsErr(err, "cannot read key from db: %v") { 61 return sql.DecodeBase64(key) 62 } 63 } 64 return nil 65 } 66 67 func (p *Pool) sqlSetKey(keyId uint64, value []byte) error { 68 _, err := sql.Exec("SET_KEY", sql.Args{"pool": p.Name, "keyId": keyId, "keyValue": sql.EncodeBase64(value)}) 69 return err 70 } 71 72 func (p *Pool) sqlGetKeystore() (Keystore, error) { 73 rows, err := sql.Query("GET_KEYSTORE", sql.Args{"pool": p.Name}) 74 if core.IsErr(err, "cannot read keystore for pool %s: %v", p.Name) { 75 return nil, err 76 } 77 defer rows.Close() 78 79 ks := Keystore{} 80 for rows.Next() { 81 var keyId uint64 82 var keyValue string 83 var err = rows.Scan(&keyId, &keyValue) 84 if !core.IsErr(err, "cannot read key from db: %v") { 85 ks[keyId] = sql.DecodeBase64(keyValue) 86 } 87 } 88 return ks, nil 89 } 90 91 func (p *Pool) sqlGetIdentities(onlyTrusted bool) (identities []Identity, err error) { 92 var q string 93 if onlyTrusted { 94 q = "GET_TRUSTED_ON_POOL" 95 } else { 96 q = "GET_IDENTITY_ON_POOL" 97 } 98 99 rows, err := sql.Query(q, sql.Args{"pool": p.Name}) 100 if core.IsErr(err, "cannot get trusted identities from db: %v") { 101 return nil, err 102 } 103 defer rows.Close() 104 105 for rows.Next() { 106 var i64 string 107 var since uint64 108 var ts int64 109 err = rows.Scan(&i64, &since, &ts) 110 if core.IsErr(err, "cannot read identity from db: %v") { 111 continue 112 } 113 114 i, err := security.IdentityFromBase64(i64) 115 if core.IsErr(err, "invalid identity '%s': %v", i64) { 116 continue 117 } 118 119 identities = append(identities, Identity{ 120 Identity: i, 121 Since: since, 122 AddedOn: sql.DecodeTime(ts), 123 }) 124 } 125 return identities, nil 126 } 127 128 func (p *Pool) sqlSetIdentity(i security.Identity, since uint64) error { 129 _, err := sql.Exec("SET_IDENTITY_ON_POOL", sql.Args{ 130 "id": i.Id(), 131 "pool": p.Name, 132 "since": since, 133 "ts": sql.EncodeTime(time.Now()), 134 }) 135 return err 136 } 137 138 func (p *Pool) sqlDeleteIdentity(i Identity) error { 139 _, err := sql.Exec("DEL_IDENTITY_ON_POOL", sql.Args{ 140 "id": i.Id(), 141 "pool": p.Name, 142 }) 143 return err 144 } 145 146 func sqlSave(name string, configs []transport.Config) error { 147 data, err := json.Marshal(&configs) 148 if core.IsErr(err, "cannot marshal transport configuration of %s: %v", name) { 149 return err 150 } 151 152 _, err = sql.Exec("SET_POOL", sql.Args{"name": name, "configs": sql.EncodeBase64(data)}) 153 core.IsErr(err, "cannot save transport configuration of %s: %v", name) 154 return err 155 } 156 157 func sqlLoad(name string) ([]transport.Config, error) { 158 var blob string 159 var configs []transport.Config 160 err := sql.QueryRow("GET_POOL", sql.Args{"name": name}, &blob) 161 if core.IsErr(err, "cannot get pool %s config: %v", name) { 162 return nil, err 163 } 164 165 data := sql.DecodeBase64(blob) 166 err = json.Unmarshal(data, &configs) 167 core.IsErr(err, "cannot unmarshal configs of %s: %v", name) 168 return configs, err 169 } 170 171 func sqlList() ([]string, error) { 172 var names []string 173 rows, err := sql.Query("LIST_POOL", nil) 174 if core.IsErr(err, "cannot list pools: %v") { 175 return nil, err 176 } 177 defer rows.Close() 178 179 for rows.Next() { 180 var n string 181 err = rows.Scan(&n) 182 if err == nil { 183 names = append(names, n) 184 } 185 } 186 return names, err 187 }