package datastore import ( "database/sql" "fmt" "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(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) 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, variables.DBTablePrefix+"_%%") if err != nil || rows.Err() != nil { return tables, err } defer rows.Close() 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(tableNameTarget string, tableNameDest string) error { _, err := d.con.Exec( fmt.Sprintf("INSERT INTO %s (key, value, encrypted) SELECT * FROM %s", tableNameDest, tableNameTarget), ) if err != nil { return err } return nil } func (d *db) deleteTable(tableName string) error { _, err := d.con.Exec("DROP TABLE IF EXISTS " + tableName) return err } func (d *db) getVar(tableName string, key string) (*types.EnvVar, error) { q := "SELECT * FROM " + tableName + " WHERE key=?" 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(tableName string) ([]*types.EnvVar, error) { entries := []*types.EnvVar{} rows, err := d.con.Query("SELECT * FROM " + tableName) if err != nil || rows.Err() != nil { return entries, err } defer rows.Close() 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(tableName string, key string, value string, encrypted bool) error { q := "INSERT INTO " + tableName + " (key,value,encrypted) values (?,?,?) ON CONFLICT (key) DO UPDATE SET value=?, encrypted=?" _, 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(tableName string, key string) { q := "DELETE FROM " + tableName + " WHERE key = ?" _, _ = 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:] }