/*
* Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software;Designed and Developed mainly by many Chinese
* opensource volunteers. you can redistribute it and/or modify it under the
* terms of the GNU General Public License version 2 only, as published by the
* Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Any questions about this component can be directed to it's project Web address
* https://code.google.com/p/opencloudb/.
*
*/
package com.akiban.sql.types;
import java.sql.ParameterMetaData;
import com.akiban.sql.types.DataTypeDescriptor;
/**
* Describe a routine (procedure or function) alias.
*
* @see AliasInfo
*/
public class RoutineAliasInfo extends MethodAliasInfo
{
public static enum SQLAllowed {
MODIFIES_SQL_DATA("MODIFIES SQL DATA"),
READS_SQL_DATA("READS SQL DATA"),
CONTAINS_SQL("CONTAINS SQL"),
NO_SQL("NO SQL");
private String sql;
private SQLAllowed(String sql) {
this.sql = sql;
}
public String getSQL() {
return sql;
}
}
private int parameterCount;
/**
* Types of the parameters. If there are no parameters
* then this may be null (or a zero length array).
*/
private DataTypeDescriptor[] parameterTypes;
/**
* Name of each parameter. As of DERBY 10.3, parameter names
* are optional. If the parameter is unnamed, parameterNames[i]
* is a string of length 0
*/
private String[] parameterNames;
/**
* ParameterMetaData.parameterModeXxx: IN, OUT, INOUT
*/
private int[] parameterModes;
private int dynamicResultSets;
/**
* Return type for functions. Null for procedures.
*/
private DataTypeDescriptor returnType;
private String language;
private String parameterStyle;
private SQLAllowed sqlAllowed;
private boolean deterministic;
private boolean definersRights;
/**
* SQL Specific name (future)
*/
private String specificName;
/**
* True if the routine is called on null input.
* (always true for procedures).
*/
private boolean calledOnNullInput;
/**
* Create a RoutineAliasInfo for a PROCEDURE or FUNCTION
*/
public RoutineAliasInfo(String methodName,
int parameterCount,
String[] parameterNames,
DataTypeDescriptor[] parameterTypes,
int[] parameterModes,
int dynamicResultSets,
String language,
String parameterStyle,
SQLAllowed sqlAllowed,
boolean deterministic,
boolean definersRights,
boolean calledOnNullInput,
DataTypeDescriptor returnType) {
super(methodName);
this.parameterCount = parameterCount;
this.parameterNames = parameterNames;
this.parameterTypes = parameterTypes;
this.parameterModes = parameterModes;
this.dynamicResultSets = dynamicResultSets;
this.language = language;
this.parameterStyle = parameterStyle;
this.sqlAllowed = sqlAllowed;
this.deterministic = deterministic;
this.definersRights = definersRights;
this.calledOnNullInput = calledOnNullInput;
this.returnType = returnType;
}
public int getParameterCount() {
return parameterCount;
}
/**
* Types of the parameters. If there are no parameters
* then this may return null (or a zero length array).
*/
public DataTypeDescriptor[] getParameterTypes() {
return parameterTypes;
}
public int[] getParameterModes() {
return parameterModes;
}
/**
* Returns an array containing the names of the parameters.
* As of DERBY 10.3, parameter names are optional (see DERBY-183
* for more information). If the i-th parameter was unnamed,
* parameterNames[i] will contain a string of length 0.
*/
public String[] getParameterNames() {
return parameterNames;
}
public int getMaxDynamicResultSets() {
return dynamicResultSets;
}
public String getLanguage() {
return language;
}
public String getParameterStyle() {
return parameterStyle;
}
public SQLAllowed getSQLAllowed() {
return sqlAllowed;
}
public boolean isDeterministic()
{
return deterministic;
}
public boolean hasDefinersRights()
{
return definersRights;
}
public boolean calledOnNullInput() {
return calledOnNullInput;
}
public DataTypeDescriptor getReturnType() {
return returnType;
}
public boolean isFunction() {
return (returnType != null);
}
public boolean isTableFunction() {
if (returnType == null) {
return false;
}
else {
return returnType.isRowMultiSet();
}
}
/**
* Get this alias info as a string.
* This method must return a string that is syntactically valid.
*/
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append('(');
for (int i = 0; i < parameterCount; i++) {
if (i != 0)
sb.append(", ");
if (returnType == null) {
// This is a PROCEDURE. We only want to print the
// parameter mode (ex. "IN", "OUT", "INOUT") for procedures--
// we don't do it for functions since use of the "IN" keyword
// is not part of the FUNCTION syntax.
sb.append(parameterMode(parameterModes[i]));
sb.append(' ');
}
if (parameterNames[i] != null) {
sb.append(parameterNames[i]);
sb.append(' ');
}
sb.append(parameterTypes[i].getSQLstring());
}
sb.append(')');
if (returnType != null) {
// this a FUNCTION, so syntax requires us to append the return type.
sb.append(" RETURNS " + returnType.getSQLstring());
}
sb.append(" LANGUAGE ");
sb.append(language);
if (parameterStyle != null) {
sb.append(" PARAMETER STYLE " );
sb.append(parameterStyle);
}
if (deterministic) {
sb.append(" DETERMINISTIC ");
}
if (definersRights) {
sb.append(" EXTERNAL SECURITY DEFINER");
}
if (sqlAllowed != null) {
sb.append(" ");
sb.append(sqlAllowed.getSQL());
}
if ((returnType == null) &&
(dynamicResultSets != 0)) {
// Only print dynamic result sets if this is a PROCEDURE
// because it's not valid syntax for FUNCTIONs.
sb.append(" DYNAMIC RESULT SETS ");
sb.append(dynamicResultSets);
}
if (returnType != null) {
// this a FUNCTION, so append the syntax telling what to
// do with a null parameter.
sb.append(calledOnNullInput ? " CALLED " : " RETURNS NULL ");
sb.append("ON NULL INPUT");
}
return sb.toString();
}
public static String parameterMode(int parameterMode) {
switch (parameterMode) {
case ParameterMetaData.parameterModeIn:
return "IN";
case ParameterMetaData.parameterModeOut:
return "OUT";
case ParameterMetaData.parameterModeInOut:
return "INOUT";
default:
return "UNKNOWN";
}
}
}