2023-03-12 18:00:57 +03:00
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// 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/>.
2021-04-19 20:42:19 +03:00
package gtsmodel
2021-08-10 14:32:39 +03:00
import (
"time"
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
"github.com/superseriousbusiness/gotosocial/internal/log"
2021-08-10 14:32:39 +03:00
)
2021-04-19 20:42:19 +03:00
// Status represents a user-created 'post' or 'status' in the database, either remote or local
type Status struct {
2021-08-30 21:20:27 +03:00
ID string ` validate:"required,ulid" bun:"type:CHAR(26),pk,nullzero,notnull,unique" ` // id of this item in the database
2021-09-20 18:41:52 +03:00
CreatedAt time . Time ` validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp" ` // when was item created
UpdatedAt time . Time ` validate:"-" bun:"type:timestamptz,nullzero,notnull,default:current_timestamp" ` // when was item last updated
2023-05-12 12:15:54 +03:00
FetchedAt time . Time ` validate:"required_with=!Local" bun:"type:timestamptz,nullzero" ` // when was item (remote) last fetched.
2023-02-25 15:16:30 +03:00
PinnedAt time . Time ` validate:"-" bun:"type:timestamptz,nullzero" ` // Status was pinned by owning account at this time.
2021-08-30 21:20:27 +03:00
URI string ` validate:"required,url" bun:",unique,nullzero,notnull" ` // activitypub URI of this status
URL string ` validate:"url" bun:",nullzero" ` // web url for viewing this status
2021-09-10 11:08:21 +03:00
Content string ` validate:"-" bun:"" ` // content of this status; likely html-formatted but not guaranteed
2021-09-01 19:29:25 +03:00
AttachmentIDs [ ] string ` validate:"dive,ulid" bun:"attachments,array" ` // Database IDs of any media attachments associated with this status
2021-08-30 21:20:27 +03:00
Attachments [ ] * MediaAttachment ` validate:"-" bun:"attached_media,rel:has-many" ` // Attachments corresponding to attachmentIDs
2021-09-01 19:29:25 +03:00
TagIDs [ ] string ` validate:"dive,ulid" bun:"tags,array" ` // Database IDs of any tags used in this status
2021-08-30 21:20:27 +03:00
Tags [ ] * Tag ` validate:"-" bun:"attached_tags,m2m:status_to_tags" ` // Tags corresponding to tagIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
2021-09-01 19:29:25 +03:00
MentionIDs [ ] string ` validate:"dive,ulid" bun:"mentions,array" ` // Database IDs of any mentions in this status
2021-08-30 21:20:27 +03:00
Mentions [ ] * Mention ` validate:"-" bun:"attached_mentions,rel:has-many" ` // Mentions corresponding to mentionIDs
2021-09-01 19:29:25 +03:00
EmojiIDs [ ] string ` validate:"dive,ulid" bun:"emojis,array" ` // Database IDs of any emojis used in this status
2021-08-30 21:20:27 +03:00
Emojis [ ] * Emoji ` validate:"-" bun:"attached_emojis,m2m:status_to_emojis" ` // Emojis corresponding to emojiIDs. https://bun.uptrace.dev/guide/relations.html#many-to-many-relation
2022-08-15 13:35:05 +03:00
Local * bool ` validate:"-" bun:",nullzero,notnull,default:false" ` // is this status from a local account?
2021-08-30 21:20:27 +03:00
AccountID string ` validate:"required,ulid" bun:"type:CHAR(26),nullzero,notnull" ` // which account posted this status?
Account * Account ` validate:"-" bun:"rel:belongs-to" ` // account corresponding to accountID
AccountURI string ` validate:"required,url" bun:",nullzero,notnull" ` // activitypub uri of the owner of this status
InReplyToID string ` validate:"required_with=InReplyToURI InReplyToAccountID,omitempty,ulid" bun:"type:CHAR(26),nullzero" ` // id of the status this status replies to
InReplyToURI string ` validate:"required_with=InReplyToID InReplyToAccountID,omitempty,url" bun:",nullzero" ` // activitypub uri of the status this status is a reply to
InReplyToAccountID string ` validate:"required_with=InReplyToID InReplyToURI,omitempty,ulid" bun:"type:CHAR(26),nullzero" ` // id of the account that this status replies to
InReplyTo * Status ` validate:"-" bun:"-" ` // status corresponding to inReplyToID
InReplyToAccount * Account ` validate:"-" bun:"rel:belongs-to" ` // account corresponding to inReplyToAccountID
BoostOfID string ` validate:"required_with=BoostOfAccountID,omitempty,ulid" bun:"type:CHAR(26),nullzero" ` // id of the status this status is a boost of
BoostOfAccountID string ` validate:"required_with=BoostOfID,omitempty,ulid" bun:"type:CHAR(26),nullzero" ` // id of the account that owns the boosted status
BoostOf * Status ` validate:"-" bun:"-" ` // status that corresponds to boostOfID
BoostOfAccount * Account ` validate:"-" bun:"rel:belongs-to" ` // account that corresponds to boostOfAccountID
ContentWarning string ` validate:"-" bun:",nullzero" ` // cw string for this status
2021-09-10 11:08:21 +03:00
Visibility Visibility ` validate:"oneof=public unlocked followers_only mutuals_only direct" bun:",nullzero,notnull" ` // visibility entry for this status
2022-08-15 13:35:05 +03:00
Sensitive * bool ` validate:"-" bun:",nullzero,notnull,default:false" ` // mark the status as sensitive?
2021-08-30 21:20:27 +03:00
Language string ` validate:"-" bun:",nullzero" ` // what language is this status written in?
CreatedWithApplicationID string ` validate:"required_if=Local true,omitempty,ulid" bun:"type:CHAR(26),nullzero" ` // Which application was used to create this status?
CreatedWithApplication * Application ` validate:"-" bun:"rel:belongs-to" ` // application corresponding to createdWithApplicationID
ActivityStreamsType string ` validate:"required" bun:",nullzero,notnull" ` // What is the activitystreams type of this status? See: https://www.w3.org/TR/activitystreams-vocabulary/#object-types. Will probably almost always be Note but who knows!.
2021-09-10 11:08:21 +03:00
Text string ` validate:"-" bun:"" ` // Original text of the status without formatting
2022-08-15 13:35:05 +03:00
Federated * bool ` validate:"-" bun:",notnull" ` // This status will be federated beyond the local timeline(s)
Boostable * bool ` validate:"-" bun:",notnull" ` // This status can be boosted/reblogged
Replyable * bool ` validate:"-" bun:",notnull" ` // This status can be replied to
Likeable * bool ` validate:"-" bun:",notnull" ` // This status can be liked/faved
2021-08-20 13:26:56 +03:00
}
2021-04-19 20:42:19 +03:00
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
// GetID implements timeline.Timelineable{}.
2022-02-05 14:47:38 +03:00
func ( s * Status ) GetID ( ) string {
return s . ID
}
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
// GetAccountID implements timeline.Timelineable{}.
2022-02-05 14:47:38 +03:00
func ( s * Status ) GetAccountID ( ) string {
return s . AccountID
}
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
// GetBoostID implements timeline.Timelineable{}.
2022-02-05 14:47:38 +03:00
func ( s * Status ) GetBoostOfID ( ) string {
return s . BoostOfID
}
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
// GetBoostOfAccountID implements timeline.Timelineable{}.
2022-02-05 14:47:38 +03:00
func ( s * Status ) GetBoostOfAccountID ( ) string {
return s . BoostOfAccountID
}
2023-05-12 12:15:54 +03:00
func ( s * Status ) GetAttachmentByID ( id string ) ( * MediaAttachment , bool ) {
for _ , media := range s . Attachments {
if media == nil {
log . Warnf ( nil , "nil attachment in slice for status %s" , s . URI )
continue
}
if media . ID == id {
return media , true
}
}
return nil , false
}
func ( s * Status ) GetAttachmentByRemoteURL ( url string ) ( * MediaAttachment , bool ) {
for _ , media := range s . Attachments {
if media == nil {
log . Warnf ( nil , "nil attachment in slice for status %s" , s . URI )
continue
}
if media . RemoteURL == url {
return media , true
}
}
return nil , false
}
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
// AttachmentsPopulated returns whether media attachments are populated according to current AttachmentIDs.
func ( s * Status ) AttachmentsPopulated ( ) bool {
if len ( s . AttachmentIDs ) != len ( s . Attachments ) {
// this is the quickest indicator.
return false
}
2023-05-12 12:15:54 +03:00
for _ , id := range s . AttachmentIDs {
if _ , ok := s . GetAttachmentByID ( id ) ; ! ok {
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
return false
}
}
return true
}
// TagsPopulated returns whether tags are populated according to current TagIDs.
func ( s * Status ) TagsPopulated ( ) bool {
if len ( s . TagIDs ) != len ( s . Tags ) {
// this is the quickest indicator.
return false
}
// Tags must be in same order.
for i , id := range s . TagIDs {
if s . Tags [ i ] == nil {
log . Warnf ( nil , "nil tag in slice for status %s" , s . URI )
continue
}
if s . Tags [ i ] . ID != id {
return false
}
}
return true
}
2023-05-12 12:15:54 +03:00
func ( s * Status ) GetMentionByID ( id string ) ( * Mention , bool ) {
for _ , mention := range s . Mentions {
if mention == nil {
log . Warnf ( nil , "nil mention in slice for status %s" , s . URI )
continue
}
if mention . ID == id {
return mention , true
}
}
return nil , false
}
func ( s * Status ) GetMentionByTargetURI ( uri string ) ( * Mention , bool ) {
for _ , mention := range s . Mentions {
if mention == nil {
log . Warnf ( nil , "nil mention in slice for status %s" , s . URI )
continue
}
if mention . TargetAccountURI == uri {
return mention , true
}
}
return nil , false
}
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
// MentionsPopulated returns whether mentions are populated according to current MentionIDs.
func ( s * Status ) MentionsPopulated ( ) bool {
if len ( s . MentionIDs ) != len ( s . Mentions ) {
// this is the quickest indicator.
return false
}
2023-05-12 12:15:54 +03:00
for _ , id := range s . MentionIDs {
if _ , ok := s . GetMentionByID ( id ) ; ! ok {
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
return false
}
}
return true
}
// EmojisPopulated returns whether emojis are populated according to current EmojiIDs.
func ( s * Status ) EmojisPopulated ( ) bool {
if len ( s . EmojiIDs ) != len ( s . Emojis ) {
// this is the quickest indicator.
return false
}
// Emojis must be in same order.
for i , id := range s . EmojiIDs {
if s . Emojis [ i ] == nil {
log . Warnf ( nil , "nil emoji in slice for status %s" , s . URI )
continue
}
if s . Emojis [ i ] . ID != id {
return false
}
}
return true
}
2023-05-12 12:15:54 +03:00
// EmojissUpToDate returns whether status emoji attachments of receiving status are up-to-date
// according to emoji attachments of the passed status, by comparing their emoji URIs. We don't
// use IDs as this is used to determine whether there are new emojis to fetch.
func ( s * Status ) EmojisUpToDate ( other * Status ) bool {
if len ( s . Emojis ) != len ( other . Emojis ) {
// this is the quickest indicator.
return false
}
// Emojis must be in same order.
for i := range s . Emojis {
if s . Emojis [ i ] == nil {
log . Warnf ( nil , "nil emoji in slice for status %s" , s . URI )
return false
}
if other . Emojis [ i ] == nil {
log . Warnf ( nil , "nil emoji in slice for status %s" , other . URI )
return false
}
if s . Emojis [ i ] . URI != other . Emojis [ i ] . URI {
// Emoji URI has changed, not up-to-date!
return false
}
}
return true
}
[performance] refactoring + add fave / follow / request / visibility caching (#1607)
* refactor visibility checking, add caching for visibility
* invalidate visibility cache items on account / status deletes
* fix requester ID passed to visibility cache nil ptr
* de-interface caches, fix home / public timeline caching + visibility
* finish adding code comments for visibility filter
* fix angry goconst linter warnings
* actually finish adding filter visibility code comments for timeline functions
* move home timeline status author check to after visibility
* remove now-unused code
* add more code comments
* add TODO code comment, update printed cache start names
* update printed cache names on stop
* start adding separate follow(request) delete db functions, add specific visibility cache tests
* add relationship type caching
* fix getting local account follows / followed-bys, other small codebase improvements
* simplify invalidation using cache hooks, add more GetAccountBy___() functions
* fix boosting to return 404 if not boostable but no error (to not leak status ID)
* remove dead code
* improved placement of cache invalidation
* update license headers
* add example follow, follow-request config entries
* add example visibility cache configuration to config file
* use specific PutFollowRequest() instead of just Put()
* add tests for all GetAccountBy()
* add GetBlockBy() tests
* update block to check primitive fields
* update and finish adding Get{Account,Block,Follow,FollowRequest}By() tests
* fix copy-pasted code
* update envparsing test
* whitespace
* fix bun struct tag
* add license header to gtscontext
* fix old license header
* improved error creation to not use fmt.Errorf() when not needed
* fix various rebase conflicts, fix account test
* remove commented-out code, fix-up mention caching
* fix mention select bun statement
* ensure mention target account populated, pass in context to customrenderer logging
* remove more uncommented code, fix typeutil test
* add statusfave database model caching
* add status fave cache configuration
* add status fave cache example config
* woops, catch missed error. nice catch linter!
* add back testrig panic on nil db
* update example configuration to match defaults, slight tweak to cache configuration defaults
* update envparsing test with new defaults
* fetch followingget to use the follow target account
* use accounnt.IsLocal() instead of empty domain check
* use constants for the cache visibility type check
* use bun.In() for notification type restriction in db query
* include replies when fetching PublicTimeline() (to account for single-author threads in Visibility{}.StatusPublicTimelineable())
* use bun query building for nested select statements to ensure working with postgres
* update public timeline future status checks to match visibility filter
* same as previous, for home timeline
* update public timeline tests to dynamically check for appropriate statuses
* migrate accounts to allow unique constraint on public_key
* provide minimal account with publicKey
---------
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
2023-03-28 16:03:14 +03:00
// MentionsAccount returns whether status mentions the given account ID.
func ( s * Status ) MentionsAccount ( id string ) bool {
for _ , mention := range s . Mentions {
if mention . TargetAccountID == id {
return true
}
}
return false
}
2021-08-20 13:26:56 +03:00
// StatusToTag is an intermediate struct to facilitate the many2many relationship between a status and one or more tags.
type StatusToTag struct {
2021-08-30 14:38:06 +03:00
StatusID string ` validate:"ulid,required" bun:"type:CHAR(26),unique:statustag,nullzero,notnull" `
Status * Status ` validate:"-" bun:"rel:belongs-to" `
TagID string ` validate:"ulid,required" bun:"type:CHAR(26),unique:statustag,nullzero,notnull" `
Tag * Tag ` validate:"-" bun:"rel:belongs-to" `
2021-08-20 13:26:56 +03:00
}
2021-04-19 20:42:19 +03:00
2021-08-20 13:26:56 +03:00
// StatusToEmoji is an intermediate struct to facilitate the many2many relationship between a status and one or more emojis.
type StatusToEmoji struct {
2021-08-30 14:38:06 +03:00
StatusID string ` validate:"ulid,required" bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull" `
Status * Status ` validate:"-" bun:"rel:belongs-to" `
EmojiID string ` validate:"ulid,required" bun:"type:CHAR(26),unique:statusemoji,nullzero,notnull" `
Emoji * Emoji ` validate:"-" bun:"rel:belongs-to" `
2021-04-19 20:42:19 +03:00
}
// Visibility represents the visibility granularity of a status.
type Visibility string
const (
2021-04-20 19:14:23 +03:00
// VisibilityPublic means this status will be visible to everyone on all timelines.
2021-04-19 20:42:19 +03:00
VisibilityPublic Visibility = "public"
2021-04-20 19:14:23 +03:00
// VisibilityUnlocked means this status will be visible to everyone, but will only show on home timeline to followers, and in lists.
2021-04-19 20:42:19 +03:00
VisibilityUnlocked Visibility = "unlocked"
2021-04-20 19:14:23 +03:00
// VisibilityFollowersOnly means this status is viewable to followers only.
2021-04-19 20:42:19 +03:00
VisibilityFollowersOnly Visibility = "followers_only"
2021-04-20 19:14:23 +03:00
// VisibilityMutualsOnly means this status is visible to mutual followers only.
2021-04-19 20:42:19 +03:00
VisibilityMutualsOnly Visibility = "mutuals_only"
2021-08-02 20:06:44 +03:00
// VisibilityDirect means this status is visible only to mentioned recipients.
2021-04-19 20:42:19 +03:00
VisibilityDirect Visibility = "direct"
2021-08-02 20:06:44 +03:00
// VisibilityDefault is used when no other setting can be found.
VisibilityDefault Visibility = VisibilityUnlocked
2021-04-19 20:42:19 +03:00
)