|
|
|
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,
|
|
|
|
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)
|
|
|
|
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},
|
|
|
|
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.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.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.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
|
|
|
|
}
|