github.com/code-to-go/safepool.lib@v0.0.0-20221205180519-ee25e63c226e/sql/init.go (about)

     1  package sql
     2  
     3  import (
     4  	"database/sql"
     5  	"errors"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"github.com/adrg/xdg"
    12  	_ "github.com/mattn/go-sqlite3"
    13  	"github.com/sirupsen/logrus"
    14  )
    15  
    16  var DbName = "safepool.db"
    17  var db *sql.DB
    18  var InitDDL string
    19  
    20  func createTables() error {
    21  	parts := strings.Split(InitDDL, "\n\n")
    22  
    23  	for line, part := range parts {
    24  		if strings.Trim(part, " ") == "" {
    25  			continue
    26  		}
    27  
    28  		if !strings.HasPrefix(part, "-- ") {
    29  			logrus.Errorf("unexpected break without a comment in '%s'", part)
    30  		}
    31  
    32  		cr := strings.Index(part, "\n")
    33  		if cr == -1 {
    34  			logrus.Error("invalid comment without CR")
    35  			return os.ErrInvalid
    36  		}
    37  		key, ql := part[3:cr], part[cr+1:]
    38  
    39  		if strings.HasPrefix(key, "INIT") {
    40  			_, err := db.Exec(ql)
    41  			if err != nil {
    42  				logrus.Errorf("cannot execute SQL Init stmt (line %d) '%s': %v", line, ql, err)
    43  				return err
    44  			}
    45  		} else {
    46  			prepareStatement(key, ql, line)
    47  		}
    48  	}
    49  	return nil
    50  }
    51  
    52  // LoadSQLFromFile loads the sql queries from the provided file path. It panics in case the file cannot be loaded
    53  func LoadSQLFromFile(name string) {
    54  	ddl, err := ioutil.ReadFile(name)
    55  	if err != nil {
    56  		logrus.Panicf("cannot load SQL queries from %s: %v", name, err)
    57  		panic(err)
    58  	}
    59  
    60  	InitDDL = string(ddl)
    61  }
    62  
    63  func OpenDB() error {
    64  	if db != nil {
    65  		return nil
    66  	}
    67  
    68  	dbPath := filepath.Join(xdg.ConfigHome, DbName)
    69  	_, err := os.Stat(dbPath)
    70  	if errors.Is(err, os.ErrNotExist) {
    71  		err := ioutil.WriteFile(dbPath, []byte{}, 0644)
    72  		if err != nil {
    73  			logrus.Errorf("cannot create SQLite db in %s: %v", dbPath, err)
    74  			return err
    75  		}
    76  
    77  	} else if err != nil {
    78  		logrus.Errorf("cannot access SQLite db file %s: %v", dbPath, err)
    79  	}
    80  
    81  	db, err = sql.Open("sqlite3", dbPath)
    82  	if err != nil {
    83  		logrus.Errorf("cannot open SQLite db in %s: %v", dbPath, err)
    84  		return err
    85  	}
    86  
    87  	return createTables()
    88  }
    89  
    90  func CloseDB() error {
    91  	if db == nil {
    92  		return os.ErrClosed
    93  	}
    94  	err := db.Close()
    95  	db = nil
    96  	return err
    97  }
    98  
    99  func DeleteDB() error {
   100  	dbPath := filepath.Join(xdg.ConfigHome, DbName)
   101  	return os.Remove(dbPath)
   102  }