Skip to content

Commit

Permalink
Feature | Add new connection property 'useFmtOnly' to retrieve Parame…
Browse files Browse the repository at this point in the history
…ter Metadata

Adds a new way to query metadata for instances where sp_describe_undeclared_parameters fail.
  • Loading branch information
rene-ye authored Jun 11, 2019
1 parent 9ff36a5 commit 7ebbc94
Show file tree
Hide file tree
Showing 27 changed files with 2,634 additions and 415 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ dependencies {
compileOnly 'com.microsoft.azure:azure-keyvault:1.2.0',
'com.microsoft.azure:azure-keyvault-webkey:1.2.0',
'com.microsoft.rest:client-runtime:1.6.5',
'com.microsoft.azure:adal4j:1.6.3'
'com.microsoft.azure:adal4j:1.6.3',
'org.antlr:antlr4-runtime:4.7.2'
testCompile 'org.junit.platform:junit-platform-console:1.4.0',
'org.junit.platform:junit-platform-commons:1.4.0',
'org.junit.platform:junit-platform-engine:1.4.0',
Expand Down
9 changes: 9 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
<rest.client.version>1.6.7</rest.client.version>
<osgi.core.version>6.0.0</osgi.core.version>
<osgi.comp.version>5.0.0</osgi.comp.version>
<antlr.runtime.version>4.7.2</antlr.runtime.version>

<!-- JUnit Test Dependencies -->
<junit.platform.version>[1.3.2, 1.4.2]</junit.platform.version>
Expand Down Expand Up @@ -93,6 +94,14 @@
<version>${rest.client.version}</version>
<optional>true</optional>
</dependency>

<!-- dependencies for ANTLR -->
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${antlr.runtime.version}</version>
<optional>true</optional>
</dependency>

<!-- dependencies provided by an OSGi-Framework -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -343,4 +343,19 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
* @return true if statement pooling is disabled, false if it is enabled.
*/
public boolean getDisableStatementPooling();

/**
* Returns the current flag value for useFmtOnly.
*
* @return 'useFmtOnly' property value.
*/
public boolean getUseFmtOnly();

/**
* Specifies the flag to use FMTONLY for parameter metadata queries.
*
* @param useFmtOnly
* boolean value for 'useFmtOnly'.
*/
public void setUseFmtOnly(boolean useFmtOnly);
}
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
* Client Key of Azure Key Vault (AKV) Provider to be used for column encryption.
*/
void setKeyVaultProviderClientKey(String keyVaultProviderClientKey);

/**
* Sets the 'domain' connection property used for NTLM Authentication.
*
Expand All @@ -858,4 +858,19 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
* @return 'domain' property value
*/
String getDomain();

/**
* Returns the current flag value for useFmtOnly.
*
* @return 'useFmtOnly' property value.
*/
public boolean getUseFmtOnly();

