/** * Helper method for *SetObject* tests. * Insert data into the given PreparedStatement, or any of its subclasses, with the following structure: * 1 - `id` INT * 2 - `ot1` VARCHAR * 3 - `ot2` BLOB * 4 - `odt1` VARCHAR * 5 - `odt2` BLOB * * @param pstmt * @return the row count of inserted records. * @throws Exception */ private int insertTestDataOffsetDTTypes(PreparedStatement pstmt) throws Exception { pstmt.setInt(1, 1); pstmt.setObject(2, testOffsetTime, JDBCType.VARCHAR); pstmt.setObject(3, testOffsetTime); pstmt.setObject(4, testOffsetDateTime, JDBCType.VARCHAR); pstmt.setObject(5, testOffsetDateTime); assertEquals(1, pstmt.executeUpdate()); if (pstmt instanceof CallableStatement) { CallableStatement cstmt = (CallableStatement) pstmt; cstmt.setInt("id", 2); cstmt.setObject("ot1", testOffsetTime, JDBCType.VARCHAR); cstmt.setObject("ot2", testOffsetTime); cstmt.setObject("odt1", testOffsetDateTime, JDBCType.VARCHAR); cstmt.setObject("odt2", testOffsetDateTime); assertEquals(1, cstmt.executeUpdate()); return 2; } return 1; }
static List<SqlParam> getJDBCInfoByColumnNames(final DatabaseMetaData meta, String catalog, String schema, String tableName, final List<SqlParam> params) throws SQLException { List<SqlParam> paramList = new ArrayList<>(); for (int i=0; i<params.size(); i++) { SqlParam param = params.get(i); String columnName = param.getColumn(); ResultSet column = meta.getColumns(catalog, schema, tableName, columnName); if (column.getFetchSize() == 0) { //Postgresql does lowercase instead, so let's try that if we don't have a match column = meta.getColumns(catalog, schema, tableName.toLowerCase(), columnName.toLowerCase()); } column.next(); param.setJdbcType(JDBCType.valueOf(column.getInt("DATA_TYPE"))); paramList.add(param); } return paramList; }
/** * {@link java.sql.Types} の値を {@link java.sql.SQLType} に変換する * @param sqlType {@link java.sql.Types} の値 * @return {@link java.sql.SQLType} の値 */ private SQLType toSqlType(final int sqlType) { for (JDBCType type : JDBCType.values()) { if (type.getVendorTypeNumber().intValue() == sqlType) { return type; } } //下位互換のため、念のため生成して返す return new SQLType() { @Override public Integer getVendorTypeNumber() { return sqlType; } @Override public String getVendor() { return "unknown"; } @Override public String getName() { return "unknown name:" + sqlType; } }; }
/** * ステートメントにストリームパラメータを登録。 * * @param preparedStatement ステートメント * @param index パラメータインデックス * @param parameterMapperManager パラメータ変換管理クラス * @return 次のパラメータインデックス * @throws SQLException SQL例外 */ protected int setStreamParameter(final PreparedStatement preparedStatement, int index, final BindParameterMapperManager parameterMapperManager) throws SQLException { if (Objects.equals(sqlType, JDBCType.BLOB)) { if (len > -1) { preparedStatement.setBinaryStream(index, stream, len); } else { preparedStatement.setBinaryStream(index, stream); } } else if (Objects.equals(sqlType, JDBCType.CLOB)) { if (len > -1) { preparedStatement.setAsciiStream(index, stream, len); } else { preparedStatement.setAsciiStream(index, stream); } } else { return super.setParameter(preparedStatement, index, parameterMapperManager); } parameterLog(index); index++; return index; }
/** * DB更新処理のテストケース。 */ @Test public void testExecuteUpdate() throws Exception { // 事前条件 cleanInsert(Paths.get("src/test/resources/data/setup", "testExecuteUpdate.ltsv")); SqlContext ctx = agent.contextFrom("example/selectinsert_product") .param("product_id", new BigDecimal("0"), JDBCType.DECIMAL) .param("jan_code", "1234567890123", Types.CHAR); int updateCount = agent.update(ctx); assertEquals("データの登録に失敗しました。", 1, updateCount); // 検証処理 List<Map<String, Object>> expectedDataList = getDataFromFile(Paths.get( "src/test/resources/data/expected/SqlAgent", "testExecuteUpdate.ltsv")); List<Map<String, Object>> actualDataList = agent.query("example/select_product") .paramList("product_id", 0, 1).stream(new MapResultSetConverter(CaseFormat.LOWER_SNAKE_CASE)) .collect(Collectors.toList()); assertEquals(expectedDataList.toString(), actualDataList.toString()); }
/** * DB更新処理のテストケース。(Fluent API) */ @Test public void testUpdateFluent() throws Exception { // 事前条件 cleanInsert(Paths.get("src/test/resources/data/setup", "testExecuteUpdate.ltsv")); int updateCount = agent.update("example/selectinsert_product") .param("product_id", new BigDecimal("0"), JDBCType.DECIMAL) .param("jan_code", "1234567890123", Types.CHAR).count(); assertEquals("データの登録に失敗しました。", 1, updateCount); // 検証処理 List<Map<String, Object>> expectedDataList = getDataFromFile(Paths.get( "src/test/resources/data/expected/SqlAgent", "testExecuteUpdate.ltsv")); List<Map<String, Object>> actualDataList = agent.query("example/select_product") .paramList("product_id", 0, 1).stream(new MapResultSetConverter(CaseFormat.LOWER_SNAKE_CASE)) .collect(Collectors.toList()); assertEquals(expectedDataList.toString(), actualDataList.toString()); }
@Test public void testExecuteUpdateFilter() throws Exception { cleanInsert(Paths.get("src/test/resources/data/setup", "testExecuteUpdate.ltsv")); List<String> log = TestAppender.getLogbackLogs(() -> { SqlContext ctx = agent.contextFrom("example/selectinsert_product").setSqlId("222") .param("_userName", "testUserName").param("_funcId", "testFunction") .param("product_id", new BigDecimal("0"), JDBCType.DECIMAL) .param("jan_code", "1234567890123", Types.CHAR); agent.update(ctx); }); assertThat(log, is(Files.readAllLines( Paths.get("src/test/resources/data/expected/DebugSqlFilter", "testExecuteUpdateFilter.txt"), StandardCharsets.UTF_8))); }
@DataProvider(name = "rowsetUsingDataTypes") protected Object[][] rowsetUsingDataTypes() throws Exception { CachedRowSet rs = createDataTypesRowSet(); return new Object[][]{ {rs, JDBCType.INTEGER}, {rs, JDBCType.CHAR}, {rs, JDBCType.VARCHAR}, {rs, JDBCType.BIGINT}, {rs, JDBCType.BOOLEAN}, {rs, JDBCType.SMALLINT}, {rs, JDBCType.DOUBLE}, {rs, JDBCType.DECIMAL}, {rs, JDBCType.REAL}, {rs, JDBCType.TINYINT}, {rs, JDBCType.DATE}, {rs, JDBCType.TIME}, {rs, JDBCType.TIMESTAMP}, {rs, JDBCType.VARBINARY}, {rs, JDBCType.ARRAY}, {rs, JDBCType.REF}, {rs, JDBCType.FLOAT} }; }
private void compareRowSets(CachedRowSet crs, CachedRowSet crs1) throws Exception { int rows = crs.size(); assertTrue(rows == crs1.size()); ResultSetMetaData rsmd = crs.getMetaData(); compareMetaData(rsmd, crs1.getMetaData()); int cols = rsmd.getColumnCount(); for (int row = 1; row <= rows; row++) { crs.absolute((row)); crs1.absolute(row); for (int col = 1; col <= cols; col++) { compareColumnValue(JDBCType.valueOf(rsmd.getColumnType(col)), crs, crs1, col); } } }
@Test public void testNull() throws Exception { DataWorldCallableStatement statement = sampleSparqlCallableStatement(); statement.setString("p", "not-null"); statement.setBigDecimal("bigdecimal", null); statement.setDate("date", null); statement.setNString("nstring", null); statement.setNull("null", Types.VARCHAR); statement.setNull("null2", Types.VARCHAR, "IGNORED"); statement.setObject("object", null); statement.setObject("object", null, Types.INTEGER); statement.setObject("object", null, JDBCType.INTEGER); statement.setString("string", null); statement.setTime("time", null); statement.setTimestamp("timestamp", null); statement.setURL("url", null); statement.execute(); verify(lastBackendRequest).handle(Method.POST, sparql.urlPath(), null, Utils.TYPE_FORM_URLENCODED, String.join("&", Utils.queryParam("query", "select ?s ?p ?o where {?s ?p ?o.} limit 10"), Utils.queryParam("$p", "\"not-null\""))); }
@Test public void testNull() throws Exception { DataWorldPreparedStatement statement = sql.prepareStatement(sql.connect(), "select * from Fielding where yearid in (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); int index = 0; statement.setString(++index, "not-null"); statement.setBigDecimal(++index, null); statement.setDate(++index, null); statement.setNString(++index, null); statement.setNull(++index, Types.VARCHAR); statement.setNull(++index, Types.VARCHAR, "IGNORED"); statement.setObject(++index, null); statement.setObject(++index, null, Types.INTEGER); statement.setObject(++index, null, JDBCType.INTEGER); statement.setString(++index, null); statement.setTime(++index, null); statement.setTimestamp(++index, null); statement.setURL(++index, null); statement.execute(); verify(lastBackendRequest).handle(Method.POST, sql.urlPath(), null, Utils.TYPE_FORM_URLENCODED, String.join("&", Utils.queryParam("query", "select * from Fielding where yearid in (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"), Utils.queryParam("$data_world_param0", "\"not-null\""))); }
@Test public void testAliasWithIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) .build() .render(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); softly.assertThat(fp.parameters().size()).isEqualTo(1); }); }
@Test public void testAliasWithoutIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); Map<SqlTable, String> tableAliases = new HashMap<>(); tableAliases.put(table, "a"); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.of(tableAliases)) .build() .render(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(fp.fragment()).isEqualTo("a.id = #{parameters.p1,jdbcType=INTEGER}"); softly.assertThat(fp.parameters().size()).isEqualTo(1); }); }
@Test public void testNoAliasWithIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) .build() .render(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); softly.assertThat(fp.parameters().size()).isEqualTo(1); }); }
@Test public void testNoAliasWithoutIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) .build() .render(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); softly.assertThat(fp.parameters().size()).isEqualTo(1); }); }
@Test public void testTypeHandler() { SqlTable table = SqlTable.of("foo"); SqlColumn<Date> column = SqlColumn.withName("id") .withTable(table) .withJdbcType(JDBCType.DATE) .withTypeHandler("foo.Bar") .build(); IsEqualTo<Date> condition = IsEqualTo.of(() -> new Date()); SqlCriterion<Date> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) .build() .render(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=DATE,typeHandler=foo.Bar}"); softly.assertThat(fp.parameters().size()).isEqualTo(1); }); }
@Test public void testTypeHandlerAndAlias() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER, "foo.Bar"); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); Map<SqlTable, String> tableAliases = new HashMap<>(); tableAliases.put(table, "a"); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.of(tableAliases)) .build() .render(); SoftAssertions.assertSoftly(softly -> { softly.assertThat(fp.fragment()).isEqualTo("a.id = #{parameters.p1,jdbcType=INTEGER,typeHandler=foo.Bar}"); softly.assertThat(fp.parameters().size()).isEqualTo(1); }); }
@Test public void testAliasWithIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) .build() .render(); assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); assertThat(fp.parameters().size()).isEqualTo(1); assertThat(fp.parameters().get("p1")).isEqualTo(3); }
@Test public void testAliasWithoutIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); Map<SqlTable, String> tableAliases = new HashMap<>(); tableAliases.put(table, "a"); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.of(tableAliases)) .build() .render(); assertThat(fp.fragment()).isEqualTo("a.id = #{parameters.p1,jdbcType=INTEGER}"); assertThat(fp.parameters().size()).isEqualTo(1); assertThat(fp.parameters().get("p1")).isEqualTo(3); }
@Test public void testNoAliasWithIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) .build() .render(); assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); assertThat(fp.parameters().size()).isEqualTo(1); assertThat(fp.parameters().get("p1")).isEqualTo(3); }
@Test public void testNoAliasWithoutIgnore() { SqlTable table = SqlTable.of("foo"); SqlColumn<Integer> column = table.column("id", JDBCType.INTEGER); IsEqualTo<Integer> condition = IsEqualTo.of(() -> 3); SqlCriterion<Integer> criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); AtomicInteger sequence = new AtomicInteger(1); FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) .withSequence(sequence) .withRenderingStrategy(RenderingStrategy.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) .build() .render(); assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); assertThat(fp.parameters().size()).isEqualTo(1); assertThat(fp.parameters().get("p1")).isEqualTo(3); }
public static ExpressionType fromJDBCType(JDBCType type) { // TODO research SQL types switch (type) { case DOUBLE: case FLOAT: case INTEGER: case NUMERIC: case DECIMAL: return NUMERIC; case VARCHAR: case LONGNVARCHAR: return VARCHAR; case BOOLEAN: return BOOLEAN; default: throw new IllegalArgumentException("Unimplemented"); } }
private String asStringValue(JDBCType jdbcType, Object o) { if (o == null) { return "null"; } switch (jdbcType) { case VARCHAR: case CHAR: case LONGNVARCHAR: return "'" + o.toString() + "'"; case TINYINT: case SMALLINT: case INTEGER: case BIGINT: case FLOAT: case REAL: case DOUBLE: case DECIMAL: return o.toString(); default: throw new IllegalArgumentException("Unsupported column type for INSERT: " + jdbcType); } }
public List<Row> getRows(List<JDBCType> columnTypes) { List<Row> values = newArrayList(); String delimiter = getColumnDelimiter(); QueryRowMapper rowMapper = new QueryRowMapper(columnTypes); Splitter valuesSplitter = Splitter.on(delimiter); if (isTrimValues()) { valuesSplitter = valuesSplitter.trimResults(); } for (String line : sqlSectionParsingResult.getContentLines()) { List<String> rowValues = parseLine(line, delimiter, valuesSplitter); values.add(rowMapper.mapToRow(rowValues)); } if (isJoinAllRowsToOne()) { checkState(columnTypes.size() == 1, "Expected single column result when 'joinAllRowsToOne' property is set, columnTypes: %s", columnTypes); String joinedRows = values.stream() .map(row -> String.valueOf(row.getValues().get(0))) .collect(joining("\n")); return ImmutableList.of(row(joinedRows)); } return values; }
private void dumpResults(QueryResult queryResult, Path path) throws IOException { if (!Files.exists(path)) { Files.createDirectory(path); } checkState(Files.isDirectory(path), "%s have to point to the directory", path); String testFileName = queryFile.getFileName().toString(); String resultsFileName = testFileName.substring(0, testFileName.lastIndexOf(".")) + ".result"; Path resultFilePath = Paths.get(path.toString(), resultsFileName); try (BufferedWriter writer = newBufferedWriter(resultFilePath)) { String types = queryResult.getColumnTypes().stream().map(JDBCType::getName).collect(joining("|")); writer.write("-- delimiter: |; types: " + types); writer.newLine(); for (List<Object> row : queryResult.rows()) { writer.write(new QueryAssert.Row(row).toString()); writer.newLine(); } } }
public <T> QueryAssert column(int columnIndex, JDBCType type, ColumnValuesAssert<T> columnValuesAssert) { if (fromSqlIndex(columnIndex) > actual.getColumnsCount()) { failWithMessage("Result contains only <%s> columns, extracting column <%s>", actual.getColumnsCount(), columnIndex); } JDBCType actualColumnType = actual.getColumnType(columnIndex); if (!type.equals(actualColumnType)) { failWithMessage("Expected <%s> column, to be type: <%s>, but was: <%s>", columnIndex, type, actualColumnType); } List<T> columnValues = actual.column(columnIndex); columnValuesAssert.assertColumnValues(Assertions.assertThat(columnValues)); return this; }
public static JDBCType jdbcType(Type type) { if (type.equals(BooleanType.BOOLEAN)) { return JDBCType.BOOLEAN; } if (type.equals(BigintType.BIGINT) || type.equals(TimestampType.TIMESTAMP)) { return JDBCType.BIGINT; } if (type.equals(DoubleType.DOUBLE)) { return JDBCType.DOUBLE; } if (type.equals(DateType.DATE)) { return JDBCType.INTEGER; } if (type.equals(VarcharType.VARCHAR)) { return JDBCType.VARBINARY; } return null; }
private static String sqlColumnType(Type type) { JDBCType jdbcType = jdbcType(type); if (jdbcType != null) { switch (jdbcType) { case BOOLEAN: return "boolean"; case BIGINT: return "bigint"; case DOUBLE: return "double"; case INTEGER: return "int"; case VARBINARY: return format("varbinary(%s)", MAX_BINARY_INDEX_SIZE); } } return null; }