github.com/pbberlin/go-pwa@v0.0.0-20220328105622-7c26e0ca1ab8/pkg/db/init.go (about)

     1  package db
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  
     7  	"github.com/pbberlin/dbg"
     8  	"gorm.io/driver/sqlite"
     9  	"gorm.io/gorm"
    10  	"gorm.io/gorm/logger"
    11  )
    12  
    13  // https://golangbyexample.com/print-output-text-color-console/
    14  const (
    15  	colorCyan  = "\033[36m"
    16  	colorRed   = "\033[31m"
    17  	colorReset = "\033[0m"
    18  )
    19  
    20  // LogRes stands for log result
    21  func LogRes(res *gorm.DB) {
    22  
    23  	// log.Printf("%2v stmt", res.Statement.SQL.String())
    24  	if res.Error != nil {
    25  		errStr := fmt.Sprintf("  %v", res.Error)
    26  		log.Print(colorRed, errStr, res.Error, colorReset)
    27  	}
    28  
    29  	if res.Error != nil || res.RowsAffected != 1 {
    30  		log.Print(colorCyan, dbg.CallingLine(0), colorReset)
    31  		log.Printf("%2v affected rows", res.RowsAffected)
    32  	}
    33  
    34  	// log.Printf("statement \n %v", res.Statement)
    35  	// res.Error = nil
    36  }
    37  
    38  // LogErr with source code line and colored terminal message
    39  func LogErr(err error) {
    40  	if err != nil {
    41  		errStr := fmt.Sprintf("  %v", err)
    42  		log.Print(colorCyan, dbg.CallingLine(0), colorReset)
    43  		log.Print(colorRed, errStr, err, colorReset)
    44  	}
    45  }
    46  
    47  var db *gorm.DB
    48  
    49  func Get() *gorm.DB {
    50  	return db
    51  }
    52  
    53  func ToInfo() {
    54  	db.Config.Logger = logger.Default.LogMode(logger.Info)
    55  }
    56  func ToWarn() {
    57  	db.Config.Logger = logger.Default.LogMode(logger.Warn)
    58  }
    59  
    60  // Init should be called on application start after config load;
    61  // or during tests
    62  // dbNames is an optional parameter for the db name; default is "main".
    63  func Init(dbNames ...string) {
    64  
    65  	if db != nil {
    66  		// making sure, gorm.Open is called only once;
    67  		// to close an existing db, use Close()
    68  		return
    69  	}
    70  
    71  	dbName := "main"
    72  	if len(dbNames) > 0 {
    73  		dbName = dbNames[0]
    74  	}
    75  
    76  	dbCfg := &gorm.Config{
    77  		CreateBatchSize: 10,
    78  
    79  		// gorm.io/docs/associations.html#Association-Mode
    80  		// FullSaveAssociations: true,
    81  	}
    82  
    83  	if false {
    84  		dbCfg.Logger = logger.Default.LogMode(logger.Info)
    85  	}
    86  
    87  	var err error
    88  	pth := fmt.Sprintf("./app-bucket/server-config/%v.sqlite", dbName)
    89  	db, err = gorm.Open(sqlite.Open(pth), dbCfg)
    90  	if err != nil {
    91  		log.Fatalf("failed to connect database: %v; %v", err, pth)
    92  	}
    93  
    94  	// activate EntryTag as custom join table
    95  	err = db.SetupJoinTable(&Entry{}, "Tags", &EntryTag{})
    96  	if err != nil {
    97  		log.Fatalf("failed to setup join table EntryTag: %v", err)
    98  	}
    99  
   100  	db.AutoMigrate(&Category{})
   101  	db.AutoMigrate(&CreditCard{})
   102  	db.AutoMigrate(&Tag{})
   103  	db.AutoMigrate(&Entry{})
   104  
   105  	initClauses()
   106  
   107  }
   108  
   109  // Close releases the database; as long as gorm.Open() was called only once on the db
   110  func Close() {
   111  	if db != nil {
   112  		db.Commit()
   113  		sqlDB, err := db.DB() // underlying golang sql.DB
   114  		if err != nil {
   115  			log.Printf("failed to get sql.DB from gorm.DB: %v", err)
   116  			return
   117  		}
   118  		err = sqlDB.Close()
   119  		if err != nil {
   120  			log.Printf("cannot close sql.DB %v", err)
   121  		} else {
   122  			log.Printf("sql.DB closing...")
   123  			db = nil
   124  		}
   125  	}
   126  }