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 '_' return tableName[len(variables.DBTablePrefix)+1:] }