Skip to content

Commit 8c47734

Browse files
authored
JDBC: Simplify JDBC entity conversion (#1564)
1 parent d7615fd commit 8c47734

File tree

8 files changed

+77
-91
lines changed

8 files changed

+77
-91
lines changed

extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/DatasourceOperations.java

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.util.List;
3333
import java.util.Objects;
3434
import java.util.function.Consumer;
35-
import java.util.function.Function;
3635
import java.util.stream.Stream;
3736
import javax.sql.DataSource;
3837
import org.apache.polaris.extension.persistence.relational.jdbc.models.Converter;
@@ -96,20 +95,14 @@ public void executeScript(String scriptFilePath) throws SQLException {
9695
* @param query : Query to executed
9796
* @param converterInstance : An instance of the type being selected, used to convert to a
9897
* business entity like PolarisBaseEntity
99-
* @param transformer Transformation of entity class to Result class
10098
* @return The list of results yielded by the query
101-
* @param <T> : Persistence entity class
102-
* @param <R> : Business entity class
99+
* @param <T> : Business entity class
103100
* @throws SQLException : Exception during the query execution.
104101
*/
105-
public <T, R> List<R> executeSelect(
106-
@Nonnull String query,
107-
@Nonnull Converter<T> converterInstance,
108-
@Nonnull Function<T, R> transformer)
102+
public <T> List<T> executeSelect(@Nonnull String query, @Nonnull Converter<T> converterInstance)
109103
throws SQLException {
110-
ArrayList<R> results = new ArrayList<>();
111-
executeSelectOverStream(
112-
query, converterInstance, stream -> stream.map(transformer).forEach(results::add));
104+
ArrayList<T> results = new ArrayList<>();
105+
executeSelectOverStream(query, converterInstance, stream -> stream.forEach(results::add));
113106
return results;
114107
}
115108

extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/JdbcBasePersistenceImpl.java

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,7 @@ public PolarisBaseEntity lookupEntityByName(
299299
@Nullable
300300
private PolarisBaseEntity getPolarisBaseEntity(String query) {
301301
try {
302-
List<PolarisBaseEntity> results =
303-
datasourceOperations.executeSelect(query, new ModelEntity(), ModelEntity::toEntity);
302+
var results = datasourceOperations.executeSelect(query, new ModelEntity());
304303
if (results.isEmpty()) {
305304
return null;
306305
} else if (results.size() > 1) {
@@ -324,7 +323,7 @@ public List<PolarisBaseEntity> lookupEntities(
324323
if (entityIds == null || entityIds.isEmpty()) return new ArrayList<>();
325324
String query = generateSelectQueryWithEntityIds(realmId, entityIds);
326325
try {
327-
return datasourceOperations.executeSelect(query, new ModelEntity(), ModelEntity::toEntity);
326+
return datasourceOperations.executeSelect(query, new ModelEntity());
328327
} catch (SQLException e) {
329328
throw new RuntimeException(
330329
String.format("Failed to retrieve polaris entities due to %s", e.getMessage()), e);
@@ -420,7 +419,7 @@ public <T> Page<T> listEntities(
420419
query,
421420
new ModelEntity(),
422421
stream -> {
423-
var data = stream.map(ModelEntity::toEntity).filter(entityFilter);
422+
var data = stream.filter(entityFilter);
424423
if (pageToken instanceof HasPageSize hasPageSize) {
425424
data = data.limit(hasPageSize.getPageSize());
426425
}
@@ -472,9 +471,7 @@ public PolarisGrantRecord lookupGrantRecord(
472471
realmId);
473472
String query = generateSelectQuery(new ModelGrantRecord(), params);
474473
try {
475-
List<PolarisGrantRecord> results =
476-
datasourceOperations.executeSelect(
477-
query, new ModelGrantRecord(), ModelGrantRecord::toGrantRecord);
474+
var results = datasourceOperations.executeSelect(query, new ModelGrantRecord());
478475
if (results.size() > 1) {
479476
throw new IllegalStateException(
480477
String.format(
@@ -503,9 +500,7 @@ public List<PolarisGrantRecord> loadAllGrantRecordsOnSecurable(
503500
realmId);
504501
String query = generateSelectQuery(new ModelGrantRecord(), params);
505502
try {
506-
List<PolarisGrantRecord> results =
507-
datasourceOperations.executeSelect(
508-
query, new ModelGrantRecord(), ModelGrantRecord::toGrantRecord);
503+
var results = datasourceOperations.executeSelect(query, new ModelGrantRecord());
509504
return results == null ? Collections.emptyList() : results;
510505
} catch (SQLException e) {
511506
throw new RuntimeException(
@@ -525,9 +520,7 @@ public List<PolarisGrantRecord> loadAllGrantRecordsOnGrantee(
525520
"grantee_catalog_id", granteeCatalogId, "grantee_id", granteeId, "realm_id", realmId);
526521
String query = generateSelectQuery(new ModelGrantRecord(), params);
527522
try {
528-
List<PolarisGrantRecord> results =
529-
datasourceOperations.executeSelect(
530-
query, new ModelGrantRecord(), ModelGrantRecord::toGrantRecord);
523+
var results = datasourceOperations.executeSelect(query, new ModelGrantRecord());
531524
return results == null ? Collections.emptyList() : results;
532525
} catch (SQLException e) {
533526
throw new RuntimeException(
@@ -553,8 +546,7 @@ public boolean hasChildren(
553546
}
554547
String query = generateSelectQuery(new ModelEntity(), params);
555548
try {
556-
List<ModelEntity> results =
557-
datasourceOperations.executeSelect(query, new ModelEntity(), Function.identity());
549+
var results = datasourceOperations.executeSelect(query, new ModelEntity());
558550
return results != null && !results.isEmpty();
559551
} catch (SQLException e) {
560552
throw new RuntimeException(
@@ -571,11 +563,8 @@ public PolarisPrincipalSecrets loadPrincipalSecrets(
571563
Map<String, Object> params = Map.of("principal_client_id", clientId, "realm_id", realmId);
572564
String query = generateSelectQuery(new ModelPrincipalAuthenticationData(), params);
573565
try {
574-
List<PolarisPrincipalSecrets> results =
575-
datasourceOperations.executeSelect(
576-
query,
577-
new ModelPrincipalAuthenticationData(),
578-
ModelPrincipalAuthenticationData::toPrincipalAuthenticationData);
566+
var results =
567+
datasourceOperations.executeSelect(query, new ModelPrincipalAuthenticationData());
579568
return results == null || results.isEmpty() ? null : results.getFirst();
580569
} catch (SQLException e) {
581570
LOGGER.error(
@@ -875,11 +864,7 @@ public List<PolarisPolicyMappingRecord> loadAllTargetsOnPolicy(
875864

876865
private List<PolarisPolicyMappingRecord> fetchPolicyMappingRecords(String query) {
877866
try {
878-
List<PolarisPolicyMappingRecord> results =
879-
datasourceOperations.executeSelect(
880-
query,
881-
new ModelPolicyMappingRecord(),
882-
ModelPolicyMappingRecord::toPolicyMappingRecord);
867+
var results = datasourceOperations.executeSelect(query, new ModelPolicyMappingRecord());
883868
return results == null ? Collections.emptyList() : results;
884869
} catch (SQLException e) {
885870
throw new RuntimeException(

extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/Converter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public interface Converter<T> {
2727
* Converts a ResultSet to model.
2828
*
2929
* @param rs : ResultSet from JDBC.
30-
* @return Model of Entity
30+
* @return the corresponding business entity
3131
* @throws SQLException : Exception while fetching from ResultSet.
3232
*/
3333
T fromResultSet(ResultSet rs) throws SQLException;

extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelEntity.java

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import org.apache.polaris.core.entity.PolarisEntitySubType;
2727
import org.apache.polaris.core.entity.PolarisEntityType;
2828

29-
public class ModelEntity implements Converter<ModelEntity> {
29+
public class ModelEntity implements Converter<PolarisBaseEntity> {
3030
// the id of the catalog associated to that entity. use 0 if this entity is top-level
3131
// like a catalog
3232
private long catalogId;
@@ -138,27 +138,29 @@ public static Builder builder() {
138138
}
139139

140140
@Override
141-
public ModelEntity fromResultSet(ResultSet r) throws SQLException {
142-
return ModelEntity.builder()
143-
.catalogId(r.getObject("catalog_id", Long.class))
144-
.id(r.getObject("id", Long.class))
145-
.parentId(r.getObject("parent_id", Long.class))
146-
.typeCode(r.getObject("type_code", Integer.class))
147-
.name(r.getObject("name", String.class))
148-
.entityVersion(r.getObject("entity_version", Integer.class))
149-
.subTypeCode(r.getObject("sub_type_code", Integer.class))
150-
.createTimestamp(r.getObject("create_timestamp", Long.class))
151-
.dropTimestamp(r.getObject("drop_timestamp", Long.class))
152-
.purgeTimestamp(r.getObject("purge_timestamp", Long.class))
153-
.toPurgeTimestamp(r.getObject("to_purge_timestamp", Long.class))
154-
.lastUpdateTimestamp(r.getObject("last_update_timestamp", Long.class))
155-
.properties(
156-
r.getString("properties")) // required for extracting when the underlying type is JSONB
157-
.internalProperties(
158-
r.getString(
159-
"internal_properties")) // required for extracting when the underlying type is JSONB
160-
.grantRecordsVersion(r.getObject("grant_records_version", Integer.class))
161-
.build();
141+
public PolarisBaseEntity fromResultSet(ResultSet r) throws SQLException {
142+
var modelEntity =
143+
ModelEntity.builder()
144+
.catalogId(r.getObject("catalog_id", Long.class))
145+
.id(r.getObject("id", Long.class))
146+
.parentId(r.getObject("parent_id", Long.class))
147+
.typeCode(r.getObject("type_code", Integer.class))
148+
.name(r.getObject("name", String.class))
149+
.entityVersion(r.getObject("entity_version", Integer.class))
150+
.subTypeCode(r.getObject("sub_type_code", Integer.class))
151+
.createTimestamp(r.getObject("create_timestamp", Long.class))
152+
.dropTimestamp(r.getObject("drop_timestamp", Long.class))
153+
.purgeTimestamp(r.getObject("purge_timestamp", Long.class))
154+
.toPurgeTimestamp(r.getObject("to_purge_timestamp", Long.class))
155+
.lastUpdateTimestamp(r.getObject("last_update_timestamp", Long.class))
156+
// JSONB: use getString(), not getObject().
157+
.properties(r.getString("properties"))
158+
// JSONB: use getString(), not getObject().
159+
.internalProperties(r.getString("internal_properties"))
160+
.grantRecordsVersion(r.getObject("grant_records_version", Integer.class))
161+
.build();
162+
163+
return toEntity(modelEntity);
162164
}
163165

164166
@Override

extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelGrantRecord.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import java.util.Map;
2525
import org.apache.polaris.core.entity.PolarisGrantRecord;
2626

27-
public class ModelGrantRecord implements Converter<ModelGrantRecord> {
27+
public class ModelGrantRecord implements Converter<PolarisGrantRecord> {
2828
// id of the catalog where the securable entity resides, use 0, if this entity is a
2929
// top-level account entity.
3030
private long securableCatalogId;
@@ -67,14 +67,17 @@ public static Builder builder() {
6767
}
6868

6969
@Override
70-
public ModelGrantRecord fromResultSet(ResultSet rs) throws SQLException {
71-
return ModelGrantRecord.builder()
72-
.securableCatalogId(rs.getObject("securable_catalog_id", Long.class))
73-
.securableId(rs.getObject("securable_id", Long.class))
74-
.granteeCatalogId(rs.getObject("grantee_catalog_id", Long.class))
75-
.granteeId(rs.getObject("grantee_id", Long.class))
76-
.privilegeCode(rs.getObject("privilege_code", Integer.class))
77-
.build();
70+
public PolarisGrantRecord fromResultSet(ResultSet rs) throws SQLException {
71+
var modelGrantRecord =
72+
ModelGrantRecord.builder()
73+
.securableCatalogId(rs.getObject("securable_catalog_id", Long.class))
74+
.securableId(rs.getObject("securable_id", Long.class))
75+
.granteeCatalogId(rs.getObject("grantee_catalog_id", Long.class))
76+
.granteeId(rs.getObject("grantee_id", Long.class))
77+
.privilegeCode(rs.getObject("privilege_code", Integer.class))
78+
.build();
79+
80+
return toGrantRecord(modelGrantRecord);
7881
}
7982

8083
@Override

extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPolicyMappingRecord.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import java.util.Map;
2525
import org.apache.polaris.core.policy.PolarisPolicyMappingRecord;
2626

27-
public class ModelPolicyMappingRecord implements Converter<ModelPolicyMappingRecord> {
27+
public class ModelPolicyMappingRecord implements Converter<PolarisPolicyMappingRecord> {
2828
// id of the catalog where target entity resides
2929
private long targetCatalogId;
3030

@@ -140,15 +140,18 @@ public static PolarisPolicyMappingRecord toPolicyMappingRecord(ModelPolicyMappin
140140
}
141141

142142
@Override
143-
public ModelPolicyMappingRecord fromResultSet(ResultSet rs) throws SQLException {
144-
return ModelPolicyMappingRecord.builder()
145-
.targetCatalogId(rs.getObject("target_catalog_id", Long.class))
146-
.targetId(rs.getObject("target_id", Long.class))
147-
.policyTypeCode(rs.getObject("policy_type_code", Integer.class))
148-
.policyCatalogId(rs.getObject("policy_catalog_id", Long.class))
149-
.policyId(rs.getObject("policy_id", Long.class))
150-
.parameters(rs.getString("parameters"))
151-
.build();
143+
public PolarisPolicyMappingRecord fromResultSet(ResultSet rs) throws SQLException {
144+
var modelRecord =
145+
ModelPolicyMappingRecord.builder()
146+
.targetCatalogId(rs.getObject("target_catalog_id", Long.class))
147+
.targetId(rs.getObject("target_id", Long.class))
148+
.policyTypeCode(rs.getObject("policy_type_code", Integer.class))
149+
.policyCatalogId(rs.getObject("policy_catalog_id", Long.class))
150+
.policyId(rs.getObject("policy_id", Long.class))
151+
.parameters(rs.getString("parameters"))
152+
.build();
153+
154+
return toPolicyMappingRecord(modelRecord);
152155
}
153156

154157
@Override

extension/persistence/relational-jdbc/src/main/java/org/apache/polaris/extension/persistence/relational/jdbc/models/ModelPrincipalAuthenticationData.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
import java.util.Map;
2525
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
2626

27-
public class ModelPrincipalAuthenticationData
28-
implements Converter<ModelPrincipalAuthenticationData> {
27+
public class ModelPrincipalAuthenticationData implements Converter<PolarisPrincipalSecrets> {
2928
// the id of the principal
3029
private long principalId;
3130

@@ -65,14 +64,17 @@ public static Builder builder() {
6564
}
6665

6766
@Override
68-
public ModelPrincipalAuthenticationData fromResultSet(ResultSet rs) throws SQLException {
69-
return ModelPrincipalAuthenticationData.builder()
70-
.principalId(rs.getObject("principal_id", Long.class))
71-
.principalClientId(rs.getObject("principal_client_id", String.class))
72-
.mainSecretHash(rs.getObject("main_secret_hash", String.class))
73-
.secondarySecretHash(rs.getObject("secondary_secret_hash", String.class))
74-
.secretSalt(rs.getObject("secret_salt", String.class))
75-
.build();
67+
public PolarisPrincipalSecrets fromResultSet(ResultSet rs) throws SQLException {
68+
var modelRecord =
69+
ModelPrincipalAuthenticationData.builder()
70+
.principalId(rs.getObject("principal_id", Long.class))
71+
.principalClientId(rs.getObject("principal_client_id", String.class))
72+
.mainSecretHash(rs.getObject("main_secret_hash", String.class))
73+
.secondarySecretHash(rs.getObject("secondary_secret_hash", String.class))
74+
.secretSalt(rs.getObject("secret_salt", String.class))
75+
.build();
76+
77+
return toPrincipalAuthenticationData(modelRecord);
7678
}
7779

7880
@Override

extension/persistence/relational-jdbc/src/test/java/org/apache/polaris/extension/persistence/impl/relational/jdbc/DatasourceOperationsTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.sql.Connection;
2525
import java.sql.SQLException;
2626
import java.sql.Statement;
27-
import java.util.function.Function;
2827
import javax.sql.DataSource;
2928
import org.apache.polaris.extension.persistence.relational.jdbc.DatasourceOperations;
3029
import org.apache.polaris.extension.persistence.relational.jdbc.models.ModelEntity;
@@ -76,8 +75,7 @@ void testExecuteSelect_exception() throws Exception {
7675
when(mockStatement.executeQuery(query)).thenThrow(new SQLException());
7776

7877
assertThrows(
79-
SQLException.class,
80-
() -> datasourceOperations.executeSelect(query, new ModelEntity(), Function.identity()));
78+
SQLException.class, () -> datasourceOperations.executeSelect(query, new ModelEntity()));
8179
}
8280

8381
@Test

0 commit comments

Comments
 (0)