envoid/internal/datastore/db.go
Sagi Dayan 33f99dd65b
All checks were successful
build bin / Make sure build does not fail (push) Successful in 2m51s
Codespell / Check for spelling errors (push) Successful in 22s
Initial commit
Signed-off-by: Sagi Dayan <sagidayan@gmail.com>
2024-12-15 17:41:31 +02:00

135 lines
3.3 KiB
Go

package datastore
import (
"fmt"
"database/sql"
"git.dayanhub.com/sagi/envoid/internal/common"
"git.dayanhub.com/sagi/envoid/internal/errors"
"git.dayanhub.com/sagi/envoid/internal/types"
"git.dayanhub.com/sagi/envoid/internal/variables"
_ "github.com/glebarez/go-sqlite"
)
type db struct {
con *sql.DB
}
func newDB() (*db, error) {
con, err := sql.Open("sqlite", variables.DBFileName)
if err != nil {
fmt.Printf("%v\n", err)
return nil, err
}
return &db{
con: con,
}, nil
}
func (d *db) close() error {
return d.con.Close()
}
func (d *db) createTableIfNotExists(table_name string) error {
_, err := d.con.Exec(fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (key TEXT PRIMARY KEY NOT NULL, value BLOB NOT NULL, encrypted BOOL NOT NULL);", table_name))
if err != nil {
return err
}
return nil
}
func (d *db) listTables() ([]string, error) {
tables := []string{}
q := "SELECT name FROM sqlite_schema WHERE type ='table' AND name NOT LIKE 'sqlite_%' AND name LIKE ?"
rows, err := d.con.Query(q, fmt.Sprintf("%s_%%", variables.DBTablePrefix))
if err != nil {
return tables, err
}
for rows.Next() {
var table string
if err := rows.Scan(&table); err != nil {
return tables, err
}
tables = append(tables, tableNameToEnvName(table))
}
return tables, nil
}
func (d *db) copyContentFromTo(table_name_target string, table_name_dest string) error {
_, err := d.con.Exec(fmt.Sprintf("INSERT INTO %s (key, value, encrypted) SELECT * FROM %s", table_name_dest, table_name_target))
if err != nil {
return err
}
return nil
}
func (d *db) deleteTable(table_name string) error {
_, err := d.con.Exec(fmt.Sprintf("DROP TABLE IF EXISTS %s", table_name))
return err
}
func (d *db) getVar(table_name string, key string) (*types.EnvVar, error) {
q := fmt.Sprintf("SELECT * FROM %s WHERE key=?", table_name)
row := d.con.QueryRow(q, key)
envVar := &types.EnvVar{}
err := row.Scan(&envVar.Key, &envVar.Value, &envVar.Encrypted)
if err != nil {
return envVar, errors.NewNoKeyFoundError(key)
}
return envVar, nil
}
func (d *db) getAll(table_name string) ([]*types.EnvVar, error) {
entries := []*types.EnvVar{}
rows, err := d.con.Query(fmt.Sprintf("SELECT * FROM %s", table_name))
if err != nil {
return entries, err
}
for rows.Next() {
key := ""
value := ""
enc := common.BoolP(false)
err := rows.Scan(&key, &value, enc)
if err != nil {
return entries, err
}
e := &types.EnvVar{
Key: key,
Value: value,
Encrypted: *enc,
}
entries = append(entries, e)
}
return entries, nil
}
func (d *db) setVar(table_name string, key string, value string, encrypted bool) error {
q := fmt.Sprintf("INSERT INTO %s (key, value, encrypted) values ( ? , ? , ? ) ON CONFLICT (key) DO UPDATE SET value = ?, encrypted = ?", table_name)
_, err := d.con.Exec(q, key, value, encrypted, value, encrypted)
if err != nil {
fmt.Println(err)
return errors.NewSecretExsistsError(key)
}
return nil
}
func (d *db) rmVar(table_name string, key string) {
q := fmt.Sprintf("DELETE FROM %s WHERE key = ?", table_name)
_, _ = d.con.Exec(q, key)
}
func envNameToTableName(envName string) string {
envSanke := common.StrToSnakeCase(envName)
return fmt.Sprintf("%s_%s", variables.DBTablePrefix, envSanke)
}
func tableNameToEnvName(tableName string) string {
// remove '<prefix>_'
return tableName[len(variables.DBTablePrefix)+1:]
}