package com.alibaba.druid.util;

import com.alibaba.druid.DbType;
import com.alibaba.druid.support.logging.Log;
import com.alibaba.druid.support.logging.LogFactory;
import java.io.Closeable;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.Driver;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.SQLRecoverableException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;

public final class JdbcUtils implements JdbcConstants {
   private static final Log LOG = LogFactory.getLog(JdbcUtils.class);
   private static final Properties DRIVER_URL_MAPPING = new Properties();
   private static Boolean mysql_driver_version_6 = null;

   public static void close(Connection x) {
      if (x != null) {
         try {
            if (x.isClosed()) {
               return;
            }

            x.close();
         } catch (SQLRecoverableException var2) {
         } catch (Exception e) {
            LOG.debug("close connection error", e);
         }

      }
   }

   public static void close(Statement x) {
      if (x != null) {
         try {
            x.close();
         } catch (Exception var3) {
            boolean printError = true;
            if (var3 instanceof SQLRecoverableException && "Closed Connection".equals(var3.getMessage())) {
               printError = false;
            }

            if (printError) {
               LOG.debug("close statement error", var3);
            }
         }

      }
   }

   public static void close(ResultSet x) {
      if (x != null) {
         try {
            x.close();
         } catch (Exception e) {
            LOG.debug("close result set error", e);
         }

      }
   }

   public static void close(Closeable x) {
      if (x != null) {
         try {
            x.close();
         } catch (Exception e) {
            LOG.debug("close error", e);
         }

      }
   }

   public static void close(Blob x) {
      if (x != null) {
         try {
            x.free();
         } catch (Exception e) {
            LOG.debug("close error", e);
         }

      }
   }

   public static void close(Clob x) {
      if (x != null) {
         try {
            x.free();
         } catch (Exception e) {
            LOG.debug("close error", e);
         }

      }
   }

   public static void printResultSet(ResultSet rs) throws SQLException {
      printResultSet(rs, System.out);
   }

   public static void printResultSet(ResultSet rs, PrintStream out) throws SQLException {
      printResultSet(rs, out, true, "\t");
   }

   public static void printResultSet(ResultSet rs, PrintStream out, boolean printHeader, String seperator) throws SQLException {
      ResultSetMetaData metadata = rs.getMetaData();
      int columnCount = metadata.getColumnCount();
      if (printHeader) {
         for(int columnIndex = 1; columnIndex <= columnCount; ++columnIndex) {
            if (columnIndex != 1) {
               out.print(seperator);
            }

            out.print(metadata.getColumnName(columnIndex));
         }
      }

      out.println();

      while(rs.next()) {
         for(int columnIndex = 1; columnIndex <= columnCount; ++columnIndex) {
            if (columnIndex != 1) {
               out.print(seperator);
            }

            int type = metadata.getColumnType(columnIndex);
            if (type != 12 && type != 1 && type != -9 && type != -15) {
               if (type == 91) {
                  Date date = rs.getDate(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(date.toString());
                  }
               } else if (type == -7) {
                  boolean value = rs.getBoolean(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(Boolean.toString(value));
                  }
               } else if (type == 16) {
                  boolean value = rs.getBoolean(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(Boolean.toString(value));
                  }
               } else if (type == -6) {
                  byte value = rs.getByte(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(Byte.toString(value));
                  }
               } else if (type == 5) {
                  short value = rs.getShort(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(Short.toString(value));
                  }
               } else if (type == 4) {
                  int value = rs.getInt(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(Integer.toString(value));
                  }
               } else if (type == -5) {
                  long value = rs.getLong(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(Long.toString(value));
                  }
               } else if (type == 93) {
                  out.print(String.valueOf(rs.getTimestamp(columnIndex)));
               } else if (type == 3) {
                  out.print(String.valueOf(rs.getBigDecimal(columnIndex)));
               } else if (type == 2005) {
                  out.print(String.valueOf(rs.getString(columnIndex)));
               } else if (type == 2000) {
                  Object object = rs.getObject(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(String.valueOf(object));
                  }
               } else if (type == -1) {
                  Object object = rs.getString(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else {
                     out.print(String.valueOf(object));
                  }
               } else if (type == 0) {
                  out.print("null");
               } else {
                  Object object = rs.getObject(columnIndex);
                  if (rs.wasNull()) {
                     out.print("null");
                  } else if (object instanceof byte[]) {
                     byte[] bytes = (byte[])object;
                     String text = HexBin.encode(bytes);
                     out.print(text);
                  } else {
                     out.print(String.valueOf(object));
                  }
               }
            } else {
               out.print(rs.getString(columnIndex));
            }
         }

         out.println();
      }

   }

   public static String getTypeName(int sqlType) {
      switch (sqlType) {
         case -16:
            return "LONGNVARCHAR";
         case -15:
            return "NCHAR";
         case -9:
            return "NVARCHAR";
         case -8:
            return "ROWID";
         case -7:
            return "BIT";
         case -6:
            return "TINYINT";
         case -5:
            return "BIGINT";
         case -4:
            return "LONGVARBINARY";
         case -3:
            return "VARBINARY";
         case -2:
            return "BINARY";
         case 0:
            return "NULL";
         case 1:
            return "CHAR";
         case 2:
            return "NUMERIC";
         case 3:
            return "DECIMAL";
         case 4:
            return "INTEGER";
         case 5:
            return "SMALLINT";
         case 6:
            return "FLOAT";
         case 7:
            return "REAL";
         case 8:
            return "DOUBLE";
         case 12:
            return "VARCHAR";
         case 16:
            return "BOOLEAN";
         case 70:
            return "DATALINK";
         case 91:
            return "DATE";
         case 92:
            return "TIME";
         case 93:
            return "TIMESTAMP";
         case 2000:
            return "JAVA_OBJECT";
         case 2001:
            return "DISTINCT";
         case 2002:
            return "STRUCT";
         case 2003:
            return "ARRAY";
         case 2004:
            return "BLOB";
         case 2005:
            return "CLOB";
         case 2006:
            return "REF";
         case 2009:
            return "SQLXML";
         case 2011:
            return "NCLOB";
         default:
            return "OTHER";
      }
   }

   public static String getDriverClassName(String rawUrl) throws SQLException {
      if (rawUrl == null) {
         return null;
      } else if (rawUrl.startsWith("jdbc:derby:")) {
         return "org.apache.derby.jdbc.EmbeddedDriver";
      } else if (rawUrl.startsWith("jdbc:mysql:")) {
         if (mysql_driver_version_6 == null) {
            mysql_driver_version_6 = Utils.loadClass("com.mysql.cj.jdbc.Driver") != null;
         }

         return mysql_driver_version_6 ? "com.mysql.cj.jdbc.Driver" : "com.mysql.jdbc.Driver";
      } else if (rawUrl.startsWith("jdbc:log4jdbc:")) {
         return "net.sf.log4jdbc.DriverSpy";
      } else if (rawUrl.startsWith("jdbc:mariadb:")) {
         return "org.mariadb.jdbc.Driver";
      } else if (!rawUrl.startsWith("jdbc:oracle:") && !rawUrl.startsWith("JDBC:oracle:")) {
         if (rawUrl.startsWith("jdbc:alibaba:oracle:")) {
            return "com.alibaba.jdbc.AlibabaDriver";
         } else if (rawUrl.startsWith("jdbc:oceanbase:")) {
            return "com.alipay.oceanbase.jdbc.Driver";
         } else if (rawUrl.startsWith("jdbc:microsoft:")) {
            return "com.microsoft.jdbc.sqlserver.SQLServerDriver";
         } else if (rawUrl.startsWith("jdbc:sqlserver:")) {
            return "com.microsoft.sqlserver.jdbc.SQLServerDriver";
         } else if (rawUrl.startsWith("jdbc:sybase:Tds:")) {
            return "com.sybase.jdbc2.jdbc.SybDriver";
         } else if (rawUrl.startsWith("jdbc:jtds:")) {
            return "net.sourceforge.jtds.jdbc.Driver";
         } else if (!rawUrl.startsWith("jdbc:fake:") && !rawUrl.startsWith("jdbc:mock:")) {
            if (rawUrl.startsWith("jdbc:postgresql:")) {
               return "org.postgresql.Driver";
            } else if (rawUrl.startsWith("jdbc:edb:")) {
               return "com.edb.Driver";
            } else if (rawUrl.startsWith("jdbc:odps:")) {
               return "com.aliyun.odps.jdbc.OdpsDriver";
            } else if (rawUrl.startsWith("jdbc:hsqldb:")) {
               return "org.hsqldb.jdbcDriver";
            } else if (rawUrl.startsWith("jdbc:db2:")) {
               String prefix = "jdbc:db2:";
               if (rawUrl.startsWith(prefix + "//")) {
                  return "com.ibm.db2.jcc.DB2Driver";
               } else {
                  String suffix = rawUrl.substring(prefix.length());
                  return suffix.indexOf(58) > 0 ? "COM.ibm.db2.jdbc.net.DB2Driver" : "COM.ibm.db2.jdbc.app.DB2Driver";
               }
            } else if (rawUrl.startsWith("jdbc:sqlite:")) {
               return "org.sqlite.JDBC";
            } else if (rawUrl.startsWith("jdbc:ingres:")) {
               return "com.ingres.jdbc.IngresDriver";
            } else if (rawUrl.startsWith("jdbc:h2:")) {
               return "org.h2.Driver";
            } else if (rawUrl.startsWith("jdbc:mckoi:")) {
               return "com.mckoi.JDBCDriver";
            } else if (rawUrl.startsWith("jdbc:cloudscape:")) {
               return "COM.cloudscape.core.JDBCDriver";
            } else if (rawUrl.startsWith("jdbc:informix-sqli:")) {
               return "com.informix.jdbc.IfxDriver";
            } else if (rawUrl.startsWith("jdbc:timesten:")) {
               return "com.timesten.jdbc.TimesTenDriver";
            } else if (rawUrl.startsWith("jdbc:as400:")) {
               return "com.ibm.as400.access.AS400JDBCDriver";
            } else if (rawUrl.startsWith("jdbc:sapdb:")) {
               return "com.sap.dbtech.jdbc.DriverSapDB";
            } else if (rawUrl.startsWith("jdbc:JSQLConnect:")) {
               return "com.jnetdirect.jsql.JSQLDriver";
            } else if (rawUrl.startsWith("jdbc:JTurbo:")) {
               return "com.newatlanta.jturbo.driver.Driver";
            } else if (rawUrl.startsWith("jdbc:firebirdsql:")) {
               return "org.firebirdsql.jdbc.FBDriver";
            } else if (rawUrl.startsWith("jdbc:interbase:")) {
               return "interbase.interclient.Driver";
            } else if (rawUrl.startsWith("jdbc:pointbase:")) {
               return "com.pointbase.jdbc.jdbcUniversalDriver";
            } else if (rawUrl.startsWith("jdbc:edbc:")) {
               return "ca.edbc.jdbc.EdbcDriver";
            } else if (rawUrl.startsWith("jdbc:mimer:multi1:")) {
               return "com.mimer.jdbc.Driver";
            } else if (rawUrl.startsWith("jdbc:dm:")) {
               return "dm.jdbc.driver.DmDriver";
            } else if (rawUrl.startsWith("jdbc:kingbase:")) {
               return "com.kingbase.Driver";
            } else if (rawUrl.startsWith("jdbc:kingbase8:")) {
               return "om.kingbase8.Driver";
            } else if (rawUrl.startsWith("jdbc:gbase:")) {
               return "com.gbase.jdbc.Driver";
            } else if (rawUrl.startsWith("jdbc:xugu:")) {
               return "com.xugu.cloudjdbc.Driver";
            } else if (rawUrl.startsWith("jdbc:hive:")) {
               return "org.apache.hive.jdbc.HiveDriver";
            } else if (rawUrl.startsWith("jdbc:hive2:")) {
               return "org.apache.hive.jdbc.HiveDriver";
            } else if (rawUrl.startsWith("jdbc:phoenix:thin:")) {
               return "org.apache.phoenix.queryserver.client.Driver";
            } else if (rawUrl.startsWith("jdbc:phoenix://")) {
               return "org.apache.phoenix.jdbc.PhoenixDriver";
            } else if (rawUrl.startsWith("jdbc:kylin:")) {
               return "org.apache.kylin.jdbc.Driver";
            } else if (rawUrl.startsWith("jdbc:elastic:")) {
               return "com.alibaba.xdriver.elastic.jdbc.ElasticDriver";
            } else if (rawUrl.startsWith("jdbc:clickhouse:")) {
               return "ru.yandex.clickhouse.ClickHouseDriver";
            } else if (rawUrl.startsWith("jdbc:presto:")) {
               return "com.facebook.presto.jdbc.PrestoDriver";
            } else if (rawUrl.startsWith("jdbc:trino:")) {
               return "io.trino.jdbc.TrinoDriver";
            } else if (rawUrl.startsWith("jdbc:inspur:")) {
               return "com.inspur.jdbc.KdDriver";
            } else if (rawUrl.startsWith("jdbc:polardb")) {
               return "com.aliyun.polardb.Driver";
            } else if (rawUrl.startsWith("jdbc:highgo:")) {
               return "com.highgo.jdbc.Driver";
            } else {
               throw new SQLException("unknown jdbc driver : " + rawUrl);
            }
         } else {
            return "com.alibaba.druid.mock.MockDriver";
         }
      } else {
         return "oracle.jdbc.OracleDriver";
      }
   }

   public static DbType getDbTypeRaw(String rawUrl, String driverClassName) {
      if (rawUrl == null) {
         return null;
      } else if (!rawUrl.startsWith("jdbc:derby:") && !rawUrl.startsWith("jdbc:log4jdbc:derby:")) {
         if (!rawUrl.startsWith("jdbc:mysql:") && !rawUrl.startsWith("jdbc:cobar:") && !rawUrl.startsWith("jdbc:log4jdbc:mysql:")) {
            if (rawUrl.startsWith("jdbc:mariadb:")) {
               return DbType.mariadb;
            } else if (!rawUrl.startsWith("jdbc:oracle:") && !rawUrl.startsWith("jdbc:log4jdbc:oracle:")) {
               if (rawUrl.startsWith("jdbc:alibaba:oracle:")) {
                  return DbType.ali_oracle;
               } else if (rawUrl.startsWith("jdbc:oceanbase:oracle:")) {
                  return DbType.oceanbase_oracle;
               } else if (rawUrl.startsWith("jdbc:oceanbase:")) {
                  return DbType.oceanbase;
               } else if (!rawUrl.startsWith("jdbc:microsoft:") && !rawUrl.startsWith("jdbc:log4jdbc:microsoft:")) {
                  if (!rawUrl.startsWith("jdbc:sqlserver:") && !rawUrl.startsWith("jdbc:log4jdbc:sqlserver:")) {
                     if (!rawUrl.startsWith("jdbc:sybase:Tds:") && !rawUrl.startsWith("jdbc:log4jdbc:sybase:")) {
                        if (!rawUrl.startsWith("jdbc:jtds:") && !rawUrl.startsWith("jdbc:log4jdbc:jtds:")) {
                           if (!rawUrl.startsWith("jdbc:fake:") && !rawUrl.startsWith("jdbc:mock:")) {
                              if (!rawUrl.startsWith("jdbc:postgresql:") && !rawUrl.startsWith("jdbc:log4jdbc:postgresql:")) {
                                 if (rawUrl.startsWith("jdbc:edb:")) {
                                    return DbType.edb;
                                 } else if (!rawUrl.startsWith("jdbc:hsqldb:") && !rawUrl.startsWith("jdbc:log4jdbc:hsqldb:")) {
                                    if (rawUrl.startsWith("jdbc:odps:")) {
                                       return DbType.odps;
                                    } else if (rawUrl.startsWith("jdbc:db2:")) {
                                       return DbType.db2;
                                    } else if (rawUrl.startsWith("jdbc:sqlite:")) {
                                       return DbType.sqlite;
                                    } else if (rawUrl.startsWith("jdbc:ingres:")) {
                                       return DbType.ingres;
                                    } else if (!rawUrl.startsWith("jdbc:h2:") && !rawUrl.startsWith("jdbc:log4jdbc:h2:")) {
                                       if (rawUrl.startsWith("jdbc:mckoi:")) {
                                          return DbType.mock;
                                       } else if (rawUrl.startsWith("jdbc:cloudscape:")) {
                                          return DbType.cloudscape;
                                       } else if (!rawUrl.startsWith("jdbc:informix-sqli:") && !rawUrl.startsWith("jdbc:log4jdbc:informix-sqli:")) {
                                          if (rawUrl.startsWith("jdbc:timesten:")) {
                                             return DbType.timesten;
                                          } else if (rawUrl.startsWith("jdbc:as400:")) {
                                             return DbType.as400;
                                          } else if (rawUrl.startsWith("jdbc:sapdb:")) {
                                             return DbType.sapdb;
                                          } else if (rawUrl.startsWith("jdbc:JSQLConnect:")) {
                                             return DbType.JSQLConnect;
                                          } else if (rawUrl.startsWith("jdbc:JTurbo:")) {
                                             return DbType.JTurbo;
                                          } else if (rawUrl.startsWith("jdbc:firebirdsql:")) {
                                             return DbType.firebirdsql;
                                          } else if (rawUrl.startsWith("jdbc:interbase:")) {
                                             return DbType.interbase;
                                          } else if (rawUrl.startsWith("jdbc:pointbase:")) {
                                             return DbType.pointbase;
                                          } else if (rawUrl.startsWith("jdbc:edbc:")) {
                                             return DbType.edbc;
                                          } else if (rawUrl.startsWith("jdbc:mimer:multi1:")) {
                                             return DbType.mimer;
                                          } else if (rawUrl.startsWith("jdbc:dm:")) {
                                             return JdbcConstants.DM;
                                          } else if (!rawUrl.startsWith("jdbc:kingbase:") && !rawUrl.startsWith("jdbc:kingbase8:")) {
                                             if (rawUrl.startsWith("jdbc:gbase:")) {
                                                return JdbcConstants.GBASE;
                                             } else if (rawUrl.startsWith("jdbc:xugu:")) {
                                                return JdbcConstants.XUGU;
                                             } else if (rawUrl.startsWith("jdbc:log4jdbc:")) {
                                                return DbType.log4jdbc;
                                             } else if (rawUrl.startsWith("jdbc:hive:")) {
                                                return DbType.hive;
                                             } else if (rawUrl.startsWith("jdbc:hive2:")) {
                                                return DbType.hive;
                                             } else if (rawUrl.startsWith("jdbc:phoenix:")) {
                                                return DbType.phoenix;
                                             } else if (rawUrl.startsWith("jdbc:kylin:")) {
                                                return DbType.kylin;
                                             } else if (rawUrl.startsWith("jdbc:elastic:")) {
                                                return DbType.elastic_search;
                                             } else if (rawUrl.startsWith("jdbc:clickhouse:")) {
                                                return DbType.clickhouse;
                                             } else if (rawUrl.startsWith("jdbc:presto:")) {
                                                return DbType.presto;
                                             } else if (rawUrl.startsWith("jdbc:inspur:")) {
                                                return DbType.kdb;
                                             } else if (rawUrl.startsWith("jdbc:polardb")) {
                                                return DbType.polardb;
                                             } else {
                                                return rawUrl.startsWith("jdbc:highgo:") ? DbType.highgo : null;
                                             }
                                          } else {
                                             return JdbcConstants.KINGBASE;
                                          }
                                       } else {
                                          return DbType.informix;
                                       }
                                    } else {
                                       return DbType.h2;
                                    }
                                 } else {
                                    return DbType.hsql;
                                 }
                              } else {
                                 return DbType.postgresql;
                              }
                           } else {
                              return DbType.mock;
                           }
                        } else {
                           return DbType.jtds;
                        }
                     } else {
                        return DbType.sybase;
                     }
                  } else {
                     return DbType.sqlserver;
                  }
               } else {
                  return DbType.sqlserver;
               }
            } else {
               return DbType.oracle;
            }
         } else {
            return DbType.mysql;
         }
      } else {
         return DbType.derby;
      }
   }

   public static String getDbType(String rawUrl, String driverClassName) {
      DbType dbType = getDbTypeRaw(rawUrl, driverClassName);
      return dbType == null ? null : dbType.name();
   }

   public static Driver createDriver(String driverClassName) throws SQLException {
      return createDriver((ClassLoader)null, driverClassName);
   }

   public static Driver createDriver(ClassLoader classLoader, String driverClassName) throws SQLException {
      Class<?> clazz = null;
      if (classLoader != null) {
         try {
            clazz = classLoader.loadClass(driverClassName);
         } catch (ClassNotFoundException var8) {
         }
      }

      if (clazz == null) {
         try {
            ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
            if (contextLoader != null) {
               clazz = contextLoader.loadClass(driverClassName);
            }
         } catch (ClassNotFoundException var7) {
         }
      }

      if (clazz == null) {
         try {
            clazz = Class.forName(driverClassName);
         } catch (ClassNotFoundException e) {
            throw new SQLException(e.getMessage(), e);
         }
      }

      try {
         return (Driver)clazz.newInstance();
      } catch (IllegalAccessException e) {
         throw new SQLException(e.getMessage(), e);
      } catch (InstantiationException e) {
         throw new SQLException(e.getMessage(), e);
      }
   }

   public static int executeUpdate(DataSource dataSource, String sql, Object... parameters) throws SQLException {
      return executeUpdate(dataSource, sql, Arrays.asList(parameters));
   }

   public static int executeUpdate(DataSource dataSource, String sql, List<Object> parameters) throws SQLException {
      Connection conn = null;

      int var4;
      try {
         conn = dataSource.getConnection();
         var4 = executeUpdate(conn, sql, parameters);
      } finally {
         close(conn);
      }

      return var4;
   }

   public static int executeUpdate(Connection conn, String sql, List<Object> parameters) throws SQLException {
      PreparedStatement stmt = null;

      int updateCount;
      try {
         stmt = conn.prepareStatement(sql);
         setParameters(stmt, parameters);
         updateCount = stmt.executeUpdate();
      } finally {
         close((Statement)stmt);
      }

      return updateCount;
   }

   public static void execute(DataSource dataSource, String sql, Object... parameters) throws SQLException {
      execute(dataSource, sql, Arrays.asList(parameters));
   }

   public static void execute(DataSource dataSource, String sql, List<Object> parameters) throws SQLException {
      Connection conn = null;

      try {
         conn = dataSource.getConnection();
         execute(conn, sql, parameters);
      } finally {
         close(conn);
      }

   }

   public static void execute(Connection conn, String sql) throws SQLException {
      execute(conn, sql, Collections.emptyList());
   }

   public static void execute(Connection conn, String sql, List<Object> parameters) throws SQLException {
      PreparedStatement stmt = null;

      try {
         stmt = conn.prepareStatement(sql);
         setParameters(stmt, parameters);
         stmt.executeUpdate();
      } finally {
         close((Statement)stmt);
      }

   }

   public static List<Map<String, Object>> executeQuery(DataSource dataSource, String sql, Object... parameters) throws SQLException {
      return executeQuery(dataSource, sql, Arrays.asList(parameters));
   }

   public static List<Map<String, Object>> executeQuery(DataSource dataSource, String sql, List<Object> parameters) throws SQLException {
      Connection conn = null;

      List var4;
      try {
         conn = dataSource.getConnection();
         var4 = executeQuery(conn, sql, parameters);
      } finally {
         close(conn);
      }

      return var4;
   }

   public static List<Map<String, Object>> executeQuery(Connection conn, String sql, List<Object> parameters) throws SQLException {
      List<Map<String, Object>> rows = new ArrayList();
      PreparedStatement stmt = null;
      ResultSet rs = null;

      try {
         stmt = conn.prepareStatement(sql);
         setParameters(stmt, parameters);
         rs = stmt.executeQuery();
         ResultSetMetaData rsMeta = rs.getMetaData();

         while(rs.next()) {
            Map<String, Object> row = new LinkedHashMap();
            int i = 0;

            for(int size = rsMeta.getColumnCount(); i < size; ++i) {
               String columName = rsMeta.getColumnLabel(i + 1);
               Object value = rs.getObject(i + 1);
               row.put(columName, value);
            }

            rows.add(row);
         }
      } finally {
         close(rs);
         close((Statement)stmt);
      }

      return rows;
   }

   private static void setParameters(PreparedStatement stmt, List<Object> parameters) throws SQLException {
      int i = 0;

      for(int size = parameters.size(); i < size; ++i) {
         Object param = parameters.get(i);
         stmt.setObject(i + 1, param);
      }

   }

   public static void insertToTable(DataSource dataSource, String tableName, Map<String, Object> data) throws SQLException {
      Connection conn = null;

      try {
         conn = dataSource.getConnection();
         insertToTable(conn, tableName, data);
      } finally {
         close(conn);
      }

   }

   public static void insertToTable(Connection conn, String tableName, Map<String, Object> data) throws SQLException {
      String sql = makeInsertToTableSql(tableName, data.keySet());
      List<Object> parameters = new ArrayList(data.values());
      execute(conn, sql, parameters);
   }

   public static String makeInsertToTableSql(String tableName, Collection<String> names) {
      StringBuilder sql = (new StringBuilder()).append("insert into ").append(tableName).append("(");
      int nameCount = 0;

      for(String name : names) {
         if (nameCount > 0) {
            sql.append(",");
         }

         sql.append(name);
         ++nameCount;
      }

      sql.append(") values (");

      for(int i = 0; i < nameCount; ++i) {
         if (i != 0) {
            sql.append(",");
         }

         sql.append("?");
      }

      sql.append(")");
      return sql.toString();
   }

   public static <T> void executeQuery(DataSource dataSource, ResultSetConsumer<T> consumer, String sql, Object... parameters) throws SQLException {
      Connection conn = null;
      PreparedStatement stmt = null;
      ResultSet rs = null;

      try {
         conn = dataSource.getConnection();
         stmt = conn.prepareStatement(sql);

         for(int i = 0; i < parameters.length; ++i) {
            stmt.setObject(i + 1, parameters[i]);
         }

         rs = stmt.executeQuery();

         while(rs.next()) {
            if (consumer != null) {
               T object = consumer.apply(rs);
               consumer.accept(object);
            }
         }
      } finally {
         close(rs);
         close((Statement)stmt);
         close(conn);
      }

   }

   public static List<String> showTables(Connection conn, DbType dbType) throws SQLException {
      if (DbType.mysql != dbType && DbType.oceanbase != dbType) {
         if (dbType != DbType.oracle && dbType != DbType.oceanbase_oracle) {
            if (dbType == DbType.postgresql) {
               return PGUtils.showTables(conn);
            } else {
               throw new SQLException("show tables dbType not support for " + dbType);
            }
         } else {
            return OracleUtils.showTables(conn);
         }
      } else {
         return MySqlUtils.showTables(conn);
      }
   }

   public static String getCreateTableScript(Connection conn, DbType dbType) throws SQLException {
      return getCreateTableScript(conn, dbType, true, true);
   }

   public static String getCreateTableScript(Connection conn, DbType dbType, boolean sorted, boolean simplify) throws SQLException {
      if (DbType.mysql != dbType && DbType.oceanbase != dbType) {
         if (dbType != DbType.oracle && dbType != DbType.oceanbase_oracle) {
            throw new SQLException("getCreateTableScript dbType not support for " + dbType);
         } else {
            return OracleUtils.getCreateTableScript(conn, sorted, simplify);
         }
      } else {
         return MySqlUtils.getCreateTableScript(conn, sorted, simplify);
      }
   }

   public static boolean isMySqlDriver(String driverClassName) {
      return driverClassName.equals("com.mysql.jdbc.Driver") || driverClassName.equals("com.mysql.cj.jdbc.Driver") || driverClassName.equals("com.mysql.jdbc.");
   }

   public static boolean isOracleDbType(String dbType) {
      return DbType.oracle.name().equals(dbType) || DbType.oceanbase.name().equals(dbType) || DbType.ali_oracle.name().equalsIgnoreCase(dbType);
   }

   public static boolean isOracleDbType(DbType dbType) {
      return DbType.oracle == dbType || DbType.oceanbase == dbType || DbType.ali_oracle == dbType;
   }

   public static boolean isDmDbType(DbType dbType) {
      return DbType.dm == dbType;
   }

   public static boolean isMysqlDbType(String dbTypeName) {
      return isMysqlDbType(DbType.of(dbTypeName));
   }

   public static boolean isMysqlDbType(DbType dbType) {
      if (dbType == null) {
         return false;
      } else {
         switch (dbType) {
            case mysql:
            case oceanbase:
            case drds:
            case mariadb:
            case h2:
               return true;
            default:
               return false;
         }
      }
   }

   public static boolean isPgsqlDbType(String dbTypeName) {
      return isPgsqlDbType(DbType.of(dbTypeName));
   }

   public static boolean isPgsqlDbType(DbType dbType) {
      if (dbType == null) {
         return false;
      } else {
         switch (dbType) {
            case postgresql:
            case edb:
            case polardb:
               return true;
            default:
               return false;
         }
      }
   }

   public static boolean isSqlserverDbType(String dbTypeName) {
      return isSqlserverDbType(DbType.of(dbTypeName));
   }

   public static boolean isSqlserverDbType(DbType dbType) {
      if (dbType == null) {
         return false;
      } else {
         switch (dbType) {
            case sqlserver:
            case jtds:
               return true;
            default:
               return false;
         }
      }
   }

   static {
      try {
         ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader();
         Properties property;
         if (ctxClassLoader != null) {
            for(Enumeration<URL> e = ctxClassLoader.getResources("META-INF/druid-driver.properties"); e.hasMoreElements(); DRIVER_URL_MAPPING.putAll(property)) {
               URL url = (URL)e.nextElement();
               property = new Properties();
               InputStream is = null;

               try {
                  is = url.openStream();
                  property.load(is);
               } finally {
                  close((Closeable)is);
               }
            }
         }
      } catch (Exception e) {
         LOG.error("load druid-driver.properties error", e);
      }

   }
}
