diff options
Diffstat (limited to 'internal/db/bundb')
| -rw-r--r-- | internal/db/bundb/bundb.go | 8 | ||||
| -rw-r--r-- | internal/db/bundb/migrations/20221108142419_create_account_tombstones.go | 57 | ||||
| -rw-r--r-- | internal/db/bundb/tombstone.go | 101 | 
3 files changed, 165 insertions, 1 deletions
| diff --git a/internal/db/bundb/bundb.go b/internal/db/bundb/bundb.go index 02522e6f7..43e9a07c9 100644 --- a/internal/db/bundb/bundb.go +++ b/internal/db/bundb/bundb.go @@ -88,6 +88,7 @@ type DBService struct {  	db.Status  	db.Timeline  	db.User +	db.Tombstone  	conn *DBConn  } @@ -181,12 +182,16 @@ func NewBunDBService(ctx context.Context) (db.DB, error) {  	status := &statusDB{conn: conn, cache: cache.NewStatusCache()}  	emoji := &emojiDB{conn: conn, cache: cache.NewEmojiCache()}  	timeline := &timelineDB{conn: conn} +	tombstone := &tombstoneDB{conn: conn}  	// Setup DB cross-referencing  	accounts.status = status  	status.accounts = accounts  	timeline.status = status +	// Initialize db structs +	tombstone.init() +  	ps := &DBService{  		Account: accounts,  		Admin: &adminDB{ @@ -228,7 +233,8 @@ func NewBunDBService(ctx context.Context) (db.DB, error) {  			conn:  conn,  			cache: userCache,  		}, -		conn: conn, +		Tombstone: tombstone, +		conn:      conn,  	}  	// we can confidently return this useable service now diff --git a/internal/db/bundb/migrations/20221108142419_create_account_tombstones.go b/internal/db/bundb/migrations/20221108142419_create_account_tombstones.go new file mode 100644 index 000000000..9f0b7b8e9 --- /dev/null +++ b/internal/db/bundb/migrations/20221108142419_create_account_tombstones.go @@ -0,0 +1,57 @@ +/* +   GoToSocial +   Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU Affero General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Affero General Public License for more details. + +   You should have received a copy of the GNU Affero General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +package migrations + +import ( +	"context" + +	gtsmodel "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +	"github.com/uptrace/bun" +) + +func init() { +	up := func(ctx context.Context, db *bun.DB) error { +		return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { +			if _, err := tx.NewCreateTable().Model(>smodel.Tombstone{}).IfNotExists().Exec(ctx); err != nil { +				return err +			} + +			if _, err := tx. +				NewCreateIndex(). +				Model(>smodel.Tombstone{}). +				Index("tombstone_uri_idx"). +				Column("uri"). +				Exec(ctx); err != nil { +				return err +			} + +			return nil +		}) +	} + +	down := func(ctx context.Context, db *bun.DB) error { +		return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { +			return nil +		}) +	} + +	if err := Migrations.Register(up, down); err != nil { +		panic(err) +	} +} diff --git a/internal/db/bundb/tombstone.go b/internal/db/bundb/tombstone.go new file mode 100644 index 000000000..35032f43a --- /dev/null +++ b/internal/db/bundb/tombstone.go @@ -0,0 +1,101 @@ +/* +   GoToSocial +   Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org + +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU Affero General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Affero General Public License for more details. + +   You should have received a copy of the GNU Affero General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +package bundb + +import ( +	"context" +	"time" + +	"github.com/superseriousbusiness/gotosocial/internal/db" +	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" +	"github.com/uptrace/bun" + +	"codeberg.org/gruf/go-cache/v3/result" +) + +type tombstoneDB struct { +	conn  *DBConn +	cache *result.Cache[*gtsmodel.Tombstone] +} + +func (t *tombstoneDB) init() { +	// Initialize tombstone result cache +	t.cache = result.NewSized([]string{ +		"ID", +		"URI", +	}, func(t1 *gtsmodel.Tombstone) *gtsmodel.Tombstone { +		t2 := new(gtsmodel.Tombstone) +		*t2 = *t1 +		return t2 +	}, 1000) + +	// Set cache TTL and start sweep routine +	t.cache.SetTTL(time.Minute*5, false) +	t.cache.Start(time.Second * 10) +} + +func (t *tombstoneDB) GetTombstoneByURI(ctx context.Context, uri string) (*gtsmodel.Tombstone, db.Error) { +	return t.cache.Load("URI", func() (*gtsmodel.Tombstone, error) { +		var tomb gtsmodel.Tombstone + +		q := t.conn. +			NewSelect(). +			Model(&tomb). +			Where("? = ?", bun.Ident("tombstone.uri"), uri) + +		if err := q.Scan(ctx); err != nil { +			return nil, t.conn.ProcessError(err) +		} + +		return &tomb, nil +	}, uri) +} + +func (t *tombstoneDB) TombstoneExistsWithURI(ctx context.Context, uri string) (bool, db.Error) { +	tomb, err := t.GetTombstoneByURI(ctx, uri) +	if err == db.ErrNoEntries { +		err = nil +	} +	return (tomb != nil), err +} + +func (t *tombstoneDB) PutTombstone(ctx context.Context, tombstone *gtsmodel.Tombstone) db.Error { +	return t.cache.Store(tombstone, func() error { +		_, err := t.conn. +			NewInsert(). +			Model(tombstone). +			Exec(ctx) +		return t.conn.ProcessError(err) +	}) +} + +func (t *tombstoneDB) DeleteTombstone(ctx context.Context, id string) db.Error { +	if _, err := t.conn. +		NewDelete(). +		TableExpr("? AS ?", bun.Ident("tombstones"), bun.Ident("tombstone")). +		Where("? = ?", bun.Ident("tombstone.id"), id). +		Exec(ctx); err != nil { +		return t.conn.ProcessError(err) +	} + +	// Invalidate from cache by ID +	t.cache.Invalidate("ID", id) + +	return nil +} | 
