/* * Copyright 2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.xd.greenplum.support; import java.util.List; import org.springframework.util.StringUtils; public abstract class SqlUtils { public static String createExternalReadableTable(LoadConfiguration config, String prefix, List<String> overrideLocations) { // TODO: this function needs a cleanup StringBuilder buf = new StringBuilder(); // unique table name String name = config.getTable() + "_ext_" + prefix; buf.append("CREATE READABLE EXTERNAL TABLE "); buf.append(name); buf.append(" ( "); // column types or like ReadableTable externalTable = config.getExternalTable(); if (externalTable.getLike() != null) { buf.append("LIKE "); buf.append(config.getTable()); } else if (StringUtils.hasText(externalTable.getColumns())) { buf.append(externalTable.getColumns()); } else { buf.append("LIKE "); buf.append(config.getTable()); } buf.append(" ) "); // locations buf.append("LOCATION("); if (overrideLocations != null && !overrideLocations.isEmpty()) { buf.append(createLocationString(overrideLocations.toArray(new String[0]))); } else { buf.append(createLocationString(externalTable.getLocations().toArray(new String[0]))); } buf.append(") "); // format type if (externalTable.getFormat() == Format.TEXT) { buf.append("FORMAT 'TEXT'"); } else { buf.append("FORMAT 'CSV'"); } // format parameters buf.append(" ( "); buf.append("DELIMITER '"); if (externalTable.getDelimiter() != null) { buf.append(unicodeEscaped(externalTable.getDelimiter().charValue())); } else { buf.append("|"); } buf.append("'"); if (externalTable.getNullString() != null) { buf.append(" NULL '"); buf.append(externalTable.getNullString()); buf.append("'"); } if (externalTable.getEscape() != null) { buf.append(" ESCAPE '"); buf.append(externalTable.getEscape()); buf.append("'"); } if (externalTable.getQuote() != null) { buf.append(" QUOTE '"); buf.append(externalTable.getQuote()); buf.append("'"); } if (externalTable.getForceQuote() != null) { buf.append(" FORCE QUOTE "); buf.append(StringUtils.arrayToCommaDelimitedString(externalTable.getForceQuote())); } buf.append(" )"); if (externalTable.getEncoding() != null) { buf.append(" ENCODING '"); buf.append(externalTable.getEncoding()); buf.append("'"); } if (externalTable.getSegmentRejectLimit() != null && externalTable.getSegmentRejectType() != null) { if (externalTable.getLogErrorsInto() != null) { buf.append(" LOG ERRORS INTO "); buf.append(externalTable.getLogErrorsInto()); } buf.append(" SEGMENT REJECT LIMIT "); buf.append(externalTable.getSegmentRejectLimit()); buf.append(" "); buf.append(externalTable.getSegmentRejectType()); } return buf.toString(); } /** * * @param config the load configuration * @param prefix the prefix * @return the drop DDL */ public static String dropExternalReadableTable(LoadConfiguration config, String prefix) { StringBuilder b = new StringBuilder(); // unique table name String name = config.getTable() + "_ext_" + prefix; b.append("DROP EXTERNAL TABLE "); b.append(name); return b.toString(); } /** * Builds sql clause to load data into a database. * * @param config * Load configuration. * @param prefix * Prefix for temporary resources. * @return * the load DDL */ public static String load(LoadConfiguration config, String prefix) { if (config.getMode() == Mode.INSERT) { return loadInsert(config, prefix); } else if (config.getMode() == Mode.UPDATE) { return loadUpdate(config, prefix); } throw new IllegalArgumentException("Unsupported mode " + config.getMode()); } private static String loadInsert(LoadConfiguration config, String prefix) { StringBuilder b = new StringBuilder(); String name = config.getTable() + "_ext_" + prefix; b.append("INSERT INTO "); b.append(config.getTable()); b.append(" SELECT "); if (StringUtils.hasText(config.getColumns())) { b.append(config.getColumns()); } else { b.append("*"); } b.append(" FROM "); b.append(name); return b.toString(); } private static String loadUpdate(LoadConfiguration config, String prefix) { StringBuilder b = new StringBuilder(); String name = config.getTable() + "_ext_" + prefix; b.append("UPDATE "); b.append(config.getTable()); b.append(" into_table set "); for (int i = 0; i < config.getUpdateColumns().size(); i++) { b.append(config.getUpdateColumns().get(i) + "=from_table." + config.getUpdateColumns().get(i)); if (i + 1 < config.getUpdateColumns().size()) { b.append(", "); } } b.append(" FROM "); b.append(name); b.append(" from_table where "); for (int i = 0; i < config.getMatchColumns().size(); i++) { b.append("into_table." + config.getMatchColumns().get(i) + "=from_table." + config.getMatchColumns().get(i)); if (i + 1 < config.getMatchColumns().size()) { b.append(" and "); } } if (StringUtils.hasText(config.getUpdateCondition())) { b.append(" and " + config.getUpdateCondition()); } return b.toString(); } /** * Converts string array to greenplum friendly string. From new * String[]{"foo","jee"} we get "'foo',jee'". * * @param strings * String array to explode * @return Comma delimited string with values encapsulated with * apostropheres. ‘' */ public static String createLocationString(String[] strings) { StringBuilder locString = new StringBuilder(); for (int i = 0; i < strings.length; i++) { String string = strings[i]; locString.append("'"); locString.append(string); locString.append("'"); if (i < strings.length - 1) { locString.append(","); } } return locString.toString(); } private static String unicodeEscaped(char ch) { if (ch < 0x10) { return "\\u000" + Integer.toHexString(ch); } else if (ch < 0x100) { return "\\u00" + Integer.toHexString(ch); } else if (ch < 0x1000) { return "\\u0" + Integer.toHexString(ch); } return "\\u" + Integer.toHexString(ch); } }