package namespace import ( "caj-larsson/bog/dataswamp/namespace" "context" "database/sql" "github.com/mattn/go-sqlite3" "time" ) var _ = sqlite3.ErrError type Repository struct { db *sql.DB } func (r *Repository) migrate() error { query := ` CREATE TABLE IF NOT EXISTS file_stats( id INTEGER PRIMARY KEY, num BIGINT NOT NULL, size_b BIGINT NOT NULL );` _, err := r.db.Exec(query) if err != nil { return err } query = ` CREATE TABLE IF NOT EXISTS namespace( id INTEGER PRIMARY KEY, name TEXT NOT NULL UNIQUE, lastseen TEXT, allowance_time BIGINT, quota_kb BIGINT, quota_usage_kb BIGINT, usage_id BIGINT NOT NULL REFERENCES file_stats(Id), download_id BIGINT NOT NULL REFERENCES file_stats(Id), upload_id BIGINT NOT NULL REFERENCES file_stats(Id) );` _, err = r.db.Exec(query) return err } func NewRepository(filename string) namespace.Repository { db, err := sql.Open("sqlite3", filename) if err != nil { panic(err) } repo := Repository{ db: db, } repo.migrate() return &repo } func (q *Queries) createFileStats(ctx context.Context, fstat namespace.FileStat) (int64, error) { return q.CreateFileStats(ctx, CreateFileStatsParams{fstat.Num, fstat.SizeB}) } func (r *Repository) Create(ns namespace.Namespace) (*namespace.Namespace, error) { ctx := context.Background() q := New(r.db) u_id, err := q.createFileStats(ctx, ns.Usage) if err != nil { return nil, err } dl_id, err := q.createFileStats(ctx, ns.Download) if err != nil { return nil, err } ul_id, err := q.createFileStats(ctx, ns.Upload) if err != nil { return nil, err } ns.LastSeen = ns.LastSeen.Round(time.Microsecond) p := CreateNamespaceParams{ Name: ns.Name, Lastseen: ns.LastSeen.UnixMicro(), AllowanceTime: sql.NullInt64{int64(ns.AllowanceDuration.Seconds()), true}, QuotaKb: sql.NullInt64{int64(ns.FileQuota.AllowanceKB), true}, QuotaUsageKb: sql.NullInt64{int64(ns.FileQuota.CurrentUsage), true}, UsageID: u_id, DownloadID: dl_id, UploadID: ul_id, } id, err := q.CreateNamespace(ctx, p) if err != nil { return nil, err } ns.ID = id return &ns, nil } func (r *Repository) All() ([]namespace.Namespace, error) { ctx := context.Background() q := New(r.db) rows, err := q.AllNamespaces(ctx) if err != nil { return nil, err } var all []namespace.Namespace for _, row := range rows { ns := namespace.Namespace{ row.ID, row.Name, time.UnixMicro(row.Lastseen), time.Duration(row.AllowanceTime.Int64 * int64(time.Second)), namespace.FileSizeQuota{row.QuotaKb.Int64, row.QuotaUsageKb.Int64}, namespace.FileStat{row.UNum, row.USizeB}, namespace.FileStat{row.DNum, row.DSizeB}, namespace.FileStat{row.UlNum, row.UlSizeB}, } all = append(all, ns) } return all, nil } func (r *Repository) GetByName(name string) (*namespace.Namespace, error) { ctx := context.Background() q := New(r.db) row, err := q.GetNamespaceByName(ctx, name) if err != nil { return nil, namespace.ErrNotExists } ns := namespace.Namespace{ row.ID, row.Name, time.UnixMicro(row.Lastseen), time.Duration(row.AllowanceTime.Int64 * int64(time.Second)), namespace.FileSizeQuota{row.QuotaKb.Int64, row.QuotaUsageKb.Int64}, namespace.FileStat{row.UNum, row.USizeB}, namespace.FileStat{row.DNum, row.DSizeB}, namespace.FileStat{row.UlNum, row.UlSizeB}, } return &ns, nil } func (q *Queries) updateFileStat(ctx context.Context, id int64, fstat namespace.FileStat) error { return q.UpdateFileStat(ctx, UpdateFileStatParams{fstat.Num, fstat.SizeB, id}) } func (r *Repository) Update(id int64, ns namespace.Namespace) (*namespace.Namespace, error) { ctx := context.Background() q := New(r.db) ids, err := q.UpdateNamespace(ctx, UpdateNamespaceParams{ ns.Name, ns.LastSeen.Round(time.Microsecond).UnixMicro(), sql.NullInt64{int64(ns.AllowanceDuration.Seconds()), true}, sql.NullInt64{int64(ns.FileQuota.AllowanceKB), true}, sql.NullInt64{int64(ns.FileQuota.CurrentUsage), true}, ns.ID, }) err = q.updateFileStat(ctx, ids.UsageID, ns.Usage) if err != nil { return nil, err } err = q.updateFileStat(ctx, ids.DownloadID, ns.Download) if err != nil { return nil, err } err = q.updateFileStat(ctx, ids.UploadID, ns.Upload) if err != nil { return nil, err } return &ns, nil } func (r *Repository) Delete(id int64) error { ctx := context.Background() q := New(r.db) err := q.DeleteNameSpace(ctx, id) if err != nil { return namespace.ErrDeleteFailed } return nil }