ExtensionTest.java
package org.sqlite;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assumptions.assumeThat;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledInNativeImage;
public class ExtensionTest {
Connection conn;
Statement stat;
@BeforeEach
public void setUp() throws Exception {
conn = DriverManager.getConnection("jdbc:sqlite:");
stat = conn.createStatement();
}
@AfterEach
public void tearDown() throws Exception {
if (stat != null) {
stat.close();
}
if (conn != null) {
conn.close();
}
}
@Test
public void loadExtensionEnabled() throws Exception {
SQLiteConnection connection =
(SQLiteConnection)
DriverManager.getConnection(
"jdbc:sqlite::memory:?enable_load_extension=true");
assertThat(connection.getDatabase().getConfig().isEnabledLoadExtension()).isTrue();
}
@Test
public void extFTS3() throws Exception {
stat.execute("create virtual table recipe using fts3(name, ingredients)");
stat.execute(
"insert into recipe (name, ingredients) values('broccoli stew', 'broccoli peppers cheese tomatoes')");
stat.execute(
"insert into recipe (name, ingredients) values('pumpkin stew', 'pumpkin onions garlic celery')");
ResultSet rs =
stat.executeQuery(
"select rowid, name, ingredients from recipe where ingredients match 'onions'");
assertThat(rs.next()).isTrue();
assertThat(rs.getString(2)).isEqualTo("pumpkin stew");
}
@Test
public void extFTS5() throws Exception {
stat.execute("create virtual table recipe using fts5(name, ingredients)");
stat.execute(
"insert into recipe (name, ingredients) values('broccoli stew', 'broccoli peppers cheese tomatoes')");
stat.execute(
"insert into recipe (name, ingredients) values('pumpkin stew', 'pumpkin onions garlic celery')");
ResultSet rs =
stat.executeQuery(
"select rowid, name, ingredients from recipe where recipe match 'onions'");
assertThat(rs.next()).isTrue();
assertThat(rs.getString(2)).isEqualTo("pumpkin stew");
}
@Test
@DisabledInNativeImage // assertj Assumptions do not work in native-image tests
public void extFunctions() throws Exception {
Utils.assumeJdbcExtensions(conn);
{
ResultSet rs = stat.executeQuery("select reverse(\"ACGT\")");
assertThat(rs.next()).isTrue();
assertThat(rs.getString(1)).isEqualTo("TGCA");
rs.close();
}
}
@Test
@DisabledInNativeImage // assertj Assumptions do not work in native-image tests
public void extFunctionsTruncatedUtf8() throws Exception {
Utils.assumeJdbcExtensions(conn);
// A text value that ends in a truncated multibyte sequence: the lead byte
// announces more trailing bytes than the value actually holds. The utf-8
// reader behind these functions used to read those missing bytes past the
// terminating nul, a heap over-read. Each lead byte below claims 1, 2 and 3
// trailing bytes respectively, so all three trailing-byte cases are covered.
String[] truncated = {"x'c3'", "x'e0'", "x'f0'", "x'f4'"};
for (String value : truncated) {
String text = "cast(" + value + " as text)";
// every call site of the reader
assertReturnsRow("select reverse(" + text + ")");
assertReturnsRow("select proper(" + text + ")");
assertReturnsRow("select leftstr(" + text + ", 1)");
assertReturnsRow("select rightstr(" + text + ", 1)");
assertReturnsRow("select charindex('a', " + text + ")");
assertReturnsRow("select strfilter(" + text + ", 'a')");
assertReturnsRow("select difference(" + text + ", 'abc')");
}
// well-formed multibyte input still decodes as before
ResultSet rs = stat.executeQuery("select reverse('a�����')");
assertThat(rs.next()).isTrue();
assertThat(rs.getString(1)).isEqualTo("�����a");
rs.close();
}
private void assertReturnsRow(String sql) throws Exception {
try (ResultSet rs = stat.executeQuery(sql)) {
assertThat(rs.next()).isTrue();
rs.getString(1);
}
}
@Test
@DisabledInNativeImage // assertj Assumptions do not work in native-image tests
public void dbstat() throws Exception {
assumeThat(Utils.getCompileOptions(conn))
.as("SQLite has to be compiled with ENABLE_DBSTAT_VTAB")
.contains("ENABLE_DBSTAT_VTAB");
{
boolean result = stat.execute("SELECT * FROM dbstat");
assertThat(result).isTrue();
}
}
}