001package io.ebean.config.dbplatform;
002
003import io.ebean.AcquireLockException;
004import io.ebean.DataIntegrityException;
005import io.ebean.DuplicateKeyException;
006import io.ebean.SerializableConflictException;
007
008import javax.persistence.PersistenceException;
009import java.sql.SQLException;
010import java.util.Collections;
011import java.util.Map;
012
013/**
014 * Translate SQLException based on SQLState codes.
015 */
016public class SqlCodeTranslator implements SqlExceptionTranslator {
017
018  private final Map<String, DataErrorType> map;
019
020  /**
021   * Create given the map of SQLState codes to error types.
022   */
023  public SqlCodeTranslator(Map<String, DataErrorType> map) {
024    this.map = map;
025  }
026
027  /**
028   * Create "No-op" implementation.
029   */
030  public SqlCodeTranslator() {
031    this.map = Collections.emptyMap();
032  }
033
034  @Override
035  public PersistenceException translate(String message, SQLException e) {
036
037    DataErrorType errorType = map.get(e.getSQLState());
038    if (errorType == null) {
039      // fall back to error code
040      errorType = map.get(String.valueOf(e.getErrorCode()));
041    }
042    if (errorType != null) {
043      switch (errorType) {
044        case AcquireLock:
045          return new AcquireLockException(message, e);
046        case DuplicateKey:
047          return new DuplicateKeyException(message, e);
048        case DataIntegrity:
049          return new DataIntegrityException(message, e);
050        case SerializableConflict:
051          return new SerializableConflictException(message, e);
052      }
053    }
054    // return a generic exception
055    return new PersistenceException(message, e);
056  }
057}