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,varchar) rows, one for each String-valued
030 * attribute in the JDBC {@link DatabaseMetaData}.
031 * @author Filip Hrbek
032 */
033public class MetaDataStrings implements ResultSetProvider {
034    public static ResultSetProvider getDatabaseMetaDataStrings()
035            throws SQLException {
036        try {
037            return new MetaDataStrings();
038        } catch (SQLException e) {
039            throw new SQLException("Error reading DatabaseMetaData",
040                    e.getMessage());
041        }
042    }
043
044    String[] methodNames;
045
046    String[] methodResults;
047
048    public MetaDataStrings() 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        String result = null;
067        ArrayList<String> mn = new ArrayList<>();
068        ArrayList<String> 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(String.class))
077                continue;
078
079            try {
080                result = (String) m[i].invoke(md, args);
081                log.info("Method: " + m[i].getName() + " => Success");
082            } catch (Exception e) {
083                log.info("Method: " + m[i].getName() + " => " + e.getMessage());
084            }
085
086            mn.add(m[i].getName());
087            mr.add(result);
088        }
089
090        methodNames = mn.toArray(new String[0]);
091        methodResults = mr.toArray(new String[0]);
092    }
093
094    @Override
095    public boolean assignRowValues(ResultSet receiver, int currentRow)
096            throws SQLException {
097        if (currentRow < methodNames.length) {
098            receiver.updateString(1, methodNames[currentRow]);
099            receiver.updateString(2, methodResults[currentRow]);
100            return true;
101        }
102        return false;
103    }
104
105    @Override
106    public void close() {
107    }
108}