2019-02-13 16:06:34 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package pgutil_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
_ "github.com/lib/pq"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2019-12-27 11:48:47 +00:00
|
|
|
"storj.io/common/testcontext"
|
2020-01-17 00:30:39 +00:00
|
|
|
"storj.io/storj/private/dbutil"
|
2019-11-14 19:46:15 +00:00
|
|
|
"storj.io/storj/private/dbutil/dbschema"
|
|
|
|
"storj.io/storj/private/dbutil/pgutil"
|
|
|
|
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
2019-12-04 03:36:21 +00:00
|
|
|
"storj.io/storj/private/dbutil/tempdb"
|
2019-02-13 16:06:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// DefaultPostgresConn is a connstring that works with docker-compose
|
|
|
|
DefaultPostgresConn = "postgres://storj:storj-pass@test-postgres/teststorj?sslmode=disable"
|
|
|
|
)
|
|
|
|
|
2019-12-04 03:36:21 +00:00
|
|
|
func TestQueryPostgres(t *testing.T) {
|
2019-04-26 14:39:11 +01:00
|
|
|
if *pgtest.ConnStr == "" {
|
2019-02-13 16:06:34 +00:00
|
|
|
t.Skip("Postgres flag missing, example: -postgres-test-db=" + DefaultPostgresConn)
|
|
|
|
}
|
|
|
|
|
2019-12-04 03:36:21 +00:00
|
|
|
doQueryTest(t, *pgtest.ConnStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestQueryCockroach(t *testing.T) {
|
|
|
|
if *pgtest.CrdbConnStr == "" {
|
|
|
|
t.Skip("Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCrdbConnStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
doQueryTest(t, *pgtest.CrdbConnStr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func doQueryTest(t *testing.T, connStr string) {
|
2019-02-13 16:06:34 +00:00
|
|
|
ctx := testcontext.New(t)
|
|
|
|
defer ctx.Cleanup()
|
|
|
|
|
2020-01-13 13:18:48 +00:00
|
|
|
db, err := tempdb.OpenUnique(ctx, connStr, "pgutil-query")
|
2019-02-13 16:06:34 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
defer ctx.Check(db.Close)
|
|
|
|
|
2020-01-13 13:18:48 +00:00
|
|
|
emptySchema, err := pgutil.QuerySchema(ctx, db)
|
2019-12-04 03:36:21 +00:00
|
|
|
require.NoError(t, err)
|
2019-02-13 16:06:34 +00:00
|
|
|
assert.Equal(t, &dbschema.Schema{}, emptySchema)
|
|
|
|
|
2020-01-19 14:41:23 +00:00
|
|
|
_, err = db.ExecContext(ctx, `
|
2019-02-13 16:06:34 +00:00
|
|
|
CREATE TABLE users (
|
2019-12-04 03:36:21 +00:00
|
|
|
a bigint NOT NULL,
|
|
|
|
b bigint NOT NULL,
|
2019-02-13 16:06:34 +00:00
|
|
|
c text,
|
|
|
|
UNIQUE (c),
|
|
|
|
PRIMARY KEY (a)
|
|
|
|
);
|
|
|
|
CREATE TABLE names (
|
2019-12-04 03:36:21 +00:00
|
|
|
users_a bigint REFERENCES users( a ) ON DELETE CASCADE,
|
2019-02-13 16:06:34 +00:00
|
|
|
a text NOT NULL,
|
|
|
|
x text,
|
|
|
|
b text,
|
|
|
|
PRIMARY KEY (a, x),
|
|
|
|
UNIQUE ( x ),
|
|
|
|
UNIQUE ( a, b )
|
|
|
|
);
|
|
|
|
`)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-01-13 13:18:48 +00:00
|
|
|
schema, err := pgutil.QuerySchema(ctx, db)
|
2019-12-04 03:36:21 +00:00
|
|
|
require.NoError(t, err)
|
2019-02-13 16:06:34 +00:00
|
|
|
|
|
|
|
expected := &dbschema.Schema{
|
|
|
|
Tables: []*dbschema.Table{
|
|
|
|
{
|
|
|
|
Name: "users",
|
|
|
|
Columns: []*dbschema.Column{
|
2019-12-04 03:36:21 +00:00
|
|
|
{Name: "a", Type: "bigint", IsNullable: false, Reference: nil},
|
|
|
|
{Name: "b", Type: "bigint", IsNullable: false, Reference: nil},
|
2019-02-13 16:06:34 +00:00
|
|
|
{Name: "c", Type: "text", IsNullable: true, Reference: nil},
|
|
|
|
},
|
|
|
|
PrimaryKey: []string{"a"},
|
|
|
|
Unique: [][]string{
|
|
|
|
{"c"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Name: "names",
|
|
|
|
Columns: []*dbschema.Column{
|
2019-12-04 03:36:21 +00:00
|
|
|
{Name: "users_a", Type: "bigint", IsNullable: true,
|
2019-02-13 16:06:34 +00:00
|
|
|
Reference: &dbschema.Reference{
|
|
|
|
Table: "users",
|
|
|
|
Column: "a",
|
|
|
|
OnDelete: "CASCADE",
|
|
|
|
}},
|
|
|
|
{Name: "a", Type: "text", IsNullable: false, Reference: nil},
|
|
|
|
{Name: "x", Type: "text", IsNullable: false, Reference: nil}, // not null, because primary key
|
|
|
|
{Name: "b", Type: "text", IsNullable: true, Reference: nil},
|
|
|
|
},
|
|
|
|
PrimaryKey: []string{"a", "x"},
|
|
|
|
Unique: [][]string{
|
|
|
|
{"a", "b"},
|
|
|
|
{"x"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2020-01-17 00:30:39 +00:00
|
|
|
Indexes: []*dbschema.Index{
|
|
|
|
{Name: "names_a_b_key", Table: "names", Columns: []string{"a", "b"}, Unique: true, Partial: ""},
|
|
|
|
{Name: "names_pkey", Table: "names", Columns: []string{"a", "x"}, Unique: true, Partial: ""},
|
|
|
|
{Name: "names_x_key", Table: "names", Columns: []string{"x"}, Unique: true, Partial: ""},
|
|
|
|
{Name: "users_c_key", Table: "users", Columns: []string{"c"}, Unique: true, Partial: ""},
|
|
|
|
{Name: "users_pkey", Table: "users", Columns: []string{"a"}, Unique: true, Partial: ""},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
if db.Implementation == dbutil.Cockroach {
|
|
|
|
expected.Indexes = append(expected.Indexes, &dbschema.Index{
|
|
|
|
Name: "names_auto_index_fk_users_a_ref_users",
|
|
|
|
Table: "names",
|
|
|
|
Columns: []string{"users_a"},
|
|
|
|
})
|
2019-02-13 16:06:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
expected.Sort()
|
|
|
|
schema.Sort()
|
|
|
|
assert.Equal(t, expected, schema)
|
|
|
|
}
|