/*******************************************************************************
 * Copyright (c) 2010 Robert "Unlogic" Olofsson (unlogic@unlogic.se).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v3
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-3.0-standalone.html
 ******************************************************************************/
package se.unlogic.standardutils.db;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class DBUtils {

   public static boolean tableExists(DataSource dataSource, String tableName) throws SQLException {

      Connection connection = null;
      ResultSet rs = null;

      try {
         connection = dataSource.getConnection();

         DatabaseMetaData meta = connection.getMetaData();

         rs = meta.getTables(null, null, tableName, null);

         if (rs.next()) {
            return true;
         }
      } finally {
         closeResultSet(rs);
         closeConnection(connection);
      }

      return false;
   }

   public static ArrayList<String> listAllTables(Connection connection) throws SQLException {

      ResultSet rs = null;

      try {
         DatabaseMetaData meta = connection.getMetaData();

         rs = meta.getTables(null, null, null, null);

         ArrayList<String> tableList = new ArrayList<String>();

         while (rs.next()) {

            tableList.add(rs.getString(3));
         }

         return tableList;

      } finally {
         closeResultSet(rs);
         closeConnection(connection);
      }
   }

   public static DataSource getDataSource(String name) throws NamingException {
      Context initContext = new InitialContext();
      Context envContext = (Context) initContext.lookup("java:/comp/env");
      return (DataSource) envContext.lookup(name);
   }

   public static boolean containsColumn(ResultSet rs, String columnName) {
      try {
         rs.findColumn(columnName);
         return true;
      } catch (SQLException e) {
         return false;
      }
   }

   public static List<String> getTableColumns(Connection connection, String selectedTable) throws SQLException {

      ResultSet rs = null;

      try {
         DatabaseMetaData meta = connection.getMetaData();

         rs = meta.getColumns(null, null, selectedTable, null);

         ArrayList<String> columnNames = new ArrayList<String>();

         while (rs.next()) {

            columnNames.add(rs.getString(4));
         }

         return columnNames;

      } finally {
         closeResultSet(rs);
         closeConnection(connection);
      }
   }

   public static int getTableColumnCount(DataSource dataSource, String selectedTable) throws SQLException {

      Connection connection = null;
      ResultSet rs = null;

      try {

         connection = dataSource.getConnection();

         DatabaseMetaData meta = connection.getMetaData();

         rs = meta.getColumns(null, null, selectedTable, null);

         rs.last();

         return rs.getRow();

      } finally {
         closeResultSet(rs);
         closeConnection(connection);
      }
   }

   public static void closeConnection(Connection connection) {
      try {
         if (connection != null && !connection.isClosed()) {
            connection.close();
         }
      } catch (SQLException e) {
      }
   }

   public static void closeResultSet(ResultSet rs) {
      try {
         if (rs != null) {
            rs.close();
         }
      } catch (SQLException e) {
      }
   }

   public static void closePreparedStatement(PreparedStatement pstmt) {

      try {
         if (pstmt != null) {
            pstmt.close();
         }
      } catch (SQLException e) {
      }
   }

}
