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

org.eclipse.dirigible.database.sql.builders.AbstractSqlBuilder Maven / Gradle / Ivy

/*
 * Copyright (c) 2021 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * SPDX-FileCopyrightText: 2021 SAP SE or an SAP affiliate company and Eclipse Dirigible contributors
 * SPDX-License-Identifier: EPL-2.0
 */
package org.eclipse.dirigible.database.sql.builders;

import org.eclipse.dirigible.commons.config.Configuration;
import org.eclipse.dirigible.database.sql.ISqlBuilder;
import org.eclipse.dirigible.database.sql.ISqlDialect;
import org.eclipse.dirigible.database.sql.dialects.mysql.MySQLSqlDialect;

import java.util.Set;
import java.util.regex.Pattern;

/**
 * The Abstract SQL Builder.
 */
public abstract class AbstractSqlBuilder implements ISqlBuilder {

	private ISqlDialect dialect;
	
	
	/**
	 * Instantiates a new abstract sql builder.
	 *
	 * @param dialect
	 *            the dialect
	 */
	protected AbstractSqlBuilder(ISqlDialect dialect) {
		this.dialect = dialect;
	}

	/**
	 * Gets the dialect.
	 *
	 * @return the dialect
	 */
	protected ISqlDialect getDialect() {
		return dialect;
	}

	/**
	 * Usually returns the default generated snippet.
	 *
	 * @return the string
	 */
	@Override
	public String toString() {
		return build();
	}

	/**
	 * Returns the default generated snippet.
	 *
	 * @return the string
	 */
	@Override
	public String build() {
		return generate();
	}
	
	/**
	 * Whether the names of tables, columns, indices are case sensitive
	 * 
	 * @return true if set
	 */
	protected boolean isCaseSensitive() {
		return Boolean.parseBoolean(Configuration.get("DIRIGIBLE_DATABASE_NAMES_CASE_SENSITIVE", "false"));
	}
	
	/**
	 * Encapsulate the name within qutes
	 * 
	 * @param name the name
	 * @return the encapsulated name
	 */
	protected String encapsulate(String name) {
		String escapeSymbol = getEscapeSymbol();
		if ("*".equals(name.trim())) {
			return name;
		}
		if (!name.startsWith(escapeSymbol)) {
			if (isColumn(name.trim())) {
				name = escapeSymbol + name + escapeSymbol;
			} else {
				name = encapsulateMany(name);
			}
		}
		return name;
	}
	
	private Pattern columnPattern = Pattern.compile("^(?![0-9]*$)[a-zA-Z0-9_#$]+$");

	public String getEscapeSymbol() {
		return (getDialect().getClass().equals(MySQLSqlDialect.class))
				? "`"
				: "\"";
	}

	/**
	 * Check whether the name is a column (one word) or it is complex expression containing functions, etc. (count(*))
	 * @param name the name of the eventual column
	 * @return true if it is one word
	 */
	protected boolean isColumn(String name) {
		if (name == null) {
	        return false; 
	    }
	    return columnPattern.matcher(name).matches();
	}
	
	/**
	 * Encapsulate all the non-function and non-numeric words
	 * 
	 * @param line the input string
	 * @return the transformed string
	 */
	protected String encapsulateMany(String line) {
		String lineWithoughContentBetweenSingleQuotes = String.join("", line.split(contentBetweenSingleQuotes.toString()));
		String regex = "([^a-zA-Z0-9_#$::']+)'*\\1*";
		String[] words = lineWithoughContentBetweenSingleQuotes.split(regex);
		Set functionsNames = getDialect().getFunctionsNames();
		for (String word : words) {
			if (isNumeric(word) || isValue(word)) {
				continue;
			}
			if (!"".equals(word.trim())
					&& !functionsNames.contains(word.toLowerCase())) {
				line = line.replace(word, "\"" + word + "\"");
			}
		}
		return line;
	}

	/**
	 * The Regex find the content between single quotes.
	 */
	private Pattern contentBetweenSingleQuotes = Pattern.compile("'([^']*?)'");
	private Pattern numericPattern = Pattern.compile("-?\\d+(\\.\\d+)?");
	
	/**
	 * Check whether the string is a number
	 * @param s the input
	 * @return true if it is a number
	 */
	protected boolean isNumeric(String s) {
	    if (s == null) {
	        return false; 
	    }
	    return numericPattern.matcher(s).matches();
	}

	protected boolean isValue(String s) {
		if (s == null) {
			return false;
		}
		return s.startsWith("'") || s.endsWith("'");
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy