// Copyright © 2015 HSL <https://www.hsl.fi>
// This program is dual-licensed under the EUPL v1.2 and AGPLv3 licenses.
package fi.hsl.parkandride.back;
import com.querydsl.core.QueryException;
import com.querydsl.sql.SQLExceptionTranslator;
import fi.hsl.parkandride.core.domain.Violation;
import fi.hsl.parkandride.core.service.ValidationException;
import java.sql.SQLException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LiipiSQLExceptionTranslator implements SQLExceptionTranslator {
/*
* Postgresql:
* ERROR: duplicate key value violates unique constraint "operator_name_fi_u"
* Detail: Key (upper(name_fi::text))=(X-PARK) already exists.
*
* H2:
* Unique index or primary key violation: "OPERATOR_NAME_FI_U ON PUBLIC.OPERATOR(NAME_FI) VALUES (CAST('X-Park' AS VARCHAR_IGNORECASE), 1)"; SQL statement:
* insert into OPERATOR (ID, NAME_FI, NAME_SV, NAME_EN)
* values (?, ?, ?, ?) [23505-181]
*/
private static Pattern UNIQUE_CONSTRAINT_NAME = Pattern.compile("\"[a-z]+_([a-z_]+)_u");
@Override
public RuntimeException translate(String sql, List<Object> bindings, SQLException e) {
chainedSQLExceptionsToSuppressed(e);
if ("23505".equals(e.getSQLState())) {
String message = e.getMessage().toLowerCase();
Matcher m = UNIQUE_CONSTRAINT_NAME.matcher(message);
if (m.find()) {
return (ValidationException)
new ValidationException(new Violation("Unique", m.group(1).replace('_', '.'), e.getMessage()))
.initCause(e);
}
}
return new QueryException(e);
}
@Override
public RuntimeException translate(SQLException e) {
chainedSQLExceptionsToSuppressed(e);
return new QueryException(e);
}
private void chainedSQLExceptionsToSuppressed(SQLException exception) {
if (exception == null) return;
for (SQLException e = exception.getNextException(); e != null; e = e.getNextException()) {
exception.addSuppressed(e);
}
}
}