Skip to content

Commit

Permalink
feat: Indicate in metadata which client info properties are supported…
Browse files Browse the repository at this point in the history
…. [metadata]

Signed-off-by: Michael Simons <[email protected]>
  • Loading branch information
michael-simons committed Jan 9, 2025
1 parent 9d179b1 commit f1baf87
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ private void setClientInfo0(String name, String value) throws SQLWarning {
var throwable = new SQLClientInfoException(Map.of("", ClientInfoStatus.REASON_UNKNOWN));
throw new SQLWarning("Client information without a name are not supported", throwable);
}
if (!Set.of("ApplicationName", "ClientUser", "ClientHostname").contains(name)) {
if (!DatabaseMetadataImpl.isSupportedClientInfoProperty(name)) {
var throwable = new SQLClientInfoException(Map.of(name, ClientInfoStatus.REASON_UNKNOWN_PROPERTY));
throw new SQLWarning("Unknown client info property `" + name + "`", throwable);
}
Expand Down
28 changes: 26 additions & 2 deletions neo4j-jdbc/src/main/java/org/neo4j/jdbc/DatabaseMetadataImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ final class DatabaseMetadataImpl implements DatabaseMetaData {
private static final List<String> TIME_DATE_FUNCTIONS = List.of("date", "datetime", "localdatetime", "localtime",
"time", "duration");

private static final List<ClientInfoProperty> SUPPORTED_CLIENT_INFO_PROPERTIES = List.of(
new ClientInfoProperty("ApplicationName", "The name of the application currently utilizing the connection"),
new ClientInfoProperty("ClientUser",
"The name of the user that the application using the connection is performing work for"),
new ClientInfoProperty("ClientHostname",
"The hostname of the computer the application using the connection is running on"));

private static final Logger LOGGER = Logger.getLogger(DatabaseMetadataImpl.class.getCanonicalName());

private final Connection connection;
Expand Down Expand Up @@ -1476,8 +1483,22 @@ public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
}

@Override
public ResultSet getClientInfoProperties() throws SQLException {
throw new SQLFeatureNotSupportedException();
public ResultSet getClientInfoProperties() {

var keys = List.of("NAME", "MAX_LEN", "DEFAULT_VALUE", "DESCRIPTION");
var values = new ArrayList<Value[]>();
for (var property : SUPPORTED_CLIENT_INFO_PROPERTIES) {
values.add(new Value[] { Values.value(property.name()), Values.value(65536), Values.NULL,
Values.value(property.description()) });
}
var response = createRunResponseForStaticKeys(keys);
var pull = staticPullResponseFor(keys, values);

return new ResultSetImpl(new LocalStatementImpl(), new ThrowingTransactionImpl(), response, pull, -1, -1, -1);
}

static boolean isSupportedClientInfoProperty(String name) {
return SUPPORTED_CLIENT_INFO_PROPERTIES.stream().anyMatch(p -> p.name().equals(name));
}

@Override
Expand Down Expand Up @@ -1640,4 +1661,7 @@ private record QueryAndRunResponse(PullResponse pullResponse, CompletableFuture<
private record UniqueConstraint(String name, List<String> labelsOrTypes, List<String> properties) {
}

private record ClientInfoProperty(String name, String description) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,31 @@ void getTypeInfoShouldWork() throws SQLException {
}
}

@Test
void getClientInfoPropertiesShouldWork() throws SQLException {
var connection = newConnection();
var maxLen = (int) Math.pow(2, 16);
try (var rs = connection.getMetaData().getClientInfoProperties()) {
assertThat(rs.next()).isTrue();
assertThat(rs.getString("NAME")).isEqualTo("ApplicationName");
assertThat(rs.getInt("MAX_LEN")).isEqualTo(maxLen);
assertThat(rs.getString("DEFAULT_VALUE")).isNull();
assertThat(rs.getString("DESCRIPTION")).isNotNull();
assertThat(rs.next()).isTrue();
assertThat(rs.getString("NAME")).isEqualTo("ClientUser");
assertThat(rs.getInt("MAX_LEN")).isEqualTo(maxLen);
assertThat(rs.getString("DESCRIPTION")).isNotNull();
assertThat(rs.next()).isTrue();
assertThat(rs.getString("NAME")).isEqualTo("ClientHostname");
assertThat(rs.getInt("MAX_LEN")).isEqualTo(maxLen);
assertThat(rs.getString("DESCRIPTION")).isNotNull();
assertThat(rs.next()).isFalse();
}

connection.setClientInfo("ApplicationName", "a unit test");
assertThat(connection.getClientInfo("ApplicationName")).isEqualTo("a unit test");
}

private Connection newConnection() throws SQLException {
var url = "jdbc:neo4j://host";

Expand Down

0 comments on commit f1baf87

Please sign in to comment.