Skip to content

Commit d6ea8b7

Browse files
committed
feat(jdbc): read key and type metadata from SQLite pragmas
getImportedKeys, getExportedKeys, and getCrossReference now map pragma foreign_key_list rows to the JDBC shape, getTypeInfo returns the sqlite-jdbc type table, and getPrimaryKeys reports the parsed constraint name in PK_NAME. Fixes #113
1 parent 662d066 commit d6ea8b7

3 files changed

Lines changed: 775 additions & 24 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.github.magnusp.libsql.itest;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import java.sql.Connection;
6+
import java.sql.DatabaseMetaData;
7+
import java.sql.DriverManager;
8+
import java.sql.ResultSet;
9+
import java.sql.SQLException;
10+
import java.sql.Statement;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
14+
import static org.assertj.core.api.Assertions.assertThat;
15+
16+
public class DatabaseMetaDataIT extends SqldContainerBase {
17+
18+
private String getDriverJdbcUrl() {
19+
return "jdbc:libsql:" + getHttpUrl();
20+
}
21+
22+
@Test
23+
void keyAndTypeMetadataRoundTripThroughHrana() throws SQLException {
24+
try (Connection conn = DriverManager.getConnection(getDriverJdbcUrl())) {
25+
try (Statement s = conn.createStatement()) {
26+
s.execute("CREATE TABLE meta_parent (id INTEGER, label TEXT, "
27+
+ "CONSTRAINT pk_meta_parent PRIMARY KEY (id))");
28+
s.execute("CREATE TABLE meta_child (id INTEGER, parent_id INTEGER, "
29+
+ "CONSTRAINT fk_meta_child_parent FOREIGN KEY (parent_id) "
30+
+ "REFERENCES meta_parent (id) ON DELETE CASCADE)");
31+
}
32+
DatabaseMetaData metadata = conn.getMetaData();
33+
34+
try (ResultSet rs = metadata.getPrimaryKeys(null, null, "meta_parent")) {
35+
assertThat(rs.next()).isTrue();
36+
assertThat(rs.getString("COLUMN_NAME")).isEqualTo("id");
37+
assertThat(rs.getInt("KEY_SEQ")).isEqualTo(1);
38+
assertThat(rs.getString("PK_NAME")).isEqualTo("pk_meta_parent");
39+
assertThat(rs.next()).isFalse();
40+
}
41+
42+
try (ResultSet rs = metadata.getImportedKeys(null, null, "meta_child")) {
43+
assertThat(rs.next()).isTrue();
44+
assertThat(rs.getString("PKTABLE_NAME")).isEqualTo("meta_parent");
45+
assertThat(rs.getString("PKCOLUMN_NAME")).isEqualTo("id");
46+
assertThat(rs.getString("FKTABLE_NAME")).isEqualTo("meta_child");
47+
assertThat(rs.getString("FKCOLUMN_NAME")).isEqualTo("parent_id");
48+
assertThat(rs.getInt("KEY_SEQ")).isEqualTo(1);
49+
assertThat(rs.getInt("DELETE_RULE")).isEqualTo(DatabaseMetaData.importedKeyCascade);
50+
assertThat(rs.getString("FK_NAME")).isEqualTo("fk_meta_child_parent");
51+
assertThat(rs.getString("PK_NAME")).isEqualTo("pk_meta_parent");
52+
assertThat(rs.next()).isFalse();
53+
}
54+
55+
try (ResultSet rs = metadata.getExportedKeys(null, null, "meta_parent")) {
56+
assertThat(rs.next()).isTrue();
57+
assertThat(rs.getString("PKTABLE_NAME")).isEqualTo("meta_parent");
58+
assertThat(rs.getString("FKTABLE_NAME")).isEqualTo("meta_child");
59+
assertThat(rs.getString("FK_NAME")).isEqualTo("fk_meta_child_parent");
60+
assertThat(rs.getString("PK_NAME")).isEqualTo("pk_meta_parent");
61+
assertThat(rs.next()).isFalse();
62+
}
63+
64+
try (ResultSet rs = metadata.getCrossReference(null, null, "meta_parent", null, null, "meta_child")) {
65+
assertThat(rs.next()).isTrue();
66+
assertThat(rs.getString("PKTABLE_NAME")).isEqualTo("meta_parent");
67+
assertThat(rs.getString("FKTABLE_NAME")).isEqualTo("meta_child");
68+
assertThat(rs.next()).isFalse();
69+
}
70+
71+
try (ResultSet rs = metadata.getTypeInfo()) {
72+
List<String> typeNames = new ArrayList<>();
73+
while (rs.next()) {
74+
typeNames.add(rs.getString("TYPE_NAME"));
75+
}
76+
assertThat(typeNames).containsExactly("NULL", "INTEGER", "REAL", "TEXT", "BLOB");
77+
}
78+
}
79+
}
80+
81+
@Test
82+
void keyMetadataWithoutForeignKeysIsEmptyAndWellFormed() throws SQLException {
83+
try (Connection conn = DriverManager.getConnection(getDriverJdbcUrl())) {
84+
try (Statement s = conn.createStatement()) {
85+
s.execute("CREATE TABLE meta_plain (id INTEGER PRIMARY KEY, value TEXT)");
86+
}
87+
DatabaseMetaData metadata = conn.getMetaData();
88+
89+
try (ResultSet rs = metadata.getImportedKeys(null, null, "meta_plain")) {
90+
assertThat(rs.getMetaData().getColumnCount()).isEqualTo(14);
91+
assertThat(rs.next()).isFalse();
92+
}
93+
try (ResultSet rs = metadata.getExportedKeys(null, null, "meta_plain")) {
94+
assertThat(rs.getMetaData().getColumnCount()).isEqualTo(14);
95+
assertThat(rs.next()).isFalse();
96+
}
97+
try (ResultSet rs = metadata.getCrossReference(null, null, "meta_plain", null, null, "meta_plain")) {
98+
assertThat(rs.getMetaData().getColumnCount()).isEqualTo(14);
99+
assertThat(rs.next()).isFalse();
100+
}
101+
try (ResultSet rs = metadata.getPrimaryKeys(null, null, "meta_plain")) {
102+
assertThat(rs.next()).isTrue();
103+
assertThat(rs.getString("PK_NAME")).isNull();
104+
assertThat(rs.next()).isFalse();
105+
}
106+
}
107+
}
108+
}

0 commit comments

Comments
 (0)