Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
fix(postgres): add workaround for gorm record not found
  • Loading branch information
jbrockopp committed May 27, 2021
commit 95e6969b501087ab414fca37f8a60ff1faed9736
46 changes: 30 additions & 16 deletions database/postgres/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@ import (
)

// GetBuild gets a build by number and repo ID from the database.
//
// nolint: dupl // ignore false positive of duplicate code
func (c *client) GetBuild(number int, r *library.Repo) (*library.Build, error) {
logrus.Tracef("getting build %s/%d from the database", r.GetFullName(), number)

// variable to store query results
b := new(database.Build)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableBuild).
Raw(dml.SelectRepoBuild, r.GetID(), number).
Scan(b).Error
Scan(b)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

return b.ToLibrary(), err
return b.ToLibrary(), result.Error
}

// GetLastBuild gets the last build by repo ID from the database.
Expand All @@ -41,17 +48,18 @@ func (c *client) GetLastBuild(r *library.Repo) (*library.Build, error) {
b := new(database.Build)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableBuild).
Raw(dml.SelectLastRepoBuild, r.GetID()).
Scan(b).Error
Scan(b)

// the record will not exist if it's a new repo
if errors.Is(err, gorm.ErrRecordNotFound) {
// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
// the record will not exist if it's a new repo
return nil, nil
}

return b.ToLibrary(), err
return b.ToLibrary(), result.Error
}

// GetLastBuildByBranch gets the last build by repo ID and branch from the database.
Expand All @@ -63,17 +71,18 @@ func (c *client) GetLastBuildByBranch(r *library.Repo, branch string) (*library.
b := new(database.Build)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableBuild).
Raw(dml.SelectLastRepoBuildByBranch, r.GetID(), branch).
Scan(b).Error
Scan(b)

// the record will not exist if it's a new repo
if errors.Is(err, gorm.ErrRecordNotFound) {
// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
// the record will not exist if it's a new repo
return nil, nil
}

return b.ToLibrary(), err
return b.ToLibrary(), result.Error
}

// GetPendingAndRunningBuilds returns the list of pending
Expand All @@ -85,10 +94,15 @@ func (c *client) GetPendingAndRunningBuilds(after string) ([]*library.BuildQueue
b := new([]database.BuildQueue)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableBuild).
Raw(dml.SelectPendingAndRunningBuilds, after).
Scan(b).Error
Scan(b)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

// variable we want to return
builds := []*library.BuildQueue{}
Expand All @@ -102,7 +116,7 @@ func (c *client) GetPendingAndRunningBuilds(after string) ([]*library.BuildQueue
builds = append(builds, tmp.ToLibrary())
}

return builds, err
return builds, result.Error
}

// CreateBuild creates a new build in the database.
Expand Down
24 changes: 16 additions & 8 deletions database/postgres/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,26 @@ import (
)

// GetHook gets a hook by number and repo ID from the database.
//
// nolint: dupl // ignore false positive of duplicate code
func (c *client) GetHook(number int, r *library.Repo) (*library.Hook, error) {
logrus.Tracef("getting hook %s/%d from the database", r.GetFullName(), number)

// variable to store query results
h := new(database.Hook)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableHook).
Raw(dml.SelectRepoHook, r.GetID(), number).
Scan(h).Error
Scan(h)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

return h.ToLibrary(), err
return h.ToLibrary(), result.Error
}

// GetLastHook gets the last hook by repo ID from the database.
Expand All @@ -41,17 +48,18 @@ func (c *client) GetLastHook(r *library.Repo) (*library.Hook, error) {
h := new(database.Hook)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableHook).
Raw(dml.SelectLastRepoHook, r.GetID()).
Scan(h).Error
Scan(h)

// the record will not exist if it's a new repo
if errors.Is(err, gorm.ErrRecordNotFound) {
// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
// the record will not exist if it's a new repo
return nil, nil
}

return h.ToLibrary(), err
return h.ToLibrary(), result.Error
}

// CreateHook creates a new hook in the database.
Expand Down
34 changes: 20 additions & 14 deletions database/postgres/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
package postgres

