diff options
Diffstat (limited to 'src/hub/src/spreadspace.org/sfive/s5store.go')
-rw-r--r-- | src/hub/src/spreadspace.org/sfive/s5store.go | 106 |
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() } |