summaryrefslogtreecommitdiff
path: root/internal/db/db.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/db/db.go')
-rw-r--r--internal/db/db.go138
1 files changed, 116 insertions, 22 deletions
diff --git a/internal/db/db.go b/internal/db/db.go
index 4921270e7..69ad7b822 100644
--- a/internal/db/db.go
+++ b/internal/db/db.go
@@ -27,8 +27,7 @@ import (
"github.com/go-fed/activity/pub"
"github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/superseriousbusiness/gotosocial/internal/db/model"
- "github.com/superseriousbusiness/gotosocial/pkg/mastotypes"
+ "github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel"
)
const dbTypePostgres string = "POSTGRES"
@@ -79,6 +78,11 @@ type DB interface {
// In case of no entries, a 'no entries' error will be returned
GetWhere(key string, value interface{}, i interface{}) error
+ // // GetWhereMany gets one entry where key = value for *ALL* parameters passed as "where".
+ // // That is, if you pass 2 'where' entries, with 1 being Key username and Value test, and the second
+ // // being Key domain and Value example.org, only entries will be returned where BOTH conditions are true.
+ // GetWhereMany(i interface{}, where ...model.Where) error
+
// GetAll will try to get all entries of type i.
// The given interface i will be set to the result of the query, whatever it is. Use a pointer or a slice.
// In case of no entries, a 'no entries' error will be returned
@@ -88,6 +92,11 @@ type DB interface {
// The given interface i will be set to the result of the query, whatever it is. Use a pointer or a slice.
Put(i interface{}) error
+ // Upsert stores or updates i based on the given conflict column, as in https://www.postgresqltutorial.com/postgresql-upsert/
+ // It is up to the implementation to figure out how to store it, and using what key.
+ // The given interface i will be set to the result of the query, whatever it is. Use a pointer or a slice.
+ Upsert(i interface{}, conflictColumn string) error
+
// UpdateByID updates i with id id.
// The given interface i will be set to the result of the query, whatever it is. Use a pointer or a slice.
UpdateByID(id string, i interface{}) error
@@ -107,41 +116,46 @@ type DB interface {
HANDY SHORTCUTS
*/
+ // CreateInstanceAccount creates an account in the database with the same username as the instance host value.
+ // Ie., if the instance is hosted at 'example.org' the instance user will have a username of 'example.org'.
+ // This is needed for things like serving files that belong to the instance and not an individual user/account.
+ CreateInstanceAccount() error
+
// GetAccountByUserID is a shortcut for the common action of fetching an account corresponding to a user ID.
// The given account pointer will be set to the result of the query, whatever it is.
// In case of no entries, a 'no entries' error will be returned
- GetAccountByUserID(userID string, account *model.Account) error
+ GetAccountByUserID(userID string, account *gtsmodel.Account) error
// GetFollowRequestsForAccountID is a shortcut for the common action of fetching a list of follow requests targeting the given account ID.
// The given slice 'followRequests' will be set to the result of the query, whatever it is.
// In case of no entries, a 'no entries' error will be returned
- GetFollowRequestsForAccountID(accountID string, followRequests *[]model.FollowRequest) error
+ GetFollowRequestsForAccountID(accountID string, followRequests *[]gtsmodel.FollowRequest) error
// GetFollowingByAccountID is a shortcut for the common action of fetching a list of accounts that accountID is following.
// The given slice 'following' will be set to the result of the query, whatever it is.
// In case of no entries, a 'no entries' error will be returned
- GetFollowingByAccountID(accountID string, following *[]model.Follow) error
+ GetFollowingByAccountID(accountID string, following *[]gtsmodel.Follow) error
// GetFollowersByAccountID is a shortcut for the common action of fetching a list of accounts that accountID is followed by.
// The given slice 'followers' will be set to the result of the query, whatever it is.
// In case of no entries, a 'no entries' error will be returned
- GetFollowersByAccountID(accountID string, followers *[]model.Follow) error
+ GetFollowersByAccountID(accountID string, followers *[]gtsmodel.Follow) error
// GetStatusesByAccountID is a shortcut for the common action of fetching a list of statuses produced by accountID.
// The given slice 'statuses' will be set to the result of the query, whatever it is.
// In case of no entries, a 'no entries' error will be returned
- GetStatusesByAccountID(accountID string, statuses *[]model.Status) error
+ GetStatusesByAccountID(accountID string, statuses *[]gtsmodel.Status) error
// GetStatusesByTimeDescending is a shortcut for getting the most recent statuses. accountID is optional, if not provided
// then all statuses will be returned. If limit is set to 0, the size of the returned slice will not be limited. This can
// be very memory intensive so you probably shouldn't do this!
// In case of no entries, a 'no entries' error will be returned
- GetStatusesByTimeDescending(accountID string, statuses *[]model.Status, limit int) error
+ GetStatusesByTimeDescending(accountID string, statuses *[]gtsmodel.Status, limit int) error
// GetLastStatusForAccountID simply gets the most recent status by the given account.
// The given slice 'status' pointer will be set to the result of the query, whatever it is.
// In case of no entries, a 'no entries' error will be returned
- GetLastStatusForAccountID(accountID string, status *model.Status) error
+ GetLastStatusForAccountID(accountID string, status *gtsmodel.Status) error
// IsUsernameAvailable checks whether a given username is available on our domain.
// Returns an error if the username is already taken, or something went wrong in the db.
@@ -156,32 +170,112 @@ type DB interface {
// NewSignup creates a new user in the database with the given parameters, with an *unconfirmed* email address.
// By the time this function is called, it should be assumed that all the parameters have passed validation!
- NewSignup(username string, reason string, requireApproval bool, email string, password string, signUpIP net.IP, locale string, appID string) (*model.User, error)
+ NewSignup(username string, reason string, requireApproval bool, email string, password string, signUpIP net.IP, locale string, appID string) (*gtsmodel.User, error)
// SetHeaderOrAvatarForAccountID sets the header or avatar for the given accountID to the given media attachment.
- SetHeaderOrAvatarForAccountID(mediaAttachment *model.MediaAttachment, accountID string) error
+ SetHeaderOrAvatarForAccountID(mediaAttachment *gtsmodel.MediaAttachment, accountID string) error
// GetHeaderAvatarForAccountID gets the current avatar for the given account ID.
// The passed mediaAttachment pointer will be populated with the value of the avatar, if it exists.
- GetAvatarForAccountID(avatar *model.MediaAttachment, accountID string) error
+ GetAvatarForAccountID(avatar *gtsmodel.MediaAttachment, accountID string) error
// GetHeaderForAccountID gets the current header for the given account ID.
// The passed mediaAttachment pointer will be populated with the value of the header, if it exists.
- GetHeaderForAccountID(header *model.MediaAttachment, accountID string) error
+ GetHeaderForAccountID(header *gtsmodel.MediaAttachment, accountID string) error
+
+ // Blocked checks whether a block exists in eiher direction between two accounts.
+ // That is, it returns true if account1 blocks account2, OR if account2 blocks account1.
+ Blocked(account1 string, account2 string) (bool, error)
+
+ // StatusVisible returns true if targetStatus is visible to requestingAccount, based on the
+ // privacy settings of the status, and any blocks/mutes that might exist between the two accounts
+ // or account domains.
+ //
+ // StatusVisible will also check through the given slice of 'otherRelevantAccounts', which should include:
+ //
+ // 1. Accounts mentioned in the targetStatus
+ //
+ // 2. Accounts replied to by the target status
+ //
+ // 3. Accounts boosted by the target status
+ //
+ // Will return an error if something goes wrong while pulling stuff out of the database.
+ StatusVisible(targetStatus *gtsmodel.Status, targetAccount *gtsmodel.Account, requestingAccount *gtsmodel.Account, relevantAccounts *gtsmodel.RelevantAccounts) (bool, error)
+
+ // Follows returns true if sourceAccount follows target account, or an error if something goes wrong while finding out.
+ Follows(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, error)
+
+ // Mutuals returns true if account1 and account2 both follow each other, or an error if something goes wrong while finding out.
+ Mutuals(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, error)
+
+ // PullRelevantAccountsFromStatus returns all accounts mentioned in a status, replied to by a status, or boosted by a status
+ PullRelevantAccountsFromStatus(status *gtsmodel.Status) (*gtsmodel.RelevantAccounts, error)
+
+ // GetReplyCountForStatus returns the amount of replies recorded for a status, or an error if something goes wrong
+ GetReplyCountForStatus(status *gtsmodel.Status) (int, error)
+
+ // GetReblogCountForStatus returns the amount of reblogs/boosts recorded for a status, or an error if something goes wrong
+ GetReblogCountForStatus(status *gtsmodel.Status) (int, error)
+
+ // GetFaveCountForStatus returns the amount of faves/likes recorded for a status, or an error if something goes wrong
+ GetFaveCountForStatus(status *gtsmodel.Status) (int, error)
+
+ // StatusFavedBy checks if a given status has been faved by a given account ID
+ StatusFavedBy(status *gtsmodel.Status, accountID string) (bool, error)
+
+ // StatusRebloggedBy checks if a given status has been reblogged/boosted by a given account ID
+ StatusRebloggedBy(status *gtsmodel.Status, accountID string) (bool, error)
+
+ // StatusMutedBy checks if a given status has been muted by a given account ID
+ StatusMutedBy(status *gtsmodel.Status, accountID string) (bool, error)
+
+ // StatusBookmarkedBy checks if a given status has been bookmarked by a given account ID
+ StatusBookmarkedBy(status *gtsmodel.Status, accountID string) (bool, error)
+
+ // StatusPinnedBy checks if a given status has been pinned by a given account ID
+ StatusPinnedBy(status *gtsmodel.Status, accountID string) (bool, error)
+
+ // FaveStatus faves the given status, using accountID as the faver.
+ // The returned fave will be nil if the status was already faved.
+ FaveStatus(status *gtsmodel.Status, accountID string) (*gtsmodel.StatusFave, error)
+
+ // UnfaveStatus unfaves the given status, using accountID as the unfaver (sure, that's a word).
+ // The returned fave will be nil if the status was already not faved.
+ UnfaveStatus(status *gtsmodel.Status, accountID string) (*gtsmodel.StatusFave, error)
+
+ // WhoFavedStatus returns a slice of accounts who faved the given status.
+ // This slice will be unfiltered, not taking account of blocks and whatnot, so filter it before serving it back to a user.
+ WhoFavedStatus(status *gtsmodel.Status) ([]*gtsmodel.Account, error)
/*
USEFUL CONVERSION FUNCTIONS
*/
- // AccountToMastoSensitive takes a db model account as a param, and returns a populated mastotype account, or an error
- // if something goes wrong. The returned account should be ready to serialize on an API level, and may have sensitive fields,
- // so serve it only to an authorized user who should have permission to see it.
- AccountToMastoSensitive(account *model.Account) (*mastotypes.Account, error)
-
- // AccountToMastoPublic takes a db model account as a param, and returns a populated mastotype account, or an error
- // if something goes wrong. The returned account should be ready to serialize on an API level, and may NOT have sensitive fields.
- // In other words, this is the public record that the server has of an account.
- AccountToMastoPublic(account *model.Account) (*mastotypes.Account, error)
+ // MentionStringsToMentions takes a slice of deduplicated, lowercase account names in the form "@test@whatever.example.org" for a remote account,
+ // or @test for a local account, which have been mentioned in a status.
+ // It takes the id of the account that wrote the status, and the id of the status itself, and then
+ // checks in the database for the mentioned accounts, and returns a slice of mentions generated based on the given parameters.
+ //
+ // Note: this func doesn't/shouldn't do any manipulation of the accounts in the DB, it's just for checking
+ // if they exist in the db and conveniently returning them if they do.
+ MentionStringsToMentions(targetAccounts []string, originAccountID string, statusID string) ([]*gtsmodel.Mention, error)
+
+ // TagStringsToTags takes a slice of deduplicated, lowercase tags in the form "somehashtag", which have been
+ // used in a status. It takes the id of the account that wrote the status, and the id of the status itself, and then
+ // returns a slice of *model.Tag corresponding to the given tags. If the tag already exists in database, that tag
+ // will be returned. Otherwise a pointer to a new tag struct will be created and returned.
+ //
+ // Note: this func doesn't/shouldn't do any manipulation of the tags in the DB, it's just for checking
+ // if they exist in the db already, and conveniently returning them, or creating new tag structs.
+ TagStringsToTags(tags []string, originAccountID string, statusID string) ([]*gtsmodel.Tag, error)
+
+ // EmojiStringsToEmojis takes a slice of deduplicated, lowercase emojis in the form ":emojiname:", which have been
+ // used in a status. It takes the id of the account that wrote the status, and the id of the status itself, and then
+ // returns a slice of *model.Emoji corresponding to the given emojis.
+ //
+ // Note: this func doesn't/shouldn't do any manipulation of the emoji in the DB, it's just for checking
+ // if they exist in the db and conveniently returning them if they do.
+ EmojiStringsToEmojis(emojis []string, originAccountID string, statusID string) ([]*gtsmodel.Emoji, error)
}
// New returns a new database service that satisfies the DB interface and, by extension,