/******************************************************************************* * This file is part of OpenNMS(R). * * Copyright (C) 2006-2011 The OpenNMS Group, Inc. * OpenNMS(R) is Copyright (C) 1999-2011 The OpenNMS Group, Inc. * * OpenNMS(R) is a registered trademark of The OpenNMS Group, Inc. * * OpenNMS(R) is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * OpenNMS(R) is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenNMS(R). If not, see: * http://www.gnu.org/licenses/ * * For more information contact: * OpenNMS(R) Licensing <license@opennms.org> * http://www.opennms.org/ * http://www.opennms.com/ *******************************************************************************/ package org.opennms.netmgt.dao.db; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Arrays; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.springframework.util.StringUtils; public class Index { private String m_name; private String m_table; private String m_using; private List<String> m_columns; private boolean m_unique; private String m_where; private static Pattern m_pattern = Pattern.compile("(?i)create" + "(\\s+unique)?" + "\\s+index\\s+(\\S+)" + "\\s+on\\s+(\\S+)" + "(?:\\s+USING\\s+(\\S+))?" + "\\s*\\(([^)]+)\\)" + "(?:\\s+WHERE\\s+(.*?))?" + "\\s*(?:;|$)"); /** * <p>Constructor for Index.</p> * * @param name a {@link java.lang.String} object. * @param table a {@link java.lang.String} object. * @param using a {@link java.lang.String} object. * @param columns a {@link java.util.List} object. * @param unique a boolean. * @param where a {@link java.lang.String} object. */ public Index(String name, String table, String using, List<String> columns, boolean unique, String where) { m_name = name; m_table = table; m_using = using; m_columns = columns; m_unique = unique; m_where = where; } /** * <p>findIndexInString</p> * * @param create a {@link java.lang.String} object. * @return a {@link org.opennms.netmgt.dao.db.Index} object. */ public static Index findIndexInString(String create) { Matcher m = m_pattern.matcher(create.toString()); if (!m.find()) { return null; } boolean unique = (m.group(1) != null); String name = m.group(2); String table = m.group(3); String using = m.group(4); String columnList = m.group(5); String where = m.group(6); String[] columns = columnList.split("\\s*,\\s*"); return new Index(name, table, using, Arrays.asList(columns), unique, where); } /** * <p>isOnDatabase</p> * * @param connection a {@link java.sql.Connection} object. * @return a boolean. * @throws java.sql.SQLException if any. */ public boolean isOnDatabase(Connection connection) throws SQLException { boolean exists; Statement st = connection.createStatement(); ResultSet rs = null; try { rs = st.executeQuery("SELECT relname FROM pg_class " + "WHERE relname = '" + m_name.toLowerCase() + "'"); exists = rs.next(); } finally { if (rs != null) { rs.close(); } st.close(); } return exists; } /** * <p>removeFromDatabase</p> * * @param connection a {@link java.sql.Connection} object. * @throws java.sql.SQLException if any. */ public void removeFromDatabase(Connection connection) throws SQLException { Statement st = connection.createStatement(); try { st.execute("DROP INDEX " + getName()); } finally{ st.close(); } } /** * <p>addToDatabase</p> * * @param connection a {@link java.sql.Connection} object. * @throws java.sql.SQLException if any. */ public void addToDatabase(Connection connection) throws SQLException { Statement st = connection.createStatement(); try { st.execute(getSql()); } finally{ st.close(); } } /** * <p>getSql</p> * * @return a {@link java.lang.String} object. */ public String getSql() { StringBuffer sql = new StringBuffer(); sql.append("CREATE "); if (m_unique) { sql.append("UNIQUE "); } sql.append("INDEX "); sql.append(m_name); sql.append(" ON "); sql.append(m_table); if (m_using != null) { sql.append(" USING "); sql.append(m_using); } sql.append(" ( "); sql.append(StringUtils.collectionToDelimitedString(m_columns, ", ")); sql.append(" )"); if (m_where != null) { sql.append(" WHERE "); sql.append(m_where); } return sql.toString(); } /** * <p>getName</p> * * @return a {@link java.lang.String} object. */ public String getName() { return m_name; } /** * <p>getTable</p> * * @return a {@link java.lang.String} object. */ public String getTable() { return m_table; } /** * <p>isUnique</p> * * @return a boolean. */ public boolean isUnique() { return m_unique; } /** * <p>getColumns</p> * * @return a {@link java.util.List} object. */ public List<String> getColumns() { return m_columns; } /** * <p>getIndexUniquenessQuery</p> * * @return a {@link java.lang.String} object. * @throws java.lang.Exception if any. */ public String getIndexUniquenessQuery() throws Exception { String firstColumn = getColumns().get(0); String columnList = StringUtils.collectionToDelimitedString(getColumns(), ", "); /* * E.g. select * from foo where (a, b) in (select a, b from foo * group by a, b having count(a) > 1 order by a, b); */ StringBuffer sql = new StringBuffer(); sql.append("SELECT * FROM " + getTable() + " WHERE ( " + columnList + " ) IN ( SELECT " + columnList + " FROM " + getTable() + " GROUP BY " + columnList + " HAVING count(" + firstColumn + ") > 1"); if (m_where != null) { sql.append(" AND ( " + m_where + " )"); } sql.append(" ORDER BY " + columnList + " ) " + "ORDER BY " + columnList); return sql.toString(); /* List<String> whereComponents = new ArrayList<String>(getColumns().size() + 2); for (String column : getColumns()) { whereComponents.add("a." + column + " = b." + column); } String lowerTable = getTable().toLowerCase(); if ("snmpinterface".equals(lowerTable)) { whereComponents.add("a.ipAddr != b.ipAddr"); } else if ("ifservices".equals(lowerTable)) { whereComponents.add("a.lastGood != b.lastGood"); } else { return null; } if (m_where != null) { whereComponents.add("( " + m_where + " )"); } return "SELECT DISTINCT a.* FROM " + getTable() + " a, " + getTable() + " b WHERE " + Installer.join(" AND ", whereComponents); */ } }