001: /**
002: * com.mckoi.database.interpret.Call 15 Sep 2002
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.io.*;
027: import java.util.ArrayList;
028: import java.util.List;
029:
030: /**
031: * A statement that calls a procedure, and returns a resultant table. This
032: * is used to perform some sort of function over the database. For example,
033: * "CALL SYSTEM_MAKE_BACKUP('/my_backups/1')" makes a copy of the database in
034: * the given directory on the disk.
035: *
036: * @author Tobias Downer
037: */
038:
039: public class Call extends Statement {
040:
041: // ---------- Implemented from Statement ----------
042:
043: public void prepare() throws DatabaseException {
044: }
045:
046: public Table evaluate() throws DatabaseException {
047:
048: DatabaseQueryContext context = new DatabaseQueryContext(
049: database);
050:
051: String proc_name = (String) cmd.getObject("proc_name");
052: Expression[] args = (Expression[]) cmd.getObject("args");
053:
054: // Get the procedure manager
055: ProcedureManager manager = database.getProcedureManager();
056: ProcedureName name;
057:
058: TableName p_name = null;
059:
060: // If no schema def given in the procedure name, first check for the
061: // function in the SYS_INFO schema.
062: if (proc_name.indexOf(".") == -1) {
063: // Resolve the procedure name into a TableName object.
064: String schema_name = database.getCurrentSchema();
065: TableName tp_name = TableName.resolve(
066: Database.SYSTEM_SCHEMA, proc_name);
067: tp_name = database.tryResolveCase(tp_name);
068:
069: // If exists then use this
070: if (manager.procedureExists(tp_name)) {
071: p_name = tp_name;
072: }
073: }
074:
075: if (p_name == null) {
076: // Resolve the procedure name into a TableName object.
077: String schema_name = database.getCurrentSchema();
078: TableName tp_name = TableName.resolve(schema_name,
079: proc_name);
080: tp_name = database.tryResolveCase(tp_name);
081:
082: // Does the schema exist?
083: boolean ignore_case = database.isInCaseInsensitiveMode();
084: SchemaDef schema = database.resolveSchemaCase(tp_name
085: .getSchema(), ignore_case);
086: if (schema == null) {
087: throw new DatabaseException("Schema '"
088: + tp_name.getSchema() + "' doesn't exist.");
089: } else {
090: tp_name = new TableName(schema.getName(), tp_name
091: .getName());
092: }
093:
094: // If this doesn't exist then generate the error
095: if (!manager.procedureExists(tp_name)) {
096: throw new DatabaseException("Stored procedure '"
097: + proc_name + "' was not found.");
098: }
099:
100: p_name = tp_name;
101: }
102:
103: // Does the procedure exist in the system schema?
104: name = new ProcedureName(p_name);
105:
106: // Check the user has privs to use this stored procedure
107: if (!database.getDatabase().canUserExecuteStoredProcedure(
108: context, user, name.toString())) {
109: throw new UserAccessException(
110: "User not permitted to call: " + proc_name);
111: }
112:
113: // Evaluate the arguments
114: TObject[] vals = new TObject[args.length];
115: for (int i = 0; i < args.length; ++i) {
116: if (args[i].isConstant()) {
117: vals[i] = args[i].evaluate(null, null, context);
118: } else {
119: throw new StatementException(
120: "CALL argument is not a constant: "
121: + args[i].text());
122: }
123: }
124:
125: // Invoke the procedure
126: TObject result = manager.invokeProcedure(name, vals);
127:
128: // Return the result of the procedure,
129: return FunctionTable.resultTable(context, result);
130:
131: }
132:
133: }
|