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  }