From 887c25ef0188d8a2ccd811c1d5896d7d71f254df Mon Sep 17 00:00:00 2001 From: Ben Morrison Date: Tue, 4 Jun 2019 16:13:27 -0400 Subject: expanding options for databases. abstractions for database push/pull functions --- cache.go | 33 +++++++++++++++++++++++++-------- getwtxt.yml | 7 ++++++- init.go | 35 ++++++++++++++++++++++++++++++----- types.go | 49 +++++++++++++++++++++++++++++++++---------------- 4 files changed, 94 insertions(+), 30 deletions(-) diff --git a/cache.go b/cache.go index 3a7886e..fb32e04 100644 --- a/cache.go +++ b/cache.go @@ -75,12 +75,7 @@ func refreshCache() { confObj.Mu.Unlock() } -// Pushes the registry's cache data to a local -// database for safe keeping. -func pushDatabase() error { - db := <-dbChan - dbChan <- db - +func (lvl dbLevel) push() error { twtxtCache.Mu.RLock() var dbBasket = &leveldb.Batch{} for k, v := range twtxtCache.Users { @@ -101,7 +96,7 @@ func pushDatabase() error { } remoteRegistries.Mu.RUnlock() - if err := db.Write(dbBasket, nil); err != nil { + if err := lvl.db.Write(dbBasket, nil); err != nil { return err } @@ -112,11 +107,33 @@ func pushDatabase() error { return nil } +func (lite dbSqlite) push() error { + + return nil +} + +func (lite dbSqlite) pull() { + +} + +// Pushes the registry's cache data to a local +// database for safe keeping. +func pushDatabase() error { + db := <-dbChan + dbChan <- db + + return db.push() +} + func pullDatabase() { db := <-dbChan dbChan <- db + db.pull() +} + +func (lvl dbLevel) pull() { - iter := db.NewIterator(nil, nil) + iter := lvl.db.NewIterator(nil, nil) for iter.Next() { key := string(iter.Key()) diff --git a/getwtxt.yml b/getwtxt.yml index 460ff4e..4c72454 100644 --- a/getwtxt.yml +++ b/getwtxt.yml @@ -22,7 +22,12 @@ # This is the port that getwtxt will bind to. ListenPort: 9001 -# The location of the LevelDB database structure. Can be +# The type of database you want to use. Currently, +# the following are supported: +# leveldb +DatabaseType: "leveldb" + +# The location of the database structure. Can be # a relative or absolute path. DatabasePath: "getwtxt.db" diff --git a/init.go b/init.go index ba3fdfc..076a7ca 100644 --- a/init.go +++ b/init.go @@ -1,6 +1,7 @@ package main import ( + "database/sql" "fmt" "html/template" "log" @@ -33,7 +34,7 @@ var closeLog = make(chan bool, 1) // used to transmit database pointer after // initialization -var dbChan = make(chan *leveldb.DB, 1) +var dbChan = make(chan dbase, 1) var tmpls *template.Template @@ -136,6 +137,7 @@ func initConfig() { confObj.Port = viper.GetInt("ListenPort") confObj.LogFile = viper.GetString("LogFile") + confObj.DBType = strings.ToLower(viper.GetString("DatabaseType")) confObj.DBPath = viper.GetString("DatabasePath") log.Printf("Using database: %v\n", confObj.DBPath) @@ -213,6 +215,7 @@ func rebindConfig() { confObj.Mu.Lock() confObj.LogFile = viper.GetString("LogFile") + confObj.DBType = strings.ToLower(viper.GetString("DatabaseType")) confObj.DBPath = viper.GetString("DatabasePath") confObj.StdoutLogging = viper.GetBool("StdoutLogging") confObj.CacheInterval = viper.GetDuration("StatusFetchInterval") @@ -235,9 +238,24 @@ func initTemplates() *template.Template { // Pull DB data into cache, if available. func initDatabase() { + var db dbase + var err error + confObj.Mu.RLock() - db, err := leveldb.OpenFile(confObj.DBPath, nil) + switch confObj.DBType { + + case "leveldb": + var lvl *leveldb.DB + lvl, err = leveldb.OpenFile(confObj.DBPath, nil) + db = &dbLevel{db: lvl} + + case "sqlite": + var lite *sql.DB + db = &dbSqlite{db: lite} + + } confObj.Mu.RUnlock() + if err != nil { log.Fatalf("%v\n", err.Error()) } @@ -259,11 +277,18 @@ func watchForInterrupt() { log.Printf("\n\nCaught %v. Cleaning up ...\n", sigint) confObj.Mu.RLock() - log.Printf("Closing database connection to %v...\n", confObj.DBPath) + db := <-dbChan - if err := db.Close(); err != nil { - log.Printf("%v\n", err.Error()) + + switch dbType := db.(type) { + + case *dbLevel: + lvl := dbType + if err := lvl.db.Close(); err != nil { + log.Printf("%v\n", err.Error()) + } + } if !confObj.StdoutLogging { diff --git a/types.go b/types.go index 16f3c55..7e78ae0 100644 --- a/types.go +++ b/types.go @@ -1,8 +1,11 @@ package main import ( + "database/sql" "sync" "time" + + "github.com/syndtr/goleveldb/leveldb" ) // content-type consts @@ -13,26 +16,40 @@ const cssutf8 = "text/css; charset=utf-8" // Configuration object definition type Configuration struct { Mu sync.RWMutex - Port int `json:"ListenPort"` - LogFile string `json:"LogFile"` - DBPath string `json:"DatabasePath"` - StdoutLogging bool `json:"StdoutLogging"` - Version string `json:"-"` - CacheInterval time.Duration `json:"StatusFetchInterval"` - DBInterval time.Duration `json:"DatabasePushInterval"` - LastCache time.Time `json:"-"` - LastPush time.Time `json:"-"` - Instance `json:"Instance"` + Port int `yaml:"ListenPort"` + LogFile string `yaml:"LogFile"` + DBType string `yaml:"DatabaseType"` + DBPath string `yaml:"DatabasePath"` + StdoutLogging bool `yaml:"StdoutLogging"` + Version string `yaml:"-"` + CacheInterval time.Duration `yaml:"StatusFetchInterval"` + DBInterval time.Duration `yaml:"DatabasePushInterval"` + LastCache time.Time `yaml:"-"` + LastPush time.Time `yaml:"-"` + Instance `yaml:"Instance"` } // Instance refers to this specific instance of getwtxt type Instance struct { - Vers string `json:"-"` - Name string `json:"Instance.SiteName"` - URL string `json:"Instance.URL"` - Owner string `json:"Instance.OwnerName"` - Mail string `json:"Instance.Email"` - Desc string `json:"Instance.Description"` + Vers string `yaml:"-"` + Name string `yaml:"Instance.SiteName"` + URL string `yaml:"Instance.URL"` + Owner string `yaml:"Instance.OwnerName"` + Mail string `yaml:"Instance.Email"` + Desc string `yaml:"Instance.Description"` +} + +type dbLevel struct { + db *leveldb.DB +} + +type dbSqlite struct { + db *sql.DB +} + +type dbase interface { + push() error + pull() } // RemoteRegistries holds a list of remote registries to -- cgit 1.4.1-2-gfad0