From 465aa3da86e9e1ffe87628d933ed1f64937f97f2 Mon Sep 17 00:00:00 2001 From: tsmethurst Date: Tue, 24 Aug 2021 19:52:02 +0200 Subject: [PATCH] and yet more --- README.md | 3 +- go.mod | 4 +-- go.sum | 8 ++--- internal/db/basic.go | 5 ---- internal/db/pg/account.go | 30 ++++++++++++------- internal/db/pg/basic.go | 21 +++---------- internal/db/pg/status.go | 16 +++++----- internal/db/pg/status_test.go | 1 + internal/gtsmodel/account.go | 14 ++++----- internal/gtsmodel/block.go | 8 ++--- internal/gtsmodel/domainblock.go | 4 +-- internal/gtsmodel/emaildomainblock.go | 4 +-- internal/gtsmodel/emoji.go | 10 +++---- internal/gtsmodel/follow.go | 8 ++--- internal/gtsmodel/followrequest.go | 12 ++++---- internal/gtsmodel/instance.go | 8 ++--- internal/gtsmodel/mediaattachment.go | 10 +++---- internal/gtsmodel/mention.go | 4 +-- internal/gtsmodel/notification.go | 2 +- internal/gtsmodel/status.go | 28 ++++++++--------- internal/gtsmodel/statusbookmark.go | 2 +- internal/gtsmodel/statusfave.go | 2 +- internal/gtsmodel/statusmute.go | 2 +- internal/gtsmodel/tag.go | 6 ++-- internal/gtsmodel/user.go | 22 +++++++------- internal/oauth/clientstore.go | 2 +- internal/processing/status/util.go | 2 +- testrig/db.go | 2 +- vendor/github.com/uptrace/bun/README.md | 4 +++ .../uptrace/bun/dialect/pgdialect/go.mod | 2 +- vendor/github.com/uptrace/bun/go.sum | 2 +- .../uptrace/bun/schema/formatter.go | 8 ++--- vendor/github.com/uptrace/bun/version.go | 2 +- vendor/modules.txt | 4 +-- 34 files changed, 128 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index 110112750..e1d57a48d 100644 --- a/README.md +++ b/README.md @@ -129,10 +129,10 @@ The following libraries and frameworks are used by GoToSocial, with gratitude * [gin-contrib/static](https://github.com/gin-contrib/static); Gin static page middleware. [MIT License](https://spdx.org/licenses/MIT.html) * [go-fed/activity](https://github.com/go-fed/activity); Golang ActivityPub/ActivityStreams library. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html). * [go-fed/httpsig](https://github.com/go-fed/httpsig); secure HTTP signature library. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html). -* [go-pg/pg](https://github.com/go-pg/pg); Postgres ORM library. [BSD-2-Clause License](https://spdx.org/licenses/BSD-2-Clause.html). * [google/uuid](https://github.com/google/uuid); UUID generation. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html) * [gorilla/websocket](https://github.com/gorilla/websocket); Websocket connectivity. [BSD-2-Clause License](https://spdx.org/licenses/BSD-2-Clause.html). * [h2non/filetype](https://github.com/h2non/filetype); filetype checking. [MIT License](https://spdx.org/licenses/MIT.html). +* [jackc/pgx](https://github.com/jackc/pgx); Postgres driver. [MIT License](https://spdx.org/licenses/MIT.html). * [microcosm-cc/bluemonday](https://github.com/microcosm-cc/bluemonday); HTML user-input sanitization. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html). * [mvdan/xurls](https://github.com/mvdan/xurls); URL parsing regular expressions. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html). * [nfnt/resize](https://github.com/nfnt/resize); convenient image resizing. [ISC License](https://spdx.org/licenses/ISC.html). @@ -145,6 +145,7 @@ The following libraries and frameworks are used by GoToSocial, with gratitude * [superseriousbusiness/oauth2](https://github.com/superseriousbusiness/oauth2) forked from [go-oauth2/oauth2](https://github.com/go-oauth2/oauth2); oauth server framework and token handling. [MIT License](https://spdx.org/licenses/MIT.html). * [go-swagger/go-swagger](https://github.com/go-swagger/go-swagger); Swagger OpenAPI spec generation. [Apache-2.0 License](https://spdx.org/licenses/Apache-2.0.html). * [tdewolff/minify](https://github.com/tdewolff/minify); HTML minification. [MIT License](https://spdx.org/licenses/MIT.html). +* [uptrace/bun](https://github.com/uptrace/bun); database ORM. [BSD-2-Clause License](https://spdx.org/licenses/BSD-2-Clause.html). * [urfave/cli](https://github.com/urfave/cli); command-line interface framework. [MIT License](https://spdx.org/licenses/MIT.html). * [wagslane/go-password-validator](https://github.com/wagslane/go-password-validator); password strength validation. [MIT License](https://spdx.org/licenses/MIT.html). diff --git a/go.mod b/go.mod index e7d052ea8..91f6f4faa 100644 --- a/go.mod +++ b/go.mod @@ -46,8 +46,8 @@ require ( github.com/superseriousbusiness/oauth2/v4 v4.3.0-SSB github.com/tdewolff/minify/v2 v2.9.21 github.com/tidwall/buntdb v1.2.4 // indirect - github.com/uptrace/bun v0.4.3 - github.com/uptrace/bun/dialect/pgdialect v0.4.3 + github.com/uptrace/bun v1.0.0-rc.1 + github.com/uptrace/bun/dialect/pgdialect v1.0.0-rc.1 github.com/urfave/cli/v2 v2.3.0 github.com/wagslane/go-password-validator v0.3.0 golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 diff --git a/go.sum b/go.sum index 42d24ad8c..56a215cd3 100644 --- a/go.sum +++ b/go.sum @@ -446,10 +446,10 @@ github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= -github.com/uptrace/bun v0.4.3 h1:x6bjDqwjxwM/9Q1eauhkznuvTrz/rLiCK2p4tT63sAE= -github.com/uptrace/bun v0.4.3/go.mod h1:aL6D9vPw8DXaTQTwGrEPtUderBYXx7ShUmPfnxnqscw= -github.com/uptrace/bun/dialect/pgdialect v0.4.3 h1:lM2IUKpU99110chKkupw3oTfXiOKpB0hTJIe6frqQDo= -github.com/uptrace/bun/dialect/pgdialect v0.4.3/go.mod h1:BaNvWejl32oKUhwpFkw/eNcWldzIlVY4nfw/sNul0s8= +github.com/uptrace/bun v1.0.0-rc.1 h1:yMjz/JdlgYRema5mk59URzjAV7HpOV58Fj3KID34K9U= +github.com/uptrace/bun v1.0.0-rc.1/go.mod h1:aL6D9vPw8DXaTQTwGrEPtUderBYXx7ShUmPfnxnqscw= +github.com/uptrace/bun/dialect/pgdialect v1.0.0-rc.1 h1:4rxcO4+x8r2xyCnduH9fhhkjhbtzLHFl3vmx2goVgio= +github.com/uptrace/bun/dialect/pgdialect v1.0.0-rc.1/go.mod h1:x48KjNeAGTSq4WNIOvtfzAOFjPG/V/Gx+SdwO5ksimU= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= diff --git a/internal/db/basic.go b/internal/db/basic.go index 97023a493..cf65ddc09 100644 --- a/internal/db/basic.go +++ b/internal/db/basic.go @@ -58,11 +58,6 @@ type Basic interface { // The given interface i will be set to the result of the query, whatever it is. Use a pointer or a slice. Put(ctx context.Context, i interface{}) Error - // Upsert stores or updates i based on the given conflict column, as in https://www.postgresqltutorial.com/postgresql-upsert/ - // It is up to the implementation to figure out how to store it, and using what key. - // The given interface i will be set to the result of the query, whatever it is. Use a pointer or a slice. - Upsert(ctx context.Context, i interface{}, conflictColumn string) Error - // UpdateByID updates i with id id. // The given interface i will be set to the result of the query, whatever it is. Use a pointer or a slice. UpdateByID(ctx context.Context, id string, i interface{}) Error diff --git a/internal/db/pg/account.go b/internal/db/pg/account.go index 4cf69df18..d448d4dc4 100644 --- a/internal/db/pg/account.go +++ b/internal/db/pg/account.go @@ -47,7 +47,7 @@ func (a *accountDB) newAccountQ(account *gtsmodel.Account) *bun.SelectQuery { } func (a *accountDB) GetAccountByID(ctx context.Context, id string) (*gtsmodel.Account, db.Error) { - account := >smodel.Account{} + account := new(gtsmodel.Account) q := a.newAccountQ(account). Where("account.id = ?", id) @@ -58,7 +58,7 @@ func (a *accountDB) GetAccountByID(ctx context.Context, id string) (*gtsmodel.Ac } func (a *accountDB) GetAccountByURI(ctx context.Context, uri string) (*gtsmodel.Account, db.Error) { - account := >smodel.Account{} + account := new(gtsmodel.Account) q := a.newAccountQ(account). Where("account.uri = ?", uri) @@ -69,7 +69,7 @@ func (a *accountDB) GetAccountByURI(ctx context.Context, uri string) (*gtsmodel. } func (a *accountDB) GetAccountByURL(ctx context.Context, uri string) (*gtsmodel.Account, db.Error) { - account := >smodel.Account{} + account := new(gtsmodel.Account) q := a.newAccountQ(account). Where("account.url = ?", uri) @@ -80,7 +80,7 @@ func (a *accountDB) GetAccountByURL(ctx context.Context, uri string) (*gtsmodel. } func (a *accountDB) GetInstanceAccount(ctx context.Context, domain string) (*gtsmodel.Account, db.Error) { - account := >smodel.Account{} + account := new(gtsmodel.Account) q := a.newAccountQ(account) @@ -100,7 +100,7 @@ func (a *accountDB) GetInstanceAccount(ctx context.Context, domain string) (*gts } func (a *accountDB) GetAccountLastPosted(ctx context.Context, accountID string) (time.Time, db.Error) { - status := >smodel.Status{} + status := new(gtsmodel.Status) q := a.conn. NewSelect(). @@ -130,18 +130,26 @@ func (a *accountDB) SetAccountHeaderOrAvatar(ctx context.Context, mediaAttachmen } // TODO: there are probably more side effects here that need to be handled - if _, err := a.conn.NewInsert().Model(mediaAttachment).On("CONFLICT (id) DO UPDATE").Exec(ctx); err != nil { + if _, err := a.conn. + NewInsert(). + Model(mediaAttachment). + Exec(ctx); err != nil { return err } - if _, err := a.conn.NewInsert().Model(>smodel.Account{}).Set(fmt.Sprintf("%s_media_attachment_id = ?", headerOrAVI), mediaAttachment.ID).Where("id = ?", accountID).Exec(ctx); err != nil { + if _, err := a.conn. + NewUpdate(). + Model(>smodel.Account{}). + Set(fmt.Sprintf("%s_media_attachment_id = ?", headerOrAVI), mediaAttachment.ID). + Where("id = ?", accountID). + Exec(ctx); err != nil { return err } return nil } func (a *accountDB) GetLocalAccountByUsername(ctx context.Context, username string) (*gtsmodel.Account, db.Error) { - account := >smodel.Account{} + account := new(gtsmodel.Account) q := a.newAccountQ(account). Where("username = ?", username). @@ -153,16 +161,16 @@ func (a *accountDB) GetLocalAccountByUsername(ctx context.Context, username stri } func (a *accountDB) GetAccountFaves(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, db.Error) { - faves := []*gtsmodel.StatusFave{} + faves := new([]*gtsmodel.StatusFave) if err := a.conn. NewSelect(). - Model(&faves). + Model(faves). Where("account_id = ?", accountID). Scan(ctx); err != nil { return nil, err } - return faves, nil + return *faves, nil } func (a *accountDB) CountAccountStatuses(ctx context.Context, accountID string) (int, db.Error) { diff --git a/internal/db/pg/basic.go b/internal/db/pg/basic.go index 2840fab63..dd91acb34 100644 --- a/internal/db/pg/basic.go +++ b/internal/db/pg/basic.go @@ -21,7 +21,6 @@ package pg import ( "context" "errors" - "fmt" "strings" "github.com/sirupsen/logrus" @@ -113,23 +112,11 @@ func (b *basicDB) DeleteWhere(ctx context.Context, where []db.Where, i interface return processErrorResponse(err) } -func (b *basicDB) Upsert(ctx context.Context, i interface{}, conflictColumn string) db.Error { - q := b.conn. - NewInsert(). - Model(i). - On(fmt.Sprintf("CONFLICT (%s) DO UPDATE", conflictColumn)) - - _, err := q.Exec(ctx) - - return processErrorResponse(err) -} - func (b *basicDB) UpdateByID(ctx context.Context, id string, i interface{}) db.Error { q := b.conn. - NewInsert(). + NewUpdate(). Model(i). - Where("id = ?", id). - On("CONFLICT (id) DO UPDATE") + Where("id = ?", id) _, err := q.Exec(ctx) @@ -170,12 +157,12 @@ func (b *basicDB) UpdateWhere(ctx context.Context, where []db.Where, key string, } func (b *basicDB) CreateTable(ctx context.Context, i interface{}) db.Error { - _, err := b.conn.NewCreateTable().IfNotExists().Model(i).Exec(ctx) + _, err := b.conn.NewCreateTable().Model(i).IfNotExists().Exec(ctx) return err } func (b *basicDB) DropTable(ctx context.Context, i interface{}) db.Error { - _, err := b.conn.NewDropTable().IfExists().Model(i).Exec(ctx) + _, err := b.conn.NewDropTable().Model(i).IfExists().Exec(ctx) return processErrorResponse(err) } diff --git a/internal/db/pg/status.go b/internal/db/pg/status.go index e299f7e55..92f611e68 100644 --- a/internal/db/pg/status.go +++ b/internal/db/pg/status.go @@ -76,13 +76,7 @@ func (s *statusDB) newStatusQ(status interface{}) *bun.SelectQuery { Relation("Attachments"). Relation("Tags"). Relation("Mentions"). - Relation("Emojis"). - Relation("Account"). - Relation("InReplyTo"). - Relation("InReplyToAccount"). - Relation("BoostOf"). - Relation("BoostOfAccount"). - Relation("CreatedWithApplication") + Relation("Emojis") } func (s *statusDB) newFaveQ(faves interface{}) *bun.SelectQuery { @@ -99,14 +93,18 @@ func (s *statusDB) GetStatusByID(ctx context.Context, id string) (*gtsmodel.Stat return status, nil } - status := >smodel.Status{} + status := new(gtsmodel.Status) q := s.newStatusQ(status). Where("status.id = ?", id) err := processErrorResponse(q.Scan(ctx)) - if err == nil && status != nil { + if err != nil { + return nil, err + } + + if status != nil { s.cacheStatus(id, status) } diff --git a/internal/db/pg/status_test.go b/internal/db/pg/status_test.go index be743ed99..05384bdd6 100644 --- a/internal/db/pg/status_test.go +++ b/internal/db/pg/status_test.go @@ -59,6 +59,7 @@ func (suite *StatusTestSuite) TearDownTest() { func (suite *StatusTestSuite) TestGetStatusByID() { status, err := suite.db.GetStatusByID(context.Background(), suite.testStatuses["local_account_1_status_1"].ID) if err != nil { + fmt.Println(err.Error()) suite.FailNow(err.Error()) } suite.NotNil(status) diff --git a/internal/gtsmodel/account.go b/internal/gtsmodel/account.go index bfac595e0..3c5fe1db4 100644 --- a/internal/gtsmodel/account.go +++ b/internal/gtsmodel/account.go @@ -65,9 +65,9 @@ type Account struct { // This account has moved this account id in the database MovedToAccountID string `bun:"type:CHAR(26)"` // When was this account created? - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"` // When was this account last updated? - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"` // Does this account identify itself as a bot? Bot bool // What reason was given for signing up when this account was created? @@ -97,7 +97,7 @@ type Account struct { // At which URL can we see the user account in a web browser? URL string `bun:",unique"` // Last time this account was located using the webfinger API. - LastWebfingeredAt time.Time `bun:"type:timestamp"` + LastWebfingeredAt time.Time `bun:",nullzero"` // Address of this account's activitypub inbox, for sending activity to InboxURI string `bun:",unique"` // Address of this account's activitypub outbox @@ -129,11 +129,11 @@ type Account struct { */ // When was this account set to have all its media shown as sensitive? - SensitizedAt time.Time `bun:"type:timestamp"` + SensitizedAt time.Time `bun:",nullzero"` // When was this account silenced (eg., statuses only visible to followers, not public)? - SilencedAt time.Time `bun:"type:timestamp"` + SilencedAt time.Time `bun:",nullzero"` // When was this account suspended (eg., don't allow it to log in/post, don't accept media/posts from this account) - SuspendedAt time.Time `bun:"type:timestamp"` + SuspendedAt time.Time `bun:",nullzero"` // Should we hide this account's collections? HideCollections bool // id of the database entry that caused this account to become suspended -- can be an account ID or a domain block ID @@ -146,5 +146,5 @@ type Account struct { type Field struct { Name string Value string - VerifiedAt time.Time `bun:"type:timestamp"` + VerifiedAt time.Time `bun:",nullzero"` } diff --git a/internal/gtsmodel/block.go b/internal/gtsmodel/block.go index 969fe85dd..d429ad5dc 100644 --- a/internal/gtsmodel/block.go +++ b/internal/gtsmodel/block.go @@ -7,15 +7,15 @@ type Block struct { // id of this block in the database ID string `bun:"type:CHAR(26),pk,notnull"` // When was this block created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this block updated - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Who created this block? AccountID string `bun:"type:CHAR(26),notnull"` - Account *Account `bun:"rel:belongs-to"` + Account *Account `bun:"-"` // Who is targeted by this block? TargetAccountID string `bun:"type:CHAR(26),notnull"` - TargetAccount *Account `bun:"rel:belongs-to"` + TargetAccount *Account `bun:"-"` // Activitypub URI for this block URI string `bun:",notnull"` } diff --git a/internal/gtsmodel/domainblock.go b/internal/gtsmodel/domainblock.go index ef3edd0fc..4462c21f3 100644 --- a/internal/gtsmodel/domainblock.go +++ b/internal/gtsmodel/domainblock.go @@ -27,9 +27,9 @@ type DomainBlock struct { // blocked domain Domain string `bun:",pk,notnull,unique"` // When was this block created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this block updated - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Account ID of the creator of this block CreatedByAccountID string `bun:"type:CHAR(26),notnull"` CreatedByAccount *Account `bun:"rel:belongs-to"` diff --git a/internal/gtsmodel/emaildomainblock.go b/internal/gtsmodel/emaildomainblock.go index 340b42b98..c561c41ee 100644 --- a/internal/gtsmodel/emaildomainblock.go +++ b/internal/gtsmodel/emaildomainblock.go @@ -27,9 +27,9 @@ type EmailDomainBlock struct { // Email domain to block. Eg. 'gmail.com' or 'hotmail.com' Domain string `bun:",notnull"` // When was this block created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this block updated - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Account ID of the creator of this block CreatedByAccountID string `bun:"type:CHAR(26),notnull"` CreatedByAccount *Account `bun:"rel:belongs-to"` diff --git a/internal/gtsmodel/emoji.go b/internal/gtsmodel/emoji.go index cd682a717..beee711e9 100644 --- a/internal/gtsmodel/emoji.go +++ b/internal/gtsmodel/emoji.go @@ -28,11 +28,11 @@ type Emoji struct { // eg., 'blob_hug' 'purple_heart' Must be unique with domain. Shortcode string `bun:",notnull,unique:shortcodedomain"` // Origin domain of this emoji, eg 'example.org', 'queer.party'. empty string for local emojis. - Domain string `bun:",notnull,default:'',use_zero,unique:shortcodedomain"` + Domain string `bun:",notnull,default:'',unique:shortcodedomain"` // When was this emoji created. Must be unique with shortcode. - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this emoji updated - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Where can this emoji be retrieved remotely? Null for local emojis. // For remote emojis, it'll be something like: // https://hackers.town/system/custom_emojis/images/000/049/842/original/1b74481204feabfd.png @@ -65,7 +65,7 @@ type Emoji struct { // Size of the static version of the emoji image file in bytes, for serving purposes. ImageStaticFileSize int `bun:",notnull"` // When was the emoji image last updated? - ImageUpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + ImageUpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Has a moderation action disabled this emoji from being shown? Disabled bool `bun:",notnull,default:false"` // ActivityStreams uri of this emoji. Something like 'https://example.org/emojis/1234' @@ -74,5 +74,5 @@ type Emoji struct { VisibleInPicker bool `bun:",notnull,default:true"` // In which emoji category is this emoji visible? CategoryID string `bun:"type:CHAR(26)"` - Status *Status `bun:"rel:belongs-to"` + Status *Status `bun:"-"` } diff --git a/internal/gtsmodel/follow.go b/internal/gtsmodel/follow.go index 40c963d8e..013cdf5d0 100644 --- a/internal/gtsmodel/follow.go +++ b/internal/gtsmodel/follow.go @@ -25,15 +25,15 @@ type Follow struct { // id of this follow in the database ID string `bun:"type:CHAR(26),pk,notnull,unique"` // When was this follow created? - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this follow last updated? - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Who does this follow belong to? AccountID string `bun:"type:CHAR(26),unique:srctarget,notnull"` - Account *Account `bun:"rel:belongs-to"` + Account *Account `bun:"-"` // Who does AccountID follow? TargetAccountID string `bun:"type:CHAR(26),unique:srctarget,notnull"` - TargetAccount *Account `bun:"rel:belongs-to"` + TargetAccount *Account `bun:"-"` // Does this follow also want to see reblogs and not just posts? ShowReblogs bool `bun:"default:true"` // What is the activitypub URI of this follow? diff --git a/internal/gtsmodel/followrequest.go b/internal/gtsmodel/followrequest.go index 5c5c987ec..a2dfb7593 100644 --- a/internal/gtsmodel/followrequest.go +++ b/internal/gtsmodel/followrequest.go @@ -25,15 +25,15 @@ type FollowRequest struct { // id of this follow request in the database ID string `bun:"type:CHAR(26),pk,notnull,unique"` // When was this follow request created? - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this follow request last updated? - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Who does this follow request originate from? - AccountID string `bun:"type:CHAR(26),unique:srctarget,notnull"` - Account Account `bun:"rel:belongs-to"` + AccountID string `bun:"type:CHAR(26),unique:frsrctarget,notnull"` + Account Account `bun:"-"` // Who is the target of this follow request? - TargetAccountID string `bun:"type:CHAR(26),unique:srctarget,notnull"` - TargetAccount Account `bun:"rel:belongs-to"` + TargetAccountID string `bun:"type:CHAR(26),unique:frsrctarget,notnull"` + TargetAccount Account `bun:"-"` // Does this follow also want to see reblogs and not just posts? ShowReblogs bool `bun:"default:true"` // What is the activitypub URI of this follow request? diff --git a/internal/gtsmodel/instance.go b/internal/gtsmodel/instance.go index 46b8d2bf6..9f9a7ce1c 100644 --- a/internal/gtsmodel/instance.go +++ b/internal/gtsmodel/instance.go @@ -13,14 +13,14 @@ type Instance struct { // base URI of this instance eg https://example.org URI string `bun:",notnull,unique"` // When was this instance created in the db? - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this instance last updated in the db? - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this instance suspended, if at all? SuspendedAt time.Time // ID of any existing domain block for this instance in the database DomainBlockID string `bun:"type:CHAR(26)"` - DomainBlock *DomainBlock `bun:"rel:belongs-to"` + DomainBlock *DomainBlock `bun:"-"` // Short description of this instance ShortDescription string // Longer description of this instance @@ -33,7 +33,7 @@ type Instance struct { ContactAccountUsername string // Contact account ID in the database for this instance ContactAccountID string `bun:"type:CHAR(26)"` - ContactAccount *Account `bun:"rel:belongs-to"` + ContactAccount *Account `bun:"-"` // Reputation score of this instance Reputation int64 `bun:",notnull,default:0"` // Version of the software used on this instance diff --git a/internal/gtsmodel/mediaattachment.go b/internal/gtsmodel/mediaattachment.go index e96827dc7..86750bcbc 100644 --- a/internal/gtsmodel/mediaattachment.go +++ b/internal/gtsmodel/mediaattachment.go @@ -34,16 +34,16 @@ type MediaAttachment struct { // Where can the attachment be retrieved on a remote server (empty for local media) RemoteURL string // When was the attachment created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was the attachment last updated - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Type of file (image/gif/audio/video) Type FileType `bun:",notnull"` // Metadata about the file FileMeta FileMeta // To which account does this attachment belong AccountID string `bun:"type:CHAR(26),notnull"` - Account *Account `bun:"rel:belongs-to"` + Account *Account `bun:"rel:has-one"` // Description of the attachment (for screenreaders) Description string // To which scheduled status does this attachment belong @@ -71,7 +71,7 @@ type File struct { // What is the size of the file in bytes. FileSize int // When was the file last updated. - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` } // Thumbnail refers to a small image thumbnail derived from a larger image, video, or audio file. @@ -83,7 +83,7 @@ type Thumbnail struct { // What is the size of the file in bytes FileSize int // When was the file last updated - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // What is the URL of the thumbnail on the local server URL string // What is the remote URL of the thumbnail (empty for local media) diff --git a/internal/gtsmodel/mention.go b/internal/gtsmodel/mention.go index 46747ec9d..d212ed468 100644 --- a/internal/gtsmodel/mention.go +++ b/internal/gtsmodel/mention.go @@ -28,9 +28,9 @@ type Mention struct { StatusID string `bun:"type:CHAR(26),notnull"` Status *Status `bun:"rel:belongs-to"` // When was this mention created? - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // When was this mention last updated? - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // What's the internal account ID of the originator of the mention? OriginAccountID string `bun:"type:CHAR(26),notnull"` OriginAccount *Account `bun:"rel:belongs-to"` diff --git a/internal/gtsmodel/notification.go b/internal/gtsmodel/notification.go index 4f0aeee56..9724e9136 100644 --- a/internal/gtsmodel/notification.go +++ b/internal/gtsmodel/notification.go @@ -27,7 +27,7 @@ type Notification struct { // Type of this notification NotificationType NotificationType `bun:",notnull"` // Creation time of this notification - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // Which account does this notification target (ie., who will receive the notification?) TargetAccountID string `bun:"type:CHAR(26),notnull"` TargetAccount *Account `bun:"rel:belongs-to"` diff --git a/internal/gtsmodel/status.go b/internal/gtsmodel/status.go index 659f4b6d4..4ef62dad7 100644 --- a/internal/gtsmodel/status.go +++ b/internal/gtsmodel/status.go @@ -37,38 +37,38 @@ type Status struct { Attachments []*MediaAttachment `bun:"attached_media,rel:has-many"` // Database IDs of any tags used in this status TagIDs []string `bun:"tags,array"` - Tags []*Tag `bun:"attached_tags,m2m:status_to_tags"` // https://pg.uptrace.dev/orm/many-to-many-relation/ + Tags []*Tag `bun:"attached_tags,m2m:status_to_tags"` // https://bun.uptrace.dev/guide/relations.html#many-to-many-relation // Database IDs of any mentions in this status MentionIDs []string `bun:"mentions,array"` Mentions []*Mention `bun:"attached_mentions,rel:has-many"` // Database IDs of any emojis used in this status EmojiIDs []string `bun:"emojis,array"` - Emojis []*Emoji `bun:"attached_emojis,m2m:status_to_emojis"` // https://pg.uptrace.dev/orm/many-to-many-relation/ + Emojis []*Emoji `bun:"attached_emojis,m2m:status_to_emojis"` // https://bun.uptrace.dev/guide/relations.html#many-to-many-relation // when was this status created? - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"` // when was this status updated? - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"` // is this status from a local account? Local bool // which account posted this status? AccountID string `bun:"type:CHAR(26),notnull"` - Account *Account `bun:"rel:belongs-to"` + Account *Account `bun:"-"` // AP uri of the owner of this status AccountURI string // id of the status this status is a reply to InReplyToID string `bun:"type:CHAR(26)"` - InReplyTo *Status `bun:"rel:belongs-to"` + InReplyTo *Status `bun:"-"` // AP uri of the status this status is a reply to InReplyToURI string // id of the account that this status replies to InReplyToAccountID string `bun:"type:CHAR(26)"` - InReplyToAccount *Account `bun:"rel:belongs-to"` + InReplyToAccount *Account `bun:"-"` // id of the status this status is a boost of BoostOfID string `bun:"type:CHAR(26)"` - BoostOf *Status `bun:"rel:belongs-to"` + BoostOf *Status `bun:"-"` // id of the account that owns the boosted status BoostOfAccountID string `bun:"type:CHAR(26)"` - BoostOfAccount *Account `bun:"rel:belongs-to"` + BoostOfAccount *Account `bun:"-"` // cw string for this status ContentWarning string // visibility entry for this status @@ -79,7 +79,7 @@ type Status struct { Language string // Which application was used to create this status? CreatedWithApplicationID string `bun:"type:CHAR(26)"` - CreatedWithApplication *Application `bun:"rel:belongs-to"` + CreatedWithApplication *Application `bun:"-"` // advanced visibility for this status VisibilityAdvanced *VisibilityAdvanced // What is the activitystreams type of this status? See: https://www.w3.org/TR/activitystreams-vocabulary/#object-types @@ -94,17 +94,17 @@ type Status struct { // StatusToTag is an intermediate struct to facilitate the many2many relationship between a status and one or more tags. type StatusToTag struct { StatusID string `bun:"type:CHAR(26),unique:statustag"` - Status *Status `bun:"rel:has-one"` + Status *Status `bun:"rel:belongs-to"` TagID string `bun:"type:CHAR(26),unique:statustag"` - Tag *Tag `bun:"rel:has-one"` + Tag *Tag `bun:"rel:belongs-to"` } // StatusToEmoji is an intermediate struct to facilitate the many2many relationship between a status and one or more emojis. type StatusToEmoji struct { StatusID string `bun:"type:CHAR(26),unique:statusemoji"` - Status *Status `bun:"rel:has-one"` + Status *Status `bun:"rel:belongs-to"` EmojiID string `bun:"type:CHAR(26),unique:statusemoji"` - Emoji *Emoji `bun:"rel:has-one"` + Emoji *Emoji `bun:"rel:belongs-to"` } // Visibility represents the visibility granularity of a status. diff --git a/internal/gtsmodel/statusbookmark.go b/internal/gtsmodel/statusbookmark.go index ac83a954c..95269a23c 100644 --- a/internal/gtsmodel/statusbookmark.go +++ b/internal/gtsmodel/statusbookmark.go @@ -25,7 +25,7 @@ type StatusBookmark struct { // id of this bookmark in the database ID string `bun:"type:CHAR(26),pk,notnull,unique"` // when was this bookmark created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // id of the account that created ('did') the bookmarking AccountID string `bun:"type:CHAR(26),notnull"` Account *Account `bun:"rel:belongs-to"` diff --git a/internal/gtsmodel/statusfave.go b/internal/gtsmodel/statusfave.go index ba6b32f62..9bd7ae63a 100644 --- a/internal/gtsmodel/statusfave.go +++ b/internal/gtsmodel/statusfave.go @@ -25,7 +25,7 @@ type StatusFave struct { // id of this fave in the database ID string `bun:"type:CHAR(26),pk,notnull,unique"` // when was this fave created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // id of the account that created ('did') the fave AccountID string `bun:"type:CHAR(26),notnull"` Account *Account `bun:"rel:belongs-to"` diff --git a/internal/gtsmodel/statusmute.go b/internal/gtsmodel/statusmute.go index 44d4b01b2..ef451c928 100644 --- a/internal/gtsmodel/statusmute.go +++ b/internal/gtsmodel/statusmute.go @@ -25,7 +25,7 @@ type StatusMute struct { // id of this mute in the database ID string `bun:"type:CHAR(26),pk,notnull,unique"` // when was this mute created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // id of the account that created ('did') the mute AccountID string `bun:"type:CHAR(26),notnull"` Account *Account `bun:"rel:belongs-to"` diff --git a/internal/gtsmodel/tag.go b/internal/gtsmodel/tag.go index 89a3538db..c69cc48c2 100644 --- a/internal/gtsmodel/tag.go +++ b/internal/gtsmodel/tag.go @@ -31,13 +31,13 @@ type Tag struct { // Which account ID is the first one we saw using this tag? FirstSeenFromAccountID string `bun:"type:CHAR(26)"` // when was this tag created - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // when was this tag last updated - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` // can our instance users use this tag? Useable bool `bun:",notnull,default:true"` // can our instance users look up this tag? Listable bool `bun:",notnull,default:true"` // when was this tag last used? - LastStatusAt time.Time `bun:"type:timestamp,notnull,default:now()"` + LastStatusAt time.Time `bun:"type:timestamp,notnull,default:current_timestamp"` } diff --git a/internal/gtsmodel/user.go b/internal/gtsmodel/user.go index ffbcba559..dfd8f93d9 100644 --- a/internal/gtsmodel/user.go +++ b/internal/gtsmodel/user.go @@ -45,19 +45,19 @@ type User struct { */ // When was this user created? - CreatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"` // From what IP was this user created? - SignUpIP net.IP + SignUpIP net.IP `bun:",nullzero"` // When was this user updated (eg., password changed, email address changed)? - UpdatedAt time.Time `bun:"type:timestamp,notnull,default:now()"` + UpdatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"` // When did this user sign in for their current session? - CurrentSignInAt time.Time `bun:"type:timestamp"` + CurrentSignInAt time.Time `bun:",nullzero"` // What's the most recent IP of this user - CurrentSignInIP net.IP + CurrentSignInIP net.IP `bun:",nullzero"` // When did this user last sign in? - LastSignInAt time.Time `bun:"type:timestamp"` + LastSignInAt time.Time `bun:",nullzero"` // What's the previous IP of this user? - LastSignInIP net.IP + LastSignInIP net.IP `bun:",nullzero"` // How many times has this user signed in? SignInCount int // id of the user who invited this user (who let this guy in?) @@ -70,9 +70,9 @@ type User struct { Locale string // Which application id created this user? See gtsmodel.Application CreatedByApplicationID string `bun:"type:CHAR(26)"` - CreatedByApplication *Application `bun:"rel:belongs-to"` + CreatedByApplication *Application `bun:"-"` // When did we last contact this user - LastEmailedAt time.Time `bun:"type:timestamp"` + LastEmailedAt time.Time `bun:",nullzero"` /* USER CONFIRMATION @@ -81,9 +81,9 @@ type User struct { // What confirmation token did we send this user/what are we expecting back? ConfirmationToken string // When did the user confirm their email address - ConfirmedAt time.Time `bun:"type:timestamp"` + ConfirmedAt time.Time `bun:",nullzero"` // When did we send email confirmation to this user? - ConfirmationSentAt time.Time `bun:"type:timestamp"` + ConfirmationSentAt time.Time `bun:",nullzero"` // Email address that hasn't yet been confirmed UnconfirmedEmail string diff --git a/internal/oauth/clientstore.go b/internal/oauth/clientstore.go index 2f04243cb..ad8dbd91e 100644 --- a/internal/oauth/clientstore.go +++ b/internal/oauth/clientstore.go @@ -55,7 +55,7 @@ func (cs *clientStore) Set(ctx context.Context, id string, cli oauth2.ClientInfo Domain: cli.GetDomain(), UserID: cli.GetUserID(), } - return cs.db.UpdateByID(ctx, id, poc) + return cs.db.Put(ctx, poc) } func (cs *clientStore) Delete(ctx context.Context, id string) error { diff --git a/internal/processing/status/util.go b/internal/processing/status/util.go index 1b3579607..26ee5d4f7 100644 --- a/internal/processing/status/util.go +++ b/internal/processing/status/util.go @@ -224,7 +224,7 @@ func (p *processor) ProcessTags(ctx context.Context, form *apimodel.AdvancedStat return fmt.Errorf("error generating hashtags from status: %s", err) } for _, tag := range gtsTags { - if err := p.db.Upsert(ctx, tag, "name"); err != nil { + if err := p.db.Put(ctx, tag); err != nil && err != db.ErrAlreadyExists { return fmt.Errorf("error putting tags in db: %s", err) } tags = append(tags, tag.ID) diff --git a/testrig/db.go b/testrig/db.go index 539c2e998..3901bea77 100644 --- a/testrig/db.go +++ b/testrig/db.go @@ -92,7 +92,7 @@ func StandardDBSetup(db db.DB, accounts map[string]*gtsmodel.Account) { for _, m := range testModels { if err := db.CreateTable(ctx, m); err != nil { - logrus.Panic(err) + logrus.Panicf("error creating table for %+v: %s", m, err) } } diff --git a/vendor/github.com/uptrace/bun/README.md b/vendor/github.com/uptrace/bun/README.md index e7cc77a60..bf57440da 100644 --- a/vendor/github.com/uptrace/bun/README.md +++ b/vendor/github.com/uptrace/bun/README.md @@ -11,6 +11,10 @@ [![Documentation](https://img.shields.io/badge/bun-documentation-informational)](https://bun.uptrace.dev/) [![Chat](https://discordapp.com/api/guilds/752070105847955518/widget.png)](https://discord.gg/rWtp5Aj) +Status: API freeze (release candidate). Note that all sub-packages (mainly extra/\* packages) are +not part of the API freeze and are developed independently. You can think of them as 3-rd party +packages. + Main features are: - Works with [PostgreSQL](https://bun.uptrace.dev/guide/drivers.html#postgresql), diff --git a/vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod b/vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod index 0cad1ce5b..c47d595d5 100644 --- a/vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod +++ b/vendor/github.com/uptrace/bun/dialect/pgdialect/go.mod @@ -4,4 +4,4 @@ go 1.16 replace github.com/uptrace/bun => ../.. -require github.com/uptrace/bun v0.4.3 +require github.com/uptrace/bun v1.0.0-rc.1 diff --git a/vendor/github.com/uptrace/bun/go.sum b/vendor/github.com/uptrace/bun/go.sum index 3bf0a4a3f..1f5ad5409 100644 --- a/vendor/github.com/uptrace/bun/go.sum +++ b/vendor/github.com/uptrace/bun/go.sum @@ -20,4 +20,4 @@ golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBc gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= \ No newline at end of file diff --git a/vendor/github.com/uptrace/bun/schema/formatter.go b/vendor/github.com/uptrace/bun/schema/formatter.go index 7b26fbaca..45a246307 100644 --- a/vendor/github.com/uptrace/bun/schema/formatter.go +++ b/vendor/github.com/uptrace/bun/schema/formatter.go @@ -89,10 +89,10 @@ func (f Formatter) AppendQuery(dst []byte, query string, args ...interface{}) [] func (f Formatter) append(dst []byte, p *parser.Parser, args []interface{}) []byte { var namedArgs NamedArgAppender if len(args) == 1 { - var ok bool - namedArgs, ok = args[0].(NamedArgAppender) - if !ok { - namedArgs, _ = newStructArgs(f, args[0]) + if v, ok := args[0].(NamedArgAppender); ok { + namedArgs = v + } else if v, ok := newStructArgs(f, args[0]); ok { + namedArgs = v } } diff --git a/vendor/github.com/uptrace/bun/version.go b/vendor/github.com/uptrace/bun/version.go index 1baf9a39c..460909509 100644 --- a/vendor/github.com/uptrace/bun/version.go +++ b/vendor/github.com/uptrace/bun/version.go @@ -2,5 +2,5 @@ package bun // Version is the current release version. func Version() string { - return "0.4.3" + return "1.0.0-rc.1" } diff --git a/vendor/modules.txt b/vendor/modules.txt index a2edd4b90..34ff7e957 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -389,7 +389,7 @@ github.com/tdewolff/parse/v2/strconv github.com/tmthrgd/go-hex # github.com/ugorji/go/codec v1.2.6 github.com/ugorji/go/codec -# github.com/uptrace/bun v0.4.3 +# github.com/uptrace/bun v1.0.0-rc.1 ## explicit github.com/uptrace/bun github.com/uptrace/bun/dialect @@ -400,7 +400,7 @@ github.com/uptrace/bun/internal github.com/uptrace/bun/internal/parser github.com/uptrace/bun/internal/tagparser github.com/uptrace/bun/schema -# github.com/uptrace/bun/dialect/pgdialect v0.4.3 +# github.com/uptrace/bun/dialect/pgdialect v1.0.0-rc.1 ## explicit github.com/uptrace/bun/dialect/pgdialect # github.com/urfave/cli/v2 v2.3.0