add support for the multiline clickhouse queries

This commit is contained in:
Anton Markelov 2018-08-03 16:08:47 +10:00
parent e968e8a5f0
commit df7ce674e9
2 changed files with 31 additions and 5 deletions

View File

@ -1,6 +1,6 @@
# ClickHouse
`clickhouse://host:port?username=user&password=qwerty&database=clicks`
`clickhouse://host:port?username=user&password=qwerty&database=clicks&x-multi-statement=true`
| URL Query | Description |
|------------|-------------|
@ -10,3 +10,10 @@
| `password` | The user's password |
| `host` | The host to connect to. |
| `port` | The port to bind to. |
| `x-multi-statement` | false | Enable multiple statements to be ran in a single migration (See note below) |
## Notes
* The Clickhouse driver does not natively support executing multipe statements in a single query. To allow for multiple statements in a single migration, you can use the `x-multi-statement` param. There are two important caveats:
* This mode splits the migration text into separately-executed statements by a semi-colon `;`. Thus `x-multi-statement` cannot be used when a statement in the migration contains a string with a semi-colon.
* The queries are not executed in any sort of transaction/batch, meaning you are responsible for fixing partial migrations.

View File

@ -6,6 +6,7 @@ import (
"io"
"io/ioutil"
"net/url"
"strings"
"time"
"github.com/golang-migrate/migrate"
@ -19,6 +20,7 @@ var ErrNilConfig = fmt.Errorf("no config")
type Config struct {
DatabaseName string
MigrationsTable string
MultiStatementEnabled bool
}
func init() {
@ -68,6 +70,7 @@ func (ch *ClickHouse) Open(dsn string) (database.Driver, error) {
config: &Config{
MigrationsTable: purl.Query().Get("x-migrations-table"),
DatabaseName: purl.Query().Get("database"),
MultiStatementEnabled: purl.Query().Get("x-multi-statement") == "true",
},
}
@ -97,6 +100,22 @@ func (ch *ClickHouse) Run(r io.Reader) error {
if err != nil {
return err
}
if ch.config.MultiStatementEnabled {
// split query by semi-colon
queries := strings.Split(string(migration), ";")
for _, q := range queries {
tq := strings.TrimSpace(q)
if tq == "" {
continue
}
if _, err := ch.conn.Exec(string(q)); err != nil {
return database.Error{OrigErr: err, Err: "migration failed", Query: []byte(q)}
}
}
return nil
}
if _, err := ch.conn.Exec(string(migration)); err != nil {
return database.Error{OrigErr: err, Err: "migration failed", Query: migration}
}