Skip to content

Commit

Permalink
improve already exists sql exception
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaojiebao committed Apr 10, 2024
1 parent abcfa96 commit be236e9
Show file tree
Hide file tree
Showing 13 changed files with 608 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.datastrato.gravitino.meta.SchemaEntity;
import com.datastrato.gravitino.meta.TableEntity;
import com.datastrato.gravitino.meta.TopicEntity;
import com.datastrato.gravitino.storage.relational.converters.SQLExceptionConverterFactory;
import com.datastrato.gravitino.storage.relational.service.CatalogMetaService;
import com.datastrato.gravitino.storage.relational.service.FilesetMetaService;
import com.datastrato.gravitino.storage.relational.service.MetalakeMetaService;
Expand All @@ -44,6 +45,7 @@ public class JDBCBackend implements RelationalBackend {
@Override
public void initialize(Config config) {
SqlSessionFactoryHelper.getInstance().init(config);
SQLExceptionConverterFactory.initConverter(config);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/
package com.datastrato.gravitino.storage.relational.converters;

import com.datastrato.gravitino.Entity;
import com.datastrato.gravitino.exceptions.AlreadyExistsException;
import com.datastrato.gravitino.exceptions.GravitinoRuntimeException;
import java.sql.SQLException;

/** Exception converter to Gravitino exception for H2. */
public class H2ExceptionConverter implements SQLExceptionConverter {

@SuppressWarnings("FormatStringAnnotation")
@Override
public GravitinoRuntimeException toGravitinoException(
SQLException se, Entity.EntityType type, String name) {
switch (se.getErrorCode()) {
case 23505:
return new AlreadyExistsException(se, se.getMessage());
default:
return new GravitinoRuntimeException(se, se.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/
package com.datastrato.gravitino.storage.relational.converters;

import com.datastrato.gravitino.Entity;
import com.datastrato.gravitino.exceptions.AlreadyExistsException;
import com.datastrato.gravitino.exceptions.GravitinoRuntimeException;
import java.sql.SQLException;

/** Exception converter to Gravitino exception for MySQL. */
public class MySQLExceptionConverter implements SQLExceptionConverter {

@SuppressWarnings("FormatStringAnnotation")
@Override
public GravitinoRuntimeException toGravitinoException(
SQLException se, Entity.EntityType type, String name) {
switch (se.getErrorCode()) {
case 1062:
return new AlreadyExistsException(se, se.getMessage());
default:
return new GravitinoRuntimeException(se, se.getMessage());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/
package com.datastrato.gravitino.storage.relational.converters;

import com.datastrato.gravitino.Entity;
import com.datastrato.gravitino.exceptions.GravitinoRuntimeException;
import java.sql.SQLException;

/** Interface for converter JDBC SQL exceptions to Gravitino exceptions. */
public interface SQLExceptionConverter {
/**
* Convert JDBC exception to GravitinoException.
*
* @param sqlException The sql exception to map
* @param type The type of the entity
* @param name The name of the entity
* @return A best attempt at a corresponding connector exception or generic with the SQLException
* as the cause
*/
GravitinoRuntimeException toGravitinoException(
SQLException sqlException, Entity.EntityType type, String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/
package com.datastrato.gravitino.storage.relational.converters;

import com.datastrato.gravitino.Config;
import com.datastrato.gravitino.Configs;
import com.google.common.base.Preconditions;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SQLExceptionConverterFactory {
private static final Pattern TYPE_PATTERN = Pattern.compile("jdbc:(\\w+):");
private static SQLExceptionConverter converter;

private SQLExceptionConverterFactory() {}

public static synchronized void initConverter(Config config) {
if (converter == null) {
String jdbcUrl = config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_URL);
Matcher typeMatcher = TYPE_PATTERN.matcher(jdbcUrl);
if (typeMatcher.find()) {
String jdbcType = typeMatcher.group(1);
if (jdbcType.equalsIgnoreCase("mysql")) {
converter = new MySQLExceptionConverter();
} else if (jdbcType.equalsIgnoreCase("h2")) {
converter = new H2ExceptionConverter();
} else {
throw new IllegalArgumentException(String.format("Unsupported jdbc type: %s", jdbcType));
}
} else {
throw new IllegalArgumentException(
String.format("Cannot find jdbc type in jdbc url: %s", jdbcUrl));
}
}
}

public static SQLExceptionConverter getConverter() {
Preconditions.checkState(converter != null, "Exception converter is not initialized.");
return converter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public void insertCatalog(CatalogEntity catalogEntity, boolean overwrite) {
}
});
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.CATALOG, catalogEntity.nameIdentifier().toString());
throw re;
}
Expand Down Expand Up @@ -147,7 +147,7 @@ public <E extends Entity & HasIdentifier> CatalogEntity updateCatalog(
POConverters.updateCatalogPOWithVersion(oldCatalogPO, newEntity, metalakeId),
oldCatalogPO));
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.CATALOG, newEntity.nameIdentifier().toString());
throw re;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public void insertFileset(FilesetEntity filesetEntity, boolean overwrite) {
}
}));
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.FILESET, filesetEntity.nameIdentifier().toString());
throw re;
}
Expand Down Expand Up @@ -177,7 +177,7 @@ public <E extends Entity & HasIdentifier> FilesetEntity updateFileset(
mapper -> mapper.updateFilesetMeta(newFilesetPO, oldFilesetPO));
}
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.FILESET, newEntity.nameIdentifier().toString());
throw re;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public void insertMetalake(BaseMetalake baseMetalake, boolean overwrite) {
}
});
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.METALAKE, baseMetalake.nameIdentifier().toString());
throw re;
}
Expand Down Expand Up @@ -125,7 +125,7 @@ public <E extends Entity & HasIdentifier> BaseMetalake updateMetalake(
MetalakeMetaMapper.class,
mapper -> mapper.updateMetalakeMeta(newMetalakePO, oldMetalakePO));
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.METALAKE, newMetalakeEntity.nameIdentifier().toString());
throw re;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public void insertSchema(SchemaEntity schemaEntity, boolean overwrite) {
}
});
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.SCHEMA, schemaEntity.nameIdentifier().toString());
throw re;
}
Expand Down Expand Up @@ -142,7 +142,7 @@ public <E extends Entity & HasIdentifier> SchemaEntity updateSchema(
mapper.updateSchemaMeta(
POConverters.updateSchemaPOWithVersion(oldSchemaPO, newEntity), oldSchemaPO));
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.SCHEMA, newEntity.nameIdentifier().toString());
throw re;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public void insertTable(TableEntity tableEntity, boolean overwrite) {
}
});
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.TABLE, tableEntity.nameIdentifier().toString());
throw re;
}
Expand Down Expand Up @@ -135,7 +135,7 @@ public <E extends Entity & HasIdentifier> TableEntity updateTable(
mapper.updateTableMeta(
POConverters.updateTablePOWithVersion(oldTablePO, newEntity), oldTablePO));
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.TABLE, newEntity.nameIdentifier().toString());
throw re;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void insertTopic(TopicEntity topicEntity, boolean overwrite) {
});
// TODO: insert topic dataLayout version after supporting it
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.TOPIC, topicEntity.nameIdentifier().toString());
throw re;
}
Expand Down Expand Up @@ -97,7 +97,7 @@ public <E extends Entity & HasIdentifier> TopicEntity updateTopic(
mapper.updateTopicMeta(
POConverters.updateTopicPOWithVersion(oldTopicPO, newEntity), oldTopicPO));
} catch (RuntimeException re) {
ExceptionUtils.checkSQLConstraintException(
ExceptionUtils.checkSQLException(
re, Entity.EntityType.TOPIC, newEntity.nameIdentifier().toString());
throw re;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@
package com.datastrato.gravitino.storage.relational.utils;

import com.datastrato.gravitino.Entity;
import com.datastrato.gravitino.exceptions.AlreadyExistsException;
import java.sql.SQLIntegrityConstraintViolationException;
import com.datastrato.gravitino.storage.relational.converters.SQLExceptionConverterFactory;
import java.sql.SQLException;

public class ExceptionUtils {
private ExceptionUtils() {}

public static void checkSQLConstraintException(
public static void checkSQLException(
RuntimeException re, Entity.EntityType type, String entityName) {
if (re.getCause() != null
&& re.getCause() instanceof SQLIntegrityConstraintViolationException) {
// TODO We should make more fine-grained exception judgments
// Usually throwing `SQLIntegrityConstraintViolationException` means that
// SQL violates the constraints of `primary key` and `unique key`.
// We simply think that the entity already exists at this time.
throw new AlreadyExistsException("%s entity: %s already exists", type.name(), entityName);
if (re.getCause() instanceof SQLException) {
throw SQLExceptionConverterFactory.getConverter()
.toGravitinoException((SQLException) re.getCause(), type, entityName);
}
}
}
Loading

0 comments on commit be236e9

Please sign in to comment.