Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unify SQL DB migration subsystem (for Postgres and SQLite) #3134

Merged
merged 12 commits into from
Sep 20, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,30 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package postgresql
package pginterfaces

import (
"context"

"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"

"github.com/dapr/components-contrib/state"
)

// dbAccess is a private interface which enables unit testing of PostgreSQL.
type dbAccess interface {
Init(ctx context.Context, metadata state.Metadata) error
Set(ctx context.Context, req *state.SetRequest) error
Get(ctx context.Context, req *state.GetRequest) (*state.GetResponse, error)
BulkGet(ctx context.Context, req []state.GetRequest) ([]state.BulkGetResponse, error)
Delete(ctx context.Context, req *state.DeleteRequest) error
ExecuteMulti(ctx context.Context, req *state.TransactionalStateRequest) error
Query(ctx context.Context, req *state.QueryRequest) (*state.QueryResponse, error)
Close() error // io.Closer
}

// Interface that contains methods for querying.
// Applies to *pgx.Conn, *pgxpool.Pool, and pgx.Tx
type dbquerier interface {
type DBQuerier interface {
Exec(context.Context, string, ...interface{}) (pgconn.CommandTag, error)
Query(context.Context, string, ...interface{}) (pgx.Rows, error)
QueryRow(context.Context, string, ...interface{}) pgx.Row
}

// Interface that applies to *pgxpool.Pool.
// We need this to be able to mock the connection in tests.
type PGXPoolConn interface {
DBQuerier

Begin(context.Context) (pgx.Tx, error)
BeginTx(ctx context.Context, txOptions pgx.TxOptions) (pgx.Tx, error)
Ping(context.Context) error
Close()
}
4 changes: 2 additions & 2 deletions internal/component/postgresql/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const (
defaultTimeout = 20 // Default timeout for network requests, in seconds
)

type postgresMetadataStruct struct {
type pgMetadata struct {
pgauth.PostgresAuthMetadata `mapstructure:",squash"`

TableName string `mapstructure:"tableName"` // Could be in the format "schema.table" or just "table"
Expand All @@ -42,7 +42,7 @@ type postgresMetadataStruct struct {
CleanupInterval *time.Duration `mapstructure:"cleanupIntervalInSeconds"`
}

func (m *postgresMetadataStruct) InitWithMetadata(meta state.Metadata, azureADEnabled bool) error {
func (m *pgMetadata) InitWithMetadata(meta state.Metadata, azureADEnabled bool) error {
// Reset the object
m.PostgresAuthMetadata.Reset()
m.TableName = defaultTableName
Expand Down
24 changes: 12 additions & 12 deletions internal/component/postgresql/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (

func TestMetadata(t *testing.T) {
t.Run("missing connection string", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{}

err := m.InitWithMetadata(state.Metadata{Base: metadata.Base{Properties: props}}, false)
Expand All @@ -34,7 +34,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("has connection string", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
}
Expand All @@ -44,7 +44,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("default table name", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
}
Expand All @@ -55,7 +55,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("custom table name", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
"tableName": "mytable",
Expand All @@ -67,7 +67,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("default timeout", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
}
Expand All @@ -78,7 +78,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("invalid timeout", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
"timeoutInSeconds": "NaN",
Expand All @@ -89,7 +89,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("positive timeout", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
"timeoutInSeconds": "42",
Expand All @@ -101,7 +101,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("zero timeout", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
"timeoutInSeconds": "0",
Expand All @@ -112,7 +112,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("default cleanupIntervalInSeconds", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
}
Expand All @@ -124,7 +124,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("invalid cleanupIntervalInSeconds", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
"cleanupIntervalInSeconds": "NaN",
Expand All @@ -135,7 +135,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("positive cleanupIntervalInSeconds", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
"cleanupIntervalInSeconds": "42",
Expand All @@ -148,7 +148,7 @@ func TestMetadata(t *testing.T) {
})

t.Run("zero cleanupIntervalInSeconds", func(t *testing.T) {
m := postgresMetadataStruct{}
m := pgMetadata{}
props := map[string]string{
"connectionString": "foo",
"cleanupIntervalInSeconds": "0",
Expand Down
Loading
Loading