All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.nimbusds.infinispan.persistence.sql.JOOQFixes Maven / Gradle / Ivy

package com.nimbusds.infinispan.persistence.sql;


import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.jcip.annotations.ThreadSafe;
import org.infinispan.persistence.spi.PersistenceException;
import org.jooq.Merge;
import org.jooq.SQLDialect;


/**
 * Fixes incorrect SQL statements generated by jOOQ.
 */
@ThreadSafe
class JOOQFixes {
	
	
	/**
	 * The SQL dialects that require a merge fix.
	 */
	static final Set REQUIRE_MERGE_FIX = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
		SQLDialect.POSTGRES_9_3,
		SQLDialect.POSTGRES_9_4,
		SQLDialect.POSTGRES_9_5
	)));
	
	
	/**
	 * Flag if PostgreSQL merge statement fix is required.
	 */
	private final boolean pgMergeFixRequired;
	
	
	/**
	 * The primary key constraint name, {@code null} if N/A.
	 */
	private final String pkConstraintName;
	
	
	/**
	 * Creates a new instance for applying fixes to jOOQ generated SQL
	 * statements.
	 *
	 * @param sqlDialect      The configured SQL dialect. Must not be
	 *                        {@code null}.
	 * @param createTableStmt The create table SQL statement. Must not be
	 *                        {@code null}.
	 */
	public JOOQFixes(final SQLDialect sqlDialect, final String createTableStmt) {
		
		if (REQUIRE_MERGE_FIX.contains(sqlDialect)) {
			pkConstraintName = parsePrimaryKeyConstraintName(createTableStmt);
			if (pkConstraintName == null) {
				throw new PersistenceException("Couldn't determine primary key constraint name from SQL create table statement: " + createTableStmt);
			}
			pgMergeFixRequired = true;
		} else {
			pgMergeFixRequired = false;
			pkConstraintName = null;
		}
	}
	
	
	/**
	 * Fixes the specified SQL merge statement for PostgreSQL databases.
	 *
	 * @param mergeStatement The ready merge statement. Must not be
	 *                       {@code null}.
	 *
	 * @return The (fixed) SQL statement ready for execution.
	 */
	String fixMergeStatement(final Merge mergeStatement) {
		
		if (! pgMergeFixRequired) {
			return mergeStatement.toString();
		}
		
		return mergeStatement.toString().replace("on conflict ([unknown primary key])", "on conflict on constraint " + pkConstraintName);
	}
	
	
	/**
	 * Parses the primary key constraint name from the specified create
	 * table SQL statement.
	 *
	 * @param createTableStatement The create table SQL statement.
	 *
	 * @return The primary key constraint name, {@code null} if missing or
	 *         not found.
	 */
	static String parsePrimaryKeyConstraintName(final String createTableStatement) {
		
		Pattern p = Pattern.compile(".*CONSTRAINT\\s+(\\w*)\\s+PRIMARY", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
		
		Matcher m = p.matcher(createTableStatement);
		
		if (! m.find()) {
			return null;
		}
		
		return m.group(1);
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy