Repository: cloudspannerecosystem/harbourbridge
Pull request #217 (2021-11-09 04:09:07)

Move constants that are used throughout to a top level common package
This is a pure refactoring only PR. No changes in functionality.

- [*] Tests pass
- [*] Appropriate changes to README are included in PR


Patch:
diff --git a/cmd/source_profile.go b/cmd/source_profile.go
index db1ff3e..01bac85 100644
--- a/cmd/source_profile.go
+++ b/cmd/source_profile.go
@@ -5,6 +5,8 @@ import (
 	"os"
 	"strconv"
 	"strings"
+
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 )
 
 type SourceProfileType int
@@ -199,9 +201,9 @@ func (src SourceProfile) ToLegacyDriver(source string) (string, error) {
 		{
 			switch strings.ToLower(source) {
 			case "mysql":
-				return "mysqldump", nil
+				return constants.MYSQLDUMP, nil
 			case "postgresql", "postgres", "pg":
-				return "pg_dump", nil
+				return constants.PGDUMP, nil
 			case "dynamodb":
 				return "", fmt.Errorf("dump files are not supported with DynamoDB")
 			default:
@@ -212,11 +214,11 @@ func (src SourceProfile) ToLegacyDriver(source string) (string, error) {
 		{
 			switch strings.ToLower(source) {
 			case "mysql":
-				return "mysql", nil
+				return constants.MYSQL, nil
 			case "postgresql", "postgres", "pg":
-				return "postgres", nil
+				return constants.POSTGRES, nil
 			case "dynamodb":
-				return "dynamodb", nil
+				return constants.DYNAMODB, nil
 			default:
 				return "", fmt.Errorf("please specify a valid source database using -source flag, received source = %v", source)
 			}
diff --git a/cmd/target_profile.go b/cmd/target_profile.go
index ceb954e..961b45e 100644
--- a/cmd/target_profile.go
+++ b/cmd/target_profile.go
@@ -3,6 +3,8 @@ package cmd
 import (
 	"fmt"
 	"strings"
+
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 )
 
 type TargetProfileType int
@@ -50,17 +52,17 @@ func (trg TargetProfile) ToLegacyTargetDb() string {
 			case TargetProfileConnectionTypeSpanner:
 				{
 					sp := conn.sp
-					if len(sp.dialect) > 0 && strings.ToLower(sp.dialect) == "postgresql" {
-						return "experimental_postgres"
+					if len(sp.dialect) > 0 && strings.ToLower(sp.dialect) == constants.DIALECT_POSTGRESQL {
+						return constants.TARGET_EXPERIMENTAL_POSTGRES
 					}
-					return "spanner"
+					return constants.TARGET_SPANNER
 				}
 			default:
-				return "spanner"
+				return constants.TARGET_SPANNER
 			}
 		}
 	default:
-		return "spanner"
+		return constants.TARGET_SPANNER
 	}
 }
 
diff --git a/common/constants/constants.go b/common/constants/constants.go
new file mode 100644
index 0000000..9631b91
--- /dev/null
+++ b/common/constants/constants.go
@@ -0,0 +1,30 @@
+// Package constants contains constants used across multiple other packages.
+// All string constants have a lower_case value and thus string matching is
+// performend against other lower_case strings.
+package constants
+
+const (
+	// PGDUMP is the driver name for pg_dump.
+	PGDUMP string = "pg_dump"
+
+	// POSTGRES is the driver name for PostgreSQL.
+	POSTGRES string = "postgres"
+
+	// MYSQLDUMP is the driver name for mysqldump.
+	MYSQLDUMP string = "mysqldump"
+
+	// MYSQL is the driver name for MySQL.
+	MYSQL string = "mysql"
+
+	// DYNAMODB is the driver name for AWS DynamoDB.
+	// This is an experimental driver; implementation in progress.
+	DYNAMODB string = "dynamodb"
+
+	// Target db for which schema is being generated.
+	TARGET_SPANNER               string = "spanner"
+	TARGET_EXPERIMENTAL_POSTGRES string = "experimental_postgres"
+
+	// Supported dialects for Cloud Spanner database.
+	DIALECT_POSTGRESQL string = "postgresql"
+	DIALECT_GOOGLESQL  string = "google_standard_sql"
+)
diff --git a/conversion/conversion.go b/conversion/conversion.go
index ebe6efd..e717bc1 100644
--- a/conversion/conversion.go
+++ b/conversion/conversion.go
@@ -55,6 +55,7 @@ import (
 	adminpb "google.golang.org/genproto/googleapis/spanner/admin/database/v1"
 	instancepb "google.golang.org/genproto/googleapis/spanner/admin/instance/v1"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/sources/common"
 	"github.com/cloudspannerecosystem/harbourbridge/sources/dynamodb"
@@ -64,24 +65,6 @@ import (
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 )
 
-const (
-	// PGDUMP is the driver name for pg_dump.
-	PGDUMP string = "pg_dump"
-	// POSTGRES is the driver name for PostgreSQL.
-	POSTGRES string = "postgres"
-	// MYSQLDUMP is the driver name for mysqldump.
-	MYSQLDUMP string = "mysqldump"
-	// MYSQL is the driver name for MySQL.
-	MYSQL string = "mysql"
-	// DYNAMODB is the driver name for AWS DynamoDB.
-	// This is an experimental driver; implementation in progress.
-	DYNAMODB string = "dynamodb"
-
-	// Target db for which schema is being generated.
-	TARGET_SPANNER               string = "spanner"
-	TARGET_EXPERIMENTAL_POSTGRES string = "experimental_postgres"
-)
-
 var (
 	// Set the maximum number of concurrent workers during foreign key creation.
 	// This number should not be too high so as to not hit the AdminQuota limit.
@@ -92,11 +75,11 @@ var (
 
 func SchemaConv(driver string, targetDb string, ioHelper *IOStreams, schemaSampleSize int64) (*internal.Conv, error) {
 	switch driver {
-	case POSTGRES, MYSQL:
+	case constants.POSTGRES, constants.MYSQL:
 		return schemaFromSQL(driver, targetDb)
-	case PGDUMP, MYSQLDUMP:
+	case constants.PGDUMP, constants.MYSQLDUMP:
 		return schemaFromDump(driver, targetDb, ioHelper)
-	case DYNAMODB:
+	case constants.DYNAMODB:
 		return schemaFromDynamoDB(schemaSampleSize)
 	default:
 		return nil, fmt.Errorf("schema conversion for driver %s not supported", driver)
@@ -111,14 +94,14 @@ func DataConv(driver string, ioHelper *IOStreams, client *sp.Client, conv *inter
 		Verbose:    internal.Verbose(),
 	}
 	switch driver {
-	case POSTGRES, MYSQL:
+	case constants.POSTGRES, constants.MYSQL:
 		return dataFromSQL(driver, config, client, conv)
-	case PGDUMP, MYSQLDUMP:
+	case constants.PGDUMP, constants.MYSQLDUMP:
 		if conv.SpSchema.CheckInterleaved() {
 			return nil, fmt.Errorf("HarbourBridge does not currently support data conversion from dump files\nif the schema contains interleaved tables. Suggest using direct access to source database\ni.e. using drivers postgres and mysql.")
 		}
 		return dataFromDump(driver, config, ioHelper, client, conv, dataOnly)
-	case DYNAMODB:
+	case constants.DYNAMODB:
 		return dataFromDynamoDB(config, client, conv)
 	default:
 		return nil, fmt.Errorf("data conversion for driver %s not supported", driver)
@@ -127,9 +110,9 @@ func DataConv(driver string, ioHelper *IOStreams, client *sp.Client, conv *inter
 
 func driverConfig(driver string) (string, error) {
 	switch driver {
-	case POSTGRES:
+	case constants.POSTGRES:
 		return pgDriverConfig()
-	case MYSQL:
+	case constants.MYSQL:
 		return mysqlDriverConfig()
 	default:
 		return "", fmt.Errorf("Driver %s not supported", driver)
@@ -292,7 +275,7 @@ type IOStreams struct {
 // Input stream defaults to stdin. Output stream is always set to stdout.
 func NewIOStreams(driver string, dumpFile string) IOStreams {
 	io := IOStreams{In: os.Stdin, Out: os.Stdout}
-	if (driver == PGDUMP || driver == MYSQLDUMP) && dumpFile != "" {
+	if (driver == constants.PGDUMP || driver == constants.MYSQLDUMP) && dumpFile != "" {
 		fmt.Printf("\nLoading dump file from path: %s\n", dumpFile)
 		f, err := os.Open(dumpFile)
 		if err != nil {
@@ -1037,9 +1020,9 @@ func GetBanner(now time.Time, db string) string {
 // ProcessDump invokes process dump function from a sql package based on driver selected.
 func ProcessDump(driver string, conv *internal.Conv, r *internal.Reader) error {
 	switch driver {
-	case MYSQLDUMP:
+	case constants.MYSQLDUMP:
 		return common.ProcessDbDump(conv, r, mysql.DbDumpImpl{})
-	case PGDUMP:
+	case constants.PGDUMP:
 		return common.ProcessDbDump(conv, r, postgres.DbDumpImpl{})
 	default:
 		return fmt.Errorf("process dump for driver %s not supported", driver)
@@ -1049,9 +1032,9 @@ func ProcessDump(driver string, conv *internal.Conv, r *internal.Reader) error {
 // ProcessInfoSchema invokes process infoschema function from a sql package based on driver selected.
 func ProcessInfoSchema(driver string, conv *internal.Conv, db *sql.DB) error {
 	switch driver {
-	case MYSQL:
+	case constants.MYSQL:
 		return common.ProcessInfoSchema(conv, db, mysql.InfoSchemaImpl{os.Getenv("MYSQLDATABASE")})
-	case POSTGRES:
+	case constants.POSTGRES:
 		return common.ProcessInfoSchema(conv, db, postgres.InfoSchemaImpl{})
 	default:
 		return fmt.Errorf("schema conversion for driver %s not supported", driver)
@@ -1061,9 +1044,9 @@ func ProcessInfoSchema(driver string, conv *internal.Conv, db *sql.DB) error {
 // SetRowStats invokes SetRowStats function from a sql package based on driver selected.
 func SetRowStats(driver string, conv *internal.Conv, db *sql.DB) error {
 	switch driver {
-	case MYSQL:
+	case constants.MYSQL:
 		common.SetRowStats(conv, db, mysql.InfoSchemaImpl{os.Getenv("MYSQLDATABASE")})
-	case POSTGRES:
+	case constants.POSTGRES:
 		common.SetRowStats(conv, db, postgres.InfoSchemaImpl{})
 	default:
 		return fmt.Errorf("Could not set rows stats for '%s' driver", driver)
@@ -1075,9 +1058,9 @@ func SetRowStats(driver string, conv *internal.Conv, db *sql.DB) error {
 func ProcessSQLData(driver string, conv *internal.Conv, db *sql.DB) error {
 	switch driver {
 	//TODO - move this logic into a factory within the sources dir
-	case MYSQL:
+	case constants.MYSQL:
 		common.ProcessSQLData(conv, db, mysql.InfoSchemaImpl{os.Getenv("MYSQLDATABASE")})
-	case POSTGRES:
+	case constants.POSTGRES:
 		common.ProcessSQLData(conv, db, postgres.InfoSchemaImpl{})
 	default:
 		return fmt.Errorf("Data conversion for driver %s is not supported", driver)
diff --git a/internal/report.go b/internal/report.go
index 1ae4d57..44b96cb 100644
--- a/internal/report.go
+++ b/internal/report.go
@@ -20,6 +20,7 @@ import (
 	"sort"
 	"strings"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/schema"
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
 )
@@ -444,11 +445,11 @@ func writeStmtStats(driverName string, conv *Conv, w *bufio.Writer) {
 		s := conv.Stats.Statement[x.statement]
 		fmt.Fprintf(w, "  %6d %6d %6d %6d  %s\n", s.Schema, s.Data, s.Skip, s.Error, x.statement)
 	}
-	if driverName == "pg_dump" {
+	if driverName == constants.PGDUMP {
 		w.WriteString("See github.com/pganalyze/pg_query_go for definitions of statement types\n")
 		w.WriteString("(pganalyze/pg_query_go is the library we use for parsing pg_dump output).\n")
 		w.WriteString("\n")
-	} else if driverName == "mysqldump" {
+	} else if driverName == constants.MYSQLDUMP {
 		w.WriteString("See https://github.com/pingcap/parser for definitions of statement types\n")
 		w.WriteString("(pingcap/parser is the library we use for parsing mysqldump output).\n")
 		w.WriteString("\n")
@@ -468,14 +469,14 @@ func writeUnexpectedConditions(driverName string, conv *Conv, w *bufio.Writer) {
 		return
 	}
 	switch driverName {
-	case "mysqldump":
+	case constants.MYSQLDUMP:
 		w.WriteString("For debugging only. This section provides details of unexpected conditions\n")
 		w.WriteString("encountered as we processed the mysqldump data. In particular, the AST node\n")
 		w.WriteString("representation used by the pingcap/parser library used for parsing\n")
 		w.WriteString("mysqldump output is highly permissive: almost any construct can appear at\n")
 		w.WriteString("any node in the AST tree. The list details all unexpected nodes and\n")
 		w.WriteString("conditions.\n")
-	case "pg_dump":
+	case constants.PGDUMP:
 		w.WriteString("For debugging only. This section provides details of unexpected conditions\n")
 		w.WriteString("encountered as we processed the pg_dump data. In particular, the AST node\n")
 		w.WriteString("representation used by the pganalyze/pg_query_go library used for parsing\n")
diff --git a/main.go b/main.go
index f250d05..cfd2204 100644
--- a/main.go
+++ b/main.go
@@ -29,6 +29,7 @@ import (
 	_ "github.com/lib/pq"
 
 	"github.com/cloudspannerecosystem/harbourbridge/cmd"
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/conversion"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/web"
@@ -39,7 +40,7 @@ var (
 	dbNameOverride   string
 	instanceOverride string
 	filePrefix       = ""
-	driverName       = conversion.PGDUMP
+	driverName       = constants.PGDUMP
 	schemaSampleSize = int64(0)
 	verbose          bool
 	schemaOnly       bool
@@ -48,14 +49,14 @@ var (
 	sessionJSON      string
 	webapi           bool
 	dumpFilePath     string
-	targetDb         = conversion.TARGET_SPANNER
+	targetDb         = constants.TARGET_SPANNER
 )
 
 func setupGlobalFlags() {
 	flag.StringVar(&dbNameOverride, "dbname", "", "dbname: name to use for Spanner DB")
 	flag.StringVar(&instanceOverride, "instance", "", "instance: Spanner instance to use")
 	flag.StringVar(&filePrefix, "prefix", "", "prefix: file prefix for generated files")
-	flag.StringVar(&driverName, "driver", "pg_dump", "driver name: flag for accessing source DB or dump files (accepted values are \"pg_dump\", \"postgres\", \"mysqldump\", and \"mysql\")")
+	flag.StringVar(&driverName, "driver", constants.PGDUMP, "driver name: flag for accessing source DB or dump files (accepted values are \"pg_dump\", \"postgres\", \"mysqldump\", and \"mysql\")")
 	flag.Int64Var(&schemaSampleSize, "schema-sample-size", int64(100000), "schema-sample-size: the number of rows to use for inferring schema (only for DynamoDB)")
 	flag.BoolVar(&verbose, "v", false, "verbose: print additional output")
 	flag.BoolVar(&verbose, "verbose", false, "verbose: print additional output")
@@ -65,7 +66,7 @@ func setupGlobalFlags() {
 	flag.StringVar(&sessionJSON, "session", "", "session: specifies the file we restore session state from (used in data-only to provide schema and data mapping)")
 	flag.BoolVar(&webapi, "web", false, "web: run the web interface (experimental)")
 	flag.StringVar(&dumpFilePath, "dump-file", "", "dump-file: location of dump file to process")
-	flag.StringVar(&targetDb, "target-db", conversion.TARGET_SPANNER, "target-db: Specifies the target DB. Defaults to spanner")
+	flag.StringVar(&targetDb, "target-db", constants.TARGET_SPANNER, "target-db: Specifies the target DB. Defaults to spanner")
 }
 
 func didSetVerboseTwice() bool {
@@ -136,11 +137,11 @@ func main() {
 		panic(fmt.Errorf("can't use both schema-only and skip-foreign-keys at once, foreign Key creation can only be skipped when data migration takes place"))
 	}
 
-	if targetDb == conversion.TARGET_EXPERIMENTAL_POSTGRES {
-		if !(driverName == conversion.PGDUMP || driverName == conversion.POSTGRES) {
-			panic(fmt.Errorf("can only convert to experimental postgres when source %s or %s. (target-db: %s driver: %s)", conversion.PGDUMP, conversion.POSTGRES, targetDb, driverName))
+	if targetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
+		if !(driverName == constants.PGDUMP || driverName == constants.POSTGRES) {
+			panic(fmt.Errorf("can only convert to experimental postgres when source %s or %s. (target-db: %s driver: %s)", constants.PGDUMP, constants.POSTGRES, targetDb, driverName))
 		}
-	} else if targetDb != conversion.TARGET_SPANNER {
+	} else if targetDb != constants.TARGET_SPANNER {
 		panic(fmt.Errorf("unkown target-db %s", targetDb))
 	}
 	fmt.Printf("Using driver (source DB): %s target-db: %s\n", driverName, targetDb)
diff --git a/sources/postgres/toddl.go b/sources/postgres/toddl.go
index 834b1a6..b01e80e 100644
--- a/sources/postgres/toddl.go
+++ b/sources/postgres/toddl.go
@@ -15,6 +15,7 @@
 package postgres
 
 import (
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/schema"
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
@@ -30,7 +31,7 @@ type ToDdlImpl struct {
 // conversion issues encountered.
 func (tdi ToDdlImpl) ToSpannerType(conv *internal.Conv, columnType schema.Type) (ddl.Type, []internal.SchemaIssue) {
 	ty, issues := toSpannerTypeInternal(conv, columnType.Name, columnType.Mods)
-	if conv.TargetDb == "experimental_postgres" { //TODO : Use constant instead. Using string to prevent import cycle
+	if conv.TargetDb == constants.TARGET_EXPERIMENTAL_POSTGRES {
 		ty = overrideExperimentalType(columnType, ty)
 	} else {
 		if len(columnType.ArrayBounds) > 1 {
diff --git a/web/web.go b/web/web.go
index 7a192bf..663910d 100644
--- a/web/web.go
+++ b/web/web.go
@@ -34,6 +34,7 @@ import (
 	"strings"
 	"time"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/conversion"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/sources/common"
@@ -88,9 +89,9 @@ func databaseConnection(w http.ResponseWriter, r *http.Request) {
 	}
 	var dataSourceName string
 	switch config.Driver {
-	case "postgres":
+	case constants.POSTGRES:
 		dataSourceName = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", config.Host, config.Port, config.User, config.Password, config.Database)
-	case "mysql":
+	case constants.MYSQL:
 		dataSourceName = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", config.User, config.Password, config.Host, config.Port, config.Database)
 	default:
 		http.Error(w, fmt.Sprintf("Driver : '%s' is not supported", config.Driver), http.StatusBadRequest)
@@ -124,9 +125,9 @@ func convertSchemaSQL(w http.ResponseWriter, r *http.Request) {
 	conv := internal.MakeConv()
 	var err error
 	switch sessionState.driver {
-	case "mysql":
+	case constants.MYSQL:
 		err = common.ProcessInfoSchema(conv, sessionState.sourceDB, mysql.InfoSchemaImpl{sessionState.dbName})
-	case "postgres":
+	case constants.POSTGRES:
 		err = common.ProcessInfoSchema(conv, sessionState.sourceDB, postgres.InfoSchemaImpl{})
 	default:
 		http.Error(w, fmt.Sprintf("Driver : '%s' is not supported", sessionState.driver), http.StatusBadRequest)
@@ -167,7 +168,7 @@ func convertSchemaDump(w http.ResponseWriter, r *http.Request) {
 		http.Error(w, fmt.Sprintf("failed to open dump file %v : %v", dc.FilePath, err), http.StatusNotFound)
 		return
 	}
-	conv, err := conversion.SchemaConv(dc.Driver, conversion.TARGET_SPANNER, &conversion.IOStreams{In: f, Out: os.Stdout}, 0)
+	conv, err := conversion.SchemaConv(dc.Driver, constants.TARGET_SPANNER, &conversion.IOStreams{In: f, Out: os.Stdout}, 0)
 	if err != nil {
 		http.Error(w, fmt.Sprintf("Schema Conversion Error : %v", err), http.StatusNotFound)
 		return
@@ -239,9 +240,9 @@ func getTypeMap(w http.ResponseWriter, r *http.Request) {
 	}
 	var typeMap map[string][]typeIssue
 	switch sessionState.driver {
-	case "mysql", "mysqldump":
+	case constants.MYSQL, constants.MYSQLDUMP:
 		typeMap = mysqlTypeMap
-	case "postgres", "pg_dump":
+	case constants.POSTGRES, constants.PGDUMP:
 		typeMap = postgresTypeMap
 	default:
 		http.Error(w, fmt.Sprintf("Driver : '%s' is not supported", sessionState.driver), http.StatusBadRequest)
@@ -1026,9 +1027,9 @@ func getType(newType, table, colName string, srcTableName string) (ddl.CreateTab
 	var ty ddl.Type
 	var issues []internal.SchemaIssue
 	switch sessionState.driver {
-	case "mysql", "mysqldump":
+	case constants.MYSQL, constants.MYSQLDUMP:
 		ty, issues = toSpannerTypeMySQL(srcCol.Type.Name, newType, srcCol.Type.Mods)
-	case "pg_dump", "postgres":
+	case constants.PGDUMP, constants.POSTGRES:
 		ty, issues = toSpannerTypePostgres(srcCol.Type.Name, newType, srcCol.Type.Mods)
 	default:
 		return sp, ty, fmt.Errorf("driver : '%s' is not supported", sessionState.driver)


Test patch:
diff --git a/sources/mysql/report_test.go b/sources/mysql/report_test.go
index 2b6d6e1..cb7e11f 100644
--- a/sources/mysql/report_test.go
+++ b/sources/mysql/report_test.go
@@ -21,6 +21,7 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/sources/common"
 	"github.com/stretchr/testify/assert"
@@ -61,7 +62,7 @@ func TestReport(t *testing.T) {
 	conv.Stats.Unexpected["Testing unexpected messages"] = 5
 	buf := new(bytes.Buffer)
 	w := bufio.NewWriter(buf)
-	internal.GenerateReport("mysqldump", conv, w, badWrites, true, true)
+	internal.GenerateReport(constants.MYSQLDUMP, conv, w, badWrites, true, true)
 	w.Flush()
 	// Print copy of report to stdout (shows up when running go test -v).
 	fmt.Print(buf.String())
diff --git a/sources/postgres/report_test.go b/sources/postgres/report_test.go
index 6101cb9..dcac524 100644
--- a/sources/postgres/report_test.go
+++ b/sources/postgres/report_test.go
@@ -21,6 +21,7 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/sources/common"
 	"github.com/stretchr/testify/assert"
@@ -57,7 +58,7 @@ func TestReport(t *testing.T) {
 	conv.Stats.Unexpected["Testing unexpected messages"] = 5
 	buf := new(bytes.Buffer)
 	w := bufio.NewWriter(buf)
-	internal.GenerateReport("pg_dump", conv, w, badWrites, true, true)
+	internal.GenerateReport(constants.PGDUMP, conv, w, badWrites, true, true)
 	w.Flush()
 	// Print copy of report to stdout (shows up when running go test -v).
 	fmt.Print(buf.String())
diff --git a/sources/postgres/toddl_test.go b/sources/postgres/toddl_test.go
index e7365d4..551e531 100644
--- a/sources/postgres/toddl_test.go
+++ b/sources/postgres/toddl_test.go
@@ -17,6 +17,7 @@ package postgres
 import (
 	"testing"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/schema"
 	"github.com/cloudspannerecosystem/harbourbridge/sources/common"
@@ -102,7 +103,7 @@ func TestToSpannerType(t *testing.T) {
 func TestToExperimentalSpannerType(t *testing.T) {
 	conv := internal.MakeConv()
 	conv.SetSchemaMode()
-	conv.TargetDb = "experimental_postgres"
+	conv.TargetDb = constants.TARGET_EXPERIMENTAL_POSTGRES
 	name := "test"
 	srcSchema := schema.Table{
 		Name:     name,
diff --git a/testing/dynamodb/integration_test.go b/testing/dynamodb/integration_test.go
index 97b4c2b..213c3bd 100644
--- a/testing/dynamodb/integration_test.go
+++ b/testing/dynamodb/integration_test.go
@@ -26,6 +26,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/conversion"
 	"github.com/cloudspannerecosystem/harbourbridge/testing/common"
 	"github.com/google/go-cmp/cmp"
@@ -213,11 +214,11 @@ func TestIntegration_DYNAMODB_Command(t *testing.T) {
 	defer os.RemoveAll(tmpdir)
 
 	now := time.Now()
-	dbName, _ := conversion.GetDatabaseName(conversion.DYNAMODB, now)
+	dbName, _ := conversion.GetDatabaseName(constants.DYNAMODB, now)
 	dbURI := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, dbName)
 	filePrefix := filepath.Join(tmpdir, dbName+".")
 
-	args := fmt.Sprintf("-driver %s -prefix %s -instance %s -dbname %s", conversion.DYNAMODB, filePrefix, instanceID, dbName)
+	args := fmt.Sprintf("-driver %s -prefix %s -instance %s -dbname %s", constants.DYNAMODB, filePrefix, instanceID, dbName)
 	err := common.RunCommand(args, projectID)
 	if err != nil {
 		t.Fatal(err)
diff --git a/testing/mysql/integration_test.go b/testing/mysql/integration_test.go
index 29bd3ea..82d927c 100644
--- a/testing/mysql/integration_test.go
+++ b/testing/mysql/integration_test.go
@@ -25,6 +25,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/conversion"
 	"github.com/cloudspannerecosystem/harbourbridge/testing/common"
 
@@ -109,12 +110,12 @@ func TestIntegration_MYSQLDUMP_Command(t *testing.T) {
 	defer os.RemoveAll(tmpdir)
 
 	now := time.Now()
-	dbName, _ := conversion.GetDatabaseName(conversion.MYSQLDUMP, now)
+	dbName, _ := conversion.GetDatabaseName(constants.MYSQLDUMP, now)
 	dbURI := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, dbName)
 	dataFilepath := "../../test_data/mysqldump.test.out"
 	filePrefix := filepath.Join(tmpdir, dbName+".")
 
-	args := fmt.Sprintf("-driver %s -prefix %s -instance %s -dbname %s < %s", conversion.MYSQLDUMP, filePrefix, instanceID, dbName, dataFilepath)
+	args := fmt.Sprintf("-driver %s -prefix %s -instance %s -dbname %s < %s", constants.MYSQLDUMP, filePrefix, instanceID, dbName, dataFilepath)
 	err := common.RunCommand(args, projectID)
 	if err != nil {
 		t.Fatal(err)
@@ -133,11 +134,11 @@ func TestIntegration_MYSQL_Command(t *testing.T) {
 	defer os.RemoveAll(tmpdir)
 
 	now := time.Now()
-	dbName, _ := conversion.GetDatabaseName(conversion.MYSQL, now)
+	dbName, _ := conversion.GetDatabaseName(constants.MYSQL, now)
 	dbURI := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, dbName)
 	filePrefix := filepath.Join(tmpdir, dbName+".")
 
-	args := fmt.Sprintf("-driver %s -prefix %s -instance %s -dbname %s", conversion.MYSQL, filePrefix, instanceID, dbName)
+	args := fmt.Sprintf("-driver %s -prefix %s -instance %s -dbname %s", constants.MYSQL, filePrefix, instanceID, dbName)
 	err := common.RunCommand(args, projectID)
 	if err != nil {
 		t.Fatal(err)
diff --git a/testing/postgres/integration_test.go b/testing/postgres/integration_test.go
index 78741e9..b859dcb 100644
--- a/testing/postgres/integration_test.go
+++ b/testing/postgres/integration_test.go
@@ -29,6 +29,7 @@ import (
 
 	"cloud.google.com/go/spanner"
 	database "cloud.google.com/go/spanner/admin/database/apiv1"
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/conversion"
 	"github.com/cloudspannerecosystem/harbourbridge/testing/common"
 	"google.golang.org/api/iterator"
@@ -111,7 +112,7 @@ func TestIntegration_PGDUMP_Command(t *testing.T) {
 	defer os.RemoveAll(tmpdir)
 
 	now := time.Now()
-	dbName, _ := conversion.GetDatabaseName(conversion.PGDUMP, now)
+	dbName, _ := conversion.GetDatabaseName(constants.PGDUMP, now)
 	dbURI := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, dbName)
 
 	dataFilepath := "../../test_data/pg_dump.test.out"
@@ -135,7 +136,7 @@ func TestIntegration_PGDUMP_EvalSubcommand(t *testing.T) {
 	defer os.RemoveAll(tmpdir)
 
 	now := time.Now()
-	dbName, _ := conversion.GetDatabaseName(conversion.PGDUMP, now)
+	dbName, _ := conversion.GetDatabaseName(constants.PGDUMP, now)
 	dbURI := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, dbName)
 
 	dataFilepath := "../../test_data/pg_dump.test.out"
@@ -175,11 +176,11 @@ func TestIntegration_POSTGRES_Command(t *testing.T) {
 	defer os.RemoveAll(tmpdir)
 
 	now := time.Now()
-	dbName, _ := conversion.GetDatabaseName(conversion.POSTGRES, now)
+	dbName, _ := conversion.GetDatabaseName(constants.POSTGRES, now)
 	dbURI := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, dbName)
 	filePrefix := filepath.Join(tmpdir, dbName+".")
 
-	args := fmt.Sprintf("-instance %s -dbname %s -prefix %s -driver %s", instanceID, dbName, filePrefix, conversion.POSTGRES)
+	args := fmt.Sprintf("-instance %s -dbname %s -prefix %s -driver %s", instanceID, dbName, filePrefix, constants.POSTGRES)
 	err := common.RunCommand(args, projectID)
 	if err != nil {
 		t.Fatal(err)
@@ -198,7 +199,7 @@ func TestIntegration_POSTGRES_EvalSubcommand(t *testing.T) {
 	defer os.RemoveAll(tmpdir)
 
 	now := time.Now()
-	dbName, _ := conversion.GetDatabaseName(conversion.POSTGRES, now)
+	dbName, _ := conversion.GetDatabaseName(constants.POSTGRES, now)
 	dbURI := fmt.Sprintf("projects/%s/instances/%s/databases/%s", projectID, instanceID, dbName)
 	filePrefix := filepath.Join(tmpdir, dbName+".")
 
diff --git a/web/web_test.go b/web/web_test.go
index a171cdb..15f4797 100644
--- a/web/web_test.go
+++ b/web/web_test.go
@@ -23,6 +23,7 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/cloudspannerecosystem/harbourbridge/common/constants"
 	"github.com/cloudspannerecosystem/harbourbridge/internal"
 	"github.com/cloudspannerecosystem/harbourbridge/schema"
 	"github.com/cloudspannerecosystem/harbourbridge/spanner/ddl"
@@ -45,7 +46,7 @@ func TestGetTypeMapNoDriver(t *testing.T) {
 }
 
 func TestGetTypeMapPostgres(t *testing.T) {
-	sessionState.driver = "postgres"
+	sessionState.driver = constants.POSTGRES
 	sessionState.conv = internal.MakeConv()
 	buildConvPostgres(sessionState.conv)
 	req, err := http.NewRequest("GET", "/typemap", nil)
@@ -624,7 +625,7 @@ func TestUpdateTableSchema(t *testing.T) {
 		},
 	}
 	for _, tc := range tc {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = tc.conv
 		payload := tc.payload
 		req, err := http.NewRequest("POST", "/typemap/table?table="+tc.table, strings.NewReader(payload))
@@ -769,7 +770,7 @@ func TestSetTypeMapGlobalLevelPostgres(t *testing.T) {
 		},
 	}
 	for _, tc := range tc {
-		sessionState.driver = "postgres"
+		sessionState.driver = constants.POSTGRES
 		sessionState.conv = internal.MakeConv()
 		buildConvPostgres(sessionState.conv)
 		payload := tc.payload
@@ -797,7 +798,7 @@ func TestSetTypeMapGlobalLevelPostgres(t *testing.T) {
 }
 
 func TestGetConversionPostgres(t *testing.T) {
-	sessionState.driver = "postgres"
+	sessionState.driver = constants.POSTGRES
 	sessionState.conv = internal.MakeConv()
 	buildConvPostgres(sessionState.conv)
 	req, err := http.NewRequest("GET", "/conversion", nil)
@@ -819,7 +820,7 @@ func TestGetConversionPostgres(t *testing.T) {
 }
 
 func TestGetTypeMapMySQL(t *testing.T) {
-	sessionState.driver = "mysql"
+	sessionState.driver = constants.MYSQL
 	sessionState.conv = internal.MakeConv()
 	buildConvMySQL(sessionState.conv)
 	req, err := http.NewRequest("GET", "/typemap", nil)
@@ -1003,7 +1004,7 @@ func TestSetTypeMapGlobalLevelMySQL(t *testing.T) {
 		},
 	}
 	for _, tc := range tc {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = internal.MakeConv()
 		buildConvMySQL(sessionState.conv)
 		payload := tc.payload
@@ -1030,7 +1031,7 @@ func TestSetTypeMapGlobalLevelMySQL(t *testing.T) {
 }
 
 func TestGetConversionMySQL(t *testing.T) {
-	sessionState.driver = "mysql"
+	sessionState.driver = constants.MYSQL
 	sessionState.conv = internal.MakeConv()
 	buildConvMySQL(sessionState.conv)
 	req, err := http.NewRequest("GET", "/conversion", nil)
@@ -1300,7 +1301,7 @@ func TestSetParentTable(t *testing.T) {
 		},
 	}
 	for _, tc := range tests {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = tc.ct
 		update := true
 		req, err := http.NewRequest("GET", fmt.Sprintf("/setparent?table=%s&update=%v", tc.table, update), nil)
@@ -1396,7 +1397,7 @@ func TestDropForeignKey(t *testing.T) {
 		},
 	}
 	for _, tc := range tc {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = tc.conv
 		req, err := http.NewRequest("GET", "/drop/fk?table="+tc.table+"&pos="+tc.position, nil)
 		if err != nil {
@@ -1620,7 +1621,7 @@ func TestRenameIndexes(t *testing.T) {
 	}
 
 	for _, tc := range tc {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = tc.conv
 
 		inputBytes, err := json.Marshal(tc.input)
@@ -1886,7 +1887,7 @@ func TestRenameForeignKeys(t *testing.T) {
 		},
 	}
 	for _, tc := range tc {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = tc.conv
 
 		inputBytes, err := json.Marshal(tc.input)
@@ -2115,7 +2116,7 @@ func TestAddIndexes(t *testing.T) {
 	}
 
 	for _, tc := range tc {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = tc.conv
 
 		inputBytes, err := json.Marshal(tc.input)
@@ -2198,7 +2199,7 @@ func TestDropSecondaryIndex(t *testing.T) {
 		},
 	}
 	for _, tc := range tc {
-		sessionState.driver = "mysql"
+		sessionState.driver = constants.MYSQL
 		sessionState.conv = tc.conv
 		req, err := http.NewRequest("GET", "/drop/secondaryindex?table="+tc.table+"&pos="+tc.position, nil)
 		if err != nil {