summaryrefslogtreecommitdiff
path: root/internal/db
diff options
context:
space:
mode:
Diffstat (limited to 'internal/db')
-rw-r--r--internal/db/bundb/admin.go30
-rw-r--r--internal/db/bundb/interaction.go34
-rw-r--r--internal/db/bundb/interaction_test.go19
-rw-r--r--internal/db/bundb/migrations/20250715095446_int_pols_forward_compat.go328
-rw-r--r--internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/new/interactionrequest.go68
-rw-r--r--internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/old/interactionrequest.go39
-rw-r--r--internal/db/bundb/notification_test.go20
-rw-r--r--internal/db/interaction.go15
8 files changed, 486 insertions, 67 deletions
diff --git a/internal/db/bundb/admin.go b/internal/db/bundb/admin.go
index dcf51c6a5..39b2c848f 100644
--- a/internal/db/bundb/admin.go
+++ b/internal/db/bundb/admin.go
@@ -106,12 +106,7 @@ func (a *adminDB) NewSignup(ctx context.Context, newSignup gtsmodel.NewSignup) (
// with this username, create one now.
if account == nil {
uris := uris.GenerateURIsForAccount(newSignup.Username)
-
- accountID, err := id.NewRandomULID()
- if err != nil {
- err := gtserror.Newf("error creating new account id: %w", err)
- return nil, err
- }
+ accountID := id.NewRandomULID()
privKey, err := rsa.GenerateKey(rand.Reader, rsaKeyBits)
if err != nil {
@@ -174,12 +169,9 @@ func (a *adminDB) NewSignup(ctx context.Context, newSignup gtsmodel.NewSignup) (
return user, nil
}
- // Had no user for this account, time to create one!
- newUserID, err := id.NewRandomULID()
- if err != nil {
- err := gtserror.Newf("error creating new user id: %w", err)
- return nil, err
- }
+ // Had no user for this
+ // account, time to create one!
+ newUserID := id.NewRandomULID()
encryptedPassword, err := bcrypt.GenerateFromPassword(
[]byte(newSignup.Password),
@@ -273,14 +265,9 @@ func (a *adminDB) CreateInstanceAccount(ctx context.Context) error {
return err
}
- aID, err := id.NewRandomULID()
- if err != nil {
- return err
- }
-
newAccountURIs := uris.GenerateURIsForAccount(username)
acct := &gtsmodel.Account{
- ID: aID,
+ ID: id.NewRandomULID(),
Username: username,
DisplayName: username,
URL: newAccountURIs.UserURL,
@@ -325,13 +312,8 @@ func (a *adminDB) CreateInstanceInstance(ctx context.Context) error {
return nil
}
- iID, err := id.NewRandomULID()
- if err != nil {
- return err
- }
-
i := &gtsmodel.Instance{
- ID: iID,
+ ID: id.NewRandomULID(),
Domain: host,
Title: host,
URI: fmt.Sprintf("%s://%s", protocol, host),
diff --git a/internal/db/bundb/interaction.go b/internal/db/bundb/interaction.go
index b42eb46f6..2128a7aa6 100644
--- a/internal/db/bundb/interaction.go
+++ b/internal/db/bundb/interaction.go
@@ -58,31 +58,45 @@ func (i *interactionDB) GetInteractionRequestByID(ctx context.Context, id string
)
}
-func (i *interactionDB) GetInteractionRequestByInteractionURI(ctx context.Context, uri string) (*gtsmodel.InteractionRequest, error) {
+func (i *interactionDB) GetInteractionRequestByInteractionURI(ctx context.Context, intURI string) (*gtsmodel.InteractionRequest, error) {
return i.getInteractionRequest(
ctx,
"InteractionURI",
func(request *gtsmodel.InteractionRequest) error {
return i.
newInteractionRequestQ(request).
- Where("? = ?", bun.Ident("interaction_request.interaction_uri"), uri).
+ Where("? = ?", bun.Ident("interaction_request.interaction_uri"), intURI).
Scan(ctx)
},
- uri,
+ intURI,
)
}
-func (i *interactionDB) GetInteractionRequestByURI(ctx context.Context, uri string) (*gtsmodel.InteractionRequest, error) {
+func (i *interactionDB) GetInteractionRequestByResponseURI(ctx context.Context, respURI string) (*gtsmodel.InteractionRequest, error) {
return i.getInteractionRequest(
ctx,
- "URI",
+ "ResponseURI",
func(request *gtsmodel.InteractionRequest) error {
return i.
newInteractionRequestQ(request).
- Where("? = ?", bun.Ident("interaction_request.uri"), uri).
+ Where("? = ?", bun.Ident("interaction_request.response_uri"), respURI).
Scan(ctx)
},
- uri,
+ respURI,
+ )
+}
+
+func (i *interactionDB) GetInteractionRequestByAuthorizationURI(ctx context.Context, authURI string) (*gtsmodel.InteractionRequest, error) {
+ return i.getInteractionRequest(
+ ctx,
+ "AuthorizationURI",
+ func(request *gtsmodel.InteractionRequest) error {
+ return i.
+ newInteractionRequestQ(request).
+ Where("? = ?", bun.Ident("interaction_request.authorization_uri"), authURI).
+ Scan(ctx)
+ },
+ authURI,
)
}
@@ -173,11 +187,11 @@ func (i *interactionDB) PopulateInteractionRequest(ctx context.Context, req *gts
errs = gtserror.NewMultiError(4)
)
- if req.Status == nil {
+ if req.TargetStatus == nil {
// Target status is not set, fetch from the database.
- req.Status, err = i.state.DB.GetStatusByID(
+ req.TargetStatus, err = i.state.DB.GetStatusByID(
gtscontext.SetBarebones(ctx),
- req.StatusID,
+ req.TargetStatusID,
)
if err != nil {
errs.Appendf("error populating interactionRequest target: %w", err)
diff --git a/internal/db/bundb/interaction_test.go b/internal/db/bundb/interaction_test.go
index 564b3a3f2..6a753dca8 100644
--- a/internal/db/bundb/interaction_test.go
+++ b/internal/db/bundb/interaction_test.go
@@ -57,9 +57,8 @@ func (suite *InteractionTestSuite) markInteractionsPending(
suite.FailNow(err.Error())
}
- // Put an interaction request
- // in the DB for this reply.
- req := typeutils.StatusToInteractionRequest(reply)
+ // Put an impolite interaction request in the DB for this reply.
+ req := typeutils.StatusToImpoliteInteractionRequest(reply)
if err := suite.state.DB.PutInteractionRequest(ctx, req); err != nil {
suite.FailNow(err.Error())
}
@@ -84,9 +83,8 @@ func (suite *InteractionTestSuite) markInteractionsPending(
suite.FailNow(err.Error())
}
- // Put an interaction request
- // in the DB for this boost.
- req := typeutils.StatusToInteractionRequest(boost)
+ // Put an impolite interaction request in the DB for this boost.
+ req := typeutils.StatusToImpoliteInteractionRequest(boost)
if err := suite.state.DB.PutInteractionRequest(ctx, req); err != nil {
suite.FailNow(err.Error())
}
@@ -111,9 +109,8 @@ func (suite *InteractionTestSuite) markInteractionsPending(
suite.FailNow(err.Error())
}
- // Put an interaction request
- // in the DB for this fave.
- req := typeutils.StatusFaveToInteractionRequest(fave)
+ // Put an impolite interaction request in the DB for this fave.
+ req := typeutils.StatusFaveToImpoliteInteractionRequest(fave)
if err := suite.state.DB.PutInteractionRequest(ctx, req); err != nil {
suite.FailNow(err.Error())
}
@@ -229,8 +226,8 @@ func (suite *InteractionTestSuite) TestInteractionRejected() {
// Update the interaction request to mark it rejected.
req.RejectedAt = time.Now()
- req.URI = "https://some.reject.uri"
- if err := suite.state.DB.UpdateInteractionRequest(ctx, req, "uri", "rejected_at"); err != nil {
+ req.ResponseURI = "https://some.reject.uri"
+ if err := suite.state.DB.UpdateInteractionRequest(ctx, req, "response_uri", "rejected_at"); err != nil {
suite.FailNow(err.Error())
}
diff --git a/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat.go b/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat.go
new file mode 100644
index 000000000..0df515082
--- /dev/null
+++ b/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat.go
@@ -0,0 +1,328 @@
+// 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/>.
+
+package migrations
+
+import (
+ "context"
+ "database/sql"
+ "errors"
+ "net/url"
+ "strings"
+
+ "code.superseriousbusiness.org/gotosocial/internal/config"
+ "code.superseriousbusiness.org/gotosocial/internal/gtserror"
+ "code.superseriousbusiness.org/gotosocial/internal/id"
+ "code.superseriousbusiness.org/gotosocial/internal/log"
+ "code.superseriousbusiness.org/gotosocial/internal/util"
+ "github.com/uptrace/bun"
+ "github.com/uptrace/bun/dialect"
+
+ new_gtsmodel "code.superseriousbusiness.org/gotosocial/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/new"
+ old_gtsmodel "code.superseriousbusiness.org/gotosocial/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/old"
+)
+
+func init() {
+ up := func(ctx context.Context, db *bun.DB) error {
+ const tmpTableName = "new_interaction_requests"
+ const tableName = "interaction_requests"
+ var host = config.GetHost()
+ var accountDomain = config.GetAccountDomain()
+
+ // Count number of interaction
+ // requests we need to update.
+ total, err := db.NewSelect().
+ Table(tableName).
+ Count(ctx)
+ if err != nil {
+ return gtserror.Newf("error geting interaction requests table count: %w", err)
+ }
+
+ // Create new interaction_requests table and convert all existing into it.
+ if err := db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
+
+ log.Info(ctx, "creating new interaction_requests table")
+ if _, err := tx.NewCreateTable().
+ ModelTableExpr(tmpTableName).
+ Model((*new_gtsmodel.InteractionRequest)(nil)).
+ Exec(ctx); err != nil {
+ return gtserror.Newf("error creating new interaction requests table: %w", err)
+ }
+
+ // Conversion batch size.
+ const batchsz = 1000
+
+ var maxID string
+ var count int
+
+ // Start at largest
+ // possible ULID value.
+ maxID = id.Highest
+
+ // Preallocate interaction request slices to maximum possible size.
+ oldRequests := make([]*old_gtsmodel.InteractionRequest, 0, batchsz)
+ newRequests := make([]*new_gtsmodel.InteractionRequest, 0, batchsz)
+
+ log.Info(ctx, "migrating interaction requests to new table, this may take some time!")
+ outer:
+ for {
+ // Reset slices slices.
+ clear(oldRequests)
+ clear(newRequests)
+ oldRequests = oldRequests[:0]
+ newRequests = newRequests[:0]
+
+ // Select next batch of
+ // interaction requests.
+ if err := tx.NewSelect().
+ Model(&oldRequests).
+ Where("? < ?", bun.Ident("id"), maxID).
+ OrderExpr("? DESC", bun.Ident("id")).
+ Limit(batchsz).
+ Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
+ return gtserror.Newf("error selecting interaction requests: %w", err)
+ }
+
+ // Reached end of requests.
+ if len(oldRequests) == 0 {
+ break outer
+ }
+
+ // Set next maxID value from old requests.
+ maxID = oldRequests[len(oldRequests)-1].ID
+
+ inner:
+ // Convert old request models to new.
+ for _, oldRequest := range oldRequests {
+ newRequest := &new_gtsmodel.InteractionRequest{
+ ID: oldRequest.ID,
+ TargetStatusID: oldRequest.StatusID,
+ TargetAccountID: oldRequest.TargetAccountID,
+ InteractingAccountID: oldRequest.InteractingAccountID,
+ InteractionURI: oldRequest.InteractionURI,
+ InteractionType: int16(oldRequest.InteractionType), // #nosec G115
+ Polite: util.Ptr(false), // old requests were always impolite
+ AcceptedAt: oldRequest.AcceptedAt,
+ RejectedAt: oldRequest.RejectedAt,
+ ResponseURI: oldRequest.URI,
+ }
+
+ // Append new request to slice,
+ // though we continue operating on
+ // its ptr in the rest of this loop.
+ newRequests = append(newRequests,
+ newRequest)
+
+ // Re-use the original interaction URI to create
+ // a mock interaction request URI on the new model.
+ switch oldRequest.InteractionType {
+ case old_gtsmodel.InteractionLike:
+ newRequest.InteractionRequestURI = oldRequest.InteractionURI + new_gtsmodel.LikeRequestSuffix
+ case old_gtsmodel.InteractionReply:
+ newRequest.InteractionRequestURI = oldRequest.InteractionURI + new_gtsmodel.ReplyRequestSuffix
+ case old_gtsmodel.InteractionAnnounce:
+ newRequest.InteractionRequestURI = oldRequest.InteractionURI + new_gtsmodel.AnnounceRequestSuffix
+ }
+
+ // If the request was accepted by us, then generate an authorization
+ // URI for it, in order to be able to serve an Authorization if necessary.
+ if oldRequest.AcceptedAt.IsZero() || oldRequest.URI == "" {
+
+ // Wasn't accepted,
+ // nothing else to do.
+ continue inner
+ }
+
+ // Parse URI details of accept URI string.
+ acceptURI, err := url.Parse(oldRequest.URI)
+ if err != nil {
+ log.Warnf(ctx, "could not parse oldRequest.URI for interaction request %s,"+
+ " skipping forward-compat hack (don't worry, this is not a big deal): %v",
+ oldRequest.ID, err)
+ continue inner
+ }
+
+ // Check whether accept URI originated from this instance.
+ if !(acceptURI.Host == host || acceptURI.Host == accountDomain) {
+
+ // Not an accept from
+ // us, leave it alone.
+ continue inner
+ }
+
+ // Reuse the Accept URI to create an Authorization URI.
+ // Creates `https://example.org/users/aaa/authorizations/[ID]`
+ // from `https://example.org/users/aaa/accepts/[ID]`.
+ authorizationURI := strings.ReplaceAll(
+ oldRequest.URI,
+ "/accepts/"+oldRequest.ID,
+ "/authorizations/"+oldRequest.ID,
+ )
+ newRequest.AuthorizationURI = authorizationURI
+
+ var updateTableName string
+
+ // Determine which table will have corresponding approved_by_uri.
+ if oldRequest.InteractionType == old_gtsmodel.InteractionLike {
+ updateTableName = "status_faves"
+ } else {
+ updateTableName = "statuses"
+ }
+
+ // Update the corresponding interaction
+ // with generated authorization URI.
+ if _, err := tx.NewUpdate().
+ Table(updateTableName).
+ Set("? = ?", bun.Ident("approved_by_uri"), authorizationURI).
+ Where("? = ?", bun.Ident("uri"), oldRequest.InteractionURI).
+ Exec(ctx); err != nil {
+ return gtserror.Newf("error updating approved_by_uri: %w", err)
+ }
+ }
+
+ // Insert converted interaction
+ // request models to new table.
+ if _, err := tx.
+ NewInsert().
+ Model(&newRequests).
+ Exec(ctx); err != nil {
+ return gtserror.Newf("error inserting interaction requests: %w", err)
+ }
+
+ // Increment insert count.
+ count += len(newRequests)
+
+ log.Infof(ctx, "[%d of %d] converting interaction requests", count, total)
+ }
+
+ return nil
+ }); err != nil {
+ return err
+ }
+
+ // Ensure that the above transaction
+ // has gone ahead without issues.
+ //
+ // Also placing this here might make
+ // breaking this into piecemeal steps
+ // easier if turns out necessary.
+ newTotal, err := db.NewSelect().
+ Table(tmpTableName).
+ Count(ctx)
+ if err != nil {
+ return gtserror.Newf("error geting new interaction requests table count: %w", err)
+ } else if total != newTotal {
+ return gtserror.Newf("new interaction requests table contains unexpected count %d, want %d", newTotal, total)
+ }
+
+ // Attempt to merge any sqlite write-ahead-log.
+ if err := doWALCheckpoint(ctx, db); err != nil {
+ return err
+ }
+
+ // Drop the old interaction requests table and rename new one to replace it.
+ if err := db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error {
+
+ log.Info(ctx, "dropping old interaction_requests table")
+ if _, err := tx.NewDropTable().
+ Table(tableName).
+ Exec(ctx); err != nil {
+ return gtserror.Newf("error dropping old interaction requests table: %w", err)
+ }
+
+ log.Info(ctx, "renaming new interaction_requests table to old")
+ if _, err := tx.NewRaw("ALTER TABLE ? RENAME TO ?",
+ bun.Ident(tmpTableName),
+ bun.Ident(tableName),
+ ).Exec(ctx); err != nil {
+ return gtserror.Newf("error renaming interaction requests table: %w", err)
+ }
+
+ // Create necessary indices on the new table.
+ for index, columns := range map[string][]string{
+ "interaction_requests_target_status_id_idx": {"target_status_id"},
+ "interaction_requests_interacting_account_id_idx": {"interacting_account_id"},
+ "interaction_requests_target_account_id_idx": {"target_account_id"},
+ "interaction_requests_accepted_at_idx": {"accepted_at"},
+ "interaction_requests_rejected_at_idx": {"rejected_at"},
+ } {
+ log.Infof(ctx, "recreating %s index", index)
+ if _, err := tx.NewCreateIndex().
+ Table(tableName).
+ Index(index).
+ Column(columns...).
+ Exec(ctx); err != nil {
+ return err
+ }
+ }
+
+ if tx.Dialect().Name() == dialect.PG {
+ // Rename postgres uniqueness constraints:
+ // "new_interaction_requests_*" -> "interaction_requests_*"
+ log.Info(ctx, "renaming interaction_requests constraints on new table")
+ for _, spec := range []struct {
+ old string
+ new string
+ }{
+ {
+ old: "new_interaction_requests_pkey",
+ new: "interaction_requests_pkey",
+ },
+ {
+ old: "new_interaction_requests_interaction_request_uri_key",
+ new: "interaction_requests_interaction_request_uri_key",
+ },
+ {
+ old: "new_interaction_requests_interaction_uri_key",
+ new: "interaction_requests_interaction_uri_key",
+ },
+ {
+ old: "new_interaction_requests_response_uri_key",
+ new: "interaction_requests_response_uri_key",
+ },
+ {
+ old: "new_interaction_requests_authorization_uri_key",
+ new: "interaction_requests_authorization_uri_key",
+ },
+ } {
+ if _, err := tx.NewRaw("ALTER TABLE ? RENAME CONSTRAINT ? TO ?",
+ bun.Ident(tableName),
+ bun.Safe(spec.old),
+ bun.Safe(spec.new),
+ ).Exec(ctx); err != nil {
+ return gtserror.Newf("error renaming postgres interaction requests constraint %s: %w", spec.new, err)
+ }
+ }
+ }
+
+ return nil
+ }); err != nil {
+ return err
+ }
+
+ // Final sqlite write-ahead-log merge.
+ return doWALCheckpoint(ctx, db)
+ }
+
+ down := func(ctx context.Context, db *bun.DB) error {
+ return nil
+ }
+
+ if err := Migrations.Register(up, down); err != nil {
+ panic(err)
+ }
+}
diff --git a/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/new/interactionrequest.go b/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/new/interactionrequest.go
new file mode 100644
index 000000000..bdd2d5811
--- /dev/null
+++ b/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/new/interactionrequest.go
@@ -0,0 +1,68 @@
+// 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/>.
+
+package gtsmodel
+
+import (
+ "time"
+
+ "github.com/uptrace/bun"
+)
+
+type InteractionRequest struct {
+ // Used only for migration.
+ bun.BaseModel `bun:"table:new_interaction_requests"`
+
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"`
+
+ // Removed in new model.
+ // CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"`
+
+ // Renamed from "StatusID" to "TargetStatusID" in new model.
+ TargetStatusID string `bun:"type:CHAR(26),nullzero,notnull"`
+
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"`
+
+ InteractingAccountID string `bun:"type:CHAR(26),nullzero,notnull"`
+
+ // Added in new model.
+ InteractionRequestURI string `bun:",nullzero,notnull,unique"`
+
+ InteractionURI string `bun:",nullzero,notnull,unique"`
+
+ // Changed type from int to int16 in new model.
+ InteractionType int16 `bun:",notnull"`
+
+ // Added in new model.
+ Polite *bool `bun:",nullzero,notnull,default:false"`
+
+ AcceptedAt time.Time `bun:"type:timestamptz,nullzero"`
+
+ RejectedAt time.Time `bun:"type:timestamptz,nullzero"`
+
+ // Renamed from "URI" to "ResponseURI" in new model.
+ ResponseURI string `bun:",nullzero,unique"`
+
+ // Added in new model.
+ AuthorizationURI string `bun:",nullzero,unique"`
+}
+
+const (
+ LikeRequestSuffix = "#LikeRequest"
+ ReplyRequestSuffix = "#ReplyRequest"
+ AnnounceRequestSuffix = "#AnnounceRequest"
+)
diff --git a/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/old/interactionrequest.go b/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/old/interactionrequest.go
new file mode 100644
index 000000000..a341f4d5b
--- /dev/null
+++ b/internal/db/bundb/migrations/20250715095446_int_pols_forward_compat/old/interactionrequest.go
@@ -0,0 +1,39 @@
+// 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/>.
+
+package gtsmodel
+
+import "time"
+
+type InteractionRequest struct {
+ ID string `bun:"type:CHAR(26),pk,nullzero,notnull,unique"`
+ CreatedAt time.Time `bun:"type:timestamptz,nullzero,notnull,default:current_timestamp"`
+ StatusID string `bun:"type:CHAR(26),nullzero,notnull"`
+ TargetAccountID string `bun:"type:CHAR(26),nullzero,notnull"`
+ InteractingAccountID string `bun:"type:CHAR(26),nullzero,notnull"`
+ InteractionURI string `bun:",nullzero,notnull,unique"`
+ InteractionType int `bun:",notnull"`
+ AcceptedAt time.Time `bun:"type:timestamptz,nullzero"`
+ RejectedAt time.Time `bun:"type:timestamptz,nullzero"`
+ URI string `bun:",nullzero,unique"`
+}
+
+const (
+ InteractionLike int = 0
+ InteractionReply int = 1
+ InteractionAnnounce int = 2
+)
diff --git a/internal/db/bundb/notification_test.go b/internal/db/bundb/notification_test.go
index 10b82b7ce..5b67d4f58 100644
--- a/internal/db/bundb/notification_test.go
+++ b/internal/db/bundb/notification_test.go
@@ -46,21 +46,7 @@ func (suite *NotificationTestSuite) spamNotifs() {
if i%2 == 0 {
targetAccountID = zork.ID
} else {
- randomAssID, err := id.NewRandomULID()
- if err != nil {
- panic(err)
- }
- targetAccountID = randomAssID
- }
-
- statusID, err := id.NewRandomULID()
- if err != nil {
- panic(err)
- }
-
- originAccountID, err := id.NewRandomULID()
- if err != nil {
- panic(err)
+ targetAccountID = id.NewRandomULID()
}
notif := &gtsmodel.Notification{
@@ -68,8 +54,8 @@ func (suite *NotificationTestSuite) spamNotifs() {
NotificationType: gtsmodel.NotificationFavourite,
CreatedAt: time.Now(),
TargetAccountID: targetAccountID,
- OriginAccountID: originAccountID,
- StatusOrEditID: statusID,
+ OriginAccountID: id.NewRandomULID(),
+ StatusOrEditID: id.NewRandomULID(),
Read: util.Ptr(false),
}
diff --git a/internal/db/interaction.go b/internal/db/interaction.go
index 4a6ec7e2e..9b45a6ab4 100644
--- a/internal/db/interaction.go
+++ b/internal/db/interaction.go
@@ -28,12 +28,17 @@ type Interaction interface {
// GetInteractionRequestByID gets one request with the given id.
GetInteractionRequestByID(ctx context.Context, id string) (*gtsmodel.InteractionRequest, error)
- // GetInteractionRequestByID gets one request with the given interaction uri.
- GetInteractionRequestByInteractionURI(ctx context.Context, uri string) (*gtsmodel.InteractionRequest, error)
+ // GetInteractionRequestByID gets one request with the given interaction
+ // uri (ie., the URI of the requested like, reply, or announce).
+ GetInteractionRequestByInteractionURI(ctx context.Context, intURI string) (*gtsmodel.InteractionRequest, error)
- // GetInteractionRequestByURI returns one accepted or rejected
- // interaction request with the given URI, if it exists in the db.
- GetInteractionRequestByURI(ctx context.Context, uri string) (*gtsmodel.InteractionRequest, error)
+ // GetInteractionRequestByResponseURI returns one accepted or rejected
+ // interaction request with the given Accept or Reject URI.
+ GetInteractionRequestByResponseURI(ctx context.Context, respURI string) (*gtsmodel.InteractionRequest, error)
+
+ // GetInteractionRequestByAuthorizationURI returns one accepted
+ // interaction request with the given authorization URI.
+ GetInteractionRequestByAuthorizationURI(ctx context.Context, authURI string) (*gtsmodel.InteractionRequest, error)
// PopulateInteractionRequest ensures that the request's struct fields are populated.
PopulateInteractionRequest(ctx context.Context, request *gtsmodel.InteractionRequest) error