diff options
author | Ben Morrison <ben@gbmor.dev> | 2019-06-08 01:04:38 -0400 |
---|---|---|
committer | Ben Morrison <ben@gbmor.dev> | 2019-06-08 02:29:33 -0400 |
commit | a5a32e7a317dd5cf156e52a71d7be432d0594bf7 (patch) | |
tree | c266a1652f78ec446b2eb85f2371e0cfabed65ff /svc/sqlite.go | |
parent | e6beae32cd45ea0057e1a5bc5e4b3f2a098a1a1e (diff) | |
download | getwtxt-a5a32e7a317dd5cf156e52a71d7be432d0594bf7.tar.gz |
split db-specific funcs into separate files
Diffstat (limited to 'svc/sqlite.go')
-rw-r--r-- | svc/sqlite.go | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/svc/sqlite.go b/svc/sqlite.go new file mode 100644 index 0000000..3f50402 --- /dev/null +++ b/svc/sqlite.go @@ -0,0 +1,148 @@ +package svc // import "github.com/getwtxt/getwtxt/svc" + +import ( + "database/sql" + "net" + "time" + + "github.com/getwtxt/registry" + _ "github.com/mattn/go-sqlite3" // for the sqlite3 driver +) + +type dbSqlite struct { + db *sql.DB + pullStmt *sql.Stmt + pushStmt *sql.Stmt +} + +func initSqlite() *dbSqlite { + + confObj.Mu.RLock() + dbpath := confObj.DBPath + confObj.Mu.RUnlock() + + lite, err := sql.Open("sqlite3", dbpath) + errFatal("Error opening sqlite3 DB: ", err) + + errFatal("", lite.Ping()) + + _, err = lite.Exec("CREATE TABLE IF NOT EXISTS getwtxt (id INTEGER PRIMARY KEY, urlKey TEXT, isUser BOOL, dataKey TEXT, data BLOB)") + errFatal("Error preparing sqlite3 DB: ", err) + + push, err := lite.Prepare("INSERT OR REPLACE INTO getwtxt (urlKey, isUser, dataKey, data) VALUES(?, ?, ?, ?)") + errFatal("", err) + + pull, err := lite.Prepare("SELECT * FROM getwtxt") + errFatal("", err) + + return &dbSqlite{ + db: lite, + pushStmt: push, + pullStmt: pull, + } +} + +func (lite dbSqlite) push() error { + err := lite.db.Ping() + if err != nil { + return err + } + + tx, err := lite.db.Begin() + errLog("", err) + txst := tx.Stmt(lite.pushStmt) + + twtxtCache.Mu.RLock() + for i, e := range twtxtCache.Users { + e.Mu.RLock() + + _, err = txst.Exec(i, true, "nickname", e.Nick) + errLog("", err) + _, err = txst.Exec(i, true, "rlen", e.RLen) + errLog("", err) + _, err = txst.Exec(i, true, "uip", e.IP) + errLog("", err) + _, err = txst.Exec(i, true, "date", e.Date) + errLog("", err) + + for k, v := range e.Status { + _, err = txst.Exec(i, true, k.Format(time.RFC3339), v) + errLog("", err) + } + + e.Mu.RUnlock() + } + twtxtCache.Mu.RUnlock() + + remoteRegistries.Mu.RLock() + for _, e := range remoteRegistries.List { + _, err = txst.Exec(e, false, "REMOTE REGISTRY", "NULL") + errLog("", err) + } + remoteRegistries.Mu.RUnlock() + + err = tx.Commit() + if err != nil { + tx.Rollback() + return err + } + + return nil +} + +func (lite dbSqlite) pull() { + errLog("Error pinging sqlite DB: ", lite.db.Ping()) + + rows, err := lite.pullStmt.Query() + errLog("", err) + + defer func(rows *sql.Rows) { + errLog("Error while finalizing DB Pull: ", rows.Close()) + }(rows) + + twtxtCache.Mu.Lock() + for rows.Next() { + var urls string + var isUser bool + var dataKey string + var dBlob []byte + + errLog("", rows.Scan(&urls, &isUser, &dataKey, &dBlob)) + + if !isUser { + remoteRegistries.Mu.Lock() + remoteRegistries.List = append(remoteRegistries.List, urls) + remoteRegistries.Mu.Unlock() + continue + } + + user := registry.NewUser() + if _, ok := twtxtCache.Users[urls]; ok { + user = twtxtCache.Users[urls] + } + user.Mu.Lock() + + switch dataKey { + case "nickname": + user.Nick = string(dBlob) + case "uip": + user.IP = net.ParseIP(string(dBlob)) + case "date": + user.Date = string(dBlob) + case "rlen": + user.RLen = string(dBlob) + default: + thetime, err := time.Parse(time.RFC3339, dataKey) + errLog("While pulling statuses from SQLite: ", err) + user.Status[thetime] = string(dBlob) + } + + twtxtCache.Users[urls] = user + user.Mu.Unlock() + } + twtxtCache.Mu.Unlock() + + remoteRegistries.Mu.Lock() + remoteRegistries.List = dedupe(remoteRegistries.List) + remoteRegistries.Mu.Unlock() +} |