All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xdev.db.StoredProcedure Maven / Gradle / Ivy

/*
 * XDEV Application Framework - XDEV Application Framework
 * Copyright © 2003 XDEV Software (https://xdev.software)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 */
package xdev.db;


import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Map;

import xdev.util.MathUtils;


/**
 * The client side counterpart of a stored procedure in a database.
 * 

* It holds information about the structure containing name, return value and * parameters of a stored procedure. *

* To actually invoke a stored procedure in the database with user defined * arguments see {@link DBConnection#call(StoredProcedure, Object...)}. *

* Example: * *

 * Param customerGroup = new Param(ParamType.IN,"customerGroup",DataType.VARCHAR);
 * Param revenue = new Param(ParamType.IN,"revenue",DataType.DECIMAL);
 * StoredProcedure getCustomerCount = new StoredProcedure(ReturnTypeFlavor.TYPE,DataType.INTEGER,
 * 		"getCustomerCount",null,customerGroup,revenue);
 * DBConnection con = DBUtils.getCurrentDataSource().openConnection();
 * con.call(getCustomerCount,"whales",1000000);
 * Integer count = (Integer)getCustomerCount.getReturnValue();
 * con.close();
 * 
* * @author XDEV Software */ public class StoredProcedure implements Comparable, Serializable, AutoCloseable { private static final long serialVersionUID = 5887159909079048104L; /** * Describes the return type of a {@link StoredProcedure}. * * @author XDEV Software * */ public static enum ReturnTypeFlavor { VOID, UNKNOWN, RESULT_SET, TYPE } private final ReturnTypeFlavor returnTypeFlavor; /** * only used if {@link #returnTypeFlavor} = {@link ReturnTypeFlavor#TYPE}. */ private final DataType returnType; private final String name; private final String description; private final Param[] params; private final Map paramMap; private transient Object returnValue; private final int hash; private transient String toString = null; /** * Constructs a new StoredProcedure with the given parameters. * * @param returnTypeFlavor * the return flavor of this stored procedure * * @param returnType * only used if {@link #returnTypeFlavor} = * {@link ReturnTypeFlavor#TYPE} * * @param name * the name of this {@link StoredProcedure} * * @param description * the description of this {@link StoredProcedure} * * @param params * a array of {@link Param} */ public StoredProcedure(ReturnTypeFlavor returnTypeFlavor, DataType returnType, String name, String description, Param... params) { this.returnTypeFlavor = returnTypeFlavor; this.returnType = returnType; this.name = name; this.description = description; this.params = params; Map paramMap = new Hashtable(); for(Param param : params) { paramMap.put(param.name,param); } this.paramMap = Collections.unmodifiableMap(paramMap); this.hash = MathUtils.computeHashDeep(returnTypeFlavor,returnType,name,params); } /** * Returns the {@link ReturnTypeFlavor} of this {@link StoredProcedure}. * * @return the {@link ReturnTypeFlavor} */ public ReturnTypeFlavor getReturnTypeFlavor() { return returnTypeFlavor; } /** * Returns the return type of this {@link StoredProcedure}. * * @return the return type if {@link #returnTypeFlavor} = * {@link ReturnTypeFlavor#TYPE}, null otherwise */ public DataType getReturnType() { return returnType; } /** * Returns the name of this {@link StoredProcedure}. * * @return the name of this {@link StoredProcedure} */ public String getName() { return name; } /** * Returns the description of this {@link StoredProcedure}. * * @return the description of this {@link StoredProcedure} */ public String getDescription() { return description; } /** * Returns the number of parameter. * * @return the number of parameter as int value. */ public int getParamCount() { return params.length; } /** * Returns the {@link Param} with the specified index. * * @param index * of the {@link Param} * * @return the {@link Param} for the specified index */ public Param getParam(int index) { return params[index]; } /** * Returns all params of this stored procedure. * * @return all params of this stored procedure * * @since 3.1 */ public Param[] getParams() { return Arrays.copyOf(params,params.length); } /** * Returns the {@link Param} with the specified name. * * @param name * of the {@link Param} * * @return the {@link Param} for the specified name */ public Param getParam(String name) { return paramMap.get(name); } /** * Prepares this procedure's params by setting the arguments. *

* This method is used by {@link DBConnection}s and is not intended to be * called by the user. * * @param args * the procedures arguments. */ public void prepareCall(Object... args) { returnValue = null; for(Param param : params) { param.value = null; } if(args != null && args.length > 0) { for(int pi = 0, ai = 0; pi < params.length && ai < args.length; pi++) { if(params[pi].getParamType() == ParamType.OUT) { continue; } params[pi].setValue(args[ai++]); } } } /** * Sets the returnValue of this {@link StoredProcedure}. * * @param returnValue * the new {@link #returnValue} */ public void setReturnValue(Object returnValue) { this.returnValue = returnValue; } /** * Returns the return value of this {@link StoredProcedure}. * * @return the return value as Object */ public Object getReturnValue() { return returnValue; } /** * Returns the result of this {@link StoredProcedure}. *

* Note that {@link #getReturnTypeFlavor()} must be * {@link ReturnTypeFlavor#RESULT_SET}, otherwise an * {@link IllegalStateException} is thrown. * * @return the procedure's result * @throws IllegalStateException * if {@link #getReturnTypeFlavor()} is not * {@link ReturnTypeFlavor#RESULT_SET} * * @since 3.1 */ public Result getResult() { if(returnTypeFlavor != ReturnTypeFlavor.RESULT_SET) { throw new IllegalStateException("Procedure doesn't return a result"); } return (Result)returnValue; } /** * {@inheritDoc} */ @Override public void close() throws DBException { if(returnValue instanceof Result) { ((Result)returnValue).close(); } } /** * {@inheritDoc} */ @Override public int compareTo(StoredProcedure other) { return toString().compareTo(other.toString()); } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { if(obj == this) { return true; } if(obj instanceof StoredProcedure) { StoredProcedure sp = (StoredProcedure)obj; if(returnTypeFlavor != sp.returnTypeFlavor || returnType != sp.returnType || !name.equals(sp.name) || params.length != sp.params.length) { return false; } for(int i = 0; i < params.length; i++) { if(!params[i].equals(sp.params[i])) { return false; } } return true; } return false; } /** * {@inheritDoc} */ @Override public int hashCode() { return hash; } /** * {@inheritDoc} */ @Override public String toString() { if(toString == null) { StringBuilder sb = new StringBuilder(); switch(returnTypeFlavor) { case TYPE: sb.append(returnType); break; default: sb.append(returnTypeFlavor); } sb.append(" "); sb.append(name); sb.append("("); for(int i = 0; i < params.length; i++) { if(i > 0) { sb.append(", "); } sb.append(params[i].toString()); } sb.append(")"); toString = sb.toString(); } return toString; } /** * Describes the type of a {@link Param}. * *

    *
  • IN
  • *
  • OUT
  • *
  • IN_OUT
  • *
* * * @author XDEV Software * */ public static enum ParamType { /** * The param is used as an argument only. */ IN, /** * The param returns a value. */ OUT, /** * The param is used as an argument and returns a value. */ IN_OUT } /** * This class includes information about the {@link StoredProcedure} * parameter. *

* The class has properties like paramType, name, dataType, value, hash. *

* * @author XDEV Software * */ public static class Param implements Serializable { private static final long serialVersionUID = 6869273219350312631L; private final ParamType paramType; private final String name; private final DataType dataType; private transient Object value; private final int hash; private transient String toString = null; /** * Constructs a new {@link Param} with the given paramType, * name and the dataType. * * @param paramType * the type of this {@link Param} * * @param name * the name of this {@link Param} * * @param dataType * the data type of this {@link Param} */ public Param(ParamType paramType, String name, DataType dataType) { this.paramType = paramType; this.name = name; this.dataType = dataType; this.hash = MathUtils.computeHash(paramType,name,dataType); } /** * Returns the {@link ParamType} of this {@link Param}. * * * @return the {@link ParamType} of this {@link Param} */ public ParamType getParamType() { return paramType; } /** * Returns the name of this {@link Param}. * * * @return the name of this {@link Param} */ public String getName() { return name; } /** * Returns the {@link DataType} of this {@link Param}. * * * @return the {@link DataType} of this {@link Param} */ public DataType getDataType() { return dataType; } /** * Sets the value of this {@link Param}. * * @param value * the new value */ public void setValue(Object value) { this.value = value; } /** * Returns the value of this {@link Param}. * * * @return the value as Object */ public Object getValue() { return value; } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { if(o == this) { return true; } if(o instanceof Param) { Param p = (Param)o; return p.paramType == paramType && p.name.equals(name) && p.dataType == dataType; } return false; } /** * {@inheritDoc} */ @Override public int hashCode() { return hash; } /** * {@inheritDoc} */ @Override public String toString() { if(toString == null) { StringBuilder sb = new StringBuilder(); sb.append(paramType); sb.append(" "); sb.append(dataType); sb.append(" "); sb.append(name); toString = sb.toString(); } return toString; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy