| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | /* | 
					
						
							|  |  |  |    GoToSocial | 
					
						
							|  |  |  |    Copyright (C) 2021 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/>. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | package bundb | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	"database/sql" | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	"fmt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/config" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/db" | 
					
						
							|  |  |  | 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel" | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	"github.com/uptrace/bun" | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type relationshipDB struct { | 
					
						
							|  |  |  | 	config *config.Config | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	conn   *DBConn | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) newBlockQ(block *gtsmodel.Block) *bun.SelectQuery { | 
					
						
							|  |  |  | 	return r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(block). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		Relation("Account"). | 
					
						
							|  |  |  | 		Relation("TargetAccount") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) newFollowQ(follow interface{}) *bun.SelectQuery { | 
					
						
							|  |  |  | 	return r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(follow). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		Relation("Account"). | 
					
						
							|  |  |  | 		Relation("TargetAccount") | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) IsBlocked(ctx context.Context, account1 string, account2 string, eitherDirection bool) (bool, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	q := r.conn. | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		NewSelect(). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		Model(>smodel.Block{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", account1). | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		Where("target_account_id = ?", account2). | 
					
						
							|  |  |  | 		Limit(1) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if eitherDirection { | 
					
						
							|  |  |  | 		q = q. | 
					
						
							|  |  |  | 			WhereOr("target_account_id = ?", account1). | 
					
						
							|  |  |  | 			Where("account_id = ?", account2) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	return r.conn.Exists(ctx, q) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) GetBlock(ctx context.Context, account1 string, account2 string) (*gtsmodel.Block, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	block := >smodel.Block{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	q := r.newBlockQ(block). | 
					
						
							|  |  |  | 		Where("block.account_id = ?", account1). | 
					
						
							|  |  |  | 		Where("block.target_account_id = ?", account2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	err := q.Scan(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return block, nil | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) GetRelationship(ctx context.Context, requestingAccount string, targetAccount string) (*gtsmodel.Relationship, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	rel := >smodel.Relationship{ | 
					
						
							|  |  |  | 		ID: targetAccount, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check if the requesting account follows the target account | 
					
						
							|  |  |  | 	follow := >smodel.Follow{} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	if err := r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(follow). | 
					
						
							|  |  |  | 		Where("account_id = ?", requestingAccount). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", targetAccount). | 
					
						
							|  |  |  | 		Limit(1). | 
					
						
							|  |  |  | 		Scan(ctx); err != nil { | 
					
						
							|  |  |  | 		if err != sql.ErrNoRows { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 			// a proper error | 
					
						
							|  |  |  | 			return nil, fmt.Errorf("getrelationship: error checking follow existence: %s", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// no follow exists so these are all false | 
					
						
							|  |  |  | 		rel.Following = false | 
					
						
							|  |  |  | 		rel.ShowingReblogs = false | 
					
						
							|  |  |  | 		rel.Notifying = false | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		// follow exists so we can fill these fields out... | 
					
						
							|  |  |  | 		rel.Following = true | 
					
						
							|  |  |  | 		rel.ShowingReblogs = follow.ShowReblogs | 
					
						
							|  |  |  | 		rel.Notifying = follow.Notify | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// check if the target account follows the requesting account | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	count, err := r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.Follow{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", targetAccount). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", requestingAccount). | 
					
						
							|  |  |  | 		Limit(1). | 
					
						
							|  |  |  | 		Count(ctx) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("getrelationship: error checking followed_by existence: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	rel.FollowedBy = count > 0 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// check if the requesting account blocks the target account | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	count, err = r.conn.NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.Block{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", requestingAccount). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", targetAccount). | 
					
						
							|  |  |  | 		Limit(1). | 
					
						
							|  |  |  | 		Count(ctx) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("getrelationship: error checking blocking existence: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	rel.Blocking = count > 0 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// check if the target account blocks the requesting account | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	count, err = r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.Block{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", targetAccount). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", requestingAccount). | 
					
						
							|  |  |  | 		Limit(1). | 
					
						
							|  |  |  | 		Count(ctx) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("getrelationship: error checking blocked existence: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	rel.BlockedBy = count > 0 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// check if there's a pending following request from requesting account to target account | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	count, err = r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(>smodel.FollowRequest{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", requestingAccount). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", targetAccount). | 
					
						
							|  |  |  | 		Limit(1). | 
					
						
							|  |  |  | 		Count(ctx) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, fmt.Errorf("getrelationship: error checking blocked existence: %s", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	rel.Requested = count > 0 | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return rel, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) IsFollowing(ctx context.Context, sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if sourceAccount == nil || targetAccount == nil { | 
					
						
							|  |  |  | 		return false, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	q := r.conn. | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		NewSelect(). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		Model(>smodel.Follow{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", sourceAccount.ID). | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		Where("target_account_id = ?", targetAccount.ID). | 
					
						
							|  |  |  | 		Limit(1) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	return r.conn.Exists(ctx, q) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) IsFollowRequested(ctx context.Context, sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if sourceAccount == nil || targetAccount == nil { | 
					
						
							|  |  |  | 		return false, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	q := r.conn. | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		NewSelect(). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		Model(>smodel.FollowRequest{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", sourceAccount.ID). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", targetAccount.ID) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	return r.conn.Exists(ctx, q) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) IsMutualFollowing(ctx context.Context, account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if account1 == nil || account2 == nil { | 
					
						
							|  |  |  | 		return false, nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// make sure account 1 follows account 2 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	f1, err := r.IsFollowing(ctx, account1, account2) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return false, err | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// make sure account 2 follows account 1 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	f2, err := r.IsFollowing(ctx, account2, account1) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return false, err | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return f1 && f2, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) AcceptFollowRequest(ctx context.Context, originAccountID string, targetAccountID string) (*gtsmodel.Follow, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	// make sure the original follow request exists | 
					
						
							|  |  |  | 	fr := >smodel.FollowRequest{} | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	if err := r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(fr). | 
					
						
							|  |  |  | 		Where("account_id = ?", originAccountID). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", targetAccountID). | 
					
						
							|  |  |  | 		Scan(ctx); err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// create a new follow to 'replace' the request with | 
					
						
							|  |  |  | 	follow := >smodel.Follow{ | 
					
						
							|  |  |  | 		ID:              fr.ID, | 
					
						
							|  |  |  | 		AccountID:       originAccountID, | 
					
						
							|  |  |  | 		TargetAccountID: targetAccountID, | 
					
						
							|  |  |  | 		URI:             fr.URI, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// if the follow already exists, just update the URI -- we don't need to do anything else | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	if _, err := r.conn. | 
					
						
							|  |  |  | 		NewInsert(). | 
					
						
							|  |  |  | 		Model(follow). | 
					
						
							| 
									
										
										
										
											2021-09-01 10:08:21 +01:00
										 |  |  | 		On("CONFLICT (account_id,target_account_id) DO UPDATE set uri = ?", follow.URI). | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		Exec(ctx); err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// now remove the follow request | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	if _, err := r.conn. | 
					
						
							|  |  |  | 		NewDelete(). | 
					
						
							|  |  |  | 		Model(>smodel.FollowRequest{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", originAccountID). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", targetAccountID). | 
					
						
							|  |  |  | 		Exec(ctx); err != nil { | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return follow, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-16 13:27:43 +02:00
										 |  |  | func (r *relationshipDB) RejectFollowRequest(ctx context.Context, originAccountID string, targetAccountID string) (*gtsmodel.FollowRequest, db.Error) { | 
					
						
							|  |  |  | 	// first get the follow request out of the database | 
					
						
							|  |  |  | 	fr := >smodel.FollowRequest{} | 
					
						
							|  |  |  | 	if err := r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(fr). | 
					
						
							|  |  |  | 		Where("account_id = ?", originAccountID). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", targetAccountID). | 
					
						
							|  |  |  | 		Scan(ctx); err != nil { | 
					
						
							|  |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// now delete it from the database by ID | 
					
						
							|  |  |  | 	if _, err := r.conn. | 
					
						
							|  |  |  | 		NewDelete(). | 
					
						
							|  |  |  | 		Model(>smodel.FollowRequest{ID: fr.ID}). | 
					
						
							|  |  |  | 		WherePK(). | 
					
						
							|  |  |  | 		Exec(ctx); err != nil { | 
					
						
							|  |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// return the deleted follow request | 
					
						
							|  |  |  | 	return fr, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) GetAccountFollowRequests(ctx context.Context, accountID string) ([]*gtsmodel.FollowRequest, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	followRequests := []*gtsmodel.FollowRequest{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	q := r.newFollowQ(&followRequests). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", accountID) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	err := q.Scan(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return followRequests, nil | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) GetAccountFollows(ctx context.Context, accountID string) ([]*gtsmodel.Follow, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	follows := []*gtsmodel.Follow{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	q := r.newFollowQ(&follows). | 
					
						
							|  |  |  | 		Where("account_id = ?", accountID) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	err := q.Scan(ctx) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return follows, nil | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) CountAccountFollows(ctx context.Context, accountID string, localOnly bool) (int, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	return r.conn. | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		NewSelect(). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		Model(&[]*gtsmodel.Follow{}). | 
					
						
							|  |  |  | 		Where("account_id = ?", accountID). | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		Count(ctx) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) GetAccountFollowedBy(ctx context.Context, accountID string, localOnly bool) ([]*gtsmodel.Follow, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	follows := []*gtsmodel.Follow{} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 	q := r.conn. | 
					
						
							|  |  |  | 		NewSelect(). | 
					
						
							|  |  |  | 		Model(&follows) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if localOnly { | 
					
						
							|  |  |  | 		q = q.ColumnExpr("follow.*"). | 
					
						
							| 
									
										
										
										
											2021-09-01 10:08:21 +01:00
										 |  |  | 			Join("JOIN accounts AS a ON follow.account_id = CAST(a.id as TEXT)"). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 			Where("follow.target_account_id = ?", accountID). | 
					
						
							| 
									
										
										
										
											2021-08-26 11:28:16 +02:00
										 |  |  | 			WhereGroup(" AND ", whereEmptyOrNull("a.domain")) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		q = q.Where("target_account_id = ?", accountID) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-29 15:41:41 +01:00
										 |  |  | 	err := q.Scan(ctx) | 
					
						
							|  |  |  | 	if err != nil && err != sql.ErrNoRows { | 
					
						
							|  |  |  | 		return nil, r.conn.ProcessError(err) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return follows, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | func (r *relationshipDB) CountAccountFollowedBy(ctx context.Context, accountID string, localOnly bool) (int, db.Error) { | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 	return r.conn. | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		NewSelect(). | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | 		Model(&[]*gtsmodel.Follow{}). | 
					
						
							|  |  |  | 		Where("target_account_id = ?", accountID). | 
					
						
							| 
									
										
										
										
											2021-08-25 15:34:33 +02:00
										 |  |  | 		Count(ctx) | 
					
						
							| 
									
										
										
										
											2021-08-20 12:26:56 +02:00
										 |  |  | } |