001/* 002 * Copyright (c) 2004-2013 Tada AB and other contributors, as listed below. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the The BSD 3-Clause License 006 * which accompanies this distribution, and is available at 007 * http://opensource.org/licenses/BSD-3-Clause 008 * 009 * Contributors: 010 * Tada AB 011 * Filip Hrbek 012 */ 013package org.postgresql.pljava.example; 014 015import java.lang.reflect.Method; 016import java.sql.Connection; 017import java.sql.DatabaseMetaData; 018import java.sql.DriverManager; 019import java.sql.ResultSet; 020import java.sql.SQLException; 021import java.util.ArrayList; 022import java.util.Arrays; 023import java.util.Comparator; 024import java.util.logging.Logger; 025 026import org.postgresql.pljava.ResultSetProvider; 027 028/** 029 * Example returning (varchar,boolean) rows, one for each boolean-valued 030 * attribute in the JDBC {@link DatabaseMetaData}. 031 * @author Filip Hrbek 032 */ 033public class MetaDataBooleans implements ResultSetProvider { 034 public static ResultSetProvider getDatabaseMetaDataBooleans() 035 throws SQLException { 036 try { 037 return new MetaDataBooleans(); 038 } catch (SQLException e) { 039 throw new SQLException("Error reading DatabaseMetaData", 040 e.getMessage()); 041 } 042 } 043 044 String[] methodNames; 045 046 Boolean[] methodResults; 047 048 public MetaDataBooleans() throws SQLException { 049 Logger log = Logger.getAnonymousLogger(); 050 051 class MethodComparator implements Comparator<Method> { 052 @Override 053 public int compare(Method a, Method b) { 054 return a.getName().compareTo(b.getName()); 055 } 056 } 057 058 Connection conn = DriverManager 059 .getConnection("jdbc:default:connection"); 060 DatabaseMetaData md = conn.getMetaData(); 061 Method[] m = DatabaseMetaData.class.getMethods(); 062 Arrays.sort(m, new MethodComparator()); 063 Class<?> prototype[]; 064 Class<?> returntype; 065 Object[] args = new Object[0]; 066 Boolean result = null; 067 ArrayList<String> mn = new ArrayList<>(); 068 ArrayList<Boolean> mr = new ArrayList<>(); 069 070 for (int i = 0; i < m.length; i++) { 071 prototype = m[i].getParameterTypes(); 072 if (prototype.length > 0) 073 continue; 074 075 returntype = m[i].getReturnType(); 076 if (!returntype.equals(boolean.class)) 077 continue; 078 079 try { 080 result = (Boolean) m[i].invoke(md, args); 081 } catch (Exception e) { 082 log.info("Method: " + m[i].getName() + " => " + e.getMessage()); 083 } catch (AbstractMethodError e) { 084 // probably a JDBC 4 method that isn't supported yet 085 log.info("Method: " + m[i].getName() + " => " + e.getMessage()); 086 } 087 088 mn.add(m[i].getName()); 089 mr.add(result); 090 } 091 092 methodNames = mn.toArray(new String[0]); 093 methodResults = mr.toArray(new Boolean[0]); 094 } 095 096 @Override 097 public boolean assignRowValues(ResultSet receiver, int currentRow) 098 throws SQLException { 099 if (currentRow < methodNames.length) { 100 receiver.updateString(1, methodNames[currentRow]); 101 receiver.updateBoolean(2, methodResults[currentRow].booleanValue()); 102 return true; 103 } 104 return false; 105 } 106 107 @Override 108 public void close() { 109 } 110}