autotest: remove unneccesary indirection in tko db handle creation

We only support a mysql based tko db, yet we have indirection to fork
between different db backends that adds confusion and complexity.

 - delete db_mysql.py and move its connect method back to tko/db.py
 - delete _get_error_class frok tko/db.py

BUG=chromium:852083, chromium:860166
TEST=grep for db_mysql and get_error_class reveals no other callers;
examination of calls to |driver| at import time to ensure that they are
satisfied by the fake if necessary

Change-Id: I1c2d0e0daae6fc6b23c4e6c084c37c6602e777ed
Reviewed-on: https://chromium-review.googlesource.com/1135814
Commit-Ready: Aviv Keshet <akeshet@chromium.org>
Tested-by: Aviv Keshet <akeshet@chromium.org>
Reviewed-by: Aviv Keshet <akeshet@chromium.org>
diff --git a/tko/db.py b/tko/db.py
index 0dda40d..1e8af23 100644
--- a/tko/db.py
+++ b/tko/db.py
@@ -2,6 +2,20 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+try:
+    import MySQLdb as driver
+except ImportError:
+    # This module (tko) is unconditionally imported by autoserv,
+    # even in environments where MyQSLdb is unavailable. Thus, we
+    # need to cope with import failure here.
+    # See https://bugs.chromium.org/p/chromium/issues/detail?id=860166#c17 for
+    # context.
+    class UtterlyFakeDb(object):
+        """Lame fake of MySQLdb for import time needs of this file."""
+        OperationalError = object()
+
+    driver = UtterlyFakeDb
+
 import math
 import os
 import random
@@ -11,9 +25,8 @@
 
 import common
 from autotest_lib.client.common_lib import global_config
+from autotest_lib.client.common_lib.cros import retry
 from autotest_lib.frontend import database_settings_helper
-from autotest_lib.tko import utils
-
 
 def _log_error(msg):
     """Log an error message.
@@ -141,6 +154,22 @@
         time.sleep(delay)
 
 
+    @retry.retry(driver.OperationalError, timeout_min=10,
+                 delay_sec=5)
+    def connect(self, host, database, user, password, port):
+        """Open and return a connection to mysql database."""
+        connection_args = {
+            'host': host,
+            'user': user,
+            'db': database,
+            'passwd': password,
+            'connect_timeout': 20,
+        }
+        if port:
+            connection_args['port'] = int(port)
+        return driver.connect(**connection_args)
+
+
     def run_with_retry(self, function, *args, **dargs):
         """Call function(*args, **dargs) until either it passes
         without an operational error, or a timeout is reached.
@@ -155,14 +184,12 @@
         @param args: The arguments
         @param dargs: The named arguments.
         """
-        OperationalError = _get_error_class("OperationalError")
-
         success = False
         start_time = time.time()
         while not success:
             try:
                 result = function(*args, **dargs)
-            except OperationalError, e:
+            except driver.OperationalError, e:
                 _log_error("%s; retrying, don't panic yet"
                            % _format_operational_error(e))
                 stop_time = time.time()
@@ -173,7 +200,7 @@
                     try:
                         self._random_delay()
                         self._init_db()
-                    except OperationalError, e:
+                    except driver.OperationalError, e:
                         _log_error('%s; panic now'
                                    % _format_operational_error(e))
             else:
@@ -790,21 +817,6 @@
             return None
 
 
-def _get_db_type():
-    """Get the database type name to use from the global config."""
-    get_value = global_config.global_config.get_config_value_with_fallback
-    return "db_" + get_value("AUTOTEST_WEB", "global_db_type", "db_type",
-                             default="mysql")
-
-
-def _get_error_class(class_name):
-    """Retrieves the appropriate error class by name from the database
-    module."""
-    db_module = __import__("autotest_lib.tko." + _get_db_type(),
-                           globals(), locals(), ["driver"])
-    return getattr(db_module.driver, class_name)
-
-
 def db(*args, **dargs):
     """Creates an instance of the database class with the arguments
     provided in args and dargs, using the database type specified by
@@ -815,8 +827,4 @@
 
     @return: An db object.
     """
-    db_type = _get_db_type()
-    db_module = __import__("autotest_lib.tko." + db_type, globals(),
-                           locals(), [db_type])
-    db = getattr(db_module, db_type)(*args, **dargs)
-    return db
+    return db_sql(*args, **dargs)