|
9 | 9 | import org.junit.jupiter.params.provider.Arguments; |
10 | 10 | import org.junit.jupiter.params.provider.MethodSource; |
11 | 11 |
|
| 12 | +import java.io.IOException; |
12 | 13 | import java.io.InputStream; |
13 | 14 | import java.io.Reader; |
14 | 15 | import java.math.BigDecimal; |
|
36 | 37 | import java.util.stream.Stream; |
37 | 38 |
|
38 | 39 | import static org.assertj.core.api.Assertions.assertThat; |
| 40 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
39 | 41 | import static org.junit.jupiter.api.Assertions.fail; |
40 | 42 |
|
41 | 43 | /** |
@@ -465,6 +467,107 @@ void b6TemporalGettersRejectNonDateText() { |
465 | 467 | } |
466 | 468 | } |
467 | 469 |
|
| 470 | + // --------------------------------------------------------------------- |
| 471 | + // PR-3 wrappers: URL, NClob, SQLXML, RowId, and the ASCII/Unicode streams. |
| 472 | + // --------------------------------------------------------------------- |
| 473 | + |
| 474 | + @Test |
| 475 | + void b1UrlGetterParsesAbsoluteTextAndRejectsTheRest() throws SQLException { |
| 476 | + LibsqlResultSet absolute = oneRow(jdbcType("DATALINK"), TEXT_URL); |
| 477 | + assertThat(absolute.next()).isTrue(); |
| 478 | + assertThat(absolute.getURL(1).toExternalForm()).isEqualTo("https://example.com"); |
| 479 | + assertThat(absolute.getURL("c").toExternalForm()).isEqualTo("https://example.com"); |
| 480 | + |
| 481 | + LibsqlResultSet malformed = oneRow(jdbcType("DATALINK"), Value.of("not a url")); |
| 482 | + assertThat(malformed.next()).isTrue(); |
| 483 | + assertThatThrownBy(() -> malformed.getURL(1)) |
| 484 | + .isInstanceOf(SQLException.class) |
| 485 | + .hasMessageContaining("URL"); |
| 486 | + } |
| 487 | + |
| 488 | + @Test |
| 489 | + void b3NewWrappersReadBackTheirContent() throws Exception { |
| 490 | + LibsqlResultSet nclobRow = oneRow(jdbcType("NCLOB"), TEXT_ABC); |
| 491 | + assertThat(nclobRow.next()).isTrue(); |
| 492 | + NClob nclob = nclobRow.getNClob(1); |
| 493 | + assertThat(nclob.length()).isEqualTo(3); |
| 494 | + assertThat(nclob.getSubString(1, 2)).isEqualTo("ab"); |
| 495 | + assertThat(readAll(nclob.getCharacterStream())).isEqualTo("abc"); |
| 496 | + assertThat(nclobRow.getNClob("c").getSubString(2, 1)).isEqualTo("b"); |
| 497 | + |
| 498 | + LibsqlResultSet xmlRow = oneRow(jdbcType("SQLXML"), TEXT_XML); |
| 499 | + assertThat(xmlRow.next()).isTrue(); |
| 500 | + SQLXML xml = xmlRow.getSQLXML(1); |
| 501 | + assertThat(xml.getString()).isEqualTo("<a/>"); |
| 502 | + assertThat(readAll(xml.getCharacterStream())).isEqualTo("<a/>"); |
| 503 | + assertThat(readAll(xml.getBinaryStream())).isEqualTo("<a/>".getBytes(StandardCharsets.UTF_8)); |
| 504 | + assertThat(xmlRow.getSQLXML("c").getString()).isEqualTo("<a/>"); |
| 505 | + |
| 506 | + LibsqlResultSet rowIdRow = oneRow(jdbcType("ROWID"), TEXT_ROWID); |
| 507 | + assertThat(rowIdRow.next()).isTrue(); |
| 508 | + assertThat(rowIdRow.getRowId(1).getBytes()) |
| 509 | + .isEqualTo("rowid-1".getBytes(StandardCharsets.UTF_8)); |
| 510 | + assertThat(rowIdRow.getRowId("c").getBytes()) |
| 511 | + .isEqualTo("rowid-1".getBytes(StandardCharsets.UTF_8)); |
| 512 | + |
| 513 | + LibsqlResultSet textRow = oneRow(jdbcType("VARCHAR"), TEXT_ABC); |
| 514 | + assertThat(textRow.next()).isTrue(); |
| 515 | + assertThat(readAll(textRow.getAsciiStream(1))) |
| 516 | + .isEqualTo("abc".getBytes(StandardCharsets.US_ASCII)); |
| 517 | + assertThat(readAll(textRow.getAsciiStream("c"))) |
| 518 | + .isEqualTo("abc".getBytes(StandardCharsets.US_ASCII)); |
| 519 | + assertThat(readAll(textRow.getNCharacterStream(1))).isEqualTo("abc"); |
| 520 | + assertThat(readAll(textRow.getNCharacterStream("c"))).isEqualTo("abc"); |
| 521 | + } |
| 522 | + |
| 523 | + @Test |
| 524 | + void b3FreedWrappersRejectFurtherReads() throws SQLException { |
| 525 | + LibsqlResultSet nclobRow = oneRow(jdbcType("NCLOB"), TEXT_ABC); |
| 526 | + assertThat(nclobRow.next()).isTrue(); |
| 527 | + NClob nclob = nclobRow.getNClob(1); |
| 528 | + nclob.free(); |
| 529 | + assertThatThrownBy(nclob::length).isInstanceOf(SQLException.class); |
| 530 | + assertThatThrownBy(() -> nclob.getSubString(1, 1)).isInstanceOf(SQLException.class); |
| 531 | + assertThatThrownBy(nclob::getCharacterStream).isInstanceOf(SQLException.class); |
| 532 | + |
| 533 | + LibsqlResultSet xmlRow = oneRow(jdbcType("SQLXML"), TEXT_XML); |
| 534 | + assertThat(xmlRow.next()).isTrue(); |
| 535 | + SQLXML xml = xmlRow.getSQLXML(1); |
| 536 | + xml.free(); |
| 537 | + assertThatThrownBy(xml::getString).isInstanceOf(SQLException.class); |
| 538 | + assertThatThrownBy(xml::getCharacterStream).isInstanceOf(SQLException.class); |
| 539 | + assertThatThrownBy(xml::getBinaryStream).isInstanceOf(SQLException.class); |
| 540 | + |
| 541 | + LibsqlResultSet clobRow = oneRow(jdbcType("CLOB"), TEXT_ABC); |
| 542 | + assertThat(clobRow.next()).isTrue(); |
| 543 | + Clob clob = clobRow.getClob(1); |
| 544 | + clob.free(); |
| 545 | + assertThatThrownBy(clob::length).isInstanceOf(SQLException.class); |
| 546 | + assertThatThrownBy(clob::getCharacterStream).isInstanceOf(SQLException.class); |
| 547 | + assertThatThrownBy(clob::getAsciiStream).isInstanceOf(SQLException.class); |
| 548 | + |
| 549 | + LibsqlResultSet blobRow = oneRow(jdbcType("BLOB"), BYTES_ABC); |
| 550 | + assertThat(blobRow.next()).isTrue(); |
| 551 | + Blob blob = blobRow.getBlob(1); |
| 552 | + blob.free(); |
| 553 | + assertThatThrownBy(blob::length).isInstanceOf(SQLException.class); |
| 554 | + assertThatThrownBy(blob::getBinaryStream).isInstanceOf(SQLException.class); |
| 555 | + assertThatThrownBy(() -> blob.getBytes(1, 1)).isInstanceOf(SQLException.class); |
| 556 | + } |
| 557 | + |
| 558 | + @Test |
| 559 | + void b3RowIdComparesAndCopiesItsBytes() { |
| 560 | + LibsqlRowId rowId = new LibsqlRowId(new byte[] {1, 2}); |
| 561 | + byte[] returned = rowId.getBytes(); |
| 562 | + returned[0] = 9; |
| 563 | + |
| 564 | + assertThat(rowId.getBytes()).containsExactly(1, 2); |
| 565 | + assertThat(rowId) |
| 566 | + .isEqualTo(new LibsqlRowId(new byte[] {1, 2})) |
| 567 | + .hasSameHashCodeAs(new LibsqlRowId(new byte[] {1, 2})) |
| 568 | + .isNotEqualTo(new LibsqlRowId(new byte[] {1, 3})); |
| 569 | + } |
| 570 | + |
468 | 571 | // --------------------------------------------------------------------- |
469 | 572 | // Fixtures and helpers. |
470 | 573 | // --------------------------------------------------------------------- |
@@ -502,6 +605,20 @@ private static LibsqlResultSet oneRow(JdbcType type, Value value) { |
502 | 605 | return oneRow(type.name(), value); |
503 | 606 | } |
504 | 607 |
|
| 608 | + private static String readAll(Reader reader) throws IOException { |
| 609 | + StringBuilder text = new StringBuilder(); |
| 610 | + char[] buffer = new char[256]; |
| 611 | + int count; |
| 612 | + while ((count = reader.read(buffer)) != -1) { |
| 613 | + text.append(buffer, 0, count); |
| 614 | + } |
| 615 | + return text.toString(); |
| 616 | + } |
| 617 | + |
| 618 | + private static byte[] readAll(InputStream stream) throws IOException { |
| 619 | + return stream.readAllBytes(); |
| 620 | + } |
| 621 | + |
505 | 622 | private static LibsqlResultSet oneRow(String declaredType, Value value) { |
506 | 623 | return new LibsqlResultSet( |
507 | 624 | new LibsqlStatement(null), |
|
0 commit comments