/**
* Specifies the flag to use FMTONLY for parameter metadata queries.
*
* @param useFmtOnly
* boolean value for 'useFmtOnly'.
*/
public void setUseFmtOnly(boolean useFmtOnly);
}
Original file line number Diff line number Diff line change
Expand Up @@ -755,12 +755,28 @@ public void setTimestamp(int parameterIndex, java.sql.Timestamp x, java.util.Cal
*
* @param forceRefresh:
* If true the cache will not be used to retrieve the metadata.
*
* @return Per the description.
*
* @throws SQLServerException
* when an error occurs
*/
public ParameterMetaData getParameterMetaData(boolean forceRefresh) throws SQLServerException;

/**
* Returns the current flag value for useFmtOnly.
*
* @return 'useFmtOnly' property value.
* @throws SQLServerException
* when the connection is closed.
*/
public boolean getUseFmtOnly() throws SQLServerException;

/**
* Specifies the flag to use FMTONLY for parameter metadata queries.
*
* @param useFmtOnly
* boolean value for 'useFmtOnly'.
* @throws SQLServerException
* when the connection is closed.
*/
public void setUseFmtOnly(boolean useFmtOnly) throws SQLServerException;
}
62 changes: 42 additions & 20 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ public void setUseBulkCopyForBatchInsert(boolean useBulkCopyForBatchInsert) {
boolean userSetTNIR = true;

private boolean sendTimeAsDatetime = SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue();
private boolean useFmtOnly = SQLServerDriverBooleanProperty.USE_FMT_ONLY.getDefaultValue();

@Override
public final boolean getSendTimeAsDatetime() {
Expand Down Expand Up @@ -1093,10 +1094,8 @@ void checkClosed() throws SQLServerException {
* Returns if Federated Authentication is in use or is about to expire soon
*
* @return true/false
* @throws SQLServerException
* if an error occurs.
*/
protected boolean needsReconnect() throws SQLServerException {
protected boolean needsReconnect() {
return (null != fedAuthToken && Util.checkIfNeedNewAccessToken(this, fedAuthToken.expiresOn));
}

Expand Down Expand Up @@ -1299,15 +1298,15 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverStringProperty.USER.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = SQLServerDriverStringProperty.USER.getDefaultValue();
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}
validateMaxSQLLoginName(sPropKey, sPropValue);

sPropKey = SQLServerDriverStringProperty.PASSWORD.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = SQLServerDriverStringProperty.PASSWORD.getDefaultValue();
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}
Expand Down Expand Up @@ -1340,7 +1339,7 @@ Connection connectInternal(Properties propsIn,
// operation of RFC 3490.
sPropKey = SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = Boolean.toString(SQLServerDriverBooleanProperty.SERVER_NAME_AS_ACE.getDefaultValue());
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}
Expand All @@ -1351,7 +1350,7 @@ Connection connectInternal(Properties propsIn,
sPropKey = SQLServerDriverStringProperty.SERVER_NAME.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);

if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = "localhost";
}

Expand Down Expand Up @@ -1401,14 +1400,14 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverStringProperty.APPLICATION_NAME.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue != null)
if (null != sPropValue)
validateMaxSQLLoginName(sPropKey, sPropValue);
else
activeConnectionProperties.setProperty(sPropKey, SQLServerDriver.DEFAULT_APP_NAME);

sPropKey = SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = Boolean.toString(SQLServerDriverBooleanProperty.LAST_UPDATE_COUNT.getDefaultValue());
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}
Expand Down Expand Up @@ -1461,15 +1460,15 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = Boolean.toString(SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.getDefaultValue());
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}
multiSubnetFailover = isBooleanPropertyOn(sPropKey, sPropValue);

sPropKey = SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
userSetTNIR = false;
sPropValue = Boolean
.toString(SQLServerDriverBooleanProperty.TRANSPARENT_NETWORK_IP_RESOLUTION.getDefaultValue());
Expand All @@ -1479,7 +1478,7 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverBooleanProperty.ENCRYPT.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = Boolean.toString(SQLServerDriverBooleanProperty.ENCRYPT.getDefaultValue());
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}
Expand All @@ -1489,7 +1488,7 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = Boolean
.toString(SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.getDefaultValue());
activeConnectionProperties.setProperty(sPropKey, sPropValue);
Expand All @@ -1504,7 +1503,7 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverStringProperty.SELECT_METHOD.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = SQLServerDriverStringProperty.SELECT_METHOD.getDefaultValue();
}

Expand All @@ -1520,7 +1519,7 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverStringProperty.RESPONSE_BUFFERING.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = SQLServerDriverStringProperty.RESPONSE_BUFFERING.getDefaultValue();
}

Expand All @@ -1534,7 +1533,7 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverStringProperty.APPLICATION_INTENT.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = SQLServerDriverStringProperty.APPLICATION_INTENT.getDefaultValue();
}

Expand All @@ -1543,13 +1542,21 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = Boolean.toString(SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue());
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}

sendTimeAsDatetime = isBooleanPropertyOn(sPropKey, sPropValue);

sPropKey = SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (null == sPropValue) {
sPropValue = Boolean.toString(SQLServerDriverBooleanProperty.USE_FMT_ONLY.getDefaultValue());
activeConnectionProperties.setProperty(sPropKey, sPropValue);
}
useFmtOnly = isBooleanPropertyOn(sPropKey, sPropValue);

// Must be set before DISABLE_STATEMENT_POOLING
sPropKey = SQLServerDriverIntProperty.STATEMENT_POOLING_CACHE_SIZE.toString();
if (activeConnectionProperties.getProperty(sPropKey) != null
Expand All @@ -1574,15 +1581,15 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverBooleanProperty.INTEGRATED_SECURITY.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue != null) {
if (null != sPropValue) {
integratedSecurity = isBooleanPropertyOn(sPropKey, sPropValue);
}

// Ignore authenticationScheme setting if integrated authentication not specified
if (integratedSecurity) {
sPropKey = SQLServerDriverStringProperty.AUTHENTICATION_SCHEME.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue != null) {
if (null != sPropValue) {
intAuthScheme = AuthenticationScheme.valueOfString(sPropValue);
}
}
Expand Down Expand Up @@ -1617,7 +1624,7 @@ Connection connectInternal(Properties propsIn,

sPropKey = SQLServerDriverStringProperty.AUTHENTICATION.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
if (null == sPropValue) {
sPropValue = SQLServerDriverStringProperty.AUTHENTICATION.getDefaultValue();
}
authenticationString = SqlAuthentication.valueOfString(sPropValue).toString().trim();
Expand Down Expand Up @@ -5445,6 +5452,16 @@ public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue) {
sendTimeAsDatetime = sendTimeAsDateTimeValue;
}

@Override
public void setUseFmtOnly(boolean useFmtOnly) {
this.useFmtOnly = useFmtOnly;
}

@Override
public final boolean getUseFmtOnly() {
return useFmtOnly;
}

@Override
public java.sql.Array createArrayOf(String typeName, Object[] elements) throws SQLException {
SQLServerException.throwNotSupportedException(this, null);
Expand Down Expand Up @@ -5645,6 +5662,7 @@ public <T> T unwrap(Class<T> iface) throws SQLException {
private boolean originalUseBulkCopyForBatchInsert;
private volatile SQLWarning originalSqlWarnings;
private List<ISQLServerStatement> openStatements;
private boolean originalUseFmtOnly;

protected void beginRequestInternal() throws SQLException {
loggerExternal.entering(getClassNameLogging(), "beginRequest", this);
Expand All @@ -5663,6 +5681,7 @@ protected void beginRequestInternal() throws SQLException {
originalUseBulkCopyForBatchInsert = getUseBulkCopyForBatchInsert();
originalSqlWarnings = sqlWarnings;
openStatements = new LinkedList<ISQLServerStatement>();
originalUseFmtOnly = useFmtOnly;
requestStarted = true;
}
}
Expand Down Expand Up @@ -5691,6 +5710,9 @@ protected void endRequestInternal() throws SQLException {
if (sendTimeAsDatetime != originalSendTimeAsDatetime) {
setSendTimeAsDatetime(originalSendTimeAsDatetime);
}
if (useFmtOnly != originalUseFmtOnly) {
setUseFmtOnly(originalUseFmtOnly);
}
if (statementPoolingCacheSize != originalStatementPoolingCacheSize) {
setStatementPoolingCacheSize(originalStatementPoolingCacheSize);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -583,4 +583,14 @@ public void setDisableStatementPooling(boolean value) {
public boolean getDisableStatementPooling() {
return wrappedConnection.getDisableStatementPooling();
}

@Override
public void setUseFmtOnly(boolean useFmtOnly) {
wrappedConnection.setUseFmtOnly(useFmtOnly);
}

@Override
public boolean getUseFmtOnly() {
return wrappedConnection.getUseFmtOnly();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,19 @@ public boolean getSendTimeAsDatetime() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(),
SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue());
}

@Override
public void setUseFmtOnly(boolean useFmtOnly) {
setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString(),
useFmtOnly);
}

@Override
public boolean getUseFmtOnly() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString(),
SQLServerDriverBooleanProperty.USE_FMT_ONLY.getDefaultValue());
}

/**
* Sets whether string parameters are sent to the server in UNICODE format.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ enum SQLServerDriverBooleanProperty {
XOPEN_STATES("xopenStates", false),
FIPS("fips", false),
ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT("enablePrepareOnFirstPreparedStatementCall", SQLServerConnection.DEFAULT_ENABLE_PREPARE_ON_FIRST_PREPARED_STATEMENT_CALL),
USE_BULK_COPY_FOR_BATCH_INSERT("useBulkCopyForBatchInsert", false);
USE_BULK_COPY_FOR_BATCH_INSERT("useBulkCopyForBatchInsert", false),
USE_FMT_ONLY("useFmtOnly", false);

private final String name;
private final boolean defaultValue;
Expand Down Expand Up @@ -529,7 +530,10 @@ public final class SQLServerDriver implements java.sql.Driver {
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.toString(),
SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_KEY.toString(),
SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_KEY.getDefaultValue(), false, null)};
SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_KEY.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString(),
Boolean.toString(SQLServerDriverBooleanProperty.USE_FMT_ONLY.getDefaultValue()), false,
TRUE_FALSE),};

/**
* Properties that can only be set by using Properties. Cannot set in connection string
Expand Down
Loading

0 comments on commit 7ebbc94

Please sign in to comment.