package com.hackerdude.apps.sqlide.plugins.pgsql.storedproc;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Properties;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JOptionPane;
import com.hackerdude.apps.sqlide.ProgramIcons;
import com.hackerdude.apps.sqlide.SqlIdeApplication;
import com.hackerdude.apps.sqlide.dataaccess.DatabaseProcess;
import com.hackerdude.apps.sqlide.nodes.ItemServerNode;
import com.hackerdude.apps.sqlide.pluginapi.BrowserExtensionPluginIF;
import com.hackerdude.apps.sqlide.pluginapi.IDENodeContextPluginIF;
import com.hackerdude.apps.sqlide.pluginapi.NodeIDEBase;
import com.hackerdude.apps.sqlide.plugins.browser.browsejdbc.ItemCatalogNode;
import com.hackerdude.apps.sqlide.plugins.browser.browsejdbc.ItemSchemaNode;
/**
* This is a stored procedure browser extension plugin.
*/
public class ProcedureBrowserExtension implements BrowserExtensionPluginIF, IDENodeContextPluginIF {
public static final String PGSQL_PROCEDURE_SQL = "storedprocedures.pgsql.properties";
public static final String SQL_RETRIEVE_PROCS_PROPERTY = "myprocs.retrieve";
public static final String SQL_RETRIEVE_PROC_SRC_PROPERTY = "myprocs.retrieve.src";
public static final String SQL_CREATE_PROC_PROPERTY = "myprocs.create.procedure";
public static final String SQL_REPLACE_PROC_PROPERTY = "myprocs.replace.procedure";
public static final String SQL_DELETE_PROC_PROPERTY = "myproc.delete.procedure";
public static final String SQL_TYPES_SELECT = "myproc.select.types";
public static final Properties sqlCalls = new Properties();
public ProcedureBrowserExtension() {
}
public void requestAddSubNodes(NodeIDEBase parentNode) {
DatabaseProcess proc = parentNode.getDatabaseProcess();
if ( parentNode instanceof ItemSchemaNode ) {
ItemSchemaNode schemaNode = (ItemSchemaNode)parentNode;
String containerName = schemaNode.toString();
parentNode.add( new CategoryStoredProcedureNode(null, containerName, proc));
}
if ( parentNode instanceof ItemCatalogNode ) {
ItemCatalogNode catalogNode = (ItemCatalogNode)parentNode;
String containerName = catalogNode.toString();
parentNode.add(new CategoryStoredProcedureNode(containerName, null, proc));
}
if ( parentNode instanceof ItemServerNode ) {
parentNode.add(new CategoryStoredProcedureNode(null, null, proc));
}
if ( parentNode instanceof CategoryStoredProcedureNode ) {
populateStoredProcedures((CategoryStoredProcedureNode)parentNode);
}
}
public void initPlugin() {
InputStream is = getClass().getResourceAsStream(PGSQL_PROCEDURE_SQL);
if ( is == null ) throw new IllegalArgumentException("Installation Error: Could not find "+PGSQL_PROCEDURE_SQL);
try {
sqlCalls.load(is);
} catch (IOException ex) {
throw new IllegalArgumentException("Could not initialize plugin - could not read "+PGSQL_PROCEDURE_SQL+" - "+ex.toString());
}
}
public String getPluginName() { return "Stored Procedure Browser"; }
public String getPluginVersion() {
return "Version 0.0";
}
public void freePlugin() {
}
public String getPluginShortName() {
return "Procedure Browser";
}
public Icon getPluginIcon() {
return ProgramIcons.getInstance().getStoredProcIcon();
}
private void populateStoredProcedures(CategoryStoredProcedureNode storedProcCategory) {
ItemStoredProcedureNode dbItem = null;
DatabaseProcess db = storedProcCategory.getDatabaseProcess();
String catalogName = storedProcCategory.getCatalogName();
String schemaName = storedProcCategory.getSchemaName();
if ( db.getHostConfiguration().getJdbc().getDriver().toLowerCase().indexOf("postgres")> -1) {
populatePostgreSQLStoredProcedures(storedProcCategory, dbItem, db, catalogName, schemaName);
} else {
populateGenericStoredProcs(storedProcCategory, dbItem, db, catalogName, schemaName);
}
}
/** @todo Hackish, but it should work. Use the properties file to retrieve the stored procedures list and start going through it. */
private void populatePostgreSQLStoredProcedures(CategoryStoredProcedureNode storedProcCategory, ItemStoredProcedureNode dbItem, DatabaseProcess db, String catalogName, String schemaName) {
Connection conn = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
if ( catalogName != null ) db.changeCatalog(catalogName);
conn = db.getConnection();
String sqlStatement = sqlCalls.getProperty(SQL_RETRIEVE_PROCS_PROPERTY);
preparedStatement = conn.prepareStatement(sqlStatement);
// if ( preparedStatement.getParameterMetaData().getParameterCount() > 0 ) {
// preparedStatement.setString(1, databaseProcess.getUserName());
// }
resultSet = preparedStatement.executeQuery();
while ( resultSet.next() ) {
String procName = resultSet.getString(1);
int numArgs = resultSet.getInt(2);
ArrayList argumentTypes = new ArrayList();
for ( int i=3; i<8; i++ ) {
int thisType = resultSet.getInt(i);
if ( thisType > 0 ) argumentTypes.add(new Integer(thisType));
}
ItemStoredProcedureNode storedProcedure = new ItemStoredProcedureNode(procName, argumentTypes, null, db);
storedProcCategory.add(storedProcedure);
}
// resultSet.close();
// preparedStatement.close();
}
catch (Exception ex) {
ex.printStackTrace();
if ( resultSet!=null ) try { resultSet.close(); } catch ( Throwable th ) {}
if ( preparedStatement!=null ) try { preparedStatement.close(); } catch ( Throwable th ) {}
if ( conn!=null ) db.returnConnection(conn);
}
}
private void populateGenericStoredProcs(CategoryStoredProcedureNode storedProcCategory, ItemStoredProcedureNode dbItem, DatabaseProcess db, String catalogName, String schemaName) {
try {
Connection conn = db.getPool().getConnection();
try {
ResultSet rs = conn.getMetaData().getProcedures(catalogName, schemaName, null );
while(rs.next()) {
dbItem = new ItemStoredProcedureNode(rs.getString("PROCEDURE_NAME"), db);
String remarks = "No remarks";
try {
remarks = rs.getString("REMARKS");
} catch ( Throwable th ) {}
dbItem.setRemarks(remarks);
storedProcCategory.add( dbItem );
}
} finally { db.getPool().releaseConnection(conn); }
} catch( SQLException sqle ) {
sqle.printStackTrace();
JOptionPane.showMessageDialog(null, sqle,
"SQL Error when getting procedures",
JOptionPane.ERROR_MESSAGE);
}
}
public Action[] getActionsFor(NodeIDEBase[] selectedNodes) {
if ( selectedNodes!= null & selectedNodes.length == 1 ) {
if ( selectedNodes[0] instanceof ItemStoredProcedureNode ) {
Action[] action = new Action[1];
action[0] = new ActionEditStoredProcedure((ItemStoredProcedureNode)selectedNodes[0]);
return action;
}
if ( selectedNodes[0] instanceof CategoryStoredProcedureNode ) {
Action[] action = new Action[1];
action[0] = new ActionCreateStoredProcedure(selectedNodes[0].getDatabaseProcess());
return action;
}
}
return NULL_ACTIONS;
}
class ActionEditStoredProcedure extends AbstractAction {
ItemStoredProcedureNode storedProcedure;
public ActionEditStoredProcedure(ItemStoredProcedureNode storedProcedure) {
super("Open "+storedProcedure.toString(), ProgramIcons.getInstance().findIcon("images/Open.gif"));
this.storedProcedure = storedProcedure;
}
public void actionPerformed(ActionEvent evt) {
StoredProcedureEditor editor = new StoredProcedureEditor();
editor.setDatabaseProcess(storedProcedure.getDatabaseProcess());
editor.setStoredProcedure(storedProcedure);
editor.readStoredProcedureSource();
editor.initPlugin();
SqlIdeApplication.getInstance().setRightPanel(editor);
}
}
class ActionCreateStoredProcedure extends AbstractAction {
DatabaseProcess proc;
public ActionCreateStoredProcedure(DatabaseProcess proc) {
super("Create new Function", ProgramIcons.getInstance().findIcon("images/storedproc.gif"));
this.proc = proc;
}
public void actionPerformed(ActionEvent evt) {
/** @todo Implement */
}
}
}