package net.javacrumbs.shedlock.provider.jdbctemplate;

import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider.Configuration;

class SqlStatementsSource {
    private final Configuration configuration;

    SqlStatementsSource(Configuration configuration) {
        this.configuration = configuration;
    }

    public static SqlStatementsSource create(Configuration configuration) {
        return new SqlStatementsSource(configuration);
    }


    String getInsertStatement() {
        return "INSERT INTO " + tableName() + "(" + name() + ", " + lockUntil() + ", " + lockedAt() + ", " + lockedBy() + ") VALUES(?, ?, ?, ?)";
    }


    public String getUpdateStatement() {
        return "UPDATE " + tableName() + " SET " + lockUntil() + " = ?, " + lockedAt() + " = ?, " + lockedBy() + " = ? WHERE " + name() + " = ? AND " + lockUntil() + " <= ?";
    }

    public String getExtendStatement() {
        return "UPDATE " + tableName() + " SET " + lockUntil() + " = ? WHERE " + name() + " = ? AND " + lockedBy() + " = ? AND " + lockUntil() + " > ? ";
    }

    public String getUnlockStatement() {
        return "UPDATE " + tableName() + " SET " + lockUntil() + " = ? WHERE " + name() + " = ?";
    }

    private String name() {
        return configuration.getColumnNames().getName();
    }

    private String lockUntil() {
        return configuration.getColumnNames().getLockUntil();
    }

    private String lockedAt() {
        return configuration.getColumnNames().getLockedAt();
    }

    private String lockedBy() {
        return configuration.getColumnNames().getLockedBy();
    }

    private String tableName() {
        return configuration.getTableName();
    }
}

@@ -146,82 +146,290 @@
 on;%0A
-%0Aclass SqlStatementsSource %7B%0A    private final Configuration configuration
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0Aimport org.springframework.jdbc.core.ConnectionCallback;%0A%0Aclass SqlStatementsSource %7B%0A    private final Configuration configuration;%0A%0A    private static final Logger logger = LoggerFactory.getLogger(SqlStatementsSource.class)
 ;%0A%0A 
@@ -537,23 +537,16 @@
  %7D%0A%0A    
-public 
 static S
@@ -614,52 +614,637 @@
     
-return new SqlStatementsSource(configuration
+String databaseProductName = getDatabaseProductName(configuration);%0A        if (%22PostgreSQL%22.equals(databaseProductName)) %7B%0A            logger.debug(%22Using PostgresSqlStatementsSource%22);%0A            return new PostgresSqlStatementsSource(configuration);%0A        %7D else %7B%0A            logger.debug(%22Using SqlStatementsSource%22);%0A            return new SqlStatementsSource(configuration);%0A        %7D%0A    %7D%0A%0A    private static String getDatabaseProductName(Configuration configuration) %7B%0A        return configuration.getJdbcTemplate().execute((ConnectionCallback%3CString%3E) connection -%3E connection.getMetaData().getDatabaseProductName()
 );%0A 
@@ -1852,17 +1852,16 @@
  + %22 %3E ?
- 
 %22;%0A    %7D
@@ -2008,32 +2008,24 @@
 %0A    %7D%0A%0A    
-private 
 String name(
@@ -2480,8 +2480,317 @@
     %7D%0A%7D%0A
+%0Aclass PostgresSqlStatementsSource extends SqlStatementsSource %7B%0A    PostgresSqlStatementsSource(Configuration configuration) %7B%0A        super(configuration);%0A    %7D%0A%0A    @Override%0A    String getInsertStatement() %7B%0A        return super.getInsertStatement() + %22 ON CONFLICT (%22 + name() + %22) DO NOTHING%22;%0A    %7D%0A%7D%0A

Use ‘ON CONFLICT’ clause for Postgres