From 087774bd3c2bd6c4581789ca137b3ec435244d54 Mon Sep 17 00:00:00 2001 From: Clayton Rosenthal Date: Wed, 31 May 2023 19:18:46 -0700 Subject: [PATCH 1/4] add check for db and table not tested, just drafting concept for now --- mysql/mysql.go | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/mysql/mysql.go b/mysql/mysql.go index 0273491..19b17e6 100644 --- a/mysql/mysql.go +++ b/mysql/mysql.go @@ -44,9 +44,16 @@ func (db *DB) Open(dataSourceName string, opt ...database.Option) error { if err != nil { return errors.Wrap(err, "error connecting to mysql") } - _, err = _db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", opts.Database)) + _db_check, err = _db.Exec(fmt.Sprintf("SHOW DATABASES LIKE `%s`", opts.Database)) if err != nil { - return errors.Wrapf(err, "error creating database %s (if not exists)", opts.Database) + return errors.Wrapf(err, "error checking if database %s exists", opts.Database) + } + // db doesn't exist, create it + if len(_db_check.allAffectedRows()) == 0 { + _, err = _db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", opts.Database)) + if err != nil { + return errors.Wrapf(err, "error creating database %s (if not exists)", opts.Database) + } } parsedDSN.DBName = opts.Database db.db, err = sql.Open("mysql", parsedDSN.FormatDSN()) @@ -82,6 +89,10 @@ func createTableQry(bucket []byte) string { return fmt.Sprintf("CREATE TABLE IF NOT EXISTS `%s`(nkey VARBINARY(255), nvalue BLOB, PRIMARY KEY (nkey));", bucket) } +func checkTableQry(bucket []byte) string { + return fmt.Sprintf("SHOW TABLES LIKE `%s`;", bucket) +} + func deleteTableQry(bucket []byte) string { return fmt.Sprintf("DROP TABLE `%s`", bucket) } @@ -261,9 +272,15 @@ func (db *DB) Update(tx *database.Tx) error { // CreateTable creates a table in the database. func (db *DB) CreateTable(bucket []byte) error { - _, err := db.db.Exec(createTableQry(bucket)) + _check, err := db.db.Exec(checkTableQry(bucket)) if err != nil { - return errors.Wrapf(err, "failed to create table %s", bucket) + return errors.Wrapf(err, "failed to check table %s", bucket) + } + if len(_check.allAffectedRows()) == 0 { + _, err := db.db.Exec(createTableQry(bucket)) + if err != nil { + return errors.Wrapf(err, "failed to create table %s", bucket) + } } return nil } From d8b114d201e660bbdcd1eb794b84dad0c4fab045 Mon Sep 17 00:00:00 2001 From: Clayton Rosenthal Date: Fri, 2 Jun 2023 15:27:31 -0700 Subject: [PATCH 2/4] fixing check --- mysql/mysql.go | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/mysql/mysql.go b/mysql/mysql.go index 19b17e6..0573198 100644 --- a/mysql/mysql.go +++ b/mysql/mysql.go @@ -44,17 +44,18 @@ func (db *DB) Open(dataSourceName string, opt ...database.Option) error { if err != nil { return errors.Wrap(err, "error connecting to mysql") } - _db_check, err = _db.Exec(fmt.Sprintf("SHOW DATABASES LIKE `%s`", opts.Database)) - if err != nil { - return errors.Wrapf(err, "error checking if database %s exists", opts.Database) - } - // db doesn't exist, create it - if len(_db_check.allAffectedRows()) == 0 { - _, err = _db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", opts.Database)) - if err != nil { - return errors.Wrapf(err, "error creating database %s (if not exists)", opts.Database) - } + _db_check, err := _db.Query(fmt.Sprintf("SHOW DATABASES LIKE `%s`", opts.Database)) + if err != nil { + return errors.Wrapf(err, "error checking if database %s exists", opts.Database) + } + // db doesn't exist, create it + if !_db_check.Next() { + _, err = _db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", opts.Database)) + if err != nil { + return errors.Wrapf(err, "error creating database %s (if not exists)", opts.Database) + } } + parsedDSN.DBName = opts.Database db.db, err = sql.Open("mysql", parsedDSN.FormatDSN()) if err != nil { @@ -270,19 +271,20 @@ func (db *DB) Update(tx *database.Tx) error { return nil } -// CreateTable creates a table in the database. -func (db *DB) CreateTable(bucket []byte) error { - _check, err := db.db.Exec(checkTableQry(bucket)) +// CreateTable creates a table in the database. +func (db *DB) CreateTable(bucket []byte) error { + _check, err := db.db.Query(checkTableQry(bucket)) if err != nil { - return errors.Wrapf(err, "failed to check table %s", bucket) - } - if len(_check.allAffectedRows()) == 0 { - _, err := db.db.Exec(createTableQry(bucket)) + return errors.Wrapf(err, "failed to check table %s", bucket) + } + // table doesn't exist, create it + if !_check.Next() { + _, err := db.db.Exec(createTableQry(bucket)) if err != nil { return errors.Wrapf(err, "failed to create table %s", bucket) } - } - return nil + } + return nil } // DeleteTable deletes a table in the database. From 3bd2ab0ace48f880e5b729f09665e14858c59047 Mon Sep 17 00:00:00 2001 From: max furman Date: Thu, 3 Aug 2023 15:23:13 -0700 Subject: [PATCH 3/4] Add Close() and error check for returned rows from check queries --- database/notsupported.go | 1 + mysql/mysql.go | 48 +++++++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/database/notsupported.go b/database/notsupported.go index a2dbf16..95748a2 100644 --- a/database/notsupported.go +++ b/database/notsupported.go @@ -1,3 +1,4 @@ +//nolint:revive // ignore unused parameters because these are stubs package database // NotSupportedDB is a db implementation used on database drivers when the diff --git a/mysql/mysql.go b/mysql/mysql.go index 0573198..98de08f 100644 --- a/mysql/mysql.go +++ b/mysql/mysql.go @@ -44,16 +44,20 @@ func (db *DB) Open(dataSourceName string, opt ...database.Option) error { if err != nil { return errors.Wrap(err, "error connecting to mysql") } - _db_check, err := _db.Query(fmt.Sprintf("SHOW DATABASES LIKE `%s`", opts.Database)) - if err != nil { - return errors.Wrapf(err, "error checking if database %s exists", opts.Database) - } - // db doesn't exist, create it - if !_db_check.Next() { - _, err = _db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", opts.Database)) - if err != nil { - return errors.Wrapf(err, "error creating database %s (if not exists)", opts.Database) - } + rows, err := _db.Query(fmt.Sprintf("SHOW DATABASES LIKE `%s`", opts.Database)) + if err != nil { + return errors.Wrapf(err, "error checking if database %s exists", opts.Database) + } + defer rows.Close() + // db doesn't exist, create it + if !rows.Next() { + _, err = _db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS `%s`", opts.Database)) + if err != nil { + return errors.Wrapf(err, "error creating database %s (if not exists)", opts.Database) + } + } + if err = rows.Err(); err != nil { + return fmt.Errorf("error accessing databases: %w", err) } parsedDSN.DBName = opts.Database @@ -271,20 +275,24 @@ func (db *DB) Update(tx *database.Tx) error { return nil } -// CreateTable creates a table in the database. -func (db *DB) CreateTable(bucket []byte) error { - _check, err := db.db.Query(checkTableQry(bucket)) +// CreateTable creates a table in the database. +func (db *DB) CreateTable(bucket []byte) error { + rows, err := db.db.Query(checkTableQry(bucket)) if err != nil { - return errors.Wrapf(err, "failed to check table %s", bucket) - } - // table doesn't exist, create it - if !_check.Next() { - _, err := db.db.Exec(createTableQry(bucket)) + return errors.Wrapf(err, "failed to check table %s", bucket) + } + defer rows.Close() + // Table doesn't exist, create it. + if !rows.Next() { + _, err := db.db.Exec(createTableQry(bucket)) if err != nil { return errors.Wrapf(err, "failed to create table %s", bucket) } - } - return nil + } + if err = rows.Err(); err != nil { + return errors.Wrap(err, "error accessing row") + } + return nil } // DeleteTable deletes a table in the database. From b1a5ab9286bd937e0ff6041f4b70b83beabb7741 Mon Sep 17 00:00:00 2001 From: max furman Date: Thu, 3 Aug 2023 17:18:56 -0700 Subject: [PATCH 4/4] Replace backticks with single quotes in `SHOW ...` queries --- mysql/mysql.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql/mysql.go b/mysql/mysql.go index 98de08f..4e89fb4 100644 --- a/mysql/mysql.go +++ b/mysql/mysql.go @@ -44,7 +44,7 @@ func (db *DB) Open(dataSourceName string, opt ...database.Option) error { if err != nil { return errors.Wrap(err, "error connecting to mysql") } - rows, err := _db.Query(fmt.Sprintf("SHOW DATABASES LIKE `%s`", opts.Database)) + rows, err := _db.Query(fmt.Sprintf("SHOW DATABASES LIKE '%s'", opts.Database)) if err != nil { return errors.Wrapf(err, "error checking if database %s exists", opts.Database) } @@ -95,7 +95,7 @@ func createTableQry(bucket []byte) string { } func checkTableQry(bucket []byte) string { - return fmt.Sprintf("SHOW TABLES LIKE `%s`;", bucket) + return fmt.Sprintf("SHOW TABLES LIKE '%s';", bucket) } func deleteTableQry(bucket []byte) string {