From 0208dc30b5f16e72719e2c92a7c88f4f9fb8012f Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Wed, 17 May 2017 16:17:02 +0200 Subject: [PATCH] [TASK] add database --- database/main.go | 79 ++++++++++++++++++++++++++++++++++++++++ database/main_test.go | 84 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 database/main.go create mode 100644 database/main_test.go diff --git a/database/main.go b/database/main.go new file mode 100644 index 0000000..7b0d674 --- /dev/null +++ b/database/main.go @@ -0,0 +1,79 @@ +// Package that provides the functionality to open, close and use a database +package database + +import ( + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/postgres" + _ "github.com/jinzhu/gorm/dialects/sqlite" + _ "github.com/jinzhu/gorm/dialects/mysql" + + "github.com/genofire/golang-lib/lib/log" +) + +// Database connection for writing purposes +var Write *gorm.DB + +// Database connection for reading purposes +var Read *gorm.DB + +// Configuration files +var ( + config *Config + runtime []interface{} +) + +// Configuration of the database connection +type Config struct { + // type of the database, currently supports sqlite and postgres + Type string + // connection configuration + Connection string + // create another connection for reading only + ReadConnection string + // enable logging of the generated sql string + Logging bool +} + +// Function to open a database and set the given configuration +func Open(c Config) (err error) { + writeLog := log.Log.WithField("db", "write") + config = &c + Write, err = gorm.Open(config.Type, config.Connection) + if err != nil { + return + } + Write.SingularTable(true) + Write.LogMode(c.Logging) + Write.SetLogger(writeLog) + Write.Callback().Create().Remove("gorm:update_time_stamp") + Write.Callback().Update().Remove("gorm:update_time_stamp") + if len(config.ReadConnection) > 0 { + readLog := log.Log.WithField("db", "read") + Read, err = gorm.Open(config.Type, config.ReadConnection) + if err != nil { + return + } + Read.SingularTable(true) + Read.LogMode(c.Logging) + Read.SetLogger(readLog) + Read.Callback().Create().Remove("gorm:update_time_stamp") + Read.Callback().Update().Remove("gorm:update_time_stamp") + } else { + Read = Write + } + Write.AutoMigrate(runtime...) + return +} + +// Function to safely close the database +func Close() { + Write.Close() + if len(config.ReadConnection) > 0 { + Read.Close() + } +} + +// Function to add a model to the runtime +func AddModel(m interface{}) { + runtime = append(runtime, m) +} diff --git a/database/main_test.go b/database/main_test.go new file mode 100644 index 0000000..e9ae1bb --- /dev/null +++ b/database/main_test.go @@ -0,0 +1,84 @@ +// Package that provides the functionality to open, close and use a database +package database + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type TestModel struct { + ID int64 + Value string `gorm:"type:varchar(255);column:value" json:"value"` +} + +// Function to test the error handling for the database opening +func TestOpenNoDB(t *testing.T) { + assert := assert.New(t) + + c := Config{} + + err := Open(c) + assert.Error(err, "error") +} + +// Function to test the opening of one database +func TestOpenOneDB(t *testing.T) { + assert := assert.New(t) + AddModel(&TestModel{}) + + c := Config{ + Type: "sqlite3", + Logging: true, + Connection: "file:database?mode=memory", + } + var count int64 + + err := Open(c) + assert.NoError(err, "no error") + + Write.Create(&TestModel{Value: "first"}) + Write.Create(&TestModel{Value: "secound"}) + + var list []*TestModel + Read.Find(&list).Count(&count) + assert.Equal(int64(2), count, "not enought entries") + Close() +} + +// Function to test the opening of a second database +func TestOpenTwoDB(t *testing.T) { + assert := assert.New(t) + AddModel(&TestModel{}) + c := Config{ + Type: "sqlite3", + Logging: true, + Connection: "file:database?mode=memory", + ReadConnection: "file/", + } + + err := Open(c) + assert.Error(err, "no error found") + + c = Config{ + Type: "sqlite3", + Logging: true, + Connection: "file:database?mode=memory", + ReadConnection: "file:database2?mode=memory", + } + var count int64 + + err = Open(c) + assert.NoError(err, "no error") + + Write.Create(&TestModel{Value: "first"}) + Write.Create(&TestModel{Value: "secound"}) + + var list []*TestModel + Write.Find(&list).Count(&count) + assert.Equal(int64(2), count, "not enought entries") + + result := Read.Find(&list) + assert.Error(result.Error, "error, because it is the wrong database") + Close() +}