summaryrefslogtreecommitdiff
path: root/src/hub/src/spreadspace.org/sfive/s5store.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/hub/src/spreadspace.org/sfive/s5store.go')
-rw-r--r--src/hub/src/spreadspace.org/sfive/s5store.go106
1 files changed, 44 insertions, 62 deletions
diff --git a/src/hub/src/spreadspace.org/sfive/s5store.go b/src/hub/src/spreadspace.org/sfive/s5store.go
index 89b449f..57a5b82 100644
--- a/src/hub/src/spreadspace.org/sfive/s5store.go
+++ b/src/hub/src/spreadspace.org/sfive/s5store.go
@@ -2,7 +2,6 @@ package sfive
import (
"database/sql"
- "log"
"time"
_ "github.com/mattn/go-sqlite3"
@@ -13,47 +12,48 @@ import (
// compared to JSON DTOs, DB types are flattened, and use key-relations instead of collections
// this is very much not normalized at all, because I'm too lazy to type
+// table names
const (
- TagsTn = "Tags"
- SourceTagsTn = "StreamToTagMap"
- SourcesTn = "Sources"
- ClientDataUpdatesTn = "ClientDataUpdates"
- DataUpdatesTn = "DataUpdates"
+ tagsTn = "Tags"
+ sourceTagsTn = "StreamToTagMap"
+ sourcesTn = "Sources"
+ clientdataUpdatesTn = "ClientDataUpdates"
+ dataUpdatesTn = "DataUpdates"
)
-// stored in TagsTn
+// stored in tagsTn
type tagDb struct {
Id int
Name string
}
-// stored in SourceTagsTn
+// stored in sourceTagsTn
// Stream m:n Tag
type sourceTagsDb struct {
- TagId int // foreign key to TagsTn
- SourceId int // foreign key to SourcesTn
+ TagId int // foreign key to tagsTn
+ SourceId int // foreign key to sourcesTn
}
-// stored in SourcesTn
+// stored in sourcesTn
type sourceDb struct {
Id int
StreamId
SourceId
}
-// stored in ClientDataUpdatesTn
+// stored in clientdataUpdatesTn
// ClientData n:1 DataUpdate
type clientDataDb struct {
Id int
- DataUpdatesId int // foreign key to DataUpdatesTn
+ DataUpdatesId int // foreign key to dataUpdatesTn
ClientData
}
-// stored in DataUpdatesTn
+// stored in dataUpdatesTn
// in DB, StatisticsData/DataUpdate is flattened compared to JSON DTOs
type dataUpdateDb struct {
Id int
- SourceId int // foreign key to SourcesTn
+ SourceId int // foreign key to sourcesTn
StartTime time.Time
Duration time.Duration
ClientCount uint
@@ -61,15 +61,6 @@ type dataUpdateDb struct {
BytesSent uint
}
-type StatsContainer interface {
- Close()
- Append(update StatisticsData) error
- GetTags() ([]string, error)
- CountUpdateEntries(filter *StatsFilter) (int64, error)
- CountClients(filter *StatsFilter) uint
- GetAverageBps(filter *StatsFilter) (uint, error)
-}
-
type sqliteStore struct {
db *gorp.DbMap
}
@@ -123,31 +114,30 @@ func updateFromStatisticsData(value StatisticsData) (dataUpdateDb, []clientDataD
return du, cd, src, tags
}
-func initDb() *gorp.DbMap {
+func initDb(path string) (res *gorp.DbMap, err error) {
// connect to db using standard Go database/sql API
- db, err := sql.Open("sqlite3", "/tmp/s5-test.sqlite")
- checkErr(err, "sql.Open failed")
+ db, err := sql.Open("sqlite3", path)
+ if err != nil {
+ return
+ }
dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
// dbmap.TraceOn("[gorp]", log.New(os.Stdout, "myapp:", log.Lmicroseconds))
- dbmap.AddTableWithName(tagDb{}, TagsTn).SetKeys(true, "Id").ColMap("Name").SetUnique(true)
- dbmap.AddTableWithName(sourceTagsDb{}, SourceTagsTn).SetKeys(false, "TagId", "SourceId")
- dbmap.AddTableWithName(sourceDb{}, SourcesTn).SetKeys(true, "Id").SetUniqueTogether("ContentId", "Format", "Quality", "Hostname")
- dbmap.AddTableWithName(clientDataDb{}, ClientDataUpdatesTn).SetKeys(true, "Id")
- dbmap.AddTableWithName(dataUpdateDb{}, DataUpdatesTn).SetKeys(true, "Id")
+ dbmap.AddTableWithName(tagDb{}, tagsTn).SetKeys(true, "Id").ColMap("Name").SetUnique(true)
+ dbmap.AddTableWithName(sourceTagsDb{}, sourceTagsTn).SetKeys(false, "TagId", "SourceId")
+ dbmap.AddTableWithName(sourceDb{}, sourcesTn).SetKeys(true, "Id").SetUniqueTogether("ContentId", "Format", "Quality", "Hostname")
+ dbmap.AddTableWithName(clientDataDb{}, clientdataUpdatesTn).SetKeys(true, "Id")
+ dbmap.AddTableWithName(dataUpdateDb{}, dataUpdatesTn).SetKeys(true, "Id")
// TODO use some real migration, yadda yadda
err = dbmap.CreateTablesIfNotExists()
- checkErr(err, "Create tables failed")
-
- return dbmap
-}
-
-func checkErr(err error, msg string) {
if err != nil {
- log.Panicln(msg, err)
+ return
}
+
+ res = dbmap
+ return
}
func isEmptyFilter(filter *StatsFilter) bool {
@@ -176,10 +166,10 @@ func insertAnd(needsAnd *bool) (res string) {
func getFilteredDataUpdateSelect(filter *StatsFilter) (string, map[string]interface{}) {
if isEmptyFilter(filter) {
- return DataUpdatesTn, nil
+ return dataUpdatesTn, nil
}
- query := "(select * from " + DataUpdatesTn + " where"
+ query := "(select * from " + dataUpdatesTn + " where"
parameters := make(map[string]interface{})
needsAnd := false
@@ -201,7 +191,7 @@ func getFilteredDataUpdateSelect(filter *StatsFilter) (string, map[string]interf
func (s sqliteStore) findTag(name string) (tag *tagDb, err error) {
t := tagDb{}
- err = s.db.SelectOne(&t, "select * from "+TagsTn+" where Name = ?", name)
+ err = s.db.SelectOne(&t, "select * from "+tagsTn+" where Name = ?", name)
if err == nil {
tag = &t
}
@@ -212,7 +202,7 @@ func (s sqliteStore) insertNewTags(tags []tagDb) (err error) {
for i := range tags {
t, err := s.findTag(tags[i].Name)
if err != nil {
- _, err = s.db.Exec("insert into "+TagsTn+" VALUES (NULL, ?)", tags[i].Name)
+ _, err = s.db.Exec("insert into "+tagsTn+" VALUES (NULL, ?)", tags[i].Name)
}
t, err = s.findTag(tags[i].Name)
@@ -230,7 +220,7 @@ func (s sqliteStore) findSource(src sourceDb) (res *sourceDb, err error) {
t := sourceDb{}
err = s.db.SelectOne(
&t,
- "select Id from "+SourcesTn+" where ContentId = ? and Format = ? and Quality = ? and Hostname = ?",
+ "select Id from "+sourcesTn+" where ContentId = ? and Format = ? and Quality = ? and Hostname = ?",
src.ContentId,
src.Format,
src.Quality,
@@ -262,11 +252,12 @@ func (s sqliteStore) insertSourceTagLinks(src sourceDb, tags []tagDb) (err error
}
for i := range st {
_, err = s.db.Exec(
- "insert or ignore into "+SourceTagsTn+" values (?,?)",
+ "insert or ignore into "+sourceTagsTn+" values (?,?)",
st[i].SourceId,
st[i].TagId)
// err = s.db.Insert(&st[i])
if err != nil {
+ // TODO
//fmt.Printf("st\n")
return
}
@@ -289,6 +280,7 @@ func (s sqliteStore) insertDataUpdateClientEntries(cd []clientDataDb, du dataUpd
cd[i].DataUpdatesId = du.Id
err = s.db.Insert(&cd[i])
if err != nil {
+ // TODO
return
}
}
@@ -341,15 +333,15 @@ func (s sqliteStore) CountUpdateEntries(filter *StatsFilter) (count int64, err e
}
func (s sqliteStore) GetTags() ([]string, error) {
- res, dbErr := s.db.Select("", "select Name from "+TagsTn)
+ res, dbErr := s.db.Select("", "select Name from "+tagsTn)
if dbErr == nil {
- sRes := ToString(res)
+ sRes := castArrayToString(res)
return sRes, nil
}
return nil, dbErr
}
-func ToString(value []interface{}) []string {
+func castArrayToString(value []interface{}) []string {
res := make([]string, len(value))
for i := range value {
res[i] = value[i].(string)
@@ -384,25 +376,15 @@ func (s sqliteStore) GetAverageBps(filter *StatsFilter) (uint, error) {
return 0, err
}
-func NewStore() (store StatsContainer, err error) {
- db := initDb()
- if db == nil {
+func NewStore(path string) (store sqliteStore, err error) {
+ db, err := initDb(path)
+ if err != nil {
return
}
- res := sqliteStore{db}
- store = res
+ store = sqliteStore{db}
return
}
-func EatDataAndClose(sc StatsContainer) {
- s := sc.(sqliteStore)
- // if s == nil {
- // return
- // }
- s.db.TruncateTables()
- s.Close()
-}
-
func (s sqliteStore) Close() {
s.db.Db.Close()
}