001: /**
002: * com.mckoi.database.interpret.Function 30 Mar 2003
003: *
004: * Mckoi SQL Database ( http://www.mckoi.com/database )
005: * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * Version 2 as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License Version 2 for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * Version 2 along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: * Change Log:
021: *
022: *
023: */package com.mckoi.database.interpret;
024:
025: import com.mckoi.database.*;
026: import java.util.ArrayList;
027: import java.util.List;
028:
029: /**
030: * A handler for defining and dropping functions.
031: *
032: * @author Tobias Downer
033: */
034:
035: public class Function extends Statement {
036:
037: /**
038: * The type of command we are running through this Function object.
039: */
040: private String type;
041:
042: /**
043: * The name of the function.
044: */
045: private TableName fun_name;
046:
047: // ----------- Implemented from Statement ----------
048:
049: public void prepare() throws DatabaseException {
050: type = (String) cmd.getObject("type");
051: String function_name = (String) cmd.getObject("function_name");
052:
053: // Resolve the function name into a TableName object.
054: String schema_name = database.getCurrentSchema();
055: fun_name = TableName.resolve(schema_name, function_name);
056: fun_name = database.tryResolveCase(fun_name);
057:
058: }
059:
060: public Table evaluate() throws DatabaseException {
061:
062: DatabaseQueryContext context = new DatabaseQueryContext(
063: database);
064:
065: // Does the schema exist?
066: boolean ignore_case = database.isInCaseInsensitiveMode();
067: SchemaDef schema = database.resolveSchemaCase(fun_name
068: .getSchema(), ignore_case);
069: if (schema == null) {
070: throw new DatabaseException("Schema '"
071: + fun_name.getSchema() + "' doesn't exist.");
072: } else {
073: fun_name = new TableName(schema.getName(), fun_name
074: .getName());
075: }
076:
077: if (type.equals("create")) {
078:
079: // Does the user have privs to create this function?
080: if (!database.getDatabase().canUserCreateProcedureObject(
081: context, user, fun_name)) {
082: throw new UserAccessException(
083: "User not permitted to create function: "
084: + fun_name);
085: }
086:
087: // Does a table already exist with this name?
088: if (database.tableExists(fun_name)) {
089: throw new DatabaseException(
090: "Database object with name '" + fun_name
091: + "' already exists.");
092: }
093:
094: // Get the information about the function we are creating
095: List arg_names = (List) cmd.getObject("arg_names");
096: List arg_types = (List) cmd.getObject("arg_types");
097: TObject loc_name = (TObject) cmd.getObject("location_name");
098: TType return_type = (TType) cmd.getObject("return_type");
099:
100: // Note that we currently ignore the arg_names list.
101:
102: // Convert arg types to an array
103: TType[] arg_type_array = (TType[]) arg_types
104: .toArray(new TType[arg_types.size()]);
105:
106: // We must parse the location name into a class name, and method name
107: String java_specification = loc_name.getObject().toString();
108: // Resolve the java_specification to an invokation method.
109: java.lang.reflect.Method proc_method = ProcedureManager
110: .javaProcedureMethod(java_specification,
111: arg_type_array);
112: if (proc_method == null) {
113: throw new DatabaseException(
114: "Unable to find invokation method for "
115: + "Java stored procedure name: "
116: + java_specification);
117: }
118:
119: // Convert the information into an easily digestible form.
120: ProcedureName proc_name = new ProcedureName(fun_name);
121: int sz = arg_types.size();
122: TType[] arg_list = new TType[sz];
123: for (int i = 0; i < sz; ++i) {
124: arg_list[i] = (TType) arg_types.get(i);
125: }
126:
127: // Create the (Java) function,
128: ProcedureManager manager = database.getProcedureManager();
129: manager.defineJavaProcedure(proc_name, java_specification,
130: return_type, arg_list, user.getUserName());
131:
132: // The initial grants for a procedure is to give the user who created it
133: // full access.
134: database.getGrantManager().addGrant(
135: Privileges.PROCEDURE_ALL_PRIVS, GrantManager.TABLE,
136: proc_name.toString(), user.getUserName(), true,
137: Database.INTERNAL_SECURE_USERNAME);
138:
139: } else if (type.equals("drop")) {
140:
141: // Does the user have privs to create this function?
142: if (!database.getDatabase().canUserDropProcedureObject(
143: context, user, fun_name)) {
144: throw new UserAccessException(
145: "User not permitted to drop function: "
146: + fun_name);
147: }
148:
149: // Drop the function
150: ProcedureName proc_name = new ProcedureName(fun_name);
151: ProcedureManager manager = database.getProcedureManager();
152: manager.deleteProcedure(proc_name);
153:
154: // Drop the grants for this object
155: database.getGrantManager().revokeAllGrantsOnObject(
156: GrantManager.TABLE, proc_name.toString());
157:
158: } else {
159: throw new RuntimeException("Unknown type: " + type);
160: }
161:
162: // Return an update result table.
163: return FunctionTable.resultTable(context, 0);
164:
165: }
166:
167: }
|