net.snowflake.client.jdbc.SnowflakeDriver Maven / Gradle / Ivy
/*
* Copyright (c) 2012-2019 Snowflake Computing Inc. All rights reserved.
*/
package net.snowflake.client.jdbc;
import net.snowflake.common.core.ResourceBundleManager;
import net.snowflake.common.core.SqlState;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.List;
import java.util.Properties;
/**
* JDBC Driver implementation of Snowflake for production.
* To use this driver, specify the following URL:
* jdbc:snowflake://host:port
*
* Note: don't add logger to this class since logger init will potentially
* break driver class loading
*/
public class SnowflakeDriver implements Driver
{
static SnowflakeDriver INSTANCE;
public final static Properties EMPTY_PROPERTIES = new Properties();
public static String implementVersion = null;
static int majorVersion = 0;
static int minorVersion = 0;
static long patchVersion = 0;
protected static boolean disableIncidents = false;
private static boolean disableArrowResultFormat = false;
private static String disableArrowResultFormatMessage;
private static final ResourceBundleManager versionResourceBundleManager
= ResourceBundleManager.getSingleton("net.snowflake.client.jdbc.version");
static
{
try
{
DriverManager.registerDriver(INSTANCE = new SnowflakeDriver());
}
catch (SQLException ex)
{
throw new IllegalStateException("Unable to register "
+ SnowflakeDriver.class.getName(), ex);
}
initializeArrowSupport();
/*
* Get the manifest properties here.
*/
initializeClientVersionFromManifest();
}
/**
* try to initialize Arrow support
* if fails, JDBC is going to use the legacy format
*/
private static void initializeArrowSupport()
{
try
{
// this is required to enable direct memory usage for Arrow buffers in Java
System.setProperty("io.netty.tryReflectionSetAccessible", "true");
}
catch (Throwable t)
{
// fail to enable required feature for Arrow
disableArrowResultFormat = true;
disableArrowResultFormatMessage = t.getLocalizedMessage();
}
}
static private void initializeClientVersionFromManifest()
{
/*
* Get JDBC version numbers from version.properties in snowflake-jdbc
*/
try
{
implementVersion = versionResourceBundleManager.getLocalizedMessage("version");
// parse implementation version major.minor.change
if (implementVersion != null)
{
String[] versionBreakdown = implementVersion.split("\\.");
if (versionBreakdown.length == 3)
{
majorVersion = Integer.parseInt(versionBreakdown[0]);
minorVersion = Integer.parseInt(versionBreakdown[1]);
patchVersion = Long.parseLong(versionBreakdown[2]);
}
else
{
throw new SnowflakeSQLException(SqlState.INTERNAL_ERROR,
ErrorCode.INTERNAL_ERROR.getMessageCode(),
"Invalid Snowflake JDBC Version: " + implementVersion);
}
}
else
{
throw new SnowflakeSQLException(SqlState.INTERNAL_ERROR,
ErrorCode.INTERNAL_ERROR.getMessageCode(),
"Snowflake JDBC Version is not set. " +
"Ensure version.properties is included.");
}
}
catch (Throwable ex)
{
}
}
public static boolean isDisableArrowResultFormat()
{
return disableArrowResultFormat;
}
public static String getDisableArrowResultFormatMessage()
{
return disableArrowResultFormatMessage;
}
/**
* Checks whether a given url is in a valid format.
*
* The current uri format is: jdbc:snowflake://[host[:port]]
*
* jdbc:snowflake:// - run in embedded mode jdbc:snowflake://localhost -
* connect to localhost default port (8080)
*
* jdbc:snowflake://localhost:8080- connect to localhost port 8080
*
* @param url url of the database including host and port
* @return true if the url is valid
*/
@Override
public boolean acceptsURL(String url)
{
return SnowflakeConnectString.parse(url, EMPTY_PROPERTIES).isValid();
}
/**
* Connect method
*
* @param url jdbc url
* @param info addition info for passing database/schema names
* @return connection
* @throws SQLException if failed to create a snowflake connection
*/
@Override
public Connection connect(String url, Properties info) throws SQLException
{
SnowflakeConnectString conStr = SnowflakeConnectString.parse(url, info);
if (!conStr.isValid())
{
return null;
}
return new SnowflakeConnectionV1(url, info);
}
@Override
public int getMajorVersion()
{
return majorVersion;
}
@Override
public int getMinorVersion()
{
return minorVersion;
}
@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
throws SQLException
{
DriverPropertyInfo[] retVal;
if (url == null || url.isEmpty())
{
retVal = new DriverPropertyInfo[1];
retVal[0] = new DriverPropertyInfo("serverURL", null);
retVal[0].description = "server URL in form of ://:/";
return retVal;
}
Connection con = new SnowflakeConnectionV1(url, info, true);
List missingProperties = ((SnowflakeConnectionV1) con).returnMissingProperties();
con.close();
retVal = new DriverPropertyInfo[missingProperties.size()];
retVal = missingProperties.toArray(retVal);
return retVal;
}
@Override
public boolean jdbcCompliant()
{
return false;
}
@Override
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException
{
return null;
}
public static boolean isDisableIncidents()
{
return disableIncidents;
}
public static void setDisableIncidents(
boolean throttleIncidents)
{
SnowflakeDriver.disableIncidents =
throttleIncidents;
}
public final static void main(String[] args)
{
if (args.length > 0 && "--version".equals(args[0]))
{
Package pkg = Package.getPackage("net.snowflake.client.jdbc");
if (pkg != null)
{
System.out.println(pkg.getImplementationVersion());
}
}
}
}