diff --git a/.travis.yml b/.travis.yml index 3c90e82b0..47c919414 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,8 +33,8 @@ install: - mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -Pbuild42 before_script: - - docker pull microsoft/mssql-server-linux - - docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=' -p 1433:1433 -d microsoft/mssql-server-linux + - docker pull microsoft/mssql-server-linux:2017-latest + - docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=' -p 1433:1433 -d microsoft/mssql-server-linux:2017-latest script: - docker ps -a diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ebc0ce1b..5e909a89d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) - Updated ADAL4J dependency to version 1.2.0 [#392](https://github.com/Microsoft/mssql-jdbc/pull/392) - Updated azure-keyvault dependency to version 1.0.0 [#397](https://github.com/Microsoft/mssql-jdbc/pull/397) +## [6.2.2] Hotfix & Stable Release +### Changed +- Updated ADAL4J to version 1.2.0 and AKV to version 1.0.0 [#516](https://github.com/Microsoft/mssql-jdbc/pull/516) + ## [6.2.1] Hotfix & Stable Release ### Fixed Issues - Fixed queries without parameters using preparedStatement [#372](https://github.com/Microsoft/mssql-jdbc/pull/372) diff --git a/README.md b/README.md index 5bb33d3bd..2196f02d4 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ We're now on the Maven Central Repository. Add the following to your POM file to com.microsoft.sqlserver mssql-jdbc - 6.2.1.jre8 + 6.2.2.jre8 ``` The driver can be downloaded from the [Microsoft Download Center](https://go.microsoft.com/fwlink/?linkid=852460). @@ -130,7 +130,7 @@ Projects that require either of the two features need to explicitly declare the 1.0.0 ``` -***Please note*** as of the v6.3.0-preview, the way to construct a `SQLServerColumnEncryptionAzureKeyVaultProvider` object has changed. Please refer to this [Wiki](https://github.com/Microsoft/mssql-jdbc/wiki/New-Constructor-Definition-for-SQLServerColumnEncryptionAzureKeyVaultProvider-after-6.3.0-Preview-Release) page for more information. +***Please note*** as of the v6.2.2, the way to construct a `SQLServerColumnEncryptionAzureKeyVaultProvider` object has changed. Please refer to this [Wiki](https://github.com/Microsoft/mssql-jdbc/wiki/New-Constructor-Definition-for-SQLServerColumnEncryptionAzureKeyVaultProvider-after-6.2.2-Release) page for more information. ## Guidelines for Creating Pull Requests We love contributions from the community. To help improve the quality of our code, we encourage you to use the mssql-jdbc_formatter.xml formatter provided on all pull requests. diff --git a/pom.xml b/pom.xml index 160fdabd0..296eb209e 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.microsoft.sqlserver mssql-jdbc - 6.3.3 + 6.3.4-SNAPSHOT jar @@ -29,8 +29,6 @@ - Andrea Lam - andrela@microsoft.com Microsoft http://www.microsoft.com diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestSetUp.java b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestSetUp.java index 30fbe46a0..2b23bf836 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestSetUp.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/bulkCopy/BulkCopyTestSetUp.java @@ -14,6 +14,7 @@ import com.microsoft.sqlserver.testframework.AbstractTest; import com.microsoft.sqlserver.testframework.DBConnection; +import com.microsoft.sqlserver.testframework.DBPreparedStatement; import com.microsoft.sqlserver.testframework.DBStatement; import com.microsoft.sqlserver.testframework.DBTable;; @@ -37,7 +38,8 @@ static void setUpSourceTable() { stmt = con.createStatement(); sourceTable = new DBTable(true); stmt.createTable(sourceTable); - stmt.populateTable(sourceTable); + DBPreparedStatement pstmt = new DBPreparedStatement(con); + pstmt.populateTable(sourceTable); } finally { con.close(); diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetWrapper42Test.java b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetWrapper42Test.java new file mode 100644 index 000000000..78612674e --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/resultset/ResultSetWrapper42Test.java @@ -0,0 +1,82 @@ +/* + * Microsoft JDBC Driver for SQL Server + * + * Copyright(c) Microsoft Corporation All rights reserved. + * + * This program is made available under the terms of the MIT License. See the LICENSE file in the project root for more information. + */ +package com.microsoft.sqlserver.jdbc.resultset; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +import com.microsoft.sqlserver.jdbc.SQLServerResultSet; +import com.microsoft.sqlserver.jdbc.SQLServerResultSet42; +import com.microsoft.sqlserver.testframework.AbstractTest; + +/** + * Test SQLServerResultSet42 class + * + */ +@RunWith(JUnitPlatform.class) +public class ResultSetWrapper42Test extends AbstractTest { + static Connection connection = null; + double javaVersion = Double.parseDouble(System.getProperty("java.specification.version")); + static int major; + static int minor; + + /** + * Tests creation of SQLServerResultSet42 object + * + * @throws SQLException + */ + @Test + public void SQLServerResultSet42Test() throws SQLException { + String sql = "SELECT SUSER_SNAME()"; + + ResultSet rs = null; + try { + rs = connection.createStatement().executeQuery(sql); + + if (1.8d <= javaVersion && 4 == major && 2 == minor) { + assertTrue(rs instanceof SQLServerResultSet42); + } + else { + assertTrue(rs instanceof SQLServerResultSet); + } + } + finally { + if (null != rs) { + rs.close(); + } + } + } + + @BeforeAll + private static void setupConnection() throws SQLException { + connection = DriverManager.getConnection(connectionString); + + DatabaseMetaData metadata = connection.getMetaData(); + major = metadata.getJDBCMajorVersion(); + minor = metadata.getJDBCMinorVersion(); + } + + @AfterAll + private static void terminateVariation() throws SQLException { + if (null != connection) { + connection.close(); + } + } + +} diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/Wrapper42Test.java b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/Wrapper42Test.java new file mode 100644 index 000000000..8322deb60 --- /dev/null +++ b/src/test/java/com/microsoft/sqlserver/jdbc/unit/statement/Wrapper42Test.java @@ -0,0 +1,96 @@ +/* + * Microsoft JDBC Driver for SQL Server + * + * Copyright(c) Microsoft Corporation All rights reserved. + * + * This program is made available under the terms of the MIT License. See the LICENSE file in the project root for more information. + */ +package com.microsoft.sqlserver.jdbc.unit.statement; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.sql.CallableStatement; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.platform.runner.JUnitPlatform; +import org.junit.runner.RunWith; + +import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement; +import com.microsoft.sqlserver.jdbc.SQLServerCallableStatement42; +import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement; +import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement42; +import com.microsoft.sqlserver.testframework.AbstractTest; + +/** + * Test SQLServerPreparedSatement42 and SQLServerCallableSatement42 classes + * + */ +@RunWith(JUnitPlatform.class) +public class Wrapper42Test extends AbstractTest { + static Connection connection = null; + double javaVersion = Double.parseDouble(System.getProperty("java.specification.version")); + static int major; + static int minor; + + /** + * Tests creation of SQLServerPreparedSatement42 object + * + * @throws SQLException + */ + @Test + public void PreparedSatement42Test() throws SQLException { + String sql = "SELECT SUSER_SNAME()"; + + PreparedStatement pstmt = connection.prepareStatement(sql); + + if (1.8d <= javaVersion && 4 == major && 2 == minor) { + assertTrue(pstmt instanceof SQLServerPreparedStatement42); + } + else { + assertTrue(pstmt instanceof SQLServerPreparedStatement); + } + } + + /** + * Tests creation of SQLServerCallableStatement42 object + * + * @throws SQLException + */ + @Test + public void CallableStatement42Test() throws SQLException { + String sql = "SELECT SUSER_SNAME()"; + + CallableStatement cstmt = connection.prepareCall(sql); + + if (1.8d <= javaVersion && 4 == major && 2 == minor) { + assertTrue(cstmt instanceof SQLServerCallableStatement42); + } + else { + assertTrue(cstmt instanceof SQLServerCallableStatement); + } + } + + @BeforeAll + private static void setupConnection() throws SQLException { + connection = DriverManager.getConnection(connectionString); + + DatabaseMetaData metadata = connection.getMetaData(); + major = metadata.getJDBCMajorVersion(); + minor = metadata.getJDBCMinorVersion(); + } + + @AfterAll + private static void terminateVariation() throws SQLException { + if (null != connection) { + connection.close(); + } + } + +} diff --git a/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java b/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java index dd7dc1c4b..e10ad94e0 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/AbstractSQLGenerator.java @@ -22,6 +22,7 @@ public abstract class AbstractSQLGenerator {// implements ISQLGenerator { protected static final String PRIMARY_KEY = "PRIMARY KEY"; protected static final String DEFAULT = "DEFAULT"; protected static final String COMMA = ","; + protected static final String QUESTION_MARK = "?"; // FIXME: Find good word for '. Better replaced by wrapIdentifier. protected static final String TICK = "'"; diff --git a/src/test/java/com/microsoft/sqlserver/testframework/DBPreparedStatement.java b/src/test/java/com/microsoft/sqlserver/testframework/DBPreparedStatement.java index 6ff5fa6f1..99d9c5ab3 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/DBPreparedStatement.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/DBPreparedStatement.java @@ -30,6 +30,10 @@ public DBPreparedStatement(DBConnection dbconnection) { } /** + * set up internal PreparedStatement with query + * + * @param query + * @return * @throws SQLException * */ @@ -84,4 +88,22 @@ public DBResultSet executeQuery() throws SQLException { return dbresultSet; } + /** + * populate table with values using prepared statement + * + * @param table + * @return true if table is populated + */ + public boolean populateTable(DBTable table) { + return table.populateTableWithPreparedStatement(this); + } + + /** + * + * @return + * @throws SQLException + */ + public boolean execute() throws SQLException { + return pstmt.execute(); + } } \ No newline at end of file diff --git a/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java b/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java index e3c9b174f..39c18785d 100644 --- a/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java +++ b/src/test/java/com/microsoft/sqlserver/testframework/DBTable.java @@ -11,6 +11,7 @@ import static org.junit.jupiter.api.Assertions.fail; import java.sql.JDBCType; +import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @@ -143,7 +144,7 @@ private void addColumns(boolean unicode) { public String getTableName() { return tableName; } - + public List getColumns() { return this.columns; } @@ -156,7 +157,7 @@ public List getColumns() { public String getEscapedTableName() { return escapedTableName; } - + public String getDefinitionOfColumns() { return tableDefinition; } @@ -234,7 +235,7 @@ else if (VariableLengthType.ScaleOnly == column.getSqlType().getVariableLengthTy tableDefinition = tableDefinition.substring(0, indexOfLastComma); sb.add(tableDefinition); - + sb.add(CLOSE_BRACKET); return sb.toString(); } @@ -257,6 +258,56 @@ boolean populateTable(DBStatement dbstatement) { return false; } + /** + * using prepared statement to populate table with values + * + * @param dbstatement + * @return + */ + boolean populateTableWithPreparedStatement(DBPreparedStatement dbPStmt) { + try { + populateValues(); + + // create the insertion query + StringJoiner sb = new StringJoiner(SPACE_CHAR); + sb.add("INSERT"); + sb.add("INTO"); + sb.add(escapedTableName); + sb.add("VALUES"); + sb.add(OPEN_BRACKET); + for (int colNum = 0; colNum < totalColumns; colNum++) { + sb.add(QUESTION_MARK); + + if (colNum < totalColumns - 1) { + sb.add(COMMA); + } + } + sb.add(CLOSE_BRACKET); + String sql = sb.toString(); + + dbPStmt.prepareStatement(sql); + + // insert data + for (int i = 0; i < totalRows; i++) { + for (int colNum = 0; colNum < totalColumns; colNum++) { + if (passDataAsHex(colNum)) { + ((PreparedStatement) dbPStmt.product()).setBytes(colNum + 1, ((byte[]) (getColumn(colNum).getRowValue(i)))); + } + else { + dbPStmt.setObject(colNum + 1, String.valueOf(getColumn(colNum).getRowValue(i))); + } + } + dbPStmt.execute(); + } + + return true; + } + catch (SQLException ex) { + fail(ex.getMessage()); + } + return false; + } + private void populateValues() { // generate values for all columns for (int i = 0; i < totalColumns; i++) {