116 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package database
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"os"
 | |
| 
 | |
| 	"database/sql"
 | |
| 
 | |
| 	"github.com/rs/zerolog"
 | |
| 	"github.com/rs/zerolog/log"
 | |
| 	"go.uber.org/fx"
 | |
| 	"gorm.io/driver/sqlite"
 | |
| 	"gorm.io/gorm"
 | |
| 	"sneak.berlin/go/directory/internal/config"
 | |
| 	"sneak.berlin/go/directory/internal/globals"
 | |
| 	"sneak.berlin/go/directory/internal/logger"
 | |
| 	"sneak.berlin/go/util"
 | |
| 
 | |
| 	// spooky action at a distance!
 | |
| 	// this populates the environment
 | |
| 	// from a ./.env file automatically
 | |
| 	// for development configuration.
 | |
| 	// .env contents should be things like
 | |
| 	// `DBURL=postgres://user:pass@.../`
 | |
| 	// (without the backticks, of course)
 | |
| 	_ "github.com/joho/godotenv/autoload"
 | |
| )
 | |
| 
 | |
| type DatabaseParams struct {
 | |
| 	fx.In
 | |
| 	Logger  *logger.Logger
 | |
| 	Config  *config.Config
 | |
| 	Globals *globals.Globals
 | |
| }
 | |
| 
 | |
| type Database struct {
 | |
| 	URL    string
 | |
| 	log    *zerolog.Logger
 | |
| 	params *DatabaseParams
 | |
| 	DB     *gorm.DB
 | |
| 	SQLDB  *sql.DB
 | |
| 	dbdir  string
 | |
| 	dbfn   string
 | |
| }
 | |
| 
 | |
| func New(lc fx.Lifecycle, params DatabaseParams) (*Database, error) {
 | |
| 	s := new(Database)
 | |
| 	s.params = ¶ms
 | |
| 	s.log = params.Logger.Get()
 | |
| 
 | |
| 	s.log.Info().Msg("Database instantiated")
 | |
| 
 | |
| 	lc.Append(fx.Hook{
 | |
| 		OnStart: func(ctx context.Context) error {
 | |
| 			s.log.Info().Msg("Database OnStart Hook")
 | |
| 			// FIXME connect to db
 | |
| 			return nil
 | |
| 		},
 | |
| 		OnStop: func(ctx context.Context) error {
 | |
| 			// FIXME disconnect from db
 | |
| 			return nil
 | |
| 		},
 | |
| 	})
 | |
| 	return s, nil
 | |
| }
 | |
| 
 | |
| func (d *Database) Close() {
 | |
| 	d.log.Info().Msg("Database Close()")
 | |
| }
 | |
| 
 | |
| func (d *Database) Get() (*gorm.DB, error) {
 | |
| 	if d.DB == nil {
 | |
| 		err := d.Connect()
 | |
| 		if err != nil {
 | |
| 			d.log.Error().Err(err).Msg("failed to connect to database")
 | |
| 			return nil, err
 | |
| 		}
 | |
| 	}
 | |
| 	return d.DB, nil
 | |
| }
 | |
| 
 | |
| func (d *Database) Connect() error {
 | |
| 	// FIXME make this get the data dir path from config
 | |
| 	d.dbdir = os.Getenv("HOME")
 | |
| 	err := util.Mkdirp(d.dbdir)
 | |
| 	if err != nil {
 | |
| 		d.log.Error().
 | |
| 			Err(err).
 | |
| 			Str("dbdir", d.dbdir).
 | |
| 			Msg("unable to create directory")
 | |
| 		return err
 | |
| 	}
 | |
| 	d.dbfn = d.dbdir + "/" + d.params.Globals.Appname + ".db"
 | |
| 	d.log.Info().
 | |
| 		Str("file", d.dbfn).
 | |
| 		Msg("opening store db")
 | |
| 
 | |
| 	// Open the database using the pure Go SQLite driver
 | |
| 	sqlDB, err := sql.Open("sqlite", d.dbfn+"?_pragma=foreign_keys(1)&_pragma=journal_mode(WAL)")
 | |
| 	if err != nil {
 | |
| 		d.log.Error().Err(err).Msg("failed to open database")
 | |
| 		return err
 | |
| 	}
 | |
| 	d.SQLDB = sqlDB
 | |
| 
 | |
| 	// Use the generic Gorm SQL driver to integrate it
 | |
| 	db, err := gorm.Open(sqlite.Dialector{Conn: d.SQLDB}, &gorm.Config{})
 | |
| 	if err != nil {
 | |
| 		log.Error().Err(err).Msg("failed to connect database")
 | |
| 		return err
 | |
| 	}
 | |
| 	d.DB = db
 | |
| 
 | |
| 	return nil
 | |
| }
 |