@@ -839,6 +839,43 @@ func (db *DB) GetSemaphoreForTable(table string) *semaphore.Weighted {
839839 }
840840}
841841
842+ // HasTable checks whether a table is present in the database.
843+ //
844+ // The first return value indicates whether a table of the given name exists. The second return value contains any
845+ // errors that occurred during the check. If the error is not nil, the first argument is always false.
846+ func (db * DB ) HasTable (ctx context.Context , table string ) (bool , error ) {
847+ var tableSchemaFunc string
848+ switch db .DriverName () {
849+ case MySQL :
850+ tableSchemaFunc = "DATABASE()"
851+ case PostgreSQL :
852+ tableSchemaFunc = "CURRENT_SCHEMA()"
853+ default :
854+ return false , errors .Errorf ("unsupported database driver %q" , db .DriverName ())
855+ }
856+
857+ var hasTable bool
858+ err := retry .WithBackoff (
859+ ctx ,
860+ func (ctx context.Context ) error {
861+ query := db .Rebind ("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=" + tableSchemaFunc + " AND TABLE_NAME=?" )
862+ rows , err := db .QueryContext (ctx , query , table )
863+ if err != nil {
864+ return CantPerformQuery (err , query )
865+ }
866+ defer func () { _ = rows .Close () }()
867+ hasTable = rows .Next ()
868+ return rows .Close ()
869+ },
870+ retry .Retryable ,
871+ backoff .NewExponentialWithJitter (128 * time .Millisecond , 1 * time .Minute ),
872+ db .GetDefaultRetrySettings ())
873+ if err != nil {
874+ return false , errors .Wrapf (err , "can't verify existence of database table %q" , table )
875+ }
876+ return hasTable , nil
877+ }
878+
842879func (db * DB ) GetDefaultRetrySettings () retry.Settings {
843880 return retry.Settings {
844881 Timeout : retry .DefaultTimeout ,
0 commit comments