001/* 002 * Copyright (c) 2004-2020 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 * Chapman Flack 013 */ 014package org.postgresql.pljava.example; 015 016import java.lang.reflect.InvocationTargetException; 017import java.lang.reflect.Method; 018import java.sql.Connection; 019import java.sql.DatabaseMetaData; 020import java.sql.DriverManager; 021import java.sql.ResultSet; 022import java.sql.SQLException; 023import java.util.ArrayList; 024import java.util.Arrays; 025import java.util.Comparator; 026import java.util.logging.Logger; 027 028import org.postgresql.pljava.ResultSetProvider; 029 030/** 031 * Example returning (varchar,int) rows, one for each int-valued 032 * attribute in the JDBC {@link DatabaseMetaData}. 033 * @author Filip Hrbek 034 */ 035public class MetaDataInts implements ResultSetProvider { 036 public static ResultSetProvider getDatabaseMetaDataInts() 037 throws SQLException { 038 try { 039 return new MetaDataInts(); 040 } catch (SQLException e) { 041 throw new SQLException("Error reading DatabaseMetaData", 042 e.getMessage()); 043 } 044 } 045 046 String[] methodNames; 047 048 Integer[] methodResults; 049 050 public MetaDataInts() throws SQLException { 051 Logger log = Logger.getAnonymousLogger(); 052 053 class MethodComparator implements Comparator<Method> { 054 @Override 055 public int compare(Method a, Method b) { 056 return a.getName().compareTo(b.getName()); 057 } 058 } 059 060 Connection conn = DriverManager 061 .getConnection("jdbc:default:connection"); 062 DatabaseMetaData md = conn.getMetaData(); 063 Method[] m = DatabaseMetaData.class.getMethods(); 064 Arrays.sort(m, new MethodComparator()); 065 Class<?> prototype[]; 066 Class<?> returntype; 067 Object[] args = new Object[0]; 068 Integer result = null; 069 ArrayList<String> mn = new ArrayList<>(); 070 ArrayList<Integer> mr = new ArrayList<>(); 071 072 for (int i = 0; i < m.length; i++) { 073 prototype = m[i].getParameterTypes(); 074 if (prototype.length > 0) 075 continue; 076 077 returntype = m[i].getReturnType(); 078 if (!returntype.equals(int.class)) 079 continue; 080 081 try { 082 result = (Integer) m[i].invoke(md, args); 083 } catch (InvocationTargetException e) { 084 log.info("Method: " + m[i].getName() + " => " 085 + e.getTargetException().getMessage()); 086 result = -1; 087 } catch (Exception e) { 088 log.info("Method: " + m[i].getName() + " => " + e.getMessage()); 089 result = -1; 090 } 091 092 mn.add(m[i].getName()); 093 mr.add(result); 094 } 095 096 methodNames = mn.toArray(new String[mn.size()]); 097 methodResults = mr.toArray(new Integer[mr.size()]); 098 } 099 100 @Override 101 public boolean assignRowValues(ResultSet receiver, int currentRow) 102 throws SQLException { 103 if (currentRow < methodNames.length) { 104 receiver.updateString(1, methodNames[currentRow]); 105 receiver.updateInt(2, methodResults[currentRow].intValue()); 106 return true; 107 } 108 return false; 109 } 110 111 @Override 112 public void close() { 113 } 114}