BVT updates#120
Conversation
| * @param charSet | ||
| * @return | ||
| */ | ||
| protected static String buildCharOrNChar(int columnLength, String charSet) { |
There was a problem hiding this comment.
move these new methods into SqlChar class, as this is an abstract class and we are not going to use these methods in all the classes that extends SqlType.
There was a problem hiding this comment.
makes sense. will do
| private static DBStatement stmt = null; | ||
|
|
||
| /////////////////////////////////////////////////////////////////// | ||
| //// Connect to specified server and close the connection |
There was a problem hiding this comment.
can we change these comments into javadocs?
| /////////////////////////////////////////////////////////////////// | ||
| // Create a statement with a query timeout | ||
| // ResultSet.Type_forward_only, | ||
| // ResultSet.CONCUR_READ_ONLY, executeQuery |
There was a problem hiding this comment.
update the comments as this test doesn't use ResultSet. Also review other comments too.
|
|
||
| try { | ||
| conn = new DBConnection(connectionString); | ||
| stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); |
There was a problem hiding this comment.
Do you think it will be better to have an enum in DBStatement/DBConnection that has all combinations of resultSetType and resultSetConcurrency? So we don't have to call and set each type (will be useful to reuse in other tests), and just have validation in btvTest
| int totalRows = 2; // default row count set to 2 | ||
| static int totalRows = 3; // default row count set to 3 | ||
| DBSchema schema; | ||
| ArrayList<ArrayList<Object>> rows; |
There was a problem hiding this comment.
any reason why we need rows and currentrow? wont the columns suffice?
There was a problem hiding this comment.
rows is all rows we need to verify our backend data. verification is done row by row.
There was a problem hiding this comment.
all the expected values must be available in
List<DBColumn> columns
try accessing them as
columns.get(Columnindex).getRowValue(row);
| * @throws SQLException | ||
| */ | ||
| public void verifydata(int ordinal, Class coercion, Object arg) throws SQLException { | ||
| Object backendData = this.currentrow().get(ordinal); |
There was a problem hiding this comment.
The name backendData gives an impression that it is actual data from DB, when it is actually expected data. It would be better to rename this variable.
|
|
||
| // Interleave resultset calls | ||
| rs1.next(); | ||
| rs1.verifyCurrentRow(table1); |
|
|
||
| rs.verify(table1); | ||
| stmt.close(); | ||
| } |
There was a problem hiding this comment.
we should verify if the stmt/rs is closed here else this test will be same as the previous one.
| } | ||
| } | ||
|
|
||
| } |
There was a problem hiding this comment.
add a method with @afterall tag to clean up the 2 tables.
| } | ||
|
|
||
| public void verifydata(int ordinal, Class coercion, Object expectedData, Object retrieved) throws SQLException { | ||
| metaData = this.getMetaData(); |
There was a problem hiding this comment.
add javadocs for this method
| * @throws SQLException | ||
| */ | ||
| public void verifydata(int ordinal, Class coercion, Object arg) throws SQLException { | ||
| Object expectedData = currentTable.columns.get(ordinal).getRowValue(_currentrow); |
There was a problem hiding this comment.
can we remove the arg variable as its not used
There was a problem hiding this comment.
or if you have any future TODOs for this variable add it as comment
| if (coercion == Object.class) { | ||
| return this.getObject(idx); | ||
| } | ||
| return null; |
There was a problem hiding this comment.
can we have warning logged here if there is no valid coercion? It will be easier to trace if we try to test with unimplemented coercion
| break; | ||
|
|
||
| case java.sql.Types.VARBINARY: | ||
| assertTrue(parseByte((byte[])expectedData, (byte[])retrieved), |
There was a problem hiding this comment.
Can we have Arrays.equals() here instead of implementing parseByte()?
| DBResultSet.TYPE_SCROLL_INSENSITIVE, DBResultSet.CONCUR_READ_ONLY), TYPE_SCROLL_SENSITIVE_CONCUR_READ_ONLY( | ||
| DBResultSet.TYPE_SCROLL_SENSITIVE, DBResultSet.CONCUR_READ_ONLY), TYPE_FORWARD_ONLY_CONCUR_UPDATABLE( | ||
| DBResultSet.TYPE_FORWARD_ONLY, DBResultSet.CONCUR_UPDATABLE), TYPE_SCROLL_SENSITIVE_CONCUR_UPDATABLE( | ||
| DBResultSet.TYPE_SCROLL_SENSITIVE, DBResultSet.CONCUR_UPDATABLE), TYPE_DYNAMIC_CONCUR_OPTIMISTIC( |
There was a problem hiding this comment.
It will increase the readability if we don't use our formatter here!
| */ | ||
| public void setObject(int parameterIndex, Object targetObject) throws SQLException { | ||
|
|
||
| ((PreparedStatement) product()).setObject(parameterIndex, targetObject); |
There was a problem hiding this comment.
these javadocs needs to be updated
| import static org.junit.Assert.assertEquals; | ||
| import static org.junit.Assert.assertTrue; | ||
| import static org.junit.Assert.fail; | ||
| import static org.junit.jupiter.api.Assertions.fail; |
There was a problem hiding this comment.
can you also use jupiter.api.Assertions for assertEquals and assertTrue
| assertEquals(e.toString(), "com.microsoft.sqlserver.jdbc.SQLServerException: The result set is closed."); | ||
| } | ||
| } | ||
| finally { |
There was a problem hiding this comment.
it will be good if we can also have an assert after catch, to verify code execution dint reach that part of code.
There was a problem hiding this comment.
the code will get executed after catch. we are just catching it and inside catch make sure that it has thrown the proper exception.
There was a problem hiding this comment.
in case the exception is not thrown, the test will pass, we don't want that to happen.
| } | ||
| } | ||
|
|
||
| public static void terminateVariation() throws SQLException { |
There was a problem hiding this comment.
both the terminate method needs javadoc
| */ | ||
| public DBPreparedStatement prepareStatement(String query) throws SQLException { | ||
| DBPreparedStatement dbpstmt = new DBPreparedStatement(this, internal, "preparedStatement"); | ||
| return dbpstmt.prepareStatement(query); |
There was a problem hiding this comment.
the variable internal passed here must be preparedStatement object. Can we have DBPreparedStatement(DBConnection dbConnection) constructor in DBPreparedStatement like the one in DBStatement? it will reduce the confusion
| public static final int CONCUR_OPTIMISTIC = ResultSet.CONCUR_UPDATABLE + 2; | ||
| public static final int TYPE_CURSOR_FORWARDONLY = ResultSet.TYPE_FORWARD_ONLY + 1001; | ||
| public static final int TYPE_FORWARD_ONLY = ResultSet.TYPE_FORWARD_ONLY; | ||
| public static final int CONCUR_READ_ONLY = ResultSet.CONCUR_READ_ONLY; |
There was a problem hiding this comment.
can you add some documentation on why some values are added?
| DBResultSetMetaData wrapper = null; | ||
| try { | ||
| product = resultSet.getMetaData(); | ||
| wrapper = new DBResultSetMetaData(parent, product, name); |
There was a problem hiding this comment.
update the constructor in DBResultSetMetaData to accept just DBResultSet, to be consistent with other classes that extend AbstractParentWrapper. Also, pass valid value for both parent and name variable, they are null at this point.
| */ | ||
| public int getColumnType(int index) throws SQLException { | ||
| int current = ((SQLServerResultSetMetaData) product()).getColumnType(index); | ||
| return current; |
There was a problem hiding this comment.
can we directly return the value whenever possible rather than storing them in temp variable and then passing them? this way value will not be stored in memory while waiting for GC.
|
|
||
| DBStatement(DBConnection parent, Statement internal, int type, int concurrency, int holdability) { | ||
| super(parent, null, "statement"); | ||
| } |
There was a problem hiding this comment.
this constructor can be removed as we are not using any of the new parameters passed
| */ | ||
| public int getTotalRows() { | ||
| public static int getTotalRows() { | ||
| return totalRows; |
There was a problem hiding this comment.
why is totalRows as static? Shouldn't the number of rows be tied to a table!
|
|
||
| DateTimeOffset maxDTS = calculateDateTimeOffsetMinMax("max", precision, "9999-12-31 23:59:59"); | ||
| DateTimeOffset minDTS = calculateDateTimeOffsetMinMax("min", precision, "0001-01-01 00:00:00"); | ||
|
|
There was a problem hiding this comment.
replace the hard coded value with SqlTypeValue.DATETIMEOFFSET.maxValue/minValue
There was a problem hiding this comment.
It will be better to move these calls into SqlDateTimeOffset() and store them in minvalue and maxvalue. So we don't have to calculate the same value over and over while generating random datetimeoffset value
| protected Object maxvalue = null; | ||
| protected Object nullvalue = null; // Primitives have non-null defaults | ||
| protected VariableLengthType variableLengthType; | ||
| static Random r = new Random(); |
There was a problem hiding this comment.
lets use ThreadLocalRandom instead
No description provided.