Add schema support.
Project: http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/commit/6eed0442 Tree: http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/tree/6eed0442 Diff: http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/diff/6eed0442 Branch: refs/heads/master Commit: 6eed044218ff888f81aa6057a1c8dd3d1ede89ac Parents: 685e11d Author: Francis Chuang <francis.chu...@boostport.com> Authored: Thu Sep 29 15:04:15 2016 +1000 Committer: Julian Hyde <jh...@apache.org> Committed: Thu Aug 10 18:47:09 2017 -0700 ---------------------------------------------------------------------- README.md | 6 ++++ driver.go | 10 ++++-- driver_test.go | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++ dsn.go | 5 +++ dsn_test.go | 12 +++++-- 5 files changed, 122 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/blob/6eed0442/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index a5dc885..f8bfe30 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,12 @@ The following parameters are supported: The `location` will be set as the location of unserialized `time.Time` values. It must be a valid timezone. If you want to use the local timezone, use `Local`. By default, this is set to `UTC`. +#### schema +The `schema` parameter sets the default schema to use for this connection. For example, if you set it to `myschema`, +then executing the query `SELECT * FROM my_table` will have the equivalence of `SELECT * FROM myschema.my_table`. +If schema is set, you can still work on tables in other schemas by supplying a schema prefix: +`SELECT * FROM myotherschema.my_other_table`. + #### maxRowsTotal The `maxRowsTotal` parameter sets the maximum number of rows to return for a given query. By default, this is set to http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/blob/6eed0442/driver.go ---------------------------------------------------------------------- diff --git a/driver.go b/driver.go index b22a398..509ed79 100644 --- a/driver.go +++ b/driver.go @@ -41,13 +41,19 @@ func (a *Driver) Open(dsn string) (driver.Conn, error) { connectionId := uuid.NewV4().String() // Open a connection to the server - _, err = httpClient.post(context.Background(), &message.OpenConnectionRequest{ + req := &message.OpenConnectionRequest{ ConnectionId: connectionId, Info: map[string]string{ "AutoCommit": "true", "Consistency": "8", }, - }) + } + + if config.schema != "" { + req.Info["schema"] = config.schema + } + + _, err = httpClient.post(context.Background(), req) if err != nil { return nil, err http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/blob/6eed0442/driver_test.go ---------------------------------------------------------------------- diff --git a/driver_test.go b/driver_test.go index fc3c626..b69e747 100644 --- a/driver_test.go +++ b/driver_test.go @@ -907,3 +907,96 @@ func TestConnectionToInvalidServerShouldReturnError(t *testing.T) { } }) } + +func TestSchemaSupport(t *testing.T) { + + db, err := sql.Open("avatica", dsn) + + if err != nil { + t.Fatalf("error connecting: %s", err.Error()) + } + + defer db.Close() + + db.Exec("CREATE SCHEMA IF NOT EXISTS avaticatest") + defer db.Exec("DROP SCHEMA IF EXISTS avaticatest") + + query := "?schema=avaticatest" + + runTests(t, dsn+query, func(dbt *DBTest) { + + // Create and seed table + dbt.mustExec(`CREATE TABLE ` + dbt.tableName + ` ( + int INTEGER PRIMARY KEY + ) TRANSACTIONAL=false`) + + defer dbt.mustExec(`DROP TABLE IF EXISTS ` + dbt.tableName) + + _, err := dbt.db.Exec(`UPSERT INTO ` + dbt.tableName + ` VALUES(1)`) + + if err != nil { + dbt.Fatal(err) + } + + rows := dbt.mustQuery(`SELECT * FROM avaticatest.` + dbt.tableName) + defer rows.Close() + + count := 0 + + for rows.Next() { + count++ + } + + if count != 1 { + dbt.Errorf("Expected 1 row, got %d rows back,", count) + } + }) +} + +func TestMultipleSchemaSupport(t *testing.T) { + + db, err := sql.Open("avatica", dsn) + + if err != nil { + t.Fatalf("error connecting: %s", err.Error()) + } + + defer db.Close() + + db.Exec("CREATE SCHEMA IF NOT EXISTS avaticatest1") + defer db.Exec("DROP SCHEMA IF EXISTS avaticatest1") + + db.Exec("CREATE SCHEMA IF NOT EXISTS avaticatest2") + defer db.Exec("DROP SCHEMA IF EXISTS avaticatest2") + + query := "?schema=avaticatest1" + + runTests(t, dsn+query, func(dbt *DBTest) { + + // Create and seed table + dbt.mustExec(`CREATE TABLE avaticatest2.` + dbt.tableName + ` ( + int INTEGER PRIMARY KEY + ) TRANSACTIONAL=false`) + + defer dbt.mustExec(`DROP TABLE IF EXISTS avaticatest2.` + dbt.tableName) + + _, err := dbt.db.Exec(`UPSERT INTO avaticatest2.` + dbt.tableName + ` VALUES(1)`) + + if err != nil { + dbt.Fatal(err) + } + + rows := dbt.mustQuery(`SELECT * FROM avaticatest2.` + dbt.tableName) + defer rows.Close() + + count := 0 + + for rows.Next() { + count++ + } + + if count != 1 { + dbt.Errorf("Expected 1 row, got %d rows back,", count) + } + }) +} http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/blob/6eed0442/dsn.go ---------------------------------------------------------------------- diff --git a/dsn.go b/dsn.go index 0467a2c..eb8270e 100644 --- a/dsn.go +++ b/dsn.go @@ -13,6 +13,7 @@ type Config struct { maxRowsTotal int64 frameMaxSize int32 location *time.Location + schema string } // ParseDSN parses a DSN string to a Config @@ -65,6 +66,10 @@ func ParseDSN(dsn string) (*Config, error) { conf.location = loc } + if v := queries.Get("schema"); v != "" { + conf.schema = v + } + parsed.RawQuery = "" parsed.Fragment = "" http://git-wip-us.apache.org/repos/asf/calcite-avatica-go/blob/6eed0442/dsn_test.go ---------------------------------------------------------------------- diff --git a/dsn_test.go b/dsn_test.go index 2cf9f6f..74a35b6 100644 --- a/dsn_test.go +++ b/dsn_test.go @@ -7,7 +7,7 @@ import ( func TestParseDSN(t *testing.T) { - config, err := ParseDSN("http://localhost:8765?maxRowsTotal=1&frameMaxSize=1&location=Australia/Melbourne") + config, err := ParseDSN("http://localhost:8765?maxRowsTotal=1&frameMaxSize=1&location=Australia/Melbourne&schema=myschema") if err != nil { t.Fatalf("Unexpected error: %s", err) @@ -28,6 +28,10 @@ func TestParseDSN(t *testing.T) { if config.location.String() != "Australia/Melbourne" { t.Errorf("Expected timezone to be %s, got %s", "Australia/Melbourne", config.location) } + + if config.schema != "myschema" { + t.Errorf("Expected schema to be %s, got %s", "myschema", config.schema) + } } func TestParseEmptyDSN(t *testing.T) { @@ -35,7 +39,7 @@ func TestParseEmptyDSN(t *testing.T) { _, err := ParseDSN("") if err == nil { - t.Fatalf("Expected error due to empty DSN, but received nothing") + t.Fatal("Expected error due to empty DSN, but received nothing") } } @@ -58,6 +62,10 @@ func TestDSNDefaults(t *testing.T) { if config.frameMaxSize == 0 { t.Error("There was no fetchMaxSize set.") } + + if config.schema != "" { + t.Errorf("Unexpected schema set: %s", config.schema) + } } func TestLocallocation(t *testing.T) {