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}