vihangk1 commented on a change in pull request #1470:
URL: https://github.com/apache/hive/pull/1470#discussion_r499869697
##########
File path:
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java
##########
@@ -20,71 +20,666 @@
import java.sql.SQLException;
import java.sql.SQLTransactionRollbackException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
-/** Database product infered via JDBC. */
-public enum DatabaseProduct {
- DERBY, MYSQL, POSTGRES, ORACLE, SQLSERVER, OTHER;
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars;
+import org.apache.hadoop.util.ReflectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+
+/** Database product inferred via JDBC. Encapsulates all SQL logic associated
with
+ * the database product.
+ * This class is a singleton, which is instantiated the first time
+ * method determineDatabaseProduct is invoked.
+ * Tests that need to create multiple instances can use the reset method
+ * */
+public class DatabaseProduct implements Configurable {
+ static final private Logger LOG =
LoggerFactory.getLogger(DatabaseProduct.class.getName());
+
+ private static enum DbType {DERBY, MYSQL, POSTGRES, ORACLE, SQLSERVER,
CUSTOM, UNDEFINED};
+ public DbType dbType;
+
+ // Singleton instance
+ private static DatabaseProduct theDatabaseProduct;
+
+ Configuration myConf;
+ /**
+ * Protected constructor for singleton class
+ * @param id
+ */
+ protected DatabaseProduct() {}
+
+ public static final String DERBY_NAME = "derby";
+ public static final String SQL_SERVER_NAME = "microsoft sql server";
+ public static final String MYSQL_NAME = "mysql";
+ public static final String POSTGRESQL_NAME = "postgresql";
+ public static final String ORACLE_NAME = "oracle";
+ public static final String UNDEFINED_NAME = "other";
+
/**
* Determine the database product type
* @param productName string to defer database connection
* @return database product type
*/
- public static DatabaseProduct determineDatabaseProduct(String productName)
throws SQLException {
- if (productName == null) {
- return OTHER;
+ public static DatabaseProduct determineDatabaseProduct(String productName,
Configuration c) {
+ DbType dbt;
+
+ if (theDatabaseProduct != null) {
+ Preconditions.checkState(theDatabaseProduct.dbType ==
getDbType(productName));
+ return theDatabaseProduct;
}
+
+ // This method may be invoked by concurrent connections
+ synchronized (DatabaseProduct.class) {
+
+ if (productName == null) {
+ productName = UNDEFINED_NAME;
+ }
+
+ dbt = getDbType(productName);
+
+ // Check for null again in case of race condition
+ if (theDatabaseProduct == null) {
+ final Configuration conf = c!= null ? c :
MetastoreConf.newMetastoreConf();
+ // Check if we are using an external database product
+ boolean isExternal = MetastoreConf.getBoolVar(conf,
ConfVars.USE_CUSTOM_RDBMS);
+
+ if (isExternal) {
+ // The DatabaseProduct will be created by instantiating an external
class via
+ // reflection. The external class can override any method in the
current class
+ String className = MetastoreConf.getVar(conf,
ConfVars.CUSTOM_RDBMS_CLASSNAME);
+
+ if (className != null) {
+ try {
+ theDatabaseProduct = (DatabaseProduct)
+ ReflectionUtils.newInstance(Class.forName(className), conf);
+
+ LOG.info(String.format("Using custom RDBMS %s. Overriding
DbType: %s", className, dbt));
+ dbt = DbType.CUSTOM;
+ }catch (Exception e) {
+ LOG.warn("Caught exception instantiating custom database
product. Reverting to " + dbt, e);
+ }
+ }
+ else {
Review comment:
nit, the else could go in the same line as 113 as per the coding
conventions.
##########
File path:
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/DatabaseProduct.java
##########
@@ -20,71 +20,666 @@
import java.sql.SQLException;
import java.sql.SQLTransactionRollbackException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
-/** Database product infered via JDBC. */
-public enum DatabaseProduct {
- DERBY, MYSQL, POSTGRES, ORACLE, SQLSERVER, OTHER;
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hive.metastore.api.MetaException;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf;
+import org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars;
+import org.apache.hadoop.util.ReflectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+
+/** Database product inferred via JDBC. Encapsulates all SQL logic associated
with
+ * the database product.
+ * This class is a singleton, which is instantiated the first time
+ * method determineDatabaseProduct is invoked.
+ * Tests that need to create multiple instances can use the reset method
+ * */
+public class DatabaseProduct implements Configurable {
+ static final private Logger LOG =
LoggerFactory.getLogger(DatabaseProduct.class.getName());
+
+ private static enum DbType {DERBY, MYSQL, POSTGRES, ORACLE, SQLSERVER,
CUSTOM, UNDEFINED};
+ public DbType dbType;
+
+ // Singleton instance
+ private static DatabaseProduct theDatabaseProduct;
+
+ Configuration myConf;
+ /**
+ * Protected constructor for singleton class
+ * @param id
+ */
+ protected DatabaseProduct() {}
+
+ public static final String DERBY_NAME = "derby";
+ public static final String SQL_SERVER_NAME = "microsoft sql server";
+ public static final String MYSQL_NAME = "mysql";
+ public static final String POSTGRESQL_NAME = "postgresql";
+ public static final String ORACLE_NAME = "oracle";
+ public static final String UNDEFINED_NAME = "other";
+
/**
* Determine the database product type
* @param productName string to defer database connection
* @return database product type
*/
- public static DatabaseProduct determineDatabaseProduct(String productName)
throws SQLException {
- if (productName == null) {
- return OTHER;
+ public static DatabaseProduct determineDatabaseProduct(String productName,
Configuration c) {
+ DbType dbt;
+
+ if (theDatabaseProduct != null) {
+ Preconditions.checkState(theDatabaseProduct.dbType ==
getDbType(productName));
+ return theDatabaseProduct;
}
+
+ // This method may be invoked by concurrent connections
+ synchronized (DatabaseProduct.class) {
+
+ if (productName == null) {
+ productName = UNDEFINED_NAME;
+ }
+
+ dbt = getDbType(productName);
+
+ // Check for null again in case of race condition
+ if (theDatabaseProduct == null) {
+ final Configuration conf = c!= null ? c :
MetastoreConf.newMetastoreConf();
+ // Check if we are using an external database product
+ boolean isExternal = MetastoreConf.getBoolVar(conf,
ConfVars.USE_CUSTOM_RDBMS);
+
+ if (isExternal) {
+ // The DatabaseProduct will be created by instantiating an external
class via
+ // reflection. The external class can override any method in the
current class
+ String className = MetastoreConf.getVar(conf,
ConfVars.CUSTOM_RDBMS_CLASSNAME);
+
+ if (className != null) {
+ try {
+ theDatabaseProduct = (DatabaseProduct)
+ ReflectionUtils.newInstance(Class.forName(className), conf);
+
+ LOG.info(String.format("Using custom RDBMS %s. Overriding
DbType: %s", className, dbt));
+ dbt = DbType.CUSTOM;
+ }catch (Exception e) {
+ LOG.warn("Caught exception instantiating custom database
product. Reverting to " + dbt, e);
Review comment:
Is there a good reason to catch the exception and reverting the dbt?
Should'nt we throw a MetaException so that HMS doesn't start if the
configuration is invalid.
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]