2024-11-22 15:29:25 +00:00
|
|
|
package datastore
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2024-12-16 18:22:58 +00:00
|
|
|
"fmt"
|
2024-11-22 15:29:25 +00:00
|
|
|
|
|
|
|
"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)
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &db{
|
|
|
|
con: con,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *db) close() error {
|
|
|
|
return d.con.Close()
|
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
func (d *db) createTableIfNotExists(tableName string) error {
|
|
|
|
q := "CREATE TABLE IF NOT EXISTS " + tableName +
|
|
|
|
" (key TEXT PRIMARY KEY NOT NULL,value BLOB NOT NULL,encrypted BOOL NOT NULL);"
|
|
|
|
|
|
|
|
_, err := d.con.Exec(q)
|
2024-11-22 15:29:25 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
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 ?"
|
2024-12-16 18:22:58 +00:00
|
|
|
|
|
|
|
rows, err := d.con.Query(q, variables.DBTablePrefix+"_%%")
|
|
|
|
if err != nil || rows.Err() != nil {
|
2024-11-22 15:29:25 +00:00
|
|
|
return tables, err
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
defer rows.Close()
|
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
for rows.Next() {
|
|
|
|
var table string
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
if err := rows.Scan(&table); err != nil {
|
|
|
|
return tables, err
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
tables = append(tables, tableNameToEnvName(table))
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
return tables, nil
|
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
func (d *db) copyContentFromTo(tableNameTarget string, tableNameDest string) error {
|
|
|
|
_, err := d.con.Exec(
|
|
|
|
fmt.Sprintf("INSERT INTO %s (key, value, encrypted) SELECT * FROM %s",
|
|
|
|
tableNameDest, tableNameTarget),
|
|
|
|
)
|
2024-11-22 15:29:25 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
func (d *db) deleteTable(tableName string) error {
|
|
|
|
_, err := d.con.Exec("DROP TABLE IF EXISTS " + tableName)
|
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
func (d *db) getVar(tableName string, key string) (*types.EnvVar, error) {
|
|
|
|
q := "SELECT * FROM " + tableName + " WHERE key=?"
|
2024-11-22 15:29:25 +00:00
|
|
|
row := d.con.QueryRow(q, key)
|
|
|
|
envVar := &types.EnvVar{}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
err := row.Scan(&envVar.Key, &envVar.Value, &envVar.Encrypted)
|
|
|
|
if err != nil {
|
|
|
|
return envVar, errors.NewNoKeyFoundError(key)
|
|
|
|
}
|
|
|
|
|
|
|
|
return envVar, nil
|
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
func (d *db) getAll(tableName string) ([]*types.EnvVar, error) {
|
2024-11-22 15:29:25 +00:00
|
|
|
entries := []*types.EnvVar{}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
|
|
|
rows, err := d.con.Query("SELECT * FROM " + tableName)
|
|
|
|
if err != nil || rows.Err() != nil {
|
2024-11-22 15:29:25 +00:00
|
|
|
return entries, err
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
defer rows.Close()
|
2024-11-22 15:29:25 +00:00
|
|
|
|
|
|
|
for rows.Next() {
|
|
|
|
key := ""
|
|
|
|
value := ""
|
|
|
|
enc := common.BoolP(false)
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
err := rows.Scan(&key, &value, enc)
|
|
|
|
if err != nil {
|
|
|
|
return entries, err
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
e := &types.EnvVar{
|
|
|
|
Key: key,
|
|
|
|
Value: value,
|
|
|
|
Encrypted: *enc,
|
|
|
|
}
|
|
|
|
entries = append(entries, e)
|
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
return entries, nil
|
2024-11-22 15:29:25 +00:00
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
func (d *db) setVar(tableName string, key string, value string, encrypted bool) error {
|
|
|
|
q := "INSERT INTO " +
|
|
|
|
tableName +
|
|
|
|
" (key,value,encrypted) values (?,?,?) ON CONFLICT (key) DO UPDATE SET valu=?, encrypted=?"
|
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
_, err := d.con.Exec(q, key, value, encrypted, value, encrypted)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Println(err)
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
return errors.NewSecretExsistsError(key)
|
|
|
|
}
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-12-16 18:22:58 +00:00
|
|
|
func (d *db) rmVar(tableName string, key string) {
|
|
|
|
q := "DELETE FROM " + tableName + " WHERE key = ?"
|
2024-11-22 15:29:25 +00:00
|
|
|
_, _ = d.con.Exec(q, key)
|
|
|
|
}
|
|
|
|
|
|
|
|
func envNameToTableName(envName string) string {
|
|
|
|
envSanke := common.StrToSnakeCase(envName)
|
2024-12-16 18:22:58 +00:00
|
|
|
|
2024-11-22 15:29:25 +00:00
|
|
|
return fmt.Sprintf("%s_%s", variables.DBTablePrefix, envSanke)
|
|
|
|
}
|
|
|
|
|
|
|
|
func tableNameToEnvName(tableName string) string {
|
|
|
|
// remove '<prefix>_'
|
|
|
|
return tableName[len(variables.DBTablePrefix)+1:]
|
|
|
|
}
|