mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-30 08:53:31 -06:00
[chore] Migrate accounts to new table, relax uniqueness constraint of actor url and collections
This commit is contained in:
parent
57c5f68e1a
commit
fe352c69b5
37 changed files with 1270 additions and 566 deletions
|
|
@ -46,48 +46,22 @@ type accountDB struct {
|
|||
state *state.State
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountByID(ctx context.Context, id string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
ctx,
|
||||
"ID",
|
||||
func(account *gtsmodel.Account) error {
|
||||
return a.db.NewSelect().
|
||||
Model(account).
|
||||
Where("? = ?", bun.Ident("account.id"), id).
|
||||
Scan(ctx)
|
||||
},
|
||||
id,
|
||||
)
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountsByIDs(ctx context.Context, ids []string) ([]*gtsmodel.Account, error) {
|
||||
// Load all input account IDs via cache loader callback.
|
||||
accounts, err := a.state.Caches.DB.Account.LoadIDs("ID",
|
||||
ids,
|
||||
func(uncached []string) ([]*gtsmodel.Account, error) {
|
||||
// Preallocate expected length of uncached accounts.
|
||||
accounts := make([]*gtsmodel.Account, 0, len(uncached))
|
||||
|
||||
// Perform database query scanning
|
||||
// the remaining (uncached) account IDs.
|
||||
if err := a.db.NewSelect().
|
||||
Model(&accounts).
|
||||
Where("? IN (?)", bun.Ident("id"), bun.In(uncached)).
|
||||
Scan(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accounts, nil
|
||||
},
|
||||
)
|
||||
func (a *accountDB) getAccountsBy(
|
||||
ctx context.Context,
|
||||
index string,
|
||||
keys []string,
|
||||
load func([]string) ([]*gtsmodel.Account, error),
|
||||
getKey func(*gtsmodel.Account) string,
|
||||
) ([]*gtsmodel.Account, error) {
|
||||
// Load all input account keys via cache loader callback.
|
||||
accounts, err := a.state.Caches.DB.Account.LoadIDs(index, keys, load)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Reorder the statuses by their
|
||||
// IDs to ensure in correct order.
|
||||
getID := func(a *gtsmodel.Account) string { return a.ID }
|
||||
xslices.OrderBy(accounts, ids, getID)
|
||||
// keys to ensure in correct order.
|
||||
xslices.OrderBy(accounts, keys, getKey)
|
||||
|
||||
if gtscontext.Barebones(ctx) {
|
||||
// no need to fully populate.
|
||||
|
|
@ -107,6 +81,75 @@ func (a *accountDB) GetAccountsByIDs(ctx context.Context, ids []string) ([]*gtsm
|
|||
return accounts, nil
|
||||
}
|
||||
|
||||
func (a *accountDB) getOneAccountBy(
|
||||
ctx context.Context,
|
||||
index string,
|
||||
key string,
|
||||
load func([]string) ([]*gtsmodel.Account, error),
|
||||
) (*gtsmodel.Account, error) {
|
||||
// Get all accounts with the given key.
|
||||
accounts, err := a.getAccountsBy(
|
||||
ctx,
|
||||
index,
|
||||
[]string{key},
|
||||
load,
|
||||
func(a *gtsmodel.Account) string { return key },
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Ensure we have one
|
||||
// and only one account.
|
||||
l := len(accounts)
|
||||
if l == 0 {
|
||||
return nil, db.ErrNoEntries
|
||||
}
|
||||
if l > 1 {
|
||||
return nil, db.ErrMultipleEntries
|
||||
}
|
||||
|
||||
return accounts[0], nil
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountByID(ctx context.Context, id string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
ctx,
|
||||
"ID",
|
||||
func(account *gtsmodel.Account) error {
|
||||
return a.db.NewSelect().
|
||||
Model(account).
|
||||
Where("? = ?", bun.Ident("account.id"), id).
|
||||
Scan(ctx)
|
||||
},
|
||||
id,
|
||||
)
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountsByIDs(ctx context.Context, ids []string) ([]*gtsmodel.Account, error) {
|
||||
return a.getAccountsBy(
|
||||
ctx,
|
||||
"ID",
|
||||
ids,
|
||||
func(uncached []string) ([]*gtsmodel.Account, error) {
|
||||
// Preallocate expected length of uncached accounts.
|
||||
accounts := make([]*gtsmodel.Account, 0, len(uncached))
|
||||
|
||||
// Perform database query scanning
|
||||
// the remaining (uncached) accounts.
|
||||
if err := a.db.NewSelect().
|
||||
Model(&accounts).
|
||||
Where("? IN (?)", bun.Ident("account.id"), bun.In(uncached)).
|
||||
Scan(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accounts, nil
|
||||
},
|
||||
func(a *gtsmodel.Account) string { return a.ID },
|
||||
)
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountByURI(ctx context.Context, uri string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
ctx,
|
||||
|
|
@ -121,17 +164,51 @@ func (a *accountDB) GetAccountByURI(ctx context.Context, uri string) (*gtsmodel.
|
|||
)
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountByURL(ctx context.Context, url string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
func (a *accountDB) GetOneAccountByURL(ctx context.Context, url string) (*gtsmodel.Account, error) {
|
||||
return a.getOneAccountBy(
|
||||
ctx,
|
||||
"URL",
|
||||
func(account *gtsmodel.Account) error {
|
||||
return a.db.NewSelect().
|
||||
Model(account).
|
||||
Where("? = ?", bun.Ident("account.url"), url).
|
||||
Scan(ctx)
|
||||
},
|
||||
url,
|
||||
func(uncached []string) ([]*gtsmodel.Account, error) {
|
||||
// Preallocate expected length of uncached accounts.
|
||||
accounts := make([]*gtsmodel.Account, 0, len(uncached))
|
||||
|
||||
// Perform database query scanning
|
||||
// the remaining (uncached) accounts.
|
||||
if err := a.db.NewSelect().
|
||||
Model(&accounts).
|
||||
Where("? IN (?)", bun.Ident("account.url"), bun.In(uncached)).
|
||||
Scan(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accounts, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountsByURL(ctx context.Context, url string) ([]*gtsmodel.Account, error) {
|
||||
// Get all accounts with the given URL.
|
||||
return a.getAccountsBy(
|
||||
ctx,
|
||||
"ID",
|
||||
[]string{url},
|
||||
func(uncached []string) ([]*gtsmodel.Account, error) {
|
||||
// Preallocate expected length of uncached accounts.
|
||||
accounts := make([]*gtsmodel.Account, 0, len(uncached))
|
||||
|
||||
// Perform database query scanning
|
||||
// the remaining (uncached) accounts.
|
||||
if err := a.db.NewSelect().
|
||||
Model(&accounts).
|
||||
Where("? IN (?)", bun.Ident("account.url"), bun.In(uncached)).
|
||||
Scan(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accounts, nil
|
||||
},
|
||||
func(a *gtsmodel.Account) string { return a.URL },
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -184,59 +261,49 @@ func (a *accountDB) GetAccountByPubkeyID(ctx context.Context, id string) (*gtsmo
|
|||
)
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountByInboxURI(ctx context.Context, uri string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
func (a *accountDB) GetOneAccountByInboxURI(ctx context.Context, uri string) (*gtsmodel.Account, error) {
|
||||
return a.getOneAccountBy(
|
||||
ctx,
|
||||
"InboxURI",
|
||||
func(account *gtsmodel.Account) error {
|
||||
return a.db.NewSelect().
|
||||
Model(account).
|
||||
Where("? = ?", bun.Ident("account.inbox_uri"), uri).
|
||||
Scan(ctx)
|
||||
},
|
||||
uri,
|
||||
func(uncached []string) ([]*gtsmodel.Account, error) {
|
||||
// Preallocate expected length of uncached accounts.
|
||||
accounts := make([]*gtsmodel.Account, 0, len(uncached))
|
||||
|
||||
// Perform database query scanning
|
||||
// the remaining (uncached) accounts.
|
||||
if err := a.db.NewSelect().
|
||||
Model(&accounts).
|
||||
Where("? IN (?)", bun.Ident("account.inbox_uri"), bun.In(uncached)).
|
||||
Scan(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return accounts, nil
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountByOutboxURI(ctx context.Context, uri string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
func (a *accountDB) GetOneAccountByOutboxURI(ctx context.Context, uri string) (*gtsmodel.Account, error) {
|
||||
return a.getOneAccountBy(
|
||||
ctx,
|
||||
"OutboxURI",
|
||||
func(account *gtsmodel.Account) error {
|
||||
return a.db.NewSelect().
|
||||
Model(account).
|
||||
Where("? = ?", bun.Ident("account.outbox_uri"), uri).
|
||||
Scan(ctx)
|
||||
},
|
||||
uri,
|
||||
)
|
||||
}
|
||||
func(uncached []string) ([]*gtsmodel.Account, error) {
|
||||
// Preallocate expected length of uncached accounts.
|
||||
accounts := make([]*gtsmodel.Account, 0, len(uncached))
|
||||
|
||||
func (a *accountDB) GetAccountByFollowersURI(ctx context.Context, uri string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
ctx,
|
||||
"FollowersURI",
|
||||
func(account *gtsmodel.Account) error {
|
||||
return a.db.NewSelect().
|
||||
Model(account).
|
||||
Where("? = ?", bun.Ident("account.followers_uri"), uri).
|
||||
Scan(ctx)
|
||||
},
|
||||
uri,
|
||||
)
|
||||
}
|
||||
// Perform database query scanning
|
||||
// the remaining (uncached) accounts.
|
||||
if err := a.db.NewSelect().
|
||||
Model(&accounts).
|
||||
Where("? IN (?)", bun.Ident("account.outbox_uri"), bun.In(uncached)).
|
||||
Scan(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (a *accountDB) GetAccountByFollowingURI(ctx context.Context, uri string) (*gtsmodel.Account, error) {
|
||||
return a.getAccount(
|
||||
ctx,
|
||||
"FollowingURI",
|
||||
func(account *gtsmodel.Account) error {
|
||||
return a.db.NewSelect().
|
||||
Model(account).
|
||||
Where("? = ?", bun.Ident("account.following_uri"), uri).
|
||||
Scan(ctx)
|
||||
return accounts, nil
|
||||
},
|
||||
uri,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -587,7 +654,11 @@ func (a *accountDB) GetAccounts(
|
|||
return a.state.DB.GetAccountsByIDs(ctx, accountIDs)
|
||||
}
|
||||
|
||||
func (a *accountDB) getAccount(ctx context.Context, lookup string, dbQuery func(*gtsmodel.Account) error, keyParts ...any) (*gtsmodel.Account, error) {
|
||||
func (a *accountDB) getAccount(
|
||||
ctx context.Context,
|
||||
lookup string,
|
||||
dbQuery func(*gtsmodel.Account) error, keyParts ...any,
|
||||
) (*gtsmodel.Account, error) {
|
||||
// Fetch account from database cache with loader callback
|
||||
account, err := a.state.Caches.DB.Account.LoadOne(lookup, func() (*gtsmodel.Account, error) {
|
||||
var account gtsmodel.Account
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue