Skip to content

Commit 32c7d09

Browse files
Added UCVolumeClient Interface and Class Implementation with Tests + prefixExists feature (#186)
* Saving my work so far * One basic test case working in DriverTester * Updated working of prefixExists testcase with LIST files instead of SHOW VOLUMES * Added basic test functions for many methods in DriverTester * Saving my work - tests + prefix exists unit and parameterised test * Added Interface and Class implementation of UCVolumeClient along with tests * did mvn spotless:apply * Addressed Madhav and Samikshya's comments. Added a case sensitive toggle for the prefixExists function. * forgot mvn spotless apply * minor changes * minor changes * Implemented Madhav's overloading suggestion + added logger statements * minor changes * addressed comments
1 parent e1e6a07 commit 32c7d09

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.databricks.jdbc.client;
2+
3+
import java.sql.SQLException;
4+
5+
public interface IDatabricksUCVolumeClient {
6+
7+
/**
8+
* prefixExists(): Determines if a specific prefix (folder-like structure) exists in the UC Volume
9+
* The prefix that we are looking for must be a part of the file name.
10+
*
11+
* @param catalog the catalog name of the cloud storage
12+
* @param schema the schema name of the cloud storage
13+
* @param volume the UC volume name of the cloud storage
14+
* @param prefix the prefix to check for existence
15+
* @param caseSensitive a boolean indicating whether the check should be case sensitive or not
16+
* @return a boolean indicating whether the prefix exists or not
17+
*/
18+
boolean prefixExists(
19+
String catalog, String schema, String volume, String prefix, boolean caseSensitive)
20+
throws SQLException;
21+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.databricks.jdbc.client.impl.sdk;
2+
3+
import com.databricks.jdbc.client.IDatabricksUCVolumeClient;
4+
import java.sql.*;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
/** Implementation for DatabricksUCVolumeClient */
9+
public class DatabricksUCVolumeClient implements IDatabricksUCVolumeClient {
10+
11+
private final Connection connection;
12+
13+
private static final Logger LOGGER = LoggerFactory.getLogger(DatabricksSdkClient.class);
14+
15+
public DatabricksUCVolumeClient(Connection connection) {
16+
this.connection = connection;
17+
}
18+
19+
private String createListQuery(String catalog, String schema, String volume) {
20+
return String.format("LIST '/Volumes/%s/%s/%s/'", catalog, schema, volume);
21+
}
22+
23+
public boolean prefixExists(String catalog, String schema, String volume, String prefix)
24+
throws SQLException {
25+
return prefixExists(catalog, schema, volume, prefix, true);
26+
}
27+
28+
@Override
29+
public boolean prefixExists(
30+
String catalog, String schema, String volume, String prefix, boolean caseSensitive)
31+
throws SQLException {
32+
33+
LOGGER.info(
34+
"Entering prefixExists method with parameters: catalog={}, schema={}, volume={}, prefix={}, caseSensitive={}",
35+
catalog,
36+
schema,
37+
volume,
38+
prefix,
39+
caseSensitive);
40+
41+
String listFilesSQLQuery = createListQuery(catalog, schema, volume);
42+
43+
try (Statement statement = connection.createStatement()) {
44+
ResultSet resultSet = statement.executeQuery(listFilesSQLQuery);
45+
LOGGER.info("SQL query executed successfully");
46+
47+
boolean exists = false;
48+
while (resultSet.next()) {
49+
String fileName = resultSet.getString("name");
50+
if (fileName.regionMatches(!caseSensitive, 0, prefix, 0, prefix.length())) {
51+
exists = true;
52+
break;
53+
}
54+
}
55+
return exists;
56+
} catch (SQLException e) {
57+
LOGGER.error("SQL query execution failed", e);
58+
throw e;
59+
}
60+
}
61+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.databricks.jdbc.core;
2+
3+
import static com.databricks.jdbc.TestConstants.*;
4+
import static org.junit.jupiter.api.Assertions.*;
5+
import static org.mockito.Mockito.*;
6+
7+
import com.databricks.jdbc.client.impl.sdk.DatabricksUCVolumeClient;
8+
import java.sql.*;
9+
import java.util.stream.Stream;
10+
import org.junit.jupiter.api.extension.ExtendWith;
11+
import org.junit.jupiter.params.ParameterizedTest;
12+
import org.junit.jupiter.params.provider.Arguments;
13+
import org.junit.jupiter.params.provider.MethodSource;
14+
import org.mockito.Mock;
15+
import org.mockito.junit.jupiter.MockitoExtension;
16+
17+
@ExtendWith(MockitoExtension.class)
18+
public class DatabricksUCVolumeClientTest {
19+
20+
@Mock Connection connection;
21+
22+
@Mock Statement statement;
23+
24+
@Mock ResultSet resultSet;
25+
26+
@ParameterizedTest
27+
@MethodSource("provideParametersForPrefixExists")
28+
public void testPrefixExists(String volume, String prefix, boolean expected) throws SQLException {
29+
DatabricksUCVolumeClient client = new DatabricksUCVolumeClient(connection);
30+
31+
when(connection.createStatement()).thenReturn(statement);
32+
String listFilesSQL =
33+
"LIST '/Volumes/" + TEST_CATALOG + "/" + TEST_SCHEMA + "/" + volume + "/'";
34+
when(statement.executeQuery(listFilesSQL)).thenReturn(resultSet);
35+
when(resultSet.next()).thenReturn(true, true, true, true, true, false);
36+
when(resultSet.getString("name"))
37+
.thenReturn("aBc_file1", "abC_file2", "def_file1", "efg_file2", "#!#_file3");
38+
39+
boolean exists = client.prefixExists(TEST_CATALOG, TEST_SCHEMA, volume, prefix, true);
40+
41+
assertEquals(expected, exists);
42+
verify(statement).executeQuery(listFilesSQL);
43+
}
44+
45+
private static Stream<Arguments> provideParametersForPrefixExists() {
46+
return Stream.of(
47+
Arguments.of("abc_volume1", "abc", false),
48+
Arguments.of("abc_volume2", "xyz", false),
49+
Arguments.of("abc_volume2", "def", true),
50+
Arguments.of("abc_volume2", "#!", true),
51+
Arguments.of("abc_volume2", "aBc", true));
52+
}
53+
}

0 commit comments

Comments
 (0)