From be2fd70e3c88e00967ff9501a65b53c5f5d0fa2a Mon Sep 17 00:00:00 2001 From: mpl Date: Wed, 3 Apr 2013 17:50:46 +0200 Subject: [PATCH] index: set MySQL to binary charset The immediate concern was to make the index case sensitive, but the values should be stored in binary anyway as this layer is just obeying the IndexStorage interface and should not be concerned with character sets. http://camlistore.org/issue/130 Change-Id: Iee913b0bd9e5c0c32a5c5570310c2ac5d0cfddf8 --- pkg/index/mysql/dbschema.go | 12 +++++++++--- pkg/index/mysql/mysqlindexer.go | 11 ++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/pkg/index/mysql/dbschema.go b/pkg/index/mysql/dbschema.go index 28cf64464..81bd23ac3 100644 --- a/pkg/index/mysql/dbschema.go +++ b/pkg/index/mysql/dbschema.go @@ -16,20 +16,26 @@ limitations under the License. package mysql -const requiredSchemaVersion = 20 +const requiredSchemaVersion = 21 func SchemaVersion() int { return requiredSchemaVersion } +// Note: using character set "binary", as any knowledge +// of character set encodings is handled by higher layers. +// At this layer we're just obeying the IndexStorage interface, +// which is purely about bytes. func SQLCreateTables() []string { return []string{ `CREATE TABLE rows ( k VARCHAR(255) NOT NULL PRIMARY KEY, - v VARCHAR(255))`, + v VARCHAR(255)) + DEFAULT CHARACTER SET binary`, `CREATE TABLE meta ( metakey VARCHAR(255) NOT NULL PRIMARY KEY, - value VARCHAR(255) NOT NULL)`, + value VARCHAR(255) NOT NULL) + DEFAULT CHARACTER SET binary`, } } diff --git a/pkg/index/mysql/mysqlindexer.go b/pkg/index/mysql/mysqlindexer.go index bb921f723..68936a87f 100644 --- a/pkg/index/mysql/mysqlindexer.go +++ b/pkg/index/mysql/mysqlindexer.go @@ -42,7 +42,7 @@ var _ index.Storage = (*myIndexStorage)(nil) // This exists mostly for testing and does not initialize the schema. func NewStorage(host, user, password, dbname string) (index.Storage, error) { // TODO(bradfitz): host is ignored; how to plumb it through with mymysql? - dsn := dbname+"/"+user+"/"+password + dsn := dbname + "/" + user + "/" + password db, err := sql.Open("mymysql", dsn) if err != nil { return nil, err @@ -60,6 +60,12 @@ func NewStorage(host, user, password, dbname string) (index.Storage, error) { }, nil } +const fixSchema20to21 = `Character set in tables changed to binary, you can fix your tables with: +ALTER TABLE rows CONVERT TO CHARACTER SET binary; +ALTER TABLE meta CONVERT TO CHARACTER SET binary; +UPDATE meta SET value=21 WHERE metakey='version' AND value=20; +` + func newFromConfig(ld blobserver.Loader, config jsonconfig.Obj) (blobserver.Storage, error) { var ( blobPrefix = config.RequiredString("blobSource") @@ -89,6 +95,9 @@ func newFromConfig(ld blobserver.Loader, config jsonconfig.Obj) (blobserver.Stor return nil, fmt.Errorf("error getting schema version (need to init database?): %v", err) } if version != requiredSchemaVersion { + if version == 20 && requiredSchemaVersion == 21 { + fmt.Fprintf(os.Stderr, fixSchema20to21) + } if os.Getenv("CAMLI_ADVERTISED_PASSWORD") != "" { // Good signal that we're using the dev-server script, so help out // the user with a more useful tip: