2001-05-23 15:26:42 +02:00
|
|
|
/*
|
|
|
|
* PROGRAM: JRD Command Oriented Query Language
|
2003-09-15 14:30:28 +02:00
|
|
|
* MODULE: proc.epp
|
2001-05-23 15:26:42 +02:00
|
|
|
* DESCRIPTION: Procedure maintenance routines
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Interbase Public
|
|
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy
|
|
|
|
* of the License at http://www.Inprise.com/IPL.html
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an
|
|
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
|
|
* or implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code was created by Inprise Corporation
|
|
|
|
* and its predecessors. Portions created by Inprise Corporation are
|
|
|
|
* Copyright (C) Inprise Corporation.
|
|
|
|
*
|
|
|
|
* All Rights Reserved.
|
|
|
|
* Contributor(s): ______________________________________.
|
2002-10-31 06:06:02 +01:00
|
|
|
*
|
|
|
|
* 2002.10.30 Sean Leyne - Removed support for obsolete "PC_PLATFORM" define
|
|
|
|
*
|
2001-05-23 15:26:42 +02:00
|
|
|
*/
|
|
|
|
|
2001-07-30 01:43:24 +02:00
|
|
|
#include "firebird.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include <string.h>
|
2003-11-08 17:40:17 +01:00
|
|
|
#include "../jrd/ibase.h"
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../qli/dtr.h"
|
|
|
|
#include "../qli/parse.h"
|
|
|
|
#include "../qli/compile.h"
|
|
|
|
#include "../qli/err_proto.h"
|
|
|
|
#include "../qli/lex_proto.h"
|
|
|
|
#include "../qli/meta_proto.h"
|
|
|
|
#include "../qli/parse_proto.h"
|
|
|
|
#include "../qli/proc_proto.h"
|
|
|
|
|
2007-03-28 06:20:36 +02:00
|
|
|
using MsgFormat::SafeArg;
|
|
|
|
|
|
|
|
|
2001-05-23 15:26:42 +02:00
|
|
|
DATABASE DB1 = EXTERN FILENAME "yachts.lnk";
|
|
|
|
DATABASE DB = EXTERN FILENAME "yachts.lnk";
|
|
|
|
|
|
|
|
static int clear_out_qli_procedures(DBB);
|
|
|
|
static void create_qli_procedures(DBB);
|
2004-02-20 07:43:27 +01:00
|
|
|
static void probe(DBB, const TEXT*);
|
2003-09-15 14:30:28 +02:00
|
|
|
static int upcase_name(const TEXT*, TEXT*);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
static const UCHAR tpb[] =
|
|
|
|
{
|
|
|
|
isc_tpb_version1, isc_tpb_write,
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_tpb_concurrency
|
2001-05-23 15:26:42 +02:00
|
|
|
};
|
|
|
|
|
2003-11-05 10:02:33 +01:00
|
|
|
static const UCHAR dyn_gdl1[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../qli/procddl1.h"
|
|
|
|
};
|
2003-11-05 10:02:33 +01:00
|
|
|
static const UCHAR dyn_gdl2[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../qli/procddl2.h"
|
|
|
|
};
|
2003-11-05 10:02:33 +01:00
|
|
|
static const UCHAR dyn_gdl3[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../qli/procddl3.h"
|
|
|
|
};
|
2003-11-05 10:02:33 +01:00
|
|
|
static const UCHAR dyn_gdl4[] = {
|
2001-05-23 15:26:42 +02:00
|
|
|
#include "../qli/procddl4.h"
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
void PRO_close( DBB database, FB_API_HANDLE blob)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ c l o s e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Close out an open procedure blob.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (database && isc_close_blob(status_vector, &blob))
|
2001-05-23 15:26:42 +02:00
|
|
|
ERRQ_database_error(database, status_vector);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PRO_commit( DBB database)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ c o m m i t
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Commit the procedure transaction.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if ((database->dbb_capabilities & DBB_cap_multi_trans) &&
|
|
|
|
!(LEX_active_procedure()))
|
2003-09-10 19:52:12 +02:00
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_commit_transaction(status_vector, &database->dbb_proc_trans)) {
|
2001-05-23 15:26:42 +02:00
|
|
|
PRO_rollback(database);
|
|
|
|
ERRQ_database_error(database, status_vector);
|
|
|
|
}
|
2003-09-10 19:52:12 +02:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PRO_copy_procedure(
|
|
|
|
DBB old_database,
|
2004-02-20 07:43:27 +01:00
|
|
|
const TEXT* old_name,
|
|
|
|
DBB new_database, const TEXT* new_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ c o p y _ p r o c e d u r e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Create a new copy of an existing
|
|
|
|
* procedure. Search databases for the
|
|
|
|
* existing procedure.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
if (!new_database)
|
|
|
|
new_database = QLI_databases;
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE old_blob;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!old_database) {
|
|
|
|
for (old_database = QLI_databases; old_database;
|
2003-09-13 13:48:09 +02:00
|
|
|
old_database = old_database->dbb_next)
|
|
|
|
{
|
2004-02-20 07:43:27 +01:00
|
|
|
if (old_blob = PRO_fetch_procedure(old_database, old_name))
|
2003-09-13 13:48:09 +02:00
|
|
|
break;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
old_blob = PRO_fetch_procedure(old_database, old_name);
|
|
|
|
|
|
|
|
if (!old_blob)
|
2007-03-28 06:20:36 +02:00
|
|
|
ERRQ_print_error(70, old_name);
|
2004-03-07 08:58:55 +01:00
|
|
|
// Msg 70 procedure \"%s\" is undefined
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (new_database != old_database)
|
|
|
|
PRO_setup(new_database);
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE new_blob = 0;
|
|
|
|
FB_API_HANDLE store_request = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
probe(new_database, new_name);
|
|
|
|
|
|
|
|
DB1 = new_database->dbb_handle;
|
|
|
|
|
2007-04-06 12:10:10 +02:00
|
|
|
// create blob parameter block since procedure is a text blob
|
|
|
|
// But nothing was done! The bpb is empty.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
UCHAR bpb[20];
|
2003-09-15 14:30:28 +02:00
|
|
|
UCHAR* p = bpb;
|
|
|
|
USHORT bpb_length = p - bpb;
|
2004-02-20 07:43:27 +01:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
|
|
|
TEXT buffer[255];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE store_request TRANSACTION_HANDLE new_database->dbb_proc_trans)
|
|
|
|
NEW IN DB1.QLI$PROCEDURES USING
|
|
|
|
|
|
|
|
strcpy(NEW.QLI$PROCEDURE_NAME, new_name);
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_create_blob2(status_vector, &new_database->dbb_handle,
|
2003-08-30 04:12:44 +02:00
|
|
|
&new_database->dbb_proc_trans, &new_blob,
|
2003-10-29 11:53:47 +01:00
|
|
|
&NEW.QLI$PROCEDURE, bpb_length,
|
|
|
|
reinterpret_cast<const char*>(bpb)))
|
|
|
|
{
|
|
|
|
ERRQ_database_error(new_database, status_vector);
|
|
|
|
}
|
2004-02-20 07:43:27 +01:00
|
|
|
USHORT length;
|
|
|
|
while (!(isc_get_segment(status_vector, &old_blob, &length,
|
2003-10-29 11:53:47 +01:00
|
|
|
sizeof(buffer), buffer)))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
buffer[length] = 0;
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_put_segment(status_vector, &new_blob, length, buffer))
|
2001-05-23 15:26:42 +02:00
|
|
|
ERRQ_database_error(new_database, status_vector);
|
|
|
|
}
|
|
|
|
PRO_close(old_database, old_blob);
|
|
|
|
PRO_close(new_database, new_blob);
|
|
|
|
END_STORE;
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// Release the FOR and STORE requests
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(gds_status, &store_request);
|
2001-05-23 15:26:42 +02:00
|
|
|
PRO_commit(new_database);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
void PRO_create( DBB database, const TEXT* name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ c r e a t e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Create a new procedure, assuming, of course, it doesn't already
|
|
|
|
* exist.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2003-09-15 14:30:28 +02:00
|
|
|
UCHAR bpb[20];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// See if procedure is already in use
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
probe(database, name);
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE blob = 0;
|
2003-09-15 14:30:28 +02:00
|
|
|
const SLONG start = QLI_token->tok_position;
|
|
|
|
SLONG stop = start;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-15 14:30:28 +02:00
|
|
|
UCHAR* p = bpb;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-15 14:30:28 +02:00
|
|
|
USHORT bpb_length = p - bpb;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PRO_setup(database);
|
|
|
|
|
|
|
|
/* Store record in QLI$PROCEDURES. Eat tokens until we run into
|
|
|
|
END_PROCEDURE, then have LEX store the procedure in blobs. */
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE database->dbb_store_blob) X IN DB.QLI$PROCEDURES
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_vtof(name, X.QLI$PROCEDURE_NAME, sizeof(X.QLI$PROCEDURE_NAME));
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_create_blob2(status_vector, &database->dbb_handle, &gds_trans,
|
2003-10-29 11:53:47 +01:00
|
|
|
&blob, &X.QLI$PROCEDURE, bpb_length,
|
|
|
|
reinterpret_cast<const char*>(bpb)))
|
|
|
|
{
|
|
|
|
ERRQ_database_error(database, status_vector);
|
|
|
|
}
|
2004-05-16 03:42:11 +02:00
|
|
|
while (!PAR_match(KW_END_PROCEDURE)) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (QLI_token->tok_type == tok_eof)
|
2004-05-16 03:42:11 +02:00
|
|
|
ERRQ_syntax(350);
|
2001-05-23 15:26:42 +02:00
|
|
|
if (QLI_token->tok_type != tok_eol)
|
|
|
|
stop = QLI_token->tok_position + QLI_token->tok_length;
|
|
|
|
LEX_token();
|
|
|
|
}
|
|
|
|
|
|
|
|
LEX_put_procedure(blob, start, stop);
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_close_blob(status_vector, &blob);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_STORE;
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// Commit the procedure transaction, if there is one
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PRO_commit(database);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
int PRO_delete_procedure( DBB database, const TEXT* name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ d e l e t e _ p r o c e d u r e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Delete a procedure.
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE request = 0;
|
2003-09-15 14:30:28 +02:00
|
|
|
USHORT count = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PRO_setup(database);
|
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE request) X IN DB.QLI$PROCEDURES WITH
|
2003-09-25 13:49:12 +02:00
|
|
|
X.QLI$PROCEDURE_NAME EQ name
|
2001-05-23 15:26:42 +02:00
|
|
|
ERASE X;
|
|
|
|
count++;
|
|
|
|
END_FOR;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(gds_status, &request);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// Commit the procedure transaction, if there is one
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PRO_commit(database);
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
void PRO_edit_procedure( DBB database, const TEXT* name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ e d i t _ p r o c e d u r e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Edit a procedure, using the token stream to get the name of
|
|
|
|
* the procedure.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
PRO_setup(database);
|
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_edit_blob) X IN DB.QLI$PROCEDURES WITH
|
|
|
|
X.QLI$PROCEDURE_NAME EQ name
|
|
|
|
MODIFY X USING
|
|
|
|
if (!BLOB_edit(&X.QLI$PROCEDURE, database->dbb_handle,
|
2001-07-12 08:32:05 +02:00
|
|
|
gds_trans, name))
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
2004-02-20 07:43:27 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
END_MODIFY
|
|
|
|
PRO_commit(database);
|
|
|
|
return;
|
|
|
|
END_FOR
|
|
|
|
|
|
|
|
STORE(REQUEST_HANDLE database->dbb_edit_store) X IN DB.QLI$PROCEDURES
|
2001-07-12 08:32:05 +02:00
|
|
|
X.QLI$PROCEDURE = gds_blob_null;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!BLOB_edit(&X.QLI$PROCEDURE, database->dbb_handle,
|
2001-07-12 08:32:05 +02:00
|
|
|
gds_trans, name))
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
2004-02-20 07:43:27 +01:00
|
|
|
}
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_vtof(name, X.QLI$PROCEDURE_NAME, sizeof(X.QLI$PROCEDURE_NAME));
|
2001-05-23 15:26:42 +02:00
|
|
|
END_STORE
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// Commit the procedure transaction, if there is one
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PRO_commit(database);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE PRO_fetch_procedure( DBB database, const TEXT* proc)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ f e t c h _ p r o c e d u r e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Fetch a procedure. Look up a name and return an open blob.
|
|
|
|
* If the name doesn't exit, return NULL.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
TEXT name[32];
|
|
|
|
|
|
|
|
upcase_name(proc, name);
|
|
|
|
PRO_setup(database);
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE blob = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_lookup_blob) X IN DB.QLI$PROCEDURES WITH
|
|
|
|
X.QLI$PROCEDURE_NAME EQ name
|
2007-04-10 12:04:00 +02:00
|
|
|
blob = PRO_open_blob(database, X.QLI$PROCEDURE);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
|
|
|
|
|
|
|
return blob;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
bool PRO_get_line(FB_API_HANDLE blob,
|
2004-02-20 07:43:27 +01:00
|
|
|
TEXT* buffer,
|
2003-09-10 19:52:12 +02:00
|
|
|
USHORT size)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ g e t _ l i n e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Get the next segment of procedure blob. If there are
|
|
|
|
* no more segments, return false.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
USHORT length;
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
isc_get_segment(status_vector, &blob, &length, size, buffer);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (status_vector[1] && status_vector[1] != isc_segment)
|
2003-09-10 19:52:12 +02:00
|
|
|
return false;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-15 14:30:28 +02:00
|
|
|
TEXT* p = buffer + length;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (p[-1] != '\n' && !status_vector[1])
|
|
|
|
*p++ = '\n';
|
|
|
|
|
|
|
|
*p = 0;
|
|
|
|
|
2003-09-10 19:52:12 +02:00
|
|
|
return true;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
void PRO_invoke( DBB database, const TEXT* name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ i n v o k e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Invoke a procedure. The qualified procedure
|
|
|
|
* block may include the database we want, or
|
|
|
|
* we may have to loop through databases. Whatever...
|
|
|
|
*
|
|
|
|
**************************************/
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE blob = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (database) {
|
|
|
|
if (!(blob = PRO_fetch_procedure(database, name)))
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
2007-03-28 06:20:36 +02:00
|
|
|
ERRQ_print_error(71, SafeArg() << name << database->dbb_symbol->sym_string);
|
2004-02-20 07:43:27 +01:00
|
|
|
}
|
2004-03-07 08:58:55 +01:00
|
|
|
// Msg 71 procedure \"%s\" is undefined in database %s
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
for (database = QLI_databases; database;
|
2003-09-13 13:48:09 +02:00
|
|
|
database = database->dbb_next)
|
|
|
|
{
|
2004-02-20 07:43:27 +01:00
|
|
|
if (blob = PRO_fetch_procedure(database, name))
|
2003-09-13 13:48:09 +02:00
|
|
|
break;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (!blob)
|
2007-03-28 06:20:36 +02:00
|
|
|
ERRQ_print_error(72, name);
|
2004-03-07 08:58:55 +01:00
|
|
|
// Msg 72 procedure \"%s\" is undefined
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-24 12:30:39 +02:00
|
|
|
LEX_procedure((dbb*)database, blob);
|
2001-05-23 15:26:42 +02:00
|
|
|
LEX_token();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-10 12:04:00 +02:00
|
|
|
FB_API_HANDLE PRO_open_blob( DBB database, ISC_QUAD& blob_id)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ o p e n _ b l o b
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Open a procedure blob.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2003-09-15 14:30:28 +02:00
|
|
|
UCHAR bpb[20];
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE blob = 0;
|
2003-09-15 14:30:28 +02:00
|
|
|
UCHAR* p = bpb;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-15 14:30:28 +02:00
|
|
|
USHORT bpb_length = p - bpb;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_open_blob2(status_vector, &database->dbb_handle,
|
2007-04-10 12:04:00 +02:00
|
|
|
&database->dbb_proc_trans, &blob, &blob_id,
|
2003-11-10 10:16:38 +01:00
|
|
|
bpb_length, bpb))
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
2003-08-30 04:12:44 +02:00
|
|
|
ERRQ_database_error(database, status_vector);
|
2004-02-20 07:43:27 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
return blob;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
int PRO_rename_procedure( DBB database, const TEXT* old_name, const TEXT* new_name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ r e n a m e _ p r o c e d u r e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Change the name of a procedure.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE request = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
PRO_setup(database);
|
|
|
|
|
|
|
|
probe(database, new_name);
|
|
|
|
|
2003-09-15 14:30:28 +02:00
|
|
|
USHORT count = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
FOR(REQUEST_HANDLE request) X IN DB.QLI$PROCEDURES WITH
|
|
|
|
X.QLI$PROCEDURE_NAME EQ old_name count++;
|
|
|
|
MODIFY X USING
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_vtof(new_name, X.QLI$PROCEDURE_NAME, sizeof(X.QLI$PROCEDURE_NAME));
|
2001-05-23 15:26:42 +02:00
|
|
|
END_MODIFY
|
|
|
|
ON_ERROR
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(gds_status, &request);
|
2001-05-23 15:26:42 +02:00
|
|
|
ERRQ_database_error(database, status_vector);
|
|
|
|
END_ERROR;
|
|
|
|
END_FOR;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(gds_status, &request);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// Commit the procedure transaction, if there is one
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
PRO_commit(database);
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PRO_rollback( DBB database)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ r o l l b a c k
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Rollback the procedure transaction,
|
|
|
|
* if there is one.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (database->dbb_capabilities & DBB_cap_multi_trans) {
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_rollback_transaction(status_vector, &database->dbb_proc_trans);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
gds_trans = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
void PRO_scan( DBB database, extract_fn_t routine, void* arg)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ s c a n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Loop thru procedures calling given routine.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
PRO_setup(database);
|
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_scan_blobs) X IN DB.QLI$PROCEDURES
|
|
|
|
SORTED BY X.QLI$PROCEDURE_NAME
|
|
|
|
|
2003-09-15 14:30:28 +02:00
|
|
|
TEXT* p = X.QLI$PROCEDURE_NAME;
|
2004-02-20 07:43:27 +01:00
|
|
|
// This loop didn't have any effect. However, the logic can't handle
|
|
|
|
// dialect 3 names. At least it's now correct for dialect 1.
|
2001-05-23 15:26:42 +02:00
|
|
|
while (*p && *p != ' ') {
|
|
|
|
p++;
|
|
|
|
}
|
2004-02-20 07:43:27 +01:00
|
|
|
(*routine) (arg, X.QLI$PROCEDURE_NAME, p - X.QLI$PROCEDURE_NAME,
|
2007-04-10 12:04:00 +02:00
|
|
|
database, X.QLI$PROCEDURE);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_FOR
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PRO_setup( DBB dbb)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ s e t u p
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Prepare for a DML operation on a database. Start a procedure
|
|
|
|
* transaction is one hasn't been started and the database
|
|
|
|
* system will start multiple transactions. Otherwise use
|
|
|
|
* the default transaction.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
|
|
|
if (!dbb)
|
|
|
|
IBERROR(77);
|
2003-09-25 13:49:12 +02:00
|
|
|
// Msg 77 database handle required
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-03-07 08:58:55 +01:00
|
|
|
// If we don't have a QLI$PROCEDURES relation, and can't get one, punt
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (dbb->dbb_type == isc_info_db_impl_rdb_vms &&
|
2004-02-20 07:43:27 +01:00
|
|
|
!(dbb->dbb_flags & DBB_procedures))
|
|
|
|
{
|
|
|
|
IBERROR(78);
|
|
|
|
}
|
2004-03-07 08:58:55 +01:00
|
|
|
// Msg 78 QLI$PROCEDURES relation must be created with RDO in Rdb/VMS databases
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
DB = dbb->dbb_handle;
|
|
|
|
|
|
|
|
if (dbb->dbb_flags & DBB_procedures) {
|
2004-02-20 07:43:27 +01:00
|
|
|
gds_trans = PRO_transaction(dbb, false);
|
2001-05-23 15:26:42 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// Sigh. Relation doesn't exist. So make it exist.
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
create_qli_procedures(dbb);
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
gds_trans = PRO_transaction(dbb, false);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE PRO_transaction( DBB database, bool update_flag)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* P R O _ t r a n s a c t i o n
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Setup transaction for procedure or form operation.
|
|
|
|
*
|
|
|
|
* In any event, we will set up the met_transaction because
|
|
|
|
* it's widely used and somebody is going to forget to test
|
|
|
|
* that the database is multi_transaction before using it.
|
|
|
|
* We have to be careful about committing or rolling back
|
|
|
|
* because we ould affect user data.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
if (!database)
|
2003-09-25 13:49:12 +02:00
|
|
|
IBERROR(248); // Msg248 no active database for operation
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE transaction = (database->dbb_capabilities & DBB_cap_multi_trans) ?
|
|
|
|
database->dbb_proc_trans : 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
DB = database->dbb_handle;
|
|
|
|
|
|
|
|
/* If we don't know whether or not the database can handle
|
|
|
|
multiple transactions, find out now */
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
if (!transaction &&
|
|
|
|
((database->dbb_capabilities & DBB_cap_multi_trans) ||
|
|
|
|
!(database->dbb_capabilities & DBB_cap_single_trans)))
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_start_transaction(status_vector, &transaction, 1,
|
2003-08-30 04:12:44 +02:00
|
|
|
&database->dbb_handle, sizeof(tpb), tpb))
|
2004-02-20 07:43:27 +01:00
|
|
|
{
|
|
|
|
database->dbb_capabilities |= DBB_cap_single_trans;
|
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
else
|
|
|
|
database->dbb_capabilities |= DBB_cap_multi_trans;
|
2004-02-20 07:43:27 +01:00
|
|
|
}
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// If we already have a procedure transaction, there's more nothing to do
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
gds_trans = transaction;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// If we only support a single transaction, use the data transaction
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
if (!gds_trans && (database->dbb_capabilities & DBB_cap_single_trans)) {
|
2001-05-23 15:26:42 +02:00
|
|
|
if (update_flag)
|
2003-09-25 13:49:12 +02:00
|
|
|
IBERROR(249); // Msg249 Interactive metadata updates are not available on Rdb
|
2001-07-12 08:32:05 +02:00
|
|
|
if (!(gds_trans = database->dbb_transaction))
|
|
|
|
gds_trans = MET_transaction(nod_start_trans, database);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
// otherwise make one more effort to start the transaction
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
else if (!gds_trans) {
|
2001-05-23 15:26:42 +02:00
|
|
|
START_TRANSACTION
|
|
|
|
ON_ERROR
|
|
|
|
ERRQ_database_error(database, status_vector);
|
|
|
|
END_ERROR;
|
|
|
|
}
|
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
database->dbb_proc_trans = gds_trans;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2001-07-12 08:32:05 +02:00
|
|
|
return gds_trans;
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int clear_out_qli_procedures( DBB dbb)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* c l e a r _ o u t _ q l i _ p r o c e d u r e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* The procedures relation can't be found. Poke
|
|
|
|
* around and delete any trash lying around.
|
|
|
|
* Before cleaning out the trash, see if somebody
|
|
|
|
* else has set up for us.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-04-16 12:18:51 +02:00
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE req = 0;
|
2003-09-15 14:30:28 +02:00
|
|
|
int count = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE req) R IN DB.RDB$RELATIONS CROSS
|
|
|
|
F IN DB.RDB$FIELDS CROSS RFR IN DB.RDB$RELATION_FIELDS WITH
|
|
|
|
RFR.RDB$RELATION_NAME = R.RDB$RELATION_NAME AND
|
|
|
|
RFR.RDB$FIELD_NAME = F.RDB$FIELD_NAME AND
|
2003-09-25 13:49:12 +02:00
|
|
|
R.RDB$RELATION_NAME = "QLI$PROCEDURES"
|
2001-05-23 15:26:42 +02:00
|
|
|
count++;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-07-12 08:32:05 +02:00
|
|
|
ERRQ_database_error(dbb, gds_status);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (count >= 2) {
|
|
|
|
dbb->dbb_flags |= DBB_procedures;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
count = 0;
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
FOR(REQUEST_HANDLE req) X IN DB.RDB$INDICES
|
|
|
|
WITH X.RDB$INDEX_NAME = "QLI$PROCEDURES_IDX1"
|
2001-05-23 15:26:42 +02:00
|
|
|
ERASE X;
|
|
|
|
count++;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-07-12 08:32:05 +02:00
|
|
|
ERRQ_database_error(dbb, gds_status);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
FOR(REQUEST_HANDLE req) X IN DB.RDB$INDEX_SEGMENTS
|
|
|
|
WITH X.RDB$INDEX_NAME = "QLI$PROCEDURES_IDX1"
|
2001-05-23 15:26:42 +02:00
|
|
|
ERASE X;
|
|
|
|
count++;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-07-12 08:32:05 +02:00
|
|
|
ERRQ_database_error(dbb, gds_status);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE req) X IN DB.RDB$RELATION_FIELDS
|
|
|
|
WITH X.RDB$FIELD_NAME = "QLI$PROCEDURE_NAME" OR
|
2003-09-25 13:49:12 +02:00
|
|
|
X.RDB$FIELD_NAME = "QLI$PROCEDURE"
|
2001-05-23 15:26:42 +02:00
|
|
|
ERASE X;
|
|
|
|
count++;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-07-12 08:32:05 +02:00
|
|
|
ERRQ_database_error(dbb, gds_status);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(gds_status, &req);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE req) X IN DB.RDB$FIELDS
|
|
|
|
WITH X.RDB$FIELD_NAME = "QLI$PROCEDURE_NAME" OR
|
2003-09-25 13:49:12 +02:00
|
|
|
X.RDB$FIELD_NAME = "QLI$PROCEDURE"
|
2001-05-23 15:26:42 +02:00
|
|
|
ERASE X;
|
|
|
|
count++;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-07-12 08:32:05 +02:00
|
|
|
ERRQ_database_error(dbb, gds_status);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(gds_status, &req);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
FOR(REQUEST_HANDLE req) X IN DB.RDB$RELATIONS
|
2003-09-25 13:49:12 +02:00
|
|
|
WITH X.RDB$RELATION_NAME = "QLI$PROCEDURES"
|
2001-05-23 15:26:42 +02:00
|
|
|
ERASE X;
|
|
|
|
count++;
|
|
|
|
END_FOR
|
|
|
|
ON_ERROR
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(status_vector, &req);
|
2001-07-12 08:32:05 +02:00
|
|
|
ERRQ_database_error(dbb, gds_status);
|
2001-05-23 15:26:42 +02:00
|
|
|
END_ERROR;
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_release_request(gds_status, &req);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void create_qli_procedures( DBB dbb)
|
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* c r e a t e _ q l i _ p r o c e d u r e s
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* The procedures relation can't be found. Clean
|
2003-09-25 13:49:12 +02:00
|
|
|
* out residual trash and (re)create the relation.
|
2001-05-23 15:26:42 +02:00
|
|
|
* Before cleaning out the trash, see if somebody
|
|
|
|
* else has set up for us.
|
|
|
|
*
|
|
|
|
**************************************/
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
gds_trans = PRO_transaction(dbb, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
if (clear_out_qli_procedures(dbb)) {
|
|
|
|
PRO_commit(dbb);
|
2004-02-20 07:43:27 +01:00
|
|
|
gds_trans = PRO_transaction(dbb, true);
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dbb->dbb_flags & DBB_procedures)
|
|
|
|
return;
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_ddl(gds_status, &DB, &gds_trans, sizeof(dyn_gdl1),
|
2004-02-20 07:43:27 +01:00
|
|
|
reinterpret_cast<const char*>(dyn_gdl1)))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
PRO_rollback(dbb);
|
|
|
|
IBERROR(73);
|
2004-03-07 08:58:55 +01:00
|
|
|
// Msg 73 Could not create QLI$PROCEDURE_NAME field
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_ddl(gds_status, &DB, &gds_trans, sizeof(dyn_gdl2),
|
2004-02-20 07:43:27 +01:00
|
|
|
reinterpret_cast<const char*>(dyn_gdl2)))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
PRO_rollback(dbb);
|
|
|
|
IBERROR(74);
|
2004-03-07 08:58:55 +01:00
|
|
|
// Msg 74 Could not create QLI$PROCEDURE field
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_ddl(gds_status, &DB, &gds_trans, sizeof(dyn_gdl3),
|
2004-02-20 07:43:27 +01:00
|
|
|
reinterpret_cast<const char*>(dyn_gdl3)))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
PRO_rollback(dbb);
|
|
|
|
IBERROR(75);
|
2004-03-07 08:58:55 +01:00
|
|
|
// Msg 75 Could not create QLI$PROCEDURES relation
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
2003-11-08 17:40:17 +01:00
|
|
|
if (isc_ddl(gds_status, &DB, &gds_trans, sizeof(dyn_gdl4),
|
2004-02-20 07:43:27 +01:00
|
|
|
reinterpret_cast<const char*>(dyn_gdl4)))
|
|
|
|
{
|
2001-05-23 15:26:42 +02:00
|
|
|
PRO_rollback(dbb);
|
|
|
|
IBERROR(409);
|
2004-03-07 08:58:55 +01:00
|
|
|
// msg 409 Could not create QLI$PROCEDURES index
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
dbb->dbb_flags |= DBB_procedures;
|
|
|
|
PRO_commit(dbb);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-02-20 07:43:27 +01:00
|
|
|
static void probe( DBB database, const TEXT* name)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* p r o b e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Check whether a procedure name is already in
|
|
|
|
* use in a particular database. IBERROR and don't
|
|
|
|
* return if it is.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-25 13:49:12 +02:00
|
|
|
// Probe to see if procedure is already in use
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2004-05-03 01:06:37 +02:00
|
|
|
FB_API_HANDLE blob = PRO_fetch_procedure(database, name);
|
2004-02-20 07:43:27 +01:00
|
|
|
if (blob) {
|
|
|
|
ISC_STATUS_ARRAY status_vector;
|
2003-11-08 17:40:17 +01:00
|
|
|
isc_close_blob(status_vector, &blob);
|
2007-03-28 06:20:36 +02:00
|
|
|
ERRQ_print_error(76, SafeArg() << name << database->dbb_symbol->sym_string);
|
2004-02-20 07:43:27 +01:00
|
|
|
// Msg 76 procedure name \"%s\" in use in database %s
|
2001-05-23 15:26:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-09-15 14:30:28 +02:00
|
|
|
static int upcase_name(const TEXT* name, TEXT* buffer)
|
2001-05-23 15:26:42 +02:00
|
|
|
{
|
|
|
|
/**************************************
|
|
|
|
*
|
|
|
|
* u p c a s e _ n a m e
|
|
|
|
*
|
|
|
|
**************************************
|
|
|
|
*
|
|
|
|
* Functional description
|
|
|
|
* Upcase a null terminated string and return its length. If the
|
|
|
|
* length is greater than 31 bytes, barf.
|
|
|
|
*
|
|
|
|
**************************************/
|
2003-09-15 14:30:28 +02:00
|
|
|
USHORT l = 0;
|
2001-05-23 15:26:42 +02:00
|
|
|
|
2003-09-10 19:52:12 +02:00
|
|
|
while (true) {
|
2003-09-15 14:30:28 +02:00
|
|
|
const TEXT c = *name++;
|
2001-05-23 15:26:42 +02:00
|
|
|
*buffer++ = UPPER(c);
|
|
|
|
if (!c)
|
|
|
|
return l;
|
|
|
|
if (++l > 31)
|
2003-09-25 13:49:12 +02:00
|
|
|
IBERROR(79); // Msg 79 procedure name over 31 characters
|
2001-05-23 15:26:42 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2003-09-15 14:30:28 +02:00
|
|
|
|
2003-09-25 13:49:12 +02:00
|
|
|
|