import (
"errors"
"fmt"

"github.com/go-vela/server/database/postgres/dml"
"github.com/go-vela/types/constants"
"github.com/go-vela/types/database"
"github.com/go-vela/types/library"
"gorm.io/gorm"

"github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -66,30 +68,32 @@ func (c *client) GetStepLog(id int64) (*library.Log, error) {
l := new(database.Log)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableLog).
Raw(dml.SelectStepLog, id).
Scan(l).Error
if err != nil {
return l.ToLibrary(), err
Scan(l)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

// decompress log data for the step
//
// https://pkg.go.dev/github.com/go-vela/types/database#Log.Decompress
err = l.Decompress()
err := l.Decompress()
if err != nil {
// ensures that the change is backwards compatible
// by logging the error instead of returning it
// which allows us to fetch uncompressed logs
logrus.Errorf("unable to decompress logs for step %d: %v", id, err)

// return the uncompressed log
return l.ToLibrary(), nil
return l.ToLibrary(), result.Error
}

// return the decompressed log
return l.ToLibrary(), nil
return l.ToLibrary(), result.Error
}

// GetServiceLog gets a log by unique ID from the database.
Expand All @@ -102,30 +106,32 @@ func (c *client) GetServiceLog(id int64) (*library.Log, error) {
l := new(database.Log)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableLog).
Raw(dml.SelectServiceLog, id).
Scan(l).Error
if err != nil {
return l.ToLibrary(), err
Scan(l)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

// decompress log data for the service
//
// https://pkg.go.dev/github.com/go-vela/types/database#Log.Decompress
err = l.Decompress()
err := l.Decompress()
if err != nil {
// ensures that the change is backwards compatible
// by logging the error instead of returning it
// which allowing us to fetch uncompressed logs
logrus.Errorf("unable to decompress logs for service %d: %v", id, err)

// return the uncompressed log
return l.ToLibrary(), nil
return l.ToLibrary(), result.Error
}

// return the decompressed log
return l.ToLibrary(), nil
return l.ToLibrary(), result.Error
}

// CreateLog creates a new log in the database.
Expand Down
18 changes: 11 additions & 7 deletions database/postgres/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
package postgres

import (
"errors"
"fmt"

"github.com/go-vela/server/database/postgres/dml"
"github.com/go-vela/types/constants"
"github.com/go-vela/types/database"
"github.com/go-vela/types/library"
"gorm.io/gorm"

"github.com/sirupsen/logrus"
)
Expand All @@ -23,30 +25,32 @@ func (c *client) GetRepo(org, name string) (*library.Repo, error) {
r := new(database.Repo)

// send query to the database and store result in variable
err := c.Postgres.
result := c.Postgres.
Table(constants.TableRepo).
Raw(dml.SelectRepo, org, name).
Scan(r).Error
if err != nil {
return nil, err
Scan(r)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

// decrypt the fields for the repo
//
// https://pkg.go.dev/github.com/go-vela/types/database#Repo.Decrypt
err = r.Decrypt(c.config.EncryptionKey)
err := r.Decrypt(c.config.EncryptionKey)
if err != nil {
// ensures that the change is backwards compatible
// by logging the error instead of returning it
// which allows us to fetch unencrypted repos
logrus.Errorf("unable to decrypt repo %s/%s: %v", org, name, err)

// return the unencrypted repo
return r.ToLibrary(), nil
return r.ToLibrary(), result.Error
}

// return the decrypted repo
return r.ToLibrary(), nil
return r.ToLibrary(), result.Error
}

// CreateRepo creates a new repo in the database.
Expand Down
35 changes: 29 additions & 6 deletions database/postgres/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
package postgres

import (
"errors"
"fmt"

"github.com/go-vela/server/database/postgres/dml"
"github.com/go-vela/types/constants"
"github.com/go-vela/types/database"
"github.com/go-vela/types/library"
"gorm.io/gorm"

"github.com/sirupsen/logrus"
)
Expand All @@ -27,20 +29,41 @@ func (c *client) GetSecret(t, o, n, secretName string) (*library.Secret, error)
// send query to the database and store result in variable
switch t {
case constants.SecretOrg:
err = c.Postgres.
result := c.Postgres.
Table(constants.TableSecret).
Raw(dml.SelectOrgSecret, o, secretName).
Scan(s).Error
Scan(s)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

err = result.Error
case constants.SecretRepo:
err = c.Postgres.
result := c.Postgres.
Table(constants.TableSecret).
Raw(dml.SelectRepoSecret, o, n, secretName).
Scan(s).Error
Scan(s)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

err = result.Error
case constants.SecretShared:
err = c.Postgres.
result := c.Postgres.
Table(constants.TableSecret).
Raw(dml.SelectSharedSecret, o, n, secretName).
Scan(s).Error
Scan(s)

// check if the query returned a record not found error or no rows were returned
if errors.Is(result.Error, gorm.ErrRecordNotFound) || result.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}

err = result.Error
}
if err != nil {
return nil, err
Expand Down
Loading