Skip to content

Commit

Permalink
Merge branch 'ms-dev' into issue531
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java
  • Loading branch information
cheenamalhotra committed May 19, 2019
2 parents f675da2 + b91c7ea commit 0e8bb83
Show file tree
Hide file tree
Showing 13 changed files with 369 additions and 62 deletions.
6 changes: 3 additions & 3 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4596,7 +4596,7 @@ void writeTVPRows(TVP value) throws SQLServerException {
writeBytes(cachedTVPHeaders.array(), 0, ((Buffer) cachedTVPHeaders).position());
}

Object[] rowData = value.getRowData();
List<Object> rowData = value.getRowData();

// ROW
writeByte((byte) TDS.TVP_ROW);
Expand All @@ -4618,8 +4618,8 @@ void writeTVPRows(TVP value) throws SQLServerException {
if (null != rowData) {
// if rowData has value for the current column, retrieve it. If not, current column will stay
// null.
if (rowData.length > currentColumn) {
currentObject = rowData[currentColumn];
if (rowData.size() > currentColumn) {
currentObject = rowData.get(currentColumn);
if (null != currentObject) {
currentColumnStringValue = String.valueOf(currentObject);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package com.microsoft.sqlserver.jdbc;

import java.util.List;

/**
* Provides an interface to create classes that read in data from any source (such as a file) and allow a structured
* type to be sent to SQL Server tables.
Expand Down Expand Up @@ -34,7 +36,7 @@ public interface ISQLServerDataRecord {
*
* @return The data for the row.
*/
public Object[] getRowData();
public List<Object> getRowData();

/**
* Advances to the next data row.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -820,4 +820,28 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
* @return msiClientId property value
*/
public String getMSIClientId();

/**
* Sets the Azure Key Vault (AKV) Provider Client Id to provided value to be used for column encryption.
*
* @param keyVaultProviderClientId
* Client Id of Azure Key Vault (AKV) Provider to be used for column encryption.
*/
public void setKeyVaultProviderClientId(String keyVaultProviderClientId);

/**
* Returns the value for the connection property 'keyVaultProviderClientId'.
*
* @return keyVaultProviderClientId
*/
public String getKeyVaultProviderClientId();

/**
* Sets the Azure Key Vault (AKV) Provider Client Key to provided value to be used for column encryption.
*
* @param keyVaultProviderClientKey
* Client Key of Azure Key Vault (AKV) Provider to be used for column encryption.
*/
public void setKeyVaultProviderClientKey(String keyVaultProviderClientKey);

}
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,24 @@ Connection connectInternal(Properties propsIn,

registerKeyStoreProviderOnConnection(keyStoreAuthentication, keyStoreSecret, keyStoreLocation);

if (null == globalCustomColumnEncryptionKeyStoreProviders) {
sPropKey = SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (null != sPropValue) {
String keyVaultColumnEncryptionProviderClientId = sPropValue;
sPropKey = SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_KEY.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (null != sPropValue) {
String keyVaultColumnEncryptionProviderClientKey = sPropValue;
SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(
keyVaultColumnEncryptionProviderClientId, keyVaultColumnEncryptionProviderClientKey);
Map<String, SQLServerColumnEncryptionKeyStoreProvider> keyStoreMap = new HashMap<String, SQLServerColumnEncryptionKeyStoreProvider>();
keyStoreMap.put(akvProvider.getName(), akvProvider);
registerColumnEncryptionKeyStoreProviders(keyStoreMap);
}
}
}

sPropKey = SQLServerDriverBooleanProperty.MULTI_SUBNET_FAILOVER.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,35 @@ public String getColumnName() {
public int getColumnType() {
return javaSqlType;
}

@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + javaSqlType;
hash = 31 * hash + precision;
hash = 31 * hash + scale;
hash = 31 * hash + numberOfDigitsIntegerPart;
hash = 31 * hash + (null != columnName ? columnName.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}

if (null != object && object.getClass() == SQLServerDataColumn.class) {
SQLServerDataColumn aSQLServerDataColumn = (SQLServerDataColumn) object;
if (hashCode() == aSQLServerDataColumn.hashCode()) {
// Compare objects to avoid collision
return ((null == columnName && null == aSQLServerDataColumn.columnName
|| columnName.equals(aSQLServerDataColumn.columnName))
&& javaSqlType == aSQLServerDataColumn.javaSqlType
&& numberOfDigitsIntegerPart == aSQLServerDataColumn.numberOfDigitsIntegerPart
&& precision == aSQLServerDataColumn.precision && scale == aSQLServerDataColumn.scale);
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,24 @@ public String getMSIClientId() {
SQLServerDriverStringProperty.MSI_CLIENT_ID.getDefaultValue());
}

@Override
public void setKeyVaultProviderClientId(String keyVaultProviderClientId) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.toString(),
keyVaultProviderClientId);
}

@Override
public String getKeyVaultProviderClientId() {
return getStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.toString(),
SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_ID.getDefaultValue());
}

@Override
public void setKeyVaultProviderClientKey(String keyVaultProviderClientKey) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.KEY_VAULT_PROVIDER_CLIENT_KEY.toString(),
keyVaultProviderClientKey);
}

/**
* Sets a property string value.
*
Expand Down
79 changes: 60 additions & 19 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
Expand All @@ -28,8 +30,7 @@ public final class SQLServerDataTable {
int columnCount = 0;
Map<Integer, SQLServerDataColumn> columnMetadata = null;
Set<String> columnNames = null;
Map<Integer, Object[]> rows = null;

Map<Integer, List<Object>> rows = null;
private String tvpName = null;

/**
Expand All @@ -53,6 +54,7 @@ public synchronized void clear() {
rowCount = 0;
columnCount = 0;
columnMetadata.clear();
columnNames.clear();
rows.clear();
}

Expand All @@ -61,7 +63,7 @@ public synchronized void clear() {
*
* @return an iterator on the rows of the data table.
*/
public synchronized Iterator<Entry<Integer, Object[]>> getIterator() {
public synchronized Iterator<Entry<Integer, List<Object>>> getIterator() {
if ((null != rows) && (null != rows.entrySet())) {
return rows.entrySet().iterator();
}
Expand Down Expand Up @@ -118,7 +120,7 @@ public synchronized void addRow(Object... values) throws SQLServerException {
}

Iterator<Entry<Integer, SQLServerDataColumn>> columnsIterator = columnMetadata.entrySet().iterator();
Object[] rowValues = new Object[columnCount];
List<Object> rowValues = new LinkedList<>();
int currentColumn = 0;
while (columnsIterator.hasNext()) {
Object val = null;
Expand Down Expand Up @@ -153,26 +155,30 @@ public synchronized void addRow(Object... values) throws SQLServerException {
* @throws SQLServerException
* when an error occurs
*/
private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
private void internalAddrow(JDBCType jdbcType, Object val, List<Object> rowValues,
Map.Entry<Integer, SQLServerDataColumn> pair) throws SQLServerException {
int key = pair.getKey();
rowValues.add(key, val);

if (null != val) {
SQLServerDataColumn currentColumnMetadata = pair.getValue();
int nValueLen;

switch (jdbcType) {
case BIGINT:
rowValues[pair.getKey()] = (val instanceof Long) ? val : Long.parseLong(val.toString());
rowValues.set(key, (val instanceof Long) ? val : Long.parseLong(val.toString()));
break;

case BIT:
if (val instanceof Boolean) {
rowValues[pair.getKey()] = val;
rowValues.set(key, val);
} else {
String valString = val.toString();

if (valString.equals("0") || valString.equalsIgnoreCase(Boolean.FALSE.toString())) {
rowValues[pair.getKey()] = Boolean.FALSE;
rowValues.set(key, Boolean.FALSE);
} else if (valString.equals("1") || valString.equalsIgnoreCase(Boolean.TRUE.toString())) {
rowValues[pair.getKey()] = Boolean.TRUE;
rowValues.set(key, Boolean.TRUE);
} else {
MessageFormat form = new MessageFormat(
SQLServerException.getErrString("R_TVPInvalidColumnValue"));
Expand All @@ -183,12 +189,12 @@ private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
break;

case INTEGER:
rowValues[pair.getKey()] = (val instanceof Integer) ? val : Integer.parseInt(val.toString());
rowValues.set(key, (val instanceof Integer) ? val : Integer.parseInt(val.toString()));
break;

case SMALLINT:
case TINYINT:
rowValues[pair.getKey()] = (val instanceof Short) ? val : Short.parseShort(val.toString());
rowValues.set(key, (val instanceof Short) ? val : Short.parseShort(val.toString()));
break;

case DECIMAL:
Expand Down Expand Up @@ -220,16 +226,16 @@ private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
+ currentColumnMetadata.numberOfDigitsIntegerPart;
columnMetadata.put(pair.getKey(), currentColumnMetadata);
}
rowValues[pair.getKey()] = bd;
rowValues.set(key, bd);
break;

case DOUBLE:
rowValues[pair.getKey()] = (val instanceof Double) ? val : Double.parseDouble(val.toString());
rowValues.set(key, (val instanceof Double) ? val : Double.parseDouble(val.toString()));
break;

case FLOAT:
case REAL:
rowValues[pair.getKey()] = (val instanceof Float) ? val : Float.parseFloat(val.toString());
rowValues.set(key, (val instanceof Float) ? val : Float.parseFloat(val.toString()));
break;

case TIMESTAMP_WITH_TIMEZONE:
Expand All @@ -247,9 +253,9 @@ private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
// java.sql.Date, java.sql.Time and java.sql.Timestamp are subclass of java.util.Date
if (val instanceof java.util.Date || val instanceof microsoft.sql.DateTimeOffset
|| val instanceof OffsetDateTime || val instanceof OffsetTime)
rowValues[pair.getKey()] = val.toString();
rowValues.set(key, val.toString());
else
rowValues[pair.getKey()] = val;
rowValues.set(key, val);
break;

case BINARY:
Expand All @@ -261,7 +267,7 @@ private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
currentColumnMetadata.precision = nValueLen;
columnMetadata.put(pair.getKey(), currentColumnMetadata);
}
rowValues[pair.getKey()] = val;
rowValues.set(key, val);
break;

case CHAR:
Expand All @@ -279,7 +285,7 @@ private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
currentColumnMetadata.precision = nValueLen;
columnMetadata.put(pair.getKey(), currentColumnMetadata);
}
rowValues[pair.getKey()] = val;
rowValues.set(key, val);
break;

case SQL_VARIANT:
Expand All @@ -295,7 +301,7 @@ private void internalAddrow(JDBCType jdbcType, Object val, Object[] rowValues,
throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
}
} else {
rowValues[pair.getKey()] = null;
rowValues.set(key, null);
if (jdbcType == JDBCType.SQL_VARIANT) {
throw new SQLServerException(SQLServerException.getErrString("R_invalidValueForTVPWithSQLVariant"),
null);
Expand Down Expand Up @@ -331,4 +337,39 @@ public String getTvpName() {
public void setTvpName(String tvpName) {
this.tvpName = tvpName;
}

@Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + rowCount;
hash = 31 * hash + columnCount;
hash = 31 * hash + (null != columnMetadata ? columnMetadata.hashCode() : 0);
hash = 31 * hash + (null != columnNames ? columnNames.hashCode() : 0);
hash = 31 * hash + (null != rows ? rows.hashCode() : 0);
hash = 31 * hash + (null != tvpName ? tvpName.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
if (this == object) {
return true;
}

if (null != object && object.getClass() == SQLServerDataTable.class) {
SQLServerDataTable aSQLServerDataTable = (SQLServerDataTable) object;
if (hashCode() == aSQLServerDataTable.hashCode()) {

// Compare objects to avoid collision
boolean equalColumnMetadata = columnMetadata.equals(aSQLServerDataTable.columnMetadata);
boolean equalColumnNames = columnNames.equals(aSQLServerDataTable.columnNames);
boolean equalRowData = rows.equals(aSQLServerDataTable.rows);

return (rowCount == aSQLServerDataTable.rowCount && columnCount == aSQLServerDataTable.columnCount
&& tvpName == aSQLServerDataTable.tvpName && equalColumnMetadata && equalColumnNames
&& equalRowData);
}
}
return false;
}
}
Loading

0 comments on commit 0e8bb83

Please sign in to comment.