/***************************************************************************** * Copyright (C) 2008 EnterpriseDB Corporation. * Copyright (C) 2011 Stado Global Development Group. * * This file is part of Stado. * * Stado 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. * * Stado 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 Stado. If not, see <http://www.gnu.org/licenses/>. * * You can find Stado at http://www.stado.us * ****************************************************************************/ package org.postgresql.stado.util; import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.postgresql.stado.common.util.Props; import org.postgresql.stado.engine.io.DataTypes; import org.postgresql.stado.engine.io.MessageTypes; /** * Some convenient utility methods * * */ public class Util implements MessageTypes { private static final int SAMPLE_SIZE = 100; // perhaps make this // configurable? /** * Print the given string to the out stream specified. If the input string * is shorter than the defined columnLength, pre-pad the string with white * spaces. * * @param out * @param str * @param columnLength * @param delimiter * @param padType * 1) right-justified; 2)left-justified; 3) centered; * otherwise it's no padding */ private static void padPrint(PrintWriter out, String str, int columnLength, String delimiter, int padType) { int diff = columnLength - str.length(); while (padType == 1 && diff-- > 0) { out.print(" "); } int remain = 0; if (diff > 0 && padType == 3) { int half = diff / 2; if (half == 0) { half = 1; } remain = diff - half; while (half-- > 0) { out.print(" "); } } out.print(" "); out.print(str); while (padType == 2 && diff-- > 0) { out.print(" "); } while (padType == 3 && remain-- > 0) { out.print(" "); } out.print(" "); out.print(delimiter); } /** * * @param out * @param length * @param delimiter */ private static void printTableLine(PrintWriter out, int length, String delimiter) { out.print("+"); while (length-- > 0) { out.print("-"); } out.println("+"); } /** * * @param rs * @param out * @param delimiter * @throws java.sql.SQLException */ public static void dumpRsTable(ResultSet rs, PrintWriter out, String delimiter) throws SQLException { if (!rs.next()) { out.println("no rows to display"); out.flush(); return; } int lineLength = 0; // estimate line length java.sql.ResultSetMetaData meta = rs.getMetaData(); int c = meta.getColumnCount(); // estimate the length of each column by looping thru the first few // records. ArrayList<List<String>> firstRows = new ArrayList<List<String>>( SAMPLE_SIZE); int[] columnSize = new int[c]; int count = 0; String tmpStr = null; do { ArrayList<String> list = new ArrayList<String>(c); for (int i = 0; i < c; i++) { String value = rs.getString(i + 1); tmpStr = value == null ? "" : value.toString(); columnSize[i] = Math.max(columnSize[i], tmpStr.length()); list.add(tmpStr); } firstRows.add(list); } while (++count < SAMPLE_SIZE && rs.next()); int[] types = new int[c]; // you can have the header names longer than the data itself for (int i = 0; i < c; i++) { types[i] = meta.getColumnType(i + 1); // out.print(meta.getColumnName(i+1).toUpperCase() + delimiter); columnSize[i] = Math.max(columnSize[i], meta.getColumnLabel(i + 1) .length()); lineLength += columnSize[i] + 2; // add 2 since we pad data in // column } lineLength += c - 1; printTableLine(out, lineLength, delimiter); out.print(delimiter); // now print the column header for (int i = 0; i < c; i++) { padPrint(out, meta.getColumnLabel(i + 1), columnSize[i], delimiter, 3); } out.println(); printTableLine(out, lineLength, delimiter); // out.println(); int rowsCnt = firstRows.size(); for (int idx = 0; idx < rowsCnt; idx++) { // printTableLine(out, lineLength, delimiter); out.print(delimiter); List<String> list = firstRows.get(idx); for (int i = 0; i < c; i++) { padPrint(out, list.get(i), columnSize[i], delimiter, (DataTypes .isNumeric(types[i]) ? 1 : 2)); } out.println(); } out.flush(); // write rows while (rs.next()) { // printTableLine(out, lineLength, delimiter); out.print(delimiter); for (int i = 0; i < c; i++) { String value = rs.getString(i + 1); padPrint(out, value == null ? "" : value.toString(), columnSize[i], delimiter, (DataTypes .isNumeric(types[i]) ? 1 : 2)); } out.println(); out.flush(); rowsCnt++; } printTableLine(out, lineLength, delimiter); out.println(rowsCnt + " row(s)."); out.flush(); } /** * * @param rs * @param out * @param delimiter * @param printTrailingDelimiter * @throws java.sql.SQLException */ public static void dumpRs(ResultSet rs, PrintWriter out, String delimiter, boolean printTrailingDelimiter) throws SQLException { if (!rs.next()) { out.println("no rows to display"); out.flush(); return; } java.sql.ResultSetMetaData meta = rs.getMetaData(); int c = meta.getColumnCount(); int types[] = new int[c]; for (int i = 0; i < c; i++) { types[i] = meta.getColumnType(i + 1); out.print(meta.getColumnLabel(i + 1).toUpperCase() + delimiter); // out.print(meta.getColumnName(i+1) + " - " + // meta.getColumnClassName(i+1) + delimiter); } out.println(); int rowsCnt = 0; // java.text.DecimalFormat aDF = new java.text.DecimalFormat(); // aDF.setGroupingUsed(false); // write rows do { for (int i = 0; i < c; i++) { String value = rs.getString(i + 1); out.print((value == null ? "null" : value.toString().trim())); if (printTrailingDelimiter || i < c - 1) { out.print(delimiter); } } out.println(); out.flush(); rowsCnt++; } while (rs.next()); out.println(rowsCnt + " rows dumped"); out.flush(); } public static Connection connect(Map<String, List<String>> parameters) throws SQLException { return connect(parameters, false); } /** * * @param parameters * @param mode * @throws java.sql.SQLException * @return */ public static Connection connect(Map<String, List<String>> parameters, boolean adminMode) throws SQLException { String url; // Alternates to URL String host = "localhost"; int port = 6453; String database = null; String username = null; String password = null; Connection con = null; url = ParseArgs.getStrArg(parameters, "j"); if (url == null) { String s = ParseArgs.getStrArg(parameters, "h"); if (s != null) { host = s; } s = ParseArgs.getStrArg(parameters, "s"); if (s != null) { try { port = Integer.parseInt(s); } catch (NumberFormatException ignore) { } } if (!adminMode) { database = ParseArgs.getStrArg(parameters, "d"); if (database == null) { System.out.println("Please, specify database"); throw new SQLException("Database name is not specified"); } } username = ParseArgs.getStrArg(parameters, "u"); if (username == null) { System.out.println("Please, specify user name"); throw new SQLException("User name is not specified"); } password = ParseArgs.getStrArg(parameters, "p"); url = "jdbc:postgresql://" + host + ":" + port + "/" + (adminMode ? Props.XDB_ADMIN_DATABASE : database); } try { Class.forName("org.postgresql.driver.Driver"); } catch (ClassNotFoundException cnfe) { throw new SQLException("JDBC driver is not available"); } if (username == null) { con = DriverManager.getConnection(url); } else if (password == null) { for (int i = 0; i < 3; i++) { try { try { password = PasswordPrompt.getPassword("password: "); } catch (IOException ioe) { throw new SQLException("Can not get password: " + ioe.getMessage()); } con = DriverManager.getConnection(url, username, password); break; } catch (SQLException e) { if (!"Invalid login".equals(e.getMessage())) { throw e; } } } } else { con = DriverManager.getConnection(url, username, password); } if (con == null) { throw new SQLException("Can not connect to server"); } return con; } }