diff --git a/go.mod b/go.mod index 0533a2625..b35b2a7a3 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/google/wire v0.5.0 github.com/gotidy/ptr v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 + github.com/guregu/null v4.0.0+incompatible github.com/jmoiron/sqlx v1.3.3 github.com/joho/godotenv v1.3.0 github.com/kelseyhightower/envconfig v1.4.0 diff --git a/go.sum b/go.sum index ff74dcf16..eab05de41 100644 --- a/go.sum +++ b/go.sum @@ -218,6 +218,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/guregu/null v4.0.0+incompatible h1:4zw0ckM7ECd6FNNddc3Fu4aty9nTlpkkzH7dPn4/4Gw= +github.com/guregu/null v4.0.0+incompatible/go.mod h1:ePGpQaN9cw0tj45IR5E5ehMvsFlLlQZAkkOXZurJ3NM= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= diff --git a/internal/store/database/null/bool.go b/internal/store/database/null/bool.go deleted file mode 100644 index 39b3030a0..000000000 --- a/internal/store/database/null/bool.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2022 Harness Inc. All rights reserved. -// Use of this source code is governed by the Polyform Free Trial License -// that can be found in the LICENSE.md file for this repository. - -package null - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" - "strconv" -) - -// Bool represents a bool that may be null. -type Bool struct { - sql.NullBool -} - -func NewBool(b bool) Bool { - return Bool{ - sql.NullBool{ - Bool: b, - Valid: true, - }, - } -} - -// FromBool returns a null Bool if the parameter is false or a true Bool. -func FromBool(b bool) Bool { - if !b { - return Bool{} - } - return NewBool(b) -} - -// FromPtrBool returns a null Bool if the parameter is nil, a valid Bool otherwise. -func FromPtrBool(b bool) Bool { - if !b { - return Bool{} - } - return NewBool(b) -} - -// ToBool converts null.Bool to a bool. -func (b *Bool) ToBool() bool { - if !b.Valid { - return false - } - return b.Bool -} - -// ToPtrBool converts null.Bool to a *bool. -func (b *Bool) ToPtrBool() *bool { - if !b.Valid { - return nil - } - return &b.Bool -} - -// UnmarshalJSON implements json.Unmarshaler. -func (b *Bool) UnmarshalJSON(input []byte) error { - var i interface{} - if err := json.Unmarshal(input, &i); err != nil { - return err - } - - switch val := i.(type) { - case bool: - b.Bool = val - b.Valid = true - default: - b.Bool = false - b.Valid = false - } - - return nil -} - -// MarshalJSON implements json.Marshaler. -func (b *Bool) MarshalJSON() ([]byte, error) { - if !b.Valid { - return []byte(null), nil - } - return json.Marshal(b.Bool) -} - -// Scan implements sql.Scanner interface -func (b *Bool) Scan(input interface{}) error { - switch val := input.(type) { - case nil: - b.Bool, b.Valid = false, false - case bool: - b.Bool, b.Valid = val, true - case int64: - b.Bool, b.Valid = val != 0, true - case float64: - b.Bool, b.Valid = val != 0.0, true - case []byte: - bb, err := strconv.ParseBool(string(val)) - b.Bool, b.Valid = bb, err == nil - case string: - bb, err := strconv.ParseBool(val) - b.Bool, b.Valid = bb, err == nil - default: - return fmt.Errorf("failed to convert %v (%T) to null.Bool", input, input) - } - - return nil -} - -// Value implements driver.Valuer interface -func (b *Bool) Value() (driver.Value, error) { - if !b.Valid { - return nil, nil - } - return b.Bool, nil -} diff --git a/internal/store/database/null/int64.go b/internal/store/database/null/int64.go deleted file mode 100644 index ed58b2a38..000000000 --- a/internal/store/database/null/int64.go +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2022 Harness Inc. All rights reserved. -// Use of this source code is governed by the Polyform Free Trial License -// that can be found in the LICENSE.md file for this repository. - -package null - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" - "strconv" -) - -// Int64 represents an int64 that may be null. -type Int64 struct { - sql.NullInt64 -} - -func NewInt64(i int64) Int64 { - return Int64{ - sql.NullInt64{ - Int64: i, - Valid: true, - }, - } -} - -// FromInt64 returns a null Int64 if the parameter is zero, a valid Int64 otherwise. -func FromInt64(i int64) Int64 { - if i == 0 { - return Int64{} - } - return NewInt64(i) -} - -// FromPtrInt64 returns a null Int64 if the parameter is nil, a valid Int64 otherwise. -func FromPtrInt64(i *int64) Int64 { - if i == nil { - return Int64{} - } - return NewInt64(*i) -} - -// ToInt64 converts the null.Int64 to an int64. -func (i *Int64) ToInt64() int64 { - if !i.Valid { - return 0 - } - return i.Int64 -} - -// ToPtrInt64 converts the null.Int64 to an *int64. -func (i *Int64) ToPtrInt64() *int64 { - if !i.Valid { - return nil - } - return &i.Int64 -} - -// UnmarshalJSON implements json.Unmarshaler. -func (i *Int64) UnmarshalJSON(input []byte) error { - var value interface{} - if err := json.Unmarshal(input, &value); err != nil { - return err - } - - switch z := value.(type) { - case float64: // in JSON a number is float64 - i.Int64 = int64(z) - i.Valid = true - default: - i.Int64 = 0 - i.Valid = false - } - - return nil -} - -// MarshalJSON implements json.Marshaler. -func (i *Int64) MarshalJSON() ([]byte, error) { - if !i.Valid { - return []byte(null), nil - } - return json.Marshal(i.Int64) -} - -// Scan implements sql.Scanner interface -func (i *Int64) Scan(input interface{}) error { - switch val := input.(type) { - case nil: - i.Int64, i.Valid = 0, false - case int64: - i.Int64, i.Valid = val, true - case float64: - i.Int64, i.Valid = int64(val), true - case []byte: - ii, err := strconv.ParseInt(string(val), 10, 64) - i.Int64, i.Valid = ii, err == nil - case string: - ii, err := strconv.ParseInt(val, 10, 64) - i.Int64, i.Valid = ii, err == nil - default: - return fmt.Errorf("failed to convert %v (%T) to null.Int64", input, input) - } - - return nil -} - -// Value implements driver.Valuer interface -func (i *Int64) Value() (driver.Value, error) { - if !i.Valid { - return nil, nil - } - return i.Int64, nil -} diff --git a/internal/store/database/null/null.go b/internal/store/database/null/null.go deleted file mode 100644 index a97ae2870..000000000 --- a/internal/store/database/null/null.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2022 Harness Inc. All rights reserved. -// Use of this source code is governed by the Polyform Free Trial License -// that can be found in the LICENSE.md file for this repository. - -package null - -const null = "null" diff --git a/internal/store/database/null/string.go b/internal/store/database/null/string.go deleted file mode 100644 index 6532e21ba..000000000 --- a/internal/store/database/null/string.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2022 Harness Inc. All rights reserved. -// Use of this source code is governed by the Polyform Free Trial License -// that can be found in the LICENSE.md file for this repository. - -package null - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" -) - -// String represents a string that may be null. -type String struct { - sql.NullString -} - -func NewString(s string) String { - return String{ - sql.NullString{ - String: s, - Valid: true, - }, - } -} - -// FromNullableString returns a null String if the parameter is empty, a valid String otherwise. -func FromNullableString(s string) String { - if s == "" { - return String{} - } - return NewString(s) -} - -// FromPtrString returns a null String if the parameter is nil, a valid String otherwise. -func FromPtrString(s *string) String { - if s == nil { - return String{} - } - return NewString(*s) -} - -// ToString converts the null.String to a string. -func (s *String) ToString() string { - if !s.Valid { - return "" - } - return s.String -} - -// ToPtrString converts the null.String to a *string. -func (s *String) ToPtrString() *string { - if !s.Valid { - return nil - } - return &s.String -} - -// UnmarshalJSON implements json.Unmarshaler. -func (s *String) UnmarshalJSON(input []byte) error { - var val interface{} - if err := json.Unmarshal(input, &val); err != nil { - return err - } - - switch z := val.(type) { - case string: - s.String = z - s.Valid = true - default: - s.String = "" - s.Valid = false - } - - return nil -} - -// MarshalJSON implements json.Marshaler. -func (s *String) MarshalJSON() ([]byte, error) { - if !s.Valid { - return []byte(null), nil - } - return json.Marshal(s.String) -} - -// Scan implements sql.Scanner interface -func (s *String) Scan(input interface{}) error { - switch val := input.(type) { - case nil: - s.String, s.Valid = "", false - case []byte: - s.String, s.Valid = string(val), true - case string: - s.String, s.Valid = val, true - default: - return fmt.Errorf("failed to convert %v (%T) to null.String", input, input) - } - - return nil -} - -// Value implements driver.Valuer interface -func (s *String) Value() (driver.Value, error) { - if !s.Valid { - return nil, nil - } - return s.String, nil -} diff --git a/internal/store/database/pullreq.go b/internal/store/database/pullreq.go index 0f06d0bf2..d98e0f175 100644 --- a/internal/store/database/pullreq.go +++ b/internal/store/database/pullreq.go @@ -9,11 +9,11 @@ import ( "github.com/harness/gitness/internal/store" "github.com/harness/gitness/internal/store/database/dbtx" - "github.com/harness/gitness/internal/store/database/null" "github.com/harness/gitness/types" "github.com/harness/gitness/types/enum" "github.com/Masterminds/squirrel" + "github.com/guregu/null" "github.com/jmoiron/sqlx" "github.com/pkg/errors" ) @@ -50,8 +50,8 @@ type pullReq struct { TargetRepoID int64 `db:"pullreq_target_repo_id"` TargetBranch string `db:"pullreq_target_branch"` - MergedBy null.Int64 `db:"pullreq_merged_by"` - Merged null.Int64 `db:"pullreq_merged"` + MergedBy null.Int `db:"pullreq_merged_by"` + Merged null.Int `db:"pullreq_merged"` MergeStrategy null.String `db:"pullreq_merge_strategy"` AuthorUID string `db:"author_uid"` @@ -333,9 +333,9 @@ func mapPullReq(pr *pullReq) *types.PullReq { SourceBranch: pr.SourceBranch, TargetRepoID: pr.TargetRepoID, TargetBranch: pr.TargetBranch, - MergedBy: pr.MergedBy.ToPtrInt64(), - Merged: pr.Merged.ToPtrInt64(), - MergeStrategy: pr.MergeStrategy.ToPtrString(), + MergedBy: pr.MergedBy.Ptr(), + Merged: pr.Merged.Ptr(), + MergeStrategy: pr.MergeStrategy.Ptr(), Author: types.PrincipalInfo{}, Merger: nil, }