mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 18:43:02 +01:00
2921 lines
78 KiB
Plaintext
2921 lines
78 KiB
Plaintext
/*
|
|
* PROGRAM: JRD Command Oriented Query Language
|
|
* MODULE: show.e
|
|
* DESCRIPTION: Show environment commands
|
|
*
|
|
* 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): ______________________________________.
|
|
*/
|
|
|
|
#include "firebird.h"
|
|
#include "../jrd/ib_stdio.h"
|
|
#include <string.h>
|
|
#include "../jrd/gds.h"
|
|
#include "../qli/dtr.h"
|
|
#include "../qli/parse.h"
|
|
#include "../qli/compile.h"
|
|
#include "../jrd/license.h"
|
|
#include "../qli/reqs.h"
|
|
#include "../jrd/flags.h"
|
|
#include "../qli/all_proto.h"
|
|
#include "../qli/comma_proto.h"
|
|
#include "../qli/err_proto.h"
|
|
#include "../qli/meta_proto.h"
|
|
#include "../qli/proc_proto.h"
|
|
#include "../qli/show_proto.h"
|
|
#include "../jrd/gds_proto.h"
|
|
|
|
extern USHORT QLI_columns, QLI_name_columns;
|
|
|
|
static void array_dimensions(DBB, TEXT *);
|
|
static void display_acl(DBB, SLONG[2]);
|
|
static void display_blob(DBB, SLONG[2], TEXT *, USHORT, UCHAR *, int);
|
|
static void display_blr(DBB, SLONG[2]);
|
|
static void display_text(DBB, SLONG[2], TEXT *, int);
|
|
static void display_procedure(DBB, UCHAR *, int *);
|
|
static USHORT get_window_size(int);
|
|
static void show_blob_info(SLONG *, SLONG *, USHORT, USHORT, DBB, TEXT *);
|
|
static void show_blr(DBB, USHORT, SLONG *, USHORT, SLONG *);
|
|
static void show_datatype(DBB, USHORT, USHORT, SSHORT, SSHORT, USHORT,
|
|
USHORT);
|
|
static void show_dbb(DBB);
|
|
static void show_dbb_parameters(DBB);
|
|
static int show_field_detail(DBB, TEXT *, TEXT *, SYN);
|
|
static int show_field_instances(DBB, TEXT *);
|
|
static void show_fields(REL, FLD);
|
|
static void show_filt(QFL);
|
|
static int show_filter_detail(DBB, TEXT *);
|
|
static void show_filts(DBB);
|
|
static int show_filters_detail(DBB);
|
|
static void show_fld(SYN);
|
|
static void show_func(QFN);
|
|
static int show_func_detail(DBB, TEXT *);
|
|
static void show_funcs(DBB);
|
|
static int show_funcs_detail(DBB);
|
|
static int show_insecure_fields(DBB, TEXT *, TEXT *);
|
|
static void show_forms_db(DBB);
|
|
static int show_forms_detail(DBB);
|
|
static void show_gbl_field(SYN);
|
|
static int show_gbl_field_detail(DBB, TEXT *);
|
|
static void show_gbl_fields(DBB);
|
|
static int show_gbl_fields_detail(DBB);
|
|
static int show_indices_detail(REL);
|
|
static void show_matching(void);
|
|
static void show_names(TEXT *, USHORT, TEXT *);
|
|
static void show_proc(QPR);
|
|
static void show_procs(DBB);
|
|
static void show_rel(REL);
|
|
static void show_rel_detail(REL);
|
|
static void show_rels(DBB, ENUM show_t, SSHORT);
|
|
static int show_security_class_detail(DBB, TEXT *);
|
|
static int show_security_classes_detail(DBB);
|
|
static void show_string(USHORT, TEXT *, USHORT, TEXT *);
|
|
static void show_sys_trigs(DBB);
|
|
static void show_text_blob(DBB, TEXT *, USHORT, SLONG *, USHORT, SLONG *,
|
|
int);
|
|
static void show_trig(REL);
|
|
static int show_trigger_detail(DBB, TEXT *);
|
|
static void show_trigger_header(TEXT *, USHORT, USHORT, USHORT, SLONG *, DBB,
|
|
TEXT *);
|
|
static void show_trigger_messages(DBB, TEXT *);
|
|
static void show_trigger_status(TEXT *, USHORT, USHORT, USHORT);
|
|
static void show_trigs(DBB);
|
|
static int show_triggers_detail(DBB);
|
|
static void show_var(NAM);
|
|
static void show_vars(void);
|
|
static void show_versions(void);
|
|
static void show_view(REL);
|
|
static int show_views_detail(DBB);
|
|
static int truncate_string(TEXT *);
|
|
static void view_info(DBB, TEXT *, TEXT *, SSHORT, SSHORT);
|
|
|
|
static CONST SCHAR db_items[] =
|
|
{ gds_info_page_size, isc_info_db_size_in_pages, gds_info_end };
|
|
static CONST UCHAR
|
|
#if (defined JPN_EUC || defined JPN_SJIS)
|
|
text_bpb[] = { gds_bpb_version1, gds_bpb_target_interp, 2,
|
|
(HOST_INTERP & 0xff), (HOST_INTERP >> 8)
|
|
},
|
|
#endif /* (defined JPN_EUC || defined JPN_SJIS) */
|
|
acl_bpb[] = {
|
|
gds_bpb_version1, gds_bpb_source_type, 1, 3,
|
|
|
|
gds_bpb_target_type, 1, 1}, blr_bpb[] = {
|
|
gds_bpb_version1, gds_bpb_source_type, 1, 2, gds_bpb_target_type, 1, 1};
|
|
|
|
#define NULL_BLOB(id) (!id [0] && !id [1])
|
|
|
|
DATABASE DB = EXTERN FILENAME "yachts.lnk";
|
|
|
|
/*
|
|
values for rdb$trigger_type, based from types.h
|
|
** Some better way should be found to pick this up dynamically (?) **
|
|
until then, this must be kept in sync with jrd/types.h manually.
|
|
*/
|
|
|
|
#define PRE_STORE 1
|
|
#define POST_STORE 2
|
|
#define PRE_MODIFY 3
|
|
#define POST_MODIFY 4
|
|
#define PRE_ERASE 5
|
|
#define POST_ERASE 6
|
|
|
|
|
|
void SHOW_stuff( SYN node)
|
|
{
|
|
/**************************************
|
|
*
|
|
* S H O W _ s t u f f
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show various stuffs.
|
|
*
|
|
**************************************/
|
|
SYN *ptr, value;
|
|
REL relation;
|
|
DBB dbb;
|
|
ENUM show_t sw;
|
|
USHORT i, count;
|
|
NAM name;
|
|
TEXT buffer[256];
|
|
SSHORT width;
|
|
|
|
QLI_skip_line = TRUE;
|
|
ptr = node->syn_arg;
|
|
|
|
for (i = 0; i < node->syn_count; i++) {
|
|
sw = (ENUM show_t) (int) * ptr++;
|
|
value = *ptr++;
|
|
if (sw != show_matching_language &&
|
|
sw != show_version &&
|
|
sw != show_variable && sw != show_variables && CMD_check_ready())
|
|
return;
|
|
switch (sw) {
|
|
case show_all:
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next) {
|
|
show_dbb(dbb);
|
|
for (relation = dbb->dbb_relations; relation;
|
|
relation = relation->rel_next) {
|
|
if (!(relation->rel_flags & REL_system)) {
|
|
show_rel(relation);
|
|
show_fields(relation, (FLD) NULL_PTR);
|
|
}
|
|
if (QLI_abort)
|
|
return;
|
|
}
|
|
ib_printf("\n");
|
|
}
|
|
if (QLI_variables)
|
|
show_vars();
|
|
break;
|
|
|
|
case show_databases:
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next) {
|
|
show_dbb(dbb);
|
|
show_dbb_parameters(dbb);
|
|
}
|
|
break;
|
|
|
|
case show_database:
|
|
if (!(dbb = (DBB) value))
|
|
dbb = QLI_databases;
|
|
show_dbb(dbb);
|
|
show_dbb_parameters(dbb);
|
|
for (relation = dbb->dbb_relations; relation;
|
|
relation = relation->rel_next)
|
|
if (!(relation->rel_flags & REL_system)) {
|
|
show_rel(relation);
|
|
show_fields(relation,(FLD) NULL_PTR);
|
|
}
|
|
ib_printf("\n");
|
|
break;
|
|
|
|
case show_relations:
|
|
case show_system_relations:
|
|
width = get_window_size(sizeof(buffer) - 1);
|
|
if (dbb = (DBB) value)
|
|
show_rels(dbb, sw, width);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
show_rels(dbb, sw, width);
|
|
break;
|
|
|
|
case show_db_fields:
|
|
dbb = (DBB) value;
|
|
for (relation = dbb->dbb_relations; relation;
|
|
relation = relation->rel_next) {
|
|
if (!(relation->rel_flags & REL_system)) {
|
|
show_rel(relation);
|
|
show_fields(relation, (FLD) NULL_PTR);
|
|
}
|
|
if (QLI_abort)
|
|
return;
|
|
}
|
|
break;
|
|
|
|
case show_security_classes:
|
|
count = 0;
|
|
if (value)
|
|
count += show_security_classes_detail((DBB) value);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
count += show_security_classes_detail(dbb);
|
|
if (!count)
|
|
ERRQ_msg_put(90, NULL, NULL, NULL, NULL, NULL); /* Msg90 No security classes defined */
|
|
break;
|
|
|
|
case show_security_class:
|
|
count = 0;
|
|
name = (NAM) value;
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
count += show_security_class_detail(dbb, name->nam_string);
|
|
if (!count)
|
|
ERRQ_msg_put(91, name->nam_string, NULL, NULL, NULL, NULL); /* Msg91 Security class %s is not defined */
|
|
break;
|
|
|
|
case show_views:
|
|
count = 0;
|
|
if (value)
|
|
count += show_views_detail((DBB) value);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
count += show_views_detail(dbb);
|
|
if (!count)
|
|
ERRQ_msg_put(92, NULL, NULL, NULL, NULL, NULL); /* Msg92 No views defined */
|
|
break;
|
|
|
|
case show_relation:
|
|
show_rel((REL) value);
|
|
show_fields((REL) value, (FLD) NULL_PTR);
|
|
show_view((REL) value);
|
|
show_rel_detail((REL) value);
|
|
break;
|
|
|
|
case show_indices:
|
|
if (value) {
|
|
show_rel((REL) value);
|
|
if (!show_indices_detail((REL) value))
|
|
ERRQ_msg_put(93, NULL, NULL, NULL, NULL, NULL); /* Msg93 No indices defined */
|
|
break;
|
|
}
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next) {
|
|
show_dbb(dbb);
|
|
for (relation = dbb->dbb_relations; relation;
|
|
relation = relation->rel_next)
|
|
if (!(relation->rel_flags & (REL_system | REL_view))) {
|
|
show_rel(relation);
|
|
if (!show_indices_detail(relation))
|
|
ERRQ_msg_put(94, NULL, NULL, NULL, NULL, NULL); /* Msg94 No indices defined */
|
|
}
|
|
}
|
|
break;
|
|
|
|
case show_db_indices:
|
|
dbb = (DBB) value;
|
|
show_dbb(dbb);
|
|
for (relation = dbb->dbb_relations; relation;
|
|
relation = relation->rel_next)
|
|
if (!(relation->rel_flags & (REL_system | REL_view))) {
|
|
show_rel(relation);
|
|
if (!show_indices_detail(relation))
|
|
ERRQ_msg_put(94, NULL, NULL, NULL, NULL, NULL); /* Msg94 No indices defined */
|
|
}
|
|
break;
|
|
|
|
case show_field:
|
|
show_fld(value);
|
|
break;
|
|
|
|
case show_filter:
|
|
show_filt((QFL) value);
|
|
break;
|
|
|
|
case show_filters:
|
|
if (value)
|
|
show_filts((DBB) value);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
show_filts(dbb);
|
|
break;
|
|
|
|
case show_forms:
|
|
if (value)
|
|
show_forms_db((DBB) value);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
show_forms_db(dbb);
|
|
break;
|
|
|
|
case show_function:
|
|
show_func((QFN) value);
|
|
break;
|
|
|
|
case show_functions:
|
|
if (value)
|
|
show_funcs((DBB) value);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
show_funcs(dbb);
|
|
break;
|
|
|
|
case show_matching_language:
|
|
show_matching();
|
|
break;
|
|
|
|
case show_procedures:
|
|
if (value)
|
|
show_procs((DBB) value);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
show_procs(dbb);
|
|
break;
|
|
|
|
case show_procedure:
|
|
show_proc((QPR) value);
|
|
break;
|
|
|
|
case show_version:
|
|
show_versions();
|
|
break;
|
|
|
|
case show_variable:
|
|
show_var((NAM) value);
|
|
break;
|
|
|
|
case show_variables:
|
|
show_vars();
|
|
break;
|
|
|
|
case show_global_field:
|
|
show_gbl_field(value);
|
|
break;
|
|
|
|
case show_global_fields:
|
|
show_gbl_fields((DBB) value);
|
|
break;
|
|
|
|
case show_trigger:
|
|
show_trig((REL) value);
|
|
break;
|
|
|
|
case show_triggers:
|
|
show_trigs((DBB) value);
|
|
break;
|
|
|
|
case show_system_triggers:
|
|
if (value)
|
|
show_sys_trigs((DBB) value);
|
|
else
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next)
|
|
show_sys_trigs(dbb);
|
|
break;
|
|
|
|
default:
|
|
BUGCHECK(7); /* Msg7 show option not implemented */
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void array_dimensions( DBB database, TEXT * field_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* a r r a y _ d i m e n s i o n s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display the dimensions of an array
|
|
*
|
|
**************************************/
|
|
TEXT s[128], *p;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
s[0] = 0;
|
|
|
|
p = s;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_dimensions])
|
|
D IN RDB$FIELD_DIMENSIONS WITH D.RDB$FIELD_NAME = field_name
|
|
SORTED BY D.RDB$DIMENSION
|
|
|
|
if (D.RDB$LOWER_BOUND != 1) {
|
|
sprintf(p, "%d:", D.RDB$LOWER_BOUND);
|
|
while (*++p);
|
|
}
|
|
|
|
sprintf(p, "%d, ", D.RDB$UPPER_BOUND);
|
|
while (*++p);
|
|
END_FOR;
|
|
|
|
--p;
|
|
*--p = 0;
|
|
|
|
ERRQ_msg_partial(479, s, NULL, NULL, NULL, NULL); /* Msg479 (%s) */
|
|
}
|
|
|
|
|
|
static void display_acl( DBB dbb, SLONG blob_id[2])
|
|
{
|
|
/**************************************
|
|
*
|
|
* d i s p l a y _ a c l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display the contents of a security class
|
|
*
|
|
**************************************/
|
|
|
|
display_blob(dbb, blob_id, "\t ", sizeof(acl_bpb), const_cast<UCHAR*>(acl_bpb), TRUE);
|
|
}
|
|
|
|
|
|
static void display_blob(
|
|
DBB dbb,
|
|
SLONG blob_id[2],
|
|
TEXT * prefix,
|
|
USHORT bpb_length, UCHAR * bpb, int strip_line)
|
|
{
|
|
/**************************************
|
|
*
|
|
* d i s p l a y _ b l o b
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display the contents of a security class
|
|
*
|
|
**************************************/
|
|
USHORT length, buffer_length;
|
|
TEXT buffer[256], *b;
|
|
int *blob;
|
|
STATUS status_vector[20], status;
|
|
|
|
blob = NULL;
|
|
|
|
if (gds__open_blob2(status_vector,
|
|
GDS_REF(dbb->dbb_handle),
|
|
GDS_REF(dbb->dbb_meta_trans),
|
|
(void**) GDS_REF(blob),
|
|
(GDS__QUAD*) GDS_VAL(blob_id),
|
|
bpb_length,
|
|
(char*) GDS_VAL(bpb)))
|
|
ERRQ_database_error(dbb, status_vector);
|
|
|
|
for (;;) {
|
|
buffer_length = sizeof(buffer) - 1;
|
|
status = gds__get_segment(status_vector,
|
|
(void**) GDS_REF(blob),
|
|
GDS_REF(length), buffer_length, buffer);
|
|
if (status && status != gds_segment)
|
|
break;
|
|
buffer[length--] = 0;
|
|
if (strip_line) {
|
|
for (b = buffer + length; b >= buffer;) {
|
|
if (*b == '\n' || *b == '\t' || *b == ' ')
|
|
*b-- = 0;
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
if (buffer[length] == '\n')
|
|
buffer[length] = 0;
|
|
}
|
|
if (buffer[0])
|
|
ib_printf("%s%s\n", prefix, buffer);
|
|
}
|
|
|
|
gds__close_blob(status_vector, (void**) GDS_REF(blob));
|
|
}
|
|
|
|
|
|
static void display_blr( DBB dbb, SLONG blob_id[2])
|
|
{
|
|
/**************************************
|
|
*
|
|
* d i s p l a y _ b l r
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display the contents of a security class
|
|
*
|
|
**************************************/
|
|
|
|
display_blob(dbb, blob_id, "\t ", sizeof(blr_bpb), const_cast<UCHAR*>(blr_bpb), TRUE);
|
|
}
|
|
|
|
|
|
static void display_text( DBB dbb, SLONG blob_id[2], TEXT * prefix, int strip)
|
|
{
|
|
/**************************************
|
|
*
|
|
* d i s p l a y _ t e x t
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display a text blob.
|
|
*
|
|
**************************************/
|
|
|
|
#if (defined JPN_EUC || defined JPN_SJIS)
|
|
display_blob(dbb, blob_id, prefix, sizeof(text_bpb), text_bpb, strip);
|
|
#else
|
|
display_blob(dbb, blob_id, prefix, 0, (UCHAR*) NULL_PTR, strip);
|
|
#endif /* (defined JPN_EUC || defined JPN_SJIS) */
|
|
}
|
|
|
|
|
|
static void display_procedure( DBB database, UCHAR * name, int *blob)
|
|
{
|
|
/**************************************
|
|
*
|
|
* d i s p l a y _ p r o c e d u r e
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show definition of procedure. Somebody
|
|
* else has already figured out what database
|
|
* it's in, and so forth.
|
|
*
|
|
**************************************/
|
|
STATUS status_vector[20];
|
|
SSHORT length;
|
|
UCHAR buffer[256];
|
|
|
|
ERRQ_msg_put(96, (TEXT*) name, /* Msg96 Procedure %s in database %s (%s) */
|
|
database->dbb_filename, database->dbb_symbol->sym_string,
|
|
NULL, NULL);
|
|
|
|
while (PRO_get_line(blob, (TEXT*) buffer, sizeof(buffer)))
|
|
ib_printf(" %s", buffer);
|
|
|
|
PRO_close(database, blob);
|
|
ib_printf("\n");
|
|
}
|
|
|
|
|
|
static USHORT get_window_size( int max_width)
|
|
{
|
|
/**************************************
|
|
*
|
|
* g e t _ w i n d o w _ s i z e
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Get the display window size.
|
|
*
|
|
**************************************/
|
|
SSHORT result;
|
|
|
|
result = QLI_columns;
|
|
|
|
if (max_width < result)
|
|
result = max_width;
|
|
return result;
|
|
}
|
|
|
|
|
|
static void show_blob_info(
|
|
SLONG * blob_blr,
|
|
SLONG * blob_src,
|
|
USHORT msg_blr,
|
|
USHORT msg_src, DBB database, TEXT * relation_name)
|
|
{
|
|
/*****************************************************
|
|
*
|
|
* s h o w _ b l o b _ i n f o
|
|
*
|
|
*****************************************************
|
|
*
|
|
* Functional description
|
|
* Display source if possible or blr.
|
|
*
|
|
*****************************************************/
|
|
|
|
if (NULL_BLOB(blob_src)) {
|
|
ERRQ_msg_put(msg_blr, NULL, NULL, NULL, NULL, NULL);
|
|
display_blr(database, blob_blr);
|
|
}
|
|
else {
|
|
ERRQ_msg_put(msg_src, relation_name, NULL, NULL, NULL, NULL);
|
|
show_text_blob(database, "\t", 0, blob_src, 0, (SLONG*) NULL_PTR, TRUE);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void show_blr(
|
|
DBB database,
|
|
USHORT source_msg,
|
|
SLONG * source, USHORT blr_msg, SLONG * blr)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ b l r
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show either source or blr for a blr item along with
|
|
* appopriate messages.
|
|
*
|
|
**************************************/
|
|
|
|
if (source[0] || source[1])
|
|
show_text_blob(database, "\t", source_msg, source, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
else if (blr[0] || blr[1]) {
|
|
if (blr_msg)
|
|
ERRQ_msg_put(blr_msg, NULL, NULL, NULL, NULL, NULL);
|
|
display_blr(database, blr);
|
|
}
|
|
}
|
|
|
|
|
|
static void show_datatype(
|
|
DBB database,
|
|
USHORT dtype,
|
|
USHORT length,
|
|
SSHORT scale,
|
|
SSHORT sub_type,
|
|
USHORT segment_length, USHORT dimensions)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ d a t a t y p e
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display datatype information.
|
|
*
|
|
**************************************/
|
|
SSHORT msg;
|
|
TEXT *p, *q, subtype[32];
|
|
|
|
msg = 0;
|
|
switch (dtype) {
|
|
case dtype_text:
|
|
msg = 97;
|
|
break;
|
|
|
|
case dtype_varying:
|
|
msg = 98;
|
|
break;
|
|
|
|
case dtype_cstring:
|
|
length -= 1;
|
|
msg = 99;
|
|
break;
|
|
|
|
case dtype_short:
|
|
msg = 100;
|
|
break;
|
|
|
|
case dtype_long:
|
|
msg = 101;
|
|
break;
|
|
|
|
case dtype_quad:
|
|
msg = 102;
|
|
break;
|
|
|
|
case dtype_real:
|
|
msg = 103;
|
|
break;
|
|
|
|
case dtype_double:
|
|
msg = 104;
|
|
break;
|
|
|
|
case dtype_blob:
|
|
ERRQ_msg_partial(105, NULL, NULL, NULL, NULL, NULL); /* Msg105 blob */
|
|
if (segment_length)
|
|
ERRQ_msg_partial(106, (TEXT *) (ULONG) segment_length, NULL, NULL,
|
|
NULL, NULL); /* Msg106 , segment length %d */
|
|
if (sub_type) {
|
|
sprintf(subtype, "%d", sub_type);
|
|
if (database && (database->dbb_capabilities & DBB_cap_types))
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_fld_subtype])
|
|
TYPE IN RDB$TYPES WITH TYPE.
|
|
RDB$FIELD_NAME EQ "RDB$FIELD_SUB_TYPE" AND TYPE.
|
|
RDB$TYPE EQ sub_type
|
|
|
|
for (p = subtype, q = TYPE.RDB$TYPE_NAME; *q && *q != ' ';)
|
|
*p++ = *q++;
|
|
*p = 0;
|
|
END_FOR;
|
|
ERRQ_msg_partial(107, subtype, NULL, NULL, NULL, NULL);
|
|
}
|
|
return;
|
|
|
|
case dtype_sql_date:
|
|
ERRQ_msg_partial(110, (TEXT *) (ULONG) length, NULL, NULL, NULL,
|
|
NULL);
|
|
ERRQ_msg_partial(107, "SQL DATE", NULL, NULL, NULL, NULL);
|
|
return;
|
|
|
|
case dtype_sql_time:
|
|
ERRQ_msg_partial(110, (TEXT *) (ULONG) length, NULL, NULL, NULL,
|
|
NULL);
|
|
ERRQ_msg_partial(107, "SQL TIME", NULL, NULL, NULL, NULL);
|
|
return;
|
|
|
|
case dtype_timestamp:
|
|
msg = 110;
|
|
break;
|
|
|
|
default:
|
|
BUGCHECK(8); /* Msg8 show_fields: dtype not done */
|
|
}
|
|
|
|
ERRQ_msg_partial(msg, (TEXT *) (ULONG) length, NULL, NULL, NULL, NULL);
|
|
|
|
if (dimensions)
|
|
ERRQ_msg_partial(433, NULL, NULL, NULL, NULL, NULL); /* Msg433 array */
|
|
|
|
if (dtype == dtype_short || dtype == dtype_long || dtype == dtype_quad)
|
|
if (scale)
|
|
ERRQ_msg_partial(111, (TEXT *) (SLONG) scale, NULL, NULL, NULL, NULL); /* Msg111 , scale %d */
|
|
|
|
if (dtype == dtype_text ||
|
|
dtype == dtype_varying || dtype == dtype_cstring) if (sub_type == 1)
|
|
ERRQ_msg_partial(112, NULL, NULL, NULL, NULL, NULL); /* Msg112 , subtype fixed */
|
|
else if (sub_type != 0) {
|
|
sprintf(subtype, "%d", sub_type);
|
|
ERRQ_msg_partial(107, subtype, NULL, NULL, NULL, NULL);
|
|
};
|
|
}
|
|
|
|
|
|
static void show_dbb( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ d b b
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Print a database name and some
|
|
* functional stuff about it.
|
|
*
|
|
**************************************/
|
|
SYM symbol;
|
|
|
|
if (database) {
|
|
if (symbol = database->dbb_symbol)
|
|
ERRQ_msg_put(113, /* Msg113 Database %s readied as %s */
|
|
database->dbb_filename, symbol->sym_string, NULL,
|
|
NULL, NULL);
|
|
else
|
|
ERRQ_msg_put(114, database->dbb_filename, NULL, NULL, NULL, NULL); /* Msg114 Database %s */
|
|
}
|
|
else
|
|
ERRQ_msg_put(115, NULL, NULL, NULL, NULL, NULL); /* Msg115 No databases are currently ready */
|
|
}
|
|
|
|
|
|
static void show_dbb_parameters( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ d b b _ p a r a m e t e r s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Print stuff about a database.
|
|
*
|
|
**************************************/
|
|
UCHAR *d, buffer[127], item;
|
|
int length;
|
|
SLONG allocation, page_size;
|
|
STATUS status_vector[20];
|
|
|
|
if (!database)
|
|
return;
|
|
|
|
if (gds__database_info(status_vector,
|
|
GDS_REF(database->dbb_handle),
|
|
sizeof(db_items),
|
|
const_cast<char*>(db_items),
|
|
sizeof(buffer),
|
|
(char*) buffer))
|
|
ERRQ_database_error(database, status_vector);
|
|
|
|
page_size = allocation = 0;
|
|
|
|
for (d = buffer; *d != gds_info_end;) {
|
|
item = *d++;
|
|
length = gds__vax_integer(d, 2);
|
|
d += 2;
|
|
switch (item) {
|
|
case (isc_info_db_size_in_pages):
|
|
allocation = gds__vax_integer(d, length);
|
|
break;
|
|
|
|
case (gds_info_page_size):
|
|
page_size = gds__vax_integer(d, length);
|
|
break;
|
|
|
|
case (gds_info_error):
|
|
break;
|
|
}
|
|
d += length;
|
|
}
|
|
|
|
ERRQ_msg_put(116, (TEXT *) (SLONG) page_size, (TEXT *) allocation, NULL,
|
|
NULL, NULL); /* Msg116 Page size is %d bytes. Current allocation is %d pages. */
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
if (database->dbb_capabilities & DBB_cap_security) {
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_dbb])
|
|
D IN RDB$DATABASE
|
|
show_string(260, D.RDB$SECURITY_CLASS, 0, (TEXT*) NULL_PTR);
|
|
show_text_blob(database, "\t", 261, (SLONG*) &D.RDB$DESCRIPTION, 0,
|
|
(SLONG*) NULL_PTR, FALSE);
|
|
END_FOR;
|
|
}
|
|
else {
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_dbb])
|
|
D IN RDB$DATABASE
|
|
show_text_blob(database, "\t", 262, (SLONG*) &D.RDB$DESCRIPTION, 0,
|
|
(SLONG*) NULL_PTR, FALSE);
|
|
END_FOR;
|
|
}
|
|
|
|
if (database->dbb_capabilities & DBB_cap_files) {
|
|
if (database->dbb_capabilities & DBB_cap_shadowing) {
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_files])
|
|
F IN DB.RDB$FILES SORTED BY F.RDB$SHADOW_NUMBER, F.RDB$FILE_START
|
|
|
|
if (F.RDB$SHADOW_NUMBER) {
|
|
if (!(F.RDB$FILE_FLAGS & FILE_conditional))
|
|
ERRQ_msg_put(385,
|
|
(TEXT *) (SLONG) F.RDB$SHADOW_NUMBER,
|
|
F.RDB$FILE_NAME,
|
|
(TEXT *) F.RDB$FILE_START, NULL, NULL); /* Msg385 Shadow %d, File:%s starting at page %d */
|
|
}
|
|
else
|
|
|
|
|
|
ERRQ_msg_put(263, F.RDB$FILE_NAME,
|
|
(TEXT *) F.RDB$FILE_START, NULL, NULL, NULL); /* Msg263 File:%s starting at page %d */
|
|
END_FOR;
|
|
}
|
|
else {
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_files])
|
|
F IN DB.RDB$FILES SORTED BY F.RDB$FILE_START
|
|
ERRQ_msg_put(263, F.RDB$FILE_NAME,
|
|
(TEXT *) F.RDB$FILE_START, NULL, NULL, NULL); /* Msg263 File:%s starting at page %d */
|
|
END_FOR;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int show_field_detail(
|
|
DBB database,
|
|
TEXT * relation_name,
|
|
TEXT * field_name, SYN idx_node)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f i e l d _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show everything we know about local
|
|
* fields with the specified name in a particular
|
|
* database.
|
|
*
|
|
**************************************/
|
|
USHORT count, dimensions;
|
|
TEXT *source_field, *p;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
count = 0;
|
|
|
|
if (!(database->dbb_capabilities & DBB_cap_security))
|
|
count += show_insecure_fields(database, relation_name, field_name);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_field])
|
|
RFR IN RDB$RELATION_FIELDS CROSS
|
|
F IN RDB$FIELDS CROSS
|
|
R IN RDB$RELATIONS WITH
|
|
RFR.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME AND
|
|
R.RDB$RELATION_NAME = RFR.RDB$RELATION_NAME AND
|
|
(RFR.RDB$FIELD_NAME = field_name OR
|
|
RFR.RDB$QUERY_NAME = field_name OR
|
|
(RFR.RDB$QUERY_NAME MISSING AND F.RDB$QUERY_NAME = field_name))
|
|
|
|
truncate_string(RFR.RDB$RELATION_NAME);
|
|
|
|
if (relation_name && (strcmp(RFR.RDB$RELATION_NAME, relation_name)))
|
|
continue;
|
|
|
|
if ((dimensions = MET_dimensions(database, F.RDB$FIELD_NAME)) &&
|
|
(idx_node
|
|
&& (dimensions !=
|
|
(USHORT) idx_node->syn_arg[s_idx_count]->
|
|
syn_count))) continue;
|
|
|
|
if (count++)
|
|
ib_printf("\n");
|
|
|
|
truncate_string(RFR.RDB$FIELD_NAME);
|
|
truncate_string(F.RDB$FIELD_NAME);
|
|
|
|
if (!R.RDB$VIEW_BLR.NULL)
|
|
ERRQ_msg_put(495, RFR.RDB$FIELD_NAME, RFR.RDB$RELATION_NAME,
|
|
database->dbb_symbol->sym_string, NULL, NULL); /* Msg495 Field %s in view %s of database %s */
|
|
else
|
|
ERRQ_msg_put(496, RFR.RDB$FIELD_NAME, RFR.RDB$RELATION_NAME,
|
|
database->dbb_symbol->sym_string, NULL, NULL); /* Msg495 Field %s in relation %s of database %s */
|
|
ERRQ_msg_put(265, F.RDB$FIELD_NAME, NULL, NULL, NULL, NULL); /* Msg265 Global field %s */
|
|
|
|
if (!RFR.RDB$BASE_FIELD.NULL) {
|
|
truncate_string(RFR.RDB$BASE_FIELD);
|
|
view_info(database, RFR.RDB$RELATION_NAME, RFR.RDB$BASE_FIELD,
|
|
RFR.RDB$VIEW_CONTEXT, 0);
|
|
}
|
|
|
|
show_text_blob(database, "\t", 266, (SLONG*) &RFR.RDB$DESCRIPTION, 339,
|
|
(SLONG*) &F.RDB$DESCRIPTION, FALSE);
|
|
ERRQ_msg_put(267, NULL, NULL, NULL, NULL, NULL); /* Msg267 Datatype information: */
|
|
ib_printf("\t");
|
|
|
|
show_datatype(database, MET_get_datatype(F.RDB$FIELD_TYPE),
|
|
F.RDB$FIELD_LENGTH, F.RDB$FIELD_SCALE,
|
|
F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH, dimensions);
|
|
if (dimensions && !idx_node)
|
|
array_dimensions(database, F.RDB$FIELD_NAME);
|
|
ib_printf("\n");
|
|
show_blr(database, 341, (SLONG*)&F.RDB$COMPUTED_SOURCE, 341,
|
|
(SLONG*) &F.RDB$COMPUTED_BLR);
|
|
show_blr(database, 342, (SLONG*)&F.RDB$VALIDATION_SOURCE, 342,
|
|
(SLONG*) &F.RDB$VALIDATION_BLR);
|
|
show_string(270, RFR.RDB$SECURITY_CLASS, 0, (TEXT*) NULL_PTR);
|
|
show_string(271, RFR.RDB$QUERY_NAME, 271, F.RDB$QUERY_NAME);
|
|
show_string(273, RFR.RDB$EDIT_STRING, 273, F.RDB$EDIT_STRING);
|
|
show_text_blob(database, "\t", 275, (SLONG*) &RFR.RDB$QUERY_HEADER, 275,
|
|
(SLONG*) &F.RDB$QUERY_HEADER, FALSE);
|
|
END_FOR;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static int show_field_instances( DBB database, TEXT * field_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f i e l d _ i n s t a n c e s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Print a list of places where a global field
|
|
* is used.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
TEXT *source_field, *p;
|
|
|
|
count = NULL;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_field_instance])
|
|
RFR IN RDB$RELATION_FIELDS WITH RFR.RDB$FIELD_SOURCE = field_name
|
|
SORTED BY RFR.RDB$RELATION_NAME
|
|
|
|
if (!count++)
|
|
ERRQ_msg_put(335, field_name, database->dbb_symbol->sym_string,
|
|
NULL, NULL, NULL); /* Msg335 Global field %s is used database %s as: */
|
|
truncate_string(RFR.RDB$FIELD_NAME);
|
|
truncate_string(RFR.RDB$RELATION_NAME);
|
|
ERRQ_msg_put(336, RFR.RDB$FIELD_NAME, RFR.RDB$RELATION_NAME, NULL,
|
|
NULL, NULL); /* Msg336 %s in relation %s */
|
|
END_FOR;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_fields( REL relation, FLD fields)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f i e l d s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show the fields for a relation.
|
|
*
|
|
**************************************/
|
|
DBB database;
|
|
FLD field;
|
|
SYM symbol;
|
|
USHORT max_name, l;
|
|
|
|
/* Find the long field name (including query name) */
|
|
|
|
if (relation) {
|
|
if (!(relation->rel_flags & REL_fields))
|
|
MET_fields(relation);
|
|
fields = relation->rel_fields;
|
|
database = relation->rel_database;
|
|
MET_meta_transaction(database, FALSE);
|
|
}
|
|
else
|
|
database = NULL;
|
|
|
|
max_name = 0;
|
|
|
|
for (field = fields; field; field = field->fld_next) {
|
|
l = field->fld_name->sym_length;
|
|
if (symbol = field->fld_query_name)
|
|
l += symbol->sym_length + 3;
|
|
max_name = MAX(max_name, l);
|
|
}
|
|
|
|
/* Now print the fields */
|
|
|
|
for (field = fields; field; field = field->fld_next) {
|
|
if (QLI_abort)
|
|
return;
|
|
|
|
symbol = field->fld_name;
|
|
l = symbol->sym_length;
|
|
ib_printf(" %s", symbol->sym_string);
|
|
|
|
if (symbol = field->fld_query_name) {
|
|
l += symbol->sym_length + 3;
|
|
ib_printf(" (%s)", symbol->sym_string);
|
|
}
|
|
|
|
for (l = max_name + 12 - l; l; --l)
|
|
ib_putchar(' ');
|
|
show_datatype(database, field->fld_dtype,
|
|
(field->fld_dtype ==
|
|
dtype_varying) ? field->fld_length -
|
|
2 : field->fld_length, field->fld_scale,
|
|
field->fld_sub_type, field->fld_segment_length,
|
|
(field->fld_flags & FLD_array) ? TRUE : FALSE);
|
|
if (database && field->fld_flags & FLD_array)
|
|
array_dimensions(database, field->fld_name->sym_string);
|
|
if (field->fld_flags & FLD_computed)
|
|
ERRQ_msg_put(119, NULL, NULL, NULL, NULL, NULL); /* Msg119 (computed expression) */
|
|
else
|
|
ib_printf("\n");
|
|
}
|
|
}
|
|
|
|
|
|
static void show_filt( QFL filter)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f i l t
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show definition of filter. If a particular database
|
|
* was specified, look there, otherwise, print all filters
|
|
* with that name.
|
|
*
|
|
**************************************/
|
|
int count, any_supported;
|
|
DBB database;
|
|
NAM name;
|
|
|
|
count = 0;
|
|
name = filter->qfl_name;
|
|
|
|
if (database = filter->qfl_database) {
|
|
if (!(database->dbb_capabilities & DBB_cap_filters)) {
|
|
/* Msg439 Filters are not supported in database %s. */
|
|
ERRQ_msg_put(439, database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL);
|
|
return;
|
|
}
|
|
count = show_filter_detail(database, name->nam_string);
|
|
if (!count)
|
|
/* Msg440 Filter %s is not defined in database %s. */
|
|
ERRQ_msg_put(440, name->nam_string,
|
|
database->dbb_symbol->sym_string, NULL, NULL, NULL);
|
|
}
|
|
else {
|
|
any_supported = 0;
|
|
for (database = QLI_databases; database;
|
|
database =
|
|
database->dbb_next) if (database->
|
|
dbb_capabilities & DBB_cap_filters) {
|
|
any_supported++;
|
|
count += show_filter_detail(database, name->nam_string);
|
|
}
|
|
if (!count) {
|
|
if (any_supported)
|
|
/* Msg441 Filter %s is not defined in any open database */
|
|
ERRQ_msg_put(441, name->nam_string, NULL, NULL, NULL, NULL);
|
|
else
|
|
/* Msg442 Filters are not supported in any open database. */
|
|
ERRQ_msg_put(442, NULL, NULL, NULL, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int show_filter_detail( DBB database, TEXT * filter_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f i l t e r _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display the following information about a
|
|
* filter with the specified name in a particular
|
|
* database: Filter name, filter library, input and
|
|
* output sub-types, and description.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
count = 0;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_filter_detail])
|
|
F IN RDB$FILTERS WITH F.RDB$FUNCTION_NAME = filter_name
|
|
|
|
count++;
|
|
truncate_string(filter_name);
|
|
|
|
ERRQ_msg_put(444, /* Msg444 Filter %s in database \"%s\" (%s): */
|
|
filter_name, database->dbb_filename,
|
|
database->dbb_symbol->sym_string, NULL, NULL);
|
|
ERRQ_msg_put(445, F.RDB$MODULE_NAME, NULL, NULL, NULL, NULL); /* Msg445 Filter library is %s */
|
|
ERRQ_msg_put(446, (TEXT *) F.RDB$INPUT_SUB_TYPE, NULL, NULL, NULL, NULL); /* Msg446 Input sub-type is %d */
|
|
ERRQ_msg_put(447, (TEXT *) F.RDB$OUTPUT_SUB_TYPE, NULL, NULL, NULL, NULL); /* Msg447 Output sub-type is %d */
|
|
show_text_blob(database, "\t", 448, (SLONG*) &F.RDB$DESCRIPTION, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
END_FOR;
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_filts( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f i l t s
|
|
*
|
|
* Functional description
|
|
* Show filter names in a database.
|
|
*
|
|
**************************************/
|
|
|
|
if (!(database->dbb_capabilities & DBB_cap_filters))
|
|
/* Msg463 Filters are not supported for database %s. */
|
|
ERRQ_msg_put(463, database->dbb_symbol->sym_string, NULL, NULL, NULL,
|
|
NULL);
|
|
else if (!(show_filters_detail(database)))
|
|
/* Msg464 no filters defined for database %s. */
|
|
ERRQ_msg_put(464, database->dbb_symbol->sym_string, NULL, NULL, NULL,
|
|
NULL);
|
|
}
|
|
|
|
|
|
static int show_filters_detail( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f i l t e r s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show filter names in a database.
|
|
*
|
|
**************************************/
|
|
SSHORT width;
|
|
TEXT buffer[256];
|
|
int count;
|
|
|
|
count = 0;
|
|
width = get_window_size(sizeof(buffer) - 1);
|
|
buffer[0] = 0;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_filters]) F IN RDB$FILTERS
|
|
SORTED BY F.RDB$FUNCTION_NAME
|
|
|
|
if (!count++)
|
|
ERRQ_msg_put(449, database->dbb_filename, /* Msg449 Filters in database %s (%s): */
|
|
database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL);
|
|
show_names(F.RDB$FUNCTION_NAME, width, buffer);
|
|
END_FOR;
|
|
|
|
if (buffer[0])
|
|
ib_printf("%s\n", buffer);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_fld( SYN field_node)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f l d
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show all details about a particular
|
|
* field. What we've got coming in
|
|
* is a list of 1, 2, or 3 name blocks,
|
|
* contain the [[database.]relation.]field
|
|
* specification. Figure out what we've
|
|
* got and let somebody else do all the work.
|
|
*
|
|
**************************************/
|
|
DBB database;
|
|
NAM field_name, relation_name;
|
|
SYN *ptr;
|
|
SYM symbol;
|
|
TEXT *string, s[65];
|
|
int count;
|
|
SYN idx_node;
|
|
|
|
count = 0;
|
|
database = NULL;
|
|
field_name = NULL;
|
|
relation_name = NULL;
|
|
idx_node = NULL;
|
|
|
|
if (field_node->syn_type == nod_index) {
|
|
idx_node = field_node;
|
|
field_node = idx_node->syn_arg[s_idx_field];
|
|
}
|
|
|
|
for (ptr = field_node->syn_arg + field_node->syn_count;
|
|
--ptr >= field_node->syn_arg;) {
|
|
if (!field_name)
|
|
field_name = (NAM) * ptr;
|
|
else if (!relation_name)
|
|
relation_name = (NAM) * ptr;
|
|
else
|
|
for (symbol = ((NAM) * ptr)->nam_symbol; symbol;
|
|
symbol = symbol->sym_homonym)
|
|
if (symbol->sym_type = SYM_database) {
|
|
database = (DBB) symbol->sym_object;
|
|
break;
|
|
}
|
|
}
|
|
|
|
string = (relation_name) ? relation_name->nam_string : NULL;
|
|
|
|
if (string)
|
|
sprintf(s, "%s.%s", string, field_name->nam_string);
|
|
else
|
|
sprintf(s, "%s", field_name->nam_string);
|
|
|
|
if (database) {
|
|
count += show_field_detail(database, string,
|
|
field_name->nam_string, (SYN) NULL_PTR);
|
|
if (!count)
|
|
ERRQ_msg_put(117, s, database->dbb_symbol->sym_string, NULL, NULL, NULL); /* Msg117 Field %s does not exist in database %s */
|
|
}
|
|
else {
|
|
for (database = QLI_databases; database;
|
|
database = database->dbb_next) count +=
|
|
show_field_detail(database, string, field_name->nam_string,
|
|
idx_node);
|
|
if (!count)
|
|
ERRQ_msg_put(118, s, NULL, NULL, NULL, NULL); /* Msg118 Field %s does not exist in any open database */
|
|
}
|
|
}
|
|
|
|
|
|
static void show_func( QFN func)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f u n c
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show definition of function. If a particular database
|
|
* was specified, look there, otherwise, print all functions
|
|
* with that name.
|
|
*
|
|
**************************************/
|
|
int count, any_supported;
|
|
DBB database;
|
|
NAM name;
|
|
|
|
count = 0;
|
|
name = func->qfn_name;
|
|
|
|
if (database = func->qfn_database) {
|
|
if (!(database->dbb_capabilities & DBB_cap_functions)) {
|
|
/* Msg417 Functions are not supported in database %s. */
|
|
ERRQ_msg_put(417, database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL);
|
|
return;
|
|
}
|
|
count = show_func_detail(database, name->nam_string);
|
|
if (!count)
|
|
/* Msg422 Function %s is not defined in database %s. */
|
|
ERRQ_msg_put(422, name->nam_string,
|
|
database->dbb_symbol->sym_string, NULL, NULL, NULL);
|
|
}
|
|
else {
|
|
any_supported = 0;
|
|
for (database = QLI_databases; database;
|
|
database =
|
|
database->dbb_next) if (database->
|
|
dbb_capabilities & DBB_cap_functions) {
|
|
any_supported++;
|
|
count += show_func_detail(database, name->nam_string);
|
|
}
|
|
if (!count) {
|
|
if (any_supported)
|
|
/* Msg423 Function is %s not defined in any open database */
|
|
ERRQ_msg_put(423, name->nam_string, NULL, NULL, NULL, NULL);
|
|
else
|
|
/* Msg420 Functions are not supported in any open database. */
|
|
ERRQ_msg_put(420, NULL, NULL, NULL, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int show_func_detail( DBB database, TEXT * func_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f u n c _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display the following information about a
|
|
* function with the specified name in a particular
|
|
* database: Function name, query name, function
|
|
* library, input and output argument datatypes, and
|
|
* description.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
USHORT array;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
count = 0;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_func_detail])
|
|
F IN RDB$FUNCTIONS WITH
|
|
(F.RDB$FUNCTION_NAME = func_name OR F.RDB$QUERY_NAME = func_name)
|
|
count++;
|
|
truncate_string(F.RDB$QUERY_NAME);
|
|
truncate_string(F.RDB$FUNCTION_NAME);
|
|
strcpy(func_name, F.RDB$FUNCTION_NAME);
|
|
|
|
if (F.RDB$QUERY_NAME[0])
|
|
ERRQ_msg_put(424, /* Msg424 Function %s (%s) in database \"%s\" (%s): */
|
|
F.RDB$FUNCTION_NAME, F.RDB$QUERY_NAME,
|
|
database->dbb_filename,
|
|
database->dbb_symbol->sym_string, NULL);
|
|
else
|
|
ERRQ_msg_put(425, /* Msg425 Function %s in database \"%s\" (%s): */
|
|
F.RDB$FUNCTION_NAME, database->dbb_filename,
|
|
database->dbb_symbol->sym_string, NULL, NULL);
|
|
|
|
ERRQ_msg_put(426, F.RDB$MODULE_NAME, NULL, NULL, NULL, NULL); /* Msg426 Function library is %s */
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_func_args])
|
|
FA IN RDB$FUNCTION_ARGUMENTS WITH
|
|
FA.RDB$FUNCTION_NAME = func_name SORTED BY FA.RDB$ARGUMENT_POSITION
|
|
if (FA.RDB$ARGUMENT_POSITION == 0)
|
|
ERRQ_msg_partial(427, NULL, NULL, NULL, NULL, NULL); /* Msg427 Return argument is */
|
|
else
|
|
ERRQ_msg_partial(428,
|
|
(TEXT *) (SLONG) FA.RDB$ARGUMENT_POSITION,
|
|
NULL, NULL, NULL, NULL); /* Msg428 Argument %d is */
|
|
|
|
array = (FA.RDB$MECHANISM == 2);
|
|
show_datatype(database, MET_get_datatype(FA.RDB$FIELD_TYPE),
|
|
FA.RDB$FIELD_LENGTH, FA.RDB$FIELD_SCALE,
|
|
FA.RDB$FIELD_SUB_TYPE, 0, array);
|
|
ib_printf("\n");
|
|
END_FOR;
|
|
|
|
show_text_blob(database, "\t", 421, (SLONG*) &F.RDB$DESCRIPTION, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
|
|
END_FOR;
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_funcs( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f u n c s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show function names in all ready databases,
|
|
* or a specific database.
|
|
*
|
|
**************************************/
|
|
|
|
if (!(database->dbb_capabilities & DBB_cap_functions))
|
|
ERRQ_msg_put(461, database->dbb_symbol->sym_string, NULL, NULL, NULL,
|
|
NULL);
|
|
/* 461 - functions aren't supported in this database */
|
|
if (!(show_funcs_detail(database)))
|
|
ERRQ_msg_put(462, database->dbb_symbol->sym_string, NULL, NULL, NULL,
|
|
NULL);
|
|
/* 462 - no functions are defined in this database */
|
|
}
|
|
|
|
|
|
static int show_funcs_detail( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f u n c s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show function names in a database.
|
|
*
|
|
**************************************/
|
|
SSHORT width;
|
|
TEXT buffer[256];
|
|
int count;
|
|
|
|
count = NULL;
|
|
width = get_window_size(sizeof(buffer) - 1);
|
|
buffer[0] = 0;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_functions]) F IN RDB$FUNCTIONS
|
|
SORTED BY F.RDB$FUNCTION_NAME
|
|
if (!count++)
|
|
ERRQ_msg_put(416, database->dbb_filename, /* Msg416 Functions in database %s (%s): */
|
|
database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL);
|
|
show_names(F.RDB$FUNCTION_NAME, width, buffer);
|
|
END_FOR;
|
|
|
|
if (buffer[0])
|
|
ib_printf("%s\n", buffer);
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static int show_insecure_fields(
|
|
DBB database,
|
|
TEXT * relation_name, TEXT * field_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ i n s e c u r e _ f i e l d s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show everything we know about local
|
|
* fields with the specified name in a particular
|
|
* database, that doesn't have security classes
|
|
* defined.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
TEXT *source_field, *p;
|
|
|
|
count = NULL;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_field])
|
|
RFR IN RDB$RELATION_FIELDS CROSS
|
|
F IN RDB$FIELDS CROSS
|
|
R IN RDB$RELATIONS WITH
|
|
RFR.RDB$FIELD_SOURCE = F.RDB$FIELD_NAME AND
|
|
R.RDB$RELATION_NAME = RFR.RDB$RELATION_NAME AND
|
|
(RFR.RDB$FIELD_NAME = field_name OR
|
|
RFR.RDB$QUERY_NAME = field_name OR
|
|
(RFR.RDB$QUERY_NAME MISSING AND F.RDB$QUERY_NAME = field_name))
|
|
|
|
truncate_string(RFR.RDB$RELATION_NAME);
|
|
if (relation_name && (strcmp(RFR.RDB$RELATION_NAME, relation_name)))
|
|
continue;
|
|
if (count++)
|
|
ib_printf("\n");
|
|
truncate_string(RFR.RDB$FIELD_NAME);
|
|
truncate_string(F.RDB$FIELD_NAME);
|
|
|
|
if (R.RDB$VIEW_BLR.NULL)
|
|
ERRQ_msg_put(496, RFR.RDB$FIELD_NAME, RFR.RDB$RELATION_NAME,
|
|
database->dbb_symbol->sym_string, NULL, NULL); /* Msg495 Field %s in relation %s of database %s */
|
|
else
|
|
ERRQ_msg_put(495, RFR.RDB$FIELD_NAME, RFR.RDB$RELATION_NAME,
|
|
database->dbb_symbol->sym_string, NULL, NULL); /* Msg495 Field %s in view %s of database %s */
|
|
ERRQ_msg_put(338, F.RDB$FIELD_NAME, NULL, NULL, NULL, NULL); /* Msg338 Global field %s */
|
|
|
|
if (!RFR.RDB$BASE_FIELD.NULL) {
|
|
truncate_string(RFR.RDB$BASE_FIELD);
|
|
view_info(database, RFR.RDB$RELATION_NAME, RFR.RDB$BASE_FIELD,
|
|
RFR.RDB$VIEW_CONTEXT, 0);
|
|
}
|
|
|
|
show_text_blob(database, "\t", 339, (SLONG*) &RFR.RDB$DESCRIPTION, 339,
|
|
(SLONG*) &F.RDB$DESCRIPTION, FALSE);
|
|
ERRQ_msg_partial(340, NULL, NULL, NULL, NULL, NULL); /* Msg340 Datatype information: */
|
|
ib_printf("\t");
|
|
show_datatype(database, MET_get_datatype(F.RDB$FIELD_TYPE),
|
|
F.RDB$FIELD_LENGTH, F.RDB$FIELD_SCALE,
|
|
F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH,
|
|
MET_dimensions(database, F.RDB$FIELD_NAME));
|
|
ib_printf("\n");
|
|
show_blr(database, 341, (SLONG*) &F.RDB$COMPUTED_SOURCE, 341,
|
|
(SLONG*) &F.RDB$COMPUTED_BLR);
|
|
show_blr(database, 342, (SLONG*) &F.RDB$VALIDATION_SOURCE, 342,
|
|
(SLONG*) &F.RDB$VALIDATION_BLR);
|
|
show_string(343, RFR.RDB$QUERY_NAME, 343, F.RDB$QUERY_NAME);
|
|
show_string(346, RFR.RDB$EDIT_STRING, 346, F.RDB$EDIT_STRING);
|
|
show_text_blob(database, "\t", 345, (SLONG*) &RFR.RDB$QUERY_HEADER, 345,
|
|
(SLONG*) &F.RDB$QUERY_HEADER, FALSE);
|
|
END_FOR;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_forms_db( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f o r m s _ d b
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show what we know about forms
|
|
* for one database.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
|
|
if (!(show_forms_detail(database)))
|
|
ERRQ_msg_put(120, database->dbb_symbol->sym_string, NULL, NULL, NULL,
|
|
NULL);
|
|
/* Msg120 There are no forms defined for database %s */
|
|
}
|
|
|
|
|
|
static int show_forms_detail( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ f o r m s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show everything we know about forms,
|
|
* meaning basically show form names
|
|
*
|
|
**************************************/
|
|
int count;
|
|
|
|
count = NULL;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_forms1])
|
|
Y IN RDB$RELATIONS WITH Y.RDB$RELATION_NAME = "PYXIS$FORMS"
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_forms2])
|
|
X IN PYXIS$FORMS
|
|
if (!count)
|
|
ERRQ_msg_put(285, database->dbb_symbol->sym_string, NULL, NULL, NULL, NULL); /* Msg285 Forms in database %s */
|
|
ib_printf(" %s\t%s\n", X.PYXIS$FORM_NAME, X.PYXIS$FORM_TYPE);
|
|
count++;
|
|
END_FOR;
|
|
END_FOR;
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_gbl_field( SYN field_node)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ g b l _ f i e l d
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show what we know about a global
|
|
* field. It may be qualified with a
|
|
* database handle, in which case, show only
|
|
* the one global field in that database,
|
|
* otherwise show them all.
|
|
*
|
|
**************************************/
|
|
DBB database;
|
|
SYN *ptr;
|
|
NAM field_name, name;
|
|
SYM symbol;
|
|
int count;
|
|
|
|
count = 0;
|
|
field_name = NULL;
|
|
database = NULL;
|
|
|
|
for (ptr = field_node->syn_arg + field_node->syn_count - 1;
|
|
ptr >= field_node->syn_arg; ptr--) {
|
|
if (!field_name)
|
|
field_name = (NAM) * ptr;
|
|
else
|
|
for (name = (NAM) * ptr, symbol = name->nam_symbol;
|
|
symbol; symbol = symbol->sym_homonym)
|
|
if (symbol->sym_type = SYM_database) {
|
|
database = (DBB) symbol->sym_object;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (database) {
|
|
count += show_gbl_field_detail(database, field_name->nam_string);
|
|
if (!count)
|
|
ERRQ_msg_put(122, /* Msg122 Global field %s does not exist in database %s */
|
|
field_name->nam_string,
|
|
database->dbb_symbol->sym_string, NULL, NULL, NULL);
|
|
}
|
|
else {
|
|
for (database = QLI_databases; database;
|
|
database = database->dbb_next) count +=
|
|
show_gbl_field_detail(database, field_name->nam_string);
|
|
if (!count)
|
|
ERRQ_msg_put(123, field_name->nam_string, NULL, NULL, NULL, NULL); /* Msg123 Global field %s does not exist in any open database */
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static int show_gbl_field_detail( DBB database, TEXT * field_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ g b l _ f i e l d _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show everything we know about a global
|
|
* field with the specified name in a particular
|
|
* database.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
TEXT *source_field, *p;
|
|
|
|
count = NULL;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_global_field])
|
|
F IN RDB$FIELDS WITH F.RDB$FIELD_NAME = field_name
|
|
|
|
if (count++)
|
|
ib_printf("\n");
|
|
truncate_string(F.RDB$FIELD_NAME);
|
|
|
|
ERRQ_msg_put(276, F.RDB$FIELD_NAME, database->dbb_symbol->sym_string,
|
|
NULL, NULL, NULL); /* Msg276 Global field %s in database %s */
|
|
|
|
show_text_blob(database, "\t", 277, (SLONG*) &F.RDB$DESCRIPTION, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
ERRQ_msg_put(278, NULL, NULL, NULL, NULL, NULL); /* Msg278 Datatype information: */
|
|
ib_printf("\t");
|
|
show_datatype(database, MET_get_datatype(F.RDB$FIELD_TYPE),
|
|
F.RDB$FIELD_LENGTH, F.RDB$FIELD_SCALE,
|
|
F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH,
|
|
MET_dimensions(database, F.RDB$FIELD_NAME));
|
|
ib_printf("\n");
|
|
show_blr(database, 279, (SLONG*) &F.RDB$COMPUTED_SOURCE, 341,
|
|
(SLONG*) &F.RDB$COMPUTED_BLR);
|
|
show_blr(database, 280, (SLONG*) &F.RDB$VALIDATION_SOURCE, 342,
|
|
(SLONG*) &F.RDB$VALIDATION_BLR);
|
|
show_string(281, F.RDB$QUERY_NAME, 0, (TEXT*) NULL_PTR);
|
|
show_string(282, F.RDB$EDIT_STRING, 0, (TEXT*) NULL_PTR);
|
|
show_text_blob(database, "\t", 283, (SLONG*) &F.RDB$QUERY_HEADER, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
END_FOR;
|
|
|
|
if (count && !(show_field_instances(database, field_name)))
|
|
ERRQ_msg_put(284, field_name, database->dbb_symbol->sym_string, NULL,
|
|
NULL, NULL); /* Msg284 %s is not used in any relations in database %s */
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_gbl_fields( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ g b l _ f i e l d s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show what we know about a global
|
|
* field. It may be qualified with a
|
|
* database handle, in which case, show only
|
|
* the global fields in that database,
|
|
* otherwise show them all.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
|
|
count = 0;
|
|
if (database) {
|
|
count += show_gbl_fields_detail(database);
|
|
if (!count)
|
|
ERRQ_msg_put(124, database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL); /* Msg124 There are no fields defined for database %s */
|
|
}
|
|
else {
|
|
for (database = QLI_databases; database;
|
|
database = database->dbb_next) count +=
|
|
show_gbl_fields_detail(database);
|
|
if (!count)
|
|
ERRQ_msg_put(125, NULL, NULL, NULL, NULL, NULL); /* Msg125 There are no fields defined in any open database */
|
|
}
|
|
}
|
|
|
|
|
|
static int show_gbl_fields_detail( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ g b l _ f i e l d s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show everything we know about
|
|
* global fields in a particular
|
|
* database.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
TEXT *source_field, *p;
|
|
|
|
count = NULL;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_global_fields])
|
|
F IN RDB$FIELDS WITH F.RDB$SYSTEM_FLAG MISSING OR
|
|
F.RDB$SYSTEM_FLAG = 0 SORTED BY F.RDB$FIELD_NAME
|
|
|
|
if (!count++)
|
|
ERRQ_msg_put(286, database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL); /* Msg286 Global fields for database %s: */
|
|
|
|
if (!F.RDB$COMPUTED_BLR.NULL)
|
|
continue;
|
|
ib_printf(" %s", F.RDB$FIELD_NAME);
|
|
show_datatype(database, MET_get_datatype(F.RDB$FIELD_TYPE),
|
|
F.RDB$FIELD_LENGTH, F.RDB$FIELD_SCALE,
|
|
F.RDB$FIELD_SUB_TYPE, F.RDB$SEGMENT_LENGTH,
|
|
MET_dimensions(database, F.RDB$FIELD_NAME));
|
|
show_text_blob(database, "\t", 262, (SLONG*) &F.RDB$DESCRIPTION, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
ib_printf("\n");
|
|
END_FOR;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static int show_indices_detail( REL relation)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ i n d i c e s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show indices for a relation. If none, return 0.
|
|
*
|
|
**************************************/
|
|
USHORT count, type;
|
|
TEXT *p;
|
|
DBB database;
|
|
|
|
type = count = 0;
|
|
database = relation->rel_database;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
if (database->dbb_capabilities & DBB_cap_idx_inactive) {
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_indices])
|
|
X IN RDB$INDICES CROSS Z IN RDB$RELATIONS
|
|
WITH X.RDB$RELATION_NAME EQ relation->rel_symbol->sym_string
|
|
AND Z.RDB$RELATION_NAME EQ X.RDB$RELATION_NAME
|
|
AND Z.RDB$VIEW_BLR MISSING SORTED BY X.RDB$INDEX_NAME++ count;
|
|
if (database->dbb_capabilities & DBB_cap_index_type)
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_index_type])
|
|
Y IN RDB$INDICES WITH Y.RDB$INDEX_NAME = X.RDB$INDEX_NAME
|
|
|
|
type = Y.RDB$INDEX_TYPE;
|
|
END_FOR;
|
|
|
|
for (p = X.RDB$INDEX_NAME; *p && *p != ' '; p++);
|
|
*p = 0;
|
|
|
|
ERRQ_msg_put(450, X.RDB$INDEX_NAME,
|
|
(X.RDB$UNIQUE_FLAG) ? (char*) " (unique)" : (char*) "",
|
|
(type == 1) ? (char*) " (descending)" : (char*) "",
|
|
(X.RDB$INDEX_INACTIVE) ? (char*) " (inactive)" : (char*) "", NULL); /* Msg450 Index %s%s%s%s */
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_index])
|
|
Y IN RDB$INDEX_SEGMENTS WITH
|
|
Y.RDB$INDEX_NAME EQ X.RDB$INDEX_NAME
|
|
SORTED BY Y.RDB$FIELD_POSITION
|
|
|
|
for (p = Y.RDB$FIELD_NAME; *p && *p != ' '; p++);
|
|
ib_printf(" %s\n", Y.RDB$FIELD_NAME);
|
|
END_FOR;
|
|
|
|
#ifdef PC_ENGINE
|
|
/*** if (!X.RDB$EXPRESSION_SOURCE.NULL)
|
|
show_text_blob (database, "\t ", 0, &X.RDB$EXPRESSION_SOURCE, 0, (SLONG*) NULL_PTR, TRUE);
|
|
else if (!X.RDB$EXPRESSION_BLR.NULL)
|
|
{
|
|
ERRQ_msg_put (485, NULL, NULL, NULL, NULL, NULL);
|
|
display_blr (database, &X.RDB$EXPRESSION_BLR);
|
|
} ***/
|
|
#endif
|
|
END_FOR;
|
|
}
|
|
else {
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_indices])
|
|
X IN RDB$INDICES CROSS Z IN RDB$RELATIONS
|
|
WITH X.RDB$RELATION_NAME EQ relation->rel_symbol->sym_string
|
|
AND Z.RDB$RELATION_NAME EQ X.RDB$RELATION_NAME
|
|
AND Z.RDB$VIEW_BLR MISSING SORTED BY X.RDB$INDEX_NAME
|
|
|
|
++count;
|
|
for (p = X.RDB$INDEX_NAME; *p && *p != ' '; p++);
|
|
*p = 0;
|
|
ERRQ_msg_put(290, X.RDB$INDEX_NAME,
|
|
(X.RDB$UNIQUE_FLAG) ? (char*) " (unique)" : (char*) "", NULL, NULL, NULL); /* Msg290 Index %s%s */
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_index])
|
|
Y IN RDB$INDEX_SEGMENTS WITH
|
|
Y.RDB$INDEX_NAME EQ X.RDB$INDEX_NAME
|
|
SORTED BY Y.RDB$FIELD_POSITION
|
|
for (p = Y.RDB$FIELD_NAME; *p && *p != ' '; p++);
|
|
ib_printf(" %s\n", Y.RDB$FIELD_NAME);
|
|
END_FOR;
|
|
END_FOR;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_matching(void)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ m a t c h i n g
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Just print the QLI matching language string.
|
|
*
|
|
**************************************/
|
|
TEXT buffer[256];
|
|
|
|
if (QLI_abort)
|
|
return;
|
|
if (QLI_matching_language) {
|
|
strncpy(buffer, (char*) QLI_matching_language->con_data,
|
|
QLI_matching_language->con_desc.dsc_length);
|
|
buffer[QLI_matching_language->con_desc.dsc_length] = 0;
|
|
ib_printf("\n\t%s\n", buffer);
|
|
}
|
|
}
|
|
|
|
|
|
static void show_names( TEXT * name, USHORT width, TEXT * buffer)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ n a m e s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
*
|
|
**************************************/
|
|
BASED ON QLI$PROCEDURES.QLI$PROCEDURE_NAME padded_name;
|
|
TEXT *s;
|
|
SSHORT len, l1, l2;
|
|
|
|
s = buffer + strlen(buffer);
|
|
len = sizeof(padded_name) - 1;
|
|
l1 = s - buffer;
|
|
if ((s != buffer) && ((l1 + len + 4) > width)) {
|
|
ib_printf("%s\n", buffer);
|
|
buffer[0] = 0;
|
|
s = buffer;
|
|
}
|
|
*s++ = ' ';
|
|
*s++ = ' ';
|
|
*s++ = ' ';
|
|
*s++ = ' ';
|
|
strcpy(s, name);
|
|
while (*s) {
|
|
s++;
|
|
len--;
|
|
}
|
|
while (len--)
|
|
*s++ = ' ';
|
|
*s = 0;
|
|
}
|
|
|
|
|
|
static void show_proc( QPR proc)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ p r o c
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show definition of procedure. If a particular database
|
|
* was specified, look there, otherwise, print all procedures
|
|
* with that name.
|
|
*
|
|
**************************************/
|
|
int *blob, count;
|
|
DBB database;
|
|
NAM name;
|
|
|
|
count = 0;
|
|
name = proc->qpr_name;
|
|
|
|
if (database = proc->qpr_database) {
|
|
if (blob = (int*) PRO_fetch_procedure(database, (TEXT*) name->nam_string))
|
|
display_procedure(database, (UCHAR*) name->nam_string, blob);
|
|
else
|
|
ERRQ_msg_put(126, /* Msg126 Procedure %s not found in database %s */
|
|
name->nam_string, database->dbb_symbol->sym_string,
|
|
NULL, NULL, NULL);
|
|
return;
|
|
}
|
|
|
|
for (database = QLI_databases; database; database = database->dbb_next)
|
|
if (blob = (int*) PRO_fetch_procedure(database, (TEXT*) name->nam_string)) {
|
|
display_procedure(database, (UCHAR*) name->nam_string, blob);
|
|
count++;
|
|
}
|
|
|
|
if (!count) {
|
|
ERRQ_msg_put(127, name->nam_string, NULL, NULL, NULL, NULL); /* Msg127 Procedure %s not found */
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
static void show_procs( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ p r o c s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show procedures in a database
|
|
*
|
|
**************************************/
|
|
SSHORT width;
|
|
TEXT buffer[256];
|
|
|
|
width = get_window_size(sizeof(buffer) - 1);
|
|
|
|
PRO_setup(database);
|
|
ERRQ_msg_put(128, database->dbb_filename, /* Msg128 Procedures in database %s (%s): */
|
|
database->dbb_symbol->sym_string, NULL, NULL, NULL);
|
|
buffer[0] = 0;
|
|
FOR(REQUEST_HANDLE database->dbb_scan_blobs) X IN DB.QLI$PROCEDURES
|
|
SORTED BY X.QLI$PROCEDURE_NAME
|
|
show_names(X.QLI$PROCEDURE_NAME, width, buffer);
|
|
END_FOR;
|
|
if (buffer[0])
|
|
ib_printf("%s\n", buffer);
|
|
}
|
|
|
|
|
|
static void show_rel( REL relation)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ r e l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Just print a relation name. Almost mindless.
|
|
*
|
|
**************************************/
|
|
|
|
if (QLI_abort)
|
|
return;
|
|
|
|
ib_printf(" %s\n", relation->rel_symbol->sym_string);
|
|
}
|
|
|
|
|
|
static void show_rel_detail( REL relation)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ r e l _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Ask META to print description,
|
|
* security class, etc.
|
|
*
|
|
**************************************/
|
|
DBB database;
|
|
TEXT *relation_name;
|
|
USHORT msg;
|
|
|
|
relation_name = relation->rel_symbol->sym_string;
|
|
database = relation->rel_database;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_rel_detail])
|
|
R IN RDB$RELATIONS WITH
|
|
R.RDB$RELATION_NAME = relation_name
|
|
show_text_blob(database, "\t", 291, (SLONG*) &R.RDB$DESCRIPTION, 0,
|
|
(SLONG*) NULL_PTR, FALSE);
|
|
|
|
if (database->dbb_capabilities & DBB_cap_security)
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_rel_secur])
|
|
S IN RDB$RELATIONS WITH S.RDB$RELATION_NAME = R.RDB$RELATION_NAME
|
|
AND S.RDB$SECURITY_CLASS NOT MISSING
|
|
show_string(292, S.RDB$SECURITY_CLASS, 0, (TEXT*) NULL_PTR);
|
|
END_FOR;
|
|
|
|
if (database->dbb_capabilities & DBB_cap_extern_file)
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_rel_extern])
|
|
E IN RDB$RELATIONS WITH E.RDB$RELATION_NAME = R.RDB$RELATION_NAME
|
|
AND E.RDB$EXTERNAL_FILE NOT MISSING
|
|
ERRQ_msg_put(293, E.RDB$EXTERNAL_FILE, NULL, NULL, NULL, NULL); /* Msg293 Stored in external file %s */
|
|
END_FOR;
|
|
|
|
/* OBSOLETE - Handling of DBB_cap_triggers (old V2 style triggers) */
|
|
/* OBSOLETE - Msg294 An erase trigger is defined for %s */
|
|
/* OBSOLETE - Msg295 A modify trigger is defined for %s */
|
|
/* OBSOLETE - Msg296 A store trigger is defined for %s */
|
|
|
|
if (database->dbb_capabilities & DBB_cap_new_triggers) {
|
|
msg = 380;
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_new_trig_exists])
|
|
X IN RDB$TRIGGERS WITH X.RDB$RELATION_NAME EQ relation->
|
|
rel_symbol->sym_string
|
|
if (!X.RDB$TRIGGER_BLR.NULL) {
|
|
if (msg) {
|
|
ERRQ_msg_put(msg, NULL, NULL, NULL, NULL, NULL); /* Msg380 Trigger defined for this relation */
|
|
msg = 0;
|
|
}
|
|
ib_printf("\t");
|
|
show_trigger_status(X.RDB$TRIGGER_NAME,
|
|
X.RDB$TRIGGER_TYPE,
|
|
X.RDB$TRIGGER_INACTIVE,
|
|
X.RDB$TRIGGER_SEQUENCE);
|
|
}
|
|
END_FOR;
|
|
}
|
|
END_FOR;
|
|
}
|
|
|
|
|
|
static void show_rels( DBB dbb, ENUM show_t sw, SSHORT width)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ r e l s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display information about a relations
|
|
* or system_relations for a specific database.
|
|
*
|
|
**************************************/
|
|
SYN *ptr, value;
|
|
REL relation;
|
|
TEXT buffer[256];
|
|
|
|
switch (sw) {
|
|
case show_relations:
|
|
{
|
|
show_dbb(dbb);
|
|
buffer[0] = 0;
|
|
for (relation = dbb->dbb_relations; relation;
|
|
relation = relation->rel_next)
|
|
if (!(relation->rel_flags & REL_system))
|
|
show_names(relation->rel_symbol->sym_string, width,
|
|
buffer);
|
|
if (buffer[0])
|
|
ib_printf("%s\n", buffer);
|
|
ib_printf("\n");
|
|
break;
|
|
}
|
|
case show_system_relations:
|
|
{
|
|
show_dbb(dbb);
|
|
buffer[0] = 0;
|
|
for (relation = dbb->dbb_relations; relation;
|
|
relation = relation->rel_next)
|
|
if (relation->rel_flags & REL_system)
|
|
show_names(relation->rel_symbol->sym_string, width,
|
|
buffer);
|
|
if (buffer[0])
|
|
ib_printf("%s\n", buffer);
|
|
ib_printf("\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static int show_security_class_detail( DBB database, TEXT * name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ s e c u r i t y _ c l a s s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show security classes for a databases.
|
|
*
|
|
**************************************/
|
|
SSHORT count;
|
|
|
|
count = 0;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
if (!database->dbb_capabilities & DBB_cap_security)
|
|
return FALSE;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_secur_class])
|
|
S IN RDB$SECURITY_CLASSES WITH S.RDB$SECURITY_CLASS = name
|
|
if (truncate_string(S.RDB$SECURITY_CLASS)) {
|
|
ib_printf("\t%s:\n", S.RDB$SECURITY_CLASS);
|
|
display_acl(database, (SLONG*) &S.RDB$ACL);
|
|
}
|
|
count++;
|
|
END_FOR;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static int show_security_classes_detail( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ s e c u r i t y _ c l a s s e s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show security classes for a databases.
|
|
*
|
|
**************************************/
|
|
SSHORT count;
|
|
|
|
count = 0;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
if (!database->dbb_capabilities & DBB_cap_security)
|
|
return FALSE;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_secur])
|
|
S IN RDB$SECURITY_CLASSES
|
|
if (!count)
|
|
ERRQ_msg_put(297, database->dbb_symbol->sym_string, NULL, NULL, NULL, NULL); /* Msg297 Security classes for database %s */
|
|
|
|
if (truncate_string(S.RDB$SECURITY_CLASS)) {
|
|
ib_printf("\t%s:\n", S.RDB$SECURITY_CLASS);
|
|
display_acl(database, (SLONG*) &S.RDB$ACL);
|
|
}
|
|
count++;
|
|
END_FOR;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_string(
|
|
USHORT msg1,
|
|
TEXT * string1, USHORT msg2, TEXT * string2)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ s t r i n g
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show one of two strings and maybe a message, too.
|
|
*
|
|
**************************************/
|
|
|
|
if (string2 && (!*string1 || *string1 == ' ')) {
|
|
msg1 = msg2;
|
|
string1 = string2;
|
|
}
|
|
|
|
if (!*string1 || *string1 == ' ')
|
|
return;
|
|
|
|
truncate_string(string1);
|
|
ERRQ_msg_put(msg1, string1, NULL, NULL, NULL, NULL);
|
|
}
|
|
|
|
|
|
static void show_sys_trigs( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ s y s _ t r i g s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Ask META to print trigger information
|
|
* for the system. Since parse
|
|
* has already swallowed a possible database
|
|
* qualifier, just assume that the database
|
|
* is the right one.
|
|
*
|
|
**************************************/
|
|
USHORT count;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
count = 0;
|
|
|
|
if (database->dbb_capabilities & DBB_cap_new_triggers)
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_sys_triggers])
|
|
X IN RDB$TRIGGERS WITH X.RDB$SYSTEM_FLAG EQ 1
|
|
SORTED BY X.RDB$RELATION_NAME, X.RDB$TRIGGER_TYPE,
|
|
X.RDB$TRIGGER_SEQUENCE,
|
|
X.RDB$TRIGGER_NAME
|
|
|
|
if (!X.RDB$TRIGGER_BLR.NULL) {
|
|
ERRQ_msg_put(379, X.RDB$RELATION_NAME, NULL, NULL, NULL, NULL); /* Msg379 System Triggers */
|
|
show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE,
|
|
X.RDB$TRIGGER_SEQUENCE,
|
|
X.RDB$TRIGGER_INACTIVE, (SLONG*) &X.RDB$DESCRIPTION,
|
|
database, X.RDB$RELATION_NAME);
|
|
show_blob_info((SLONG*) &X.RDB$TRIGGER_BLR, (SLONG*) &X.RDB$TRIGGER_SOURCE, 377, /* Msg377 Source for the trigger is not available. Trigger BLR: */
|
|
376, /* Msg376 Source for the trigger */
|
|
database, X.RDB$RELATION_NAME);
|
|
show_trigger_messages(database, X.RDB$TRIGGER_NAME);
|
|
count++;
|
|
}
|
|
END_FOR;
|
|
|
|
if (!count)
|
|
ERRQ_msg_put(378, NULL, NULL, NULL, NULL, NULL); /* Msg378 No system triggers */
|
|
}
|
|
|
|
|
|
static void show_text_blob(
|
|
DBB database,
|
|
TEXT * column,
|
|
USHORT msg1,
|
|
SLONG * blob1,
|
|
USHORT msg2, SLONG * blob2, int strip)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ t e x t _ b l o b
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display a text blob.
|
|
*
|
|
**************************************/
|
|
|
|
if (blob2 && !blob1[0] && !blob1[1]) {
|
|
blob1 = blob2;
|
|
msg1 = msg2;
|
|
}
|
|
|
|
if (!blob1[0] && !blob1[1])
|
|
return;
|
|
|
|
if (msg1)
|
|
ERRQ_msg_put(msg1, NULL, NULL, NULL, NULL, NULL);
|
|
|
|
display_text(database, blob1, column, strip);
|
|
}
|
|
|
|
|
|
static void show_trig( REL relation)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ t r i g
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Ask META to print trigger information
|
|
* for a particular relation. Since parse
|
|
* has already swallowed a possible database
|
|
* qualifier, just assume that the database
|
|
* is the right one.
|
|
*
|
|
**************************************/
|
|
|
|
if (!(show_trigger_detail(relation->rel_database,
|
|
relation->rel_symbol->sym_string)))
|
|
ERRQ_msg_put(129, relation->rel_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL); /* Msg129 No triggers are defined for relation %s */
|
|
}
|
|
|
|
|
|
static int show_trigger_detail( DBB database, TEXT * relation_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ t r i g g e r _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show trigger definitions for a particular
|
|
* relation.
|
|
*
|
|
**************************************/
|
|
USHORT count;
|
|
|
|
if (!(database->dbb_capabilities & DBB_cap_new_triggers))
|
|
return 0;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
count = 0;
|
|
|
|
/* New style triggers */
|
|
|
|
if (database->dbb_capabilities & DBB_cap_new_triggers) {
|
|
ERRQ_msg_put(365, relation_name, NULL, NULL, NULL, NULL); /* Msg365 Triggers for relation %s */
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_new_trigger])
|
|
X IN RDB$TRIGGERS WITH X.RDB$RELATION_NAME EQ relation_name
|
|
AND(X.RDB$SYSTEM_FLAG MISSING OR X.RDB$SYSTEM_FLAG EQ 0)
|
|
SORTED BY X.RDB$TRIGGER_TYPE, X.RDB$TRIGGER_SEQUENCE,
|
|
X.RDB$TRIGGER_NAME
|
|
|
|
if (!X.RDB$TRIGGER_BLR.NULL) {
|
|
show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE,
|
|
X.RDB$TRIGGER_SEQUENCE,
|
|
X.RDB$TRIGGER_INACTIVE,
|
|
(SLONG*) &X.RDB$DESCRIPTION, database,
|
|
relation_name);
|
|
show_blob_info((SLONG*) &X.RDB$TRIGGER_BLR, (SLONG*) &X.RDB$TRIGGER_SOURCE, 377, /* Msg377 Source for the trigger is not available. Trigger BLR: */
|
|
376, /* Msg376 Source for the trigger */
|
|
database, relation_name);
|
|
show_trigger_messages(database, X.RDB$TRIGGER_NAME);
|
|
count++;
|
|
}
|
|
END_FOR;
|
|
return count;
|
|
}
|
|
|
|
/* Old style triggers */
|
|
/* OBSOLETE - 1996-Aug-06 David Schnepper */
|
|
|
|
/* OBSOLETE - Msg298 Triggers for relation %s: */
|
|
/* OBSOLETE - Msg299 Source for the erase trigger is not available. Trigger BLR: */
|
|
/* OBSOLETE - Msg300 Erase trigger for relation %s: */
|
|
/* OBSOLETE - Msg301 Source for the modify trigger is not available. Trigger BLR: */
|
|
/* OBSOLETE - Msg302 Modify trigger for relation %s: */
|
|
/* OBSOLETE - Msg303 Source for the store trigger is not available. Trigger BLR: */
|
|
/* OBSOLETE - Msg304 Store trigger for relation %s: */
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_trigger_header(
|
|
TEXT * name,
|
|
USHORT type,
|
|
USHORT sequence,
|
|
USHORT inactive,
|
|
SLONG * description, DBB database, TEXT * relation_name)
|
|
{
|
|
/*****************************************************
|
|
*
|
|
* s h o w _ t r i g g e r _ h e a d e r
|
|
*
|
|
*****************************************************
|
|
*
|
|
* Functional description
|
|
* Display header information for a new style
|
|
* trigger only.
|
|
*
|
|
*****************************************************/
|
|
|
|
show_trigger_status(name, type, inactive, sequence);
|
|
show_text_blob(database, "\t ", 375, description, 0, (SLONG*) NULL_PTR, TRUE);
|
|
}
|
|
|
|
|
|
static void show_trigger_messages( DBB database, TEXT * name)
|
|
{
|
|
/*****************************************************
|
|
*
|
|
* s h o w _ t r i g g e r _ m e s s a g e s
|
|
*
|
|
*****************************************************
|
|
*
|
|
* Display error messages associated with
|
|
* a new style (V3) trigger
|
|
*
|
|
*****************************************************/
|
|
int first;
|
|
|
|
first = TRUE;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_trig_message])
|
|
M IN RDB$TRIGGER_MESSAGES WITH M.RDB$TRIGGER_NAME = name
|
|
SORTED BY M.RDB$MESSAGE_NUMBER
|
|
|
|
if (first) {
|
|
ERRQ_msg_put(456, name, NULL, NULL, NULL, NULL);
|
|
/* msg 456: Messages associated with %s:\n */
|
|
first = FALSE;
|
|
}
|
|
ERRQ_msg_put(457, (TEXT *) M.RDB$MESSAGE_NUMBER, M.RDB$MESSAGE,
|
|
NULL, NULL, NULL);
|
|
/* msg 457: message %ld: %s\n */
|
|
END_FOR;
|
|
|
|
if (!first)
|
|
ib_printf("\n");
|
|
}
|
|
|
|
|
|
static void show_trigger_status(
|
|
TEXT * name,
|
|
USHORT type, USHORT status, USHORT sequence)
|
|
{
|
|
/*****************************************************
|
|
*
|
|
* s h o w _ t r i g g e r _ s t a t u s
|
|
*
|
|
*****************************************************
|
|
*
|
|
* Display type and active status of a new style (V3) trigger
|
|
*
|
|
*****************************************************/
|
|
SCHAR trigger_type[16], trigger_active[9];
|
|
int msg_num;
|
|
|
|
switch (type) {
|
|
case PRE_STORE:
|
|
msg_num = 367;
|
|
break; /* Msg367 pre-store */
|
|
case POST_STORE:
|
|
msg_num = 368;
|
|
break; /* Msg368 post-store */
|
|
case PRE_MODIFY:
|
|
msg_num = 369;
|
|
break; /* Msg369 pre-modify */
|
|
case POST_MODIFY:
|
|
msg_num = 370;
|
|
break; /* Msg370 post-modify */
|
|
case PRE_ERASE:
|
|
msg_num = 371;
|
|
break; /* Msg371 pre-erase */
|
|
case POST_ERASE:
|
|
msg_num = 372;
|
|
break; /* Msg372 post-erase */
|
|
default:
|
|
msg_num = 372;
|
|
break; /* Should never happen, not worth an error */
|
|
}
|
|
|
|
ERRQ_msg_format(msg_num, sizeof(trigger_type), trigger_type, NULL, NULL,
|
|
NULL, NULL, NULL);
|
|
msg_num = (status) ? 374 : 373;
|
|
ERRQ_msg_format(msg_num, sizeof(trigger_active), trigger_active, NULL,
|
|
NULL, NULL, NULL, NULL);
|
|
|
|
truncate_string(name);
|
|
ERRQ_msg_put(366, name, trigger_type, (TEXT *) (ULONG) sequence,
|
|
trigger_active, NULL); /* Msg366 Name: %s, Type: %s, Sequence: %d, Active: %s */
|
|
}
|
|
|
|
|
|
static void show_trigs( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ t r i g s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Ask META to print all trigger information
|
|
* for a particular database or all databases.
|
|
*
|
|
**************************************/
|
|
|
|
if (database) {
|
|
if (!(show_triggers_detail(database)))
|
|
ERRQ_msg_put(130, database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL); /* Msg130 No triggers are defined in database %s */
|
|
}
|
|
else
|
|
for (database = QLI_databases; database;
|
|
database =
|
|
database->
|
|
dbb_next) if (!(show_triggers_detail(database)))
|
|
ERRQ_msg_put(131, database->dbb_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL); /* Msg131 No triggers are defined in database %s */
|
|
}
|
|
|
|
|
|
static int show_triggers_detail( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ t r i g g e r s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show trigger definitions for a particular
|
|
* database
|
|
*
|
|
**************************************/
|
|
USHORT count;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
count = 0;
|
|
|
|
if (!(database->dbb_capabilities & DBB_cap_new_triggers))
|
|
return count;
|
|
|
|
if (database->dbb_capabilities & DBB_cap_new_triggers) {
|
|
|
|
/* New style triggers */
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_new_triggers])
|
|
X IN RDB$TRIGGERS WITH X.RDB$SYSTEM_FLAG MISSING
|
|
OR X.RDB$SYSTEM_FLAG EQ 0 SORTED BY X.RDB$RELATION_NAME,
|
|
X.RDB$TRIGGER_TYPE, X.RDB$TRIGGER_SEQUENCE, X.RDB$TRIGGER_NAME
|
|
if (!X.RDB$TRIGGER_BLR.NULL) {
|
|
truncate_string(X.RDB$RELATION_NAME);
|
|
ERRQ_msg_put(381, X.RDB$RELATION_NAME, NULL, NULL, NULL, NULL); /* Msg365 Triggers for relation %s */
|
|
show_trigger_header(X.RDB$TRIGGER_NAME, X.RDB$TRIGGER_TYPE,
|
|
X.RDB$TRIGGER_SEQUENCE,
|
|
X.RDB$TRIGGER_INACTIVE,
|
|
(SLONG*) &X.RDB$DESCRIPTION, database,
|
|
X.RDB$RELATION_NAME);
|
|
show_blob_info((SLONG*) &X.RDB$TRIGGER_BLR, (SLONG*) &X.RDB$TRIGGER_SOURCE, 377, /* Msg377 Source for the trigger is not available. Trigger BLR: */
|
|
376, /* Msg376 Source for the trigger */
|
|
database, X.RDB$RELATION_NAME);
|
|
show_trigger_messages(database, X.RDB$TRIGGER_NAME);
|
|
count++;
|
|
}
|
|
END_FOR;
|
|
}
|
|
else {
|
|
|
|
/* Old style triggers */
|
|
/* OBSOLETE - 1996-Aug-06 David Schnepper */
|
|
/* OBSOLETE - Msg305 Triggers for relation %s: */
|
|
|
|
/* OBSOLETE - Msg306 Source for the erase trigger is not available. Trigger BLR: */
|
|
/* OBSOLETE - Msg307 Erase trigger for relation %s: */
|
|
|
|
/* OBSOLETE - Msg308 Source for the modify trigger is not available. Trigger BLR: */
|
|
/* OBSOLETE - Msg309 Modify trigger for relation %s: */
|
|
|
|
/* OBSOLETE - Msg310 Source for the store trigger is not available. Trigger BLR: */
|
|
/* OBSOLETE - Msg311 Store trigger for relation %s: */
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static void show_var( NAM var_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ v a r
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display a global variables.
|
|
*
|
|
**************************************/
|
|
FLD variable;
|
|
|
|
for (variable = QLI_variables; variable; variable = variable->fld_next)
|
|
if (!strcmp(var_name->nam_string, variable->fld_name->sym_string))
|
|
break;
|
|
|
|
if (!variable) {
|
|
ERRQ_msg_put(474, var_name->nam_string, NULL, NULL, NULL, NULL); /* Msg474 Variable %s has not been declared */
|
|
return;
|
|
}
|
|
|
|
ERRQ_msg_put(471, variable->fld_name->sym_string, NULL, NULL, NULL, NULL); /* Msg471 Variable %s */
|
|
ERRQ_msg_put(475, NULL, NULL, NULL, NULL, NULL);
|
|
ib_printf("\t");
|
|
show_datatype(NULL, variable->fld_dtype,
|
|
(variable->fld_dtype ==
|
|
dtype_varying) ? variable->fld_length -
|
|
2 : variable->fld_length, variable->fld_scale,
|
|
variable->fld_sub_type, variable->fld_segment_length,
|
|
(variable->fld_flags & FLD_array) ? 1 : 0);
|
|
ib_printf("\n");
|
|
if (variable->fld_query_name)
|
|
ERRQ_msg_put(472, variable->fld_query_name->sym_string, NULL, NULL,
|
|
NULL, NULL);
|
|
if (variable->fld_edit_string)
|
|
ERRQ_msg_put(473, variable->fld_edit_string, NULL, NULL, NULL, NULL);
|
|
}
|
|
|
|
|
|
static void show_vars(void)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ v a r s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Display global variables. If there aren't any, don't
|
|
* display any.
|
|
*
|
|
**************************************/
|
|
|
|
ERRQ_msg_put(132, NULL, NULL, NULL, NULL, NULL); /* Msg132 Variables: */
|
|
show_fields((REL) NULL_PTR, QLI_variables);
|
|
}
|
|
|
|
|
|
static void show_versions(void)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ v e r s i o n s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show the version for QLI and all databases.
|
|
*
|
|
**************************************/
|
|
DBB dbb;
|
|
|
|
ERRQ_msg_put(133, GDS_VERSION, NULL, NULL, NULL, NULL); /* Msg133 QLI, version %s */
|
|
|
|
for (dbb = QLI_databases; dbb; dbb = dbb->dbb_next) {
|
|
ERRQ_msg_put(134, dbb->dbb_filename, NULL, NULL, NULL, NULL); /* Msg134 Version(s) for database %s */
|
|
gds__version(&dbb->dbb_handle, (FPTR_VOID) NULL_PTR, NULL_PTR);
|
|
}
|
|
}
|
|
|
|
|
|
static void show_view( REL relation)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ v i e w
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Call MET to show the view definition
|
|
* if there is one.
|
|
*
|
|
**************************************/
|
|
DBB database;
|
|
|
|
database = relation->rel_database;
|
|
MET_meta_transaction(database, FALSE);
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_view])
|
|
X IN RDB$RELATIONS WITH X.RDB$RELATION_NAME EQ relation->rel_symbol->
|
|
sym_string AND X.RDB$VIEW_BLR NOT MISSING
|
|
|
|
if (X.RDB$VIEW_SOURCE.NULL) {
|
|
ERRQ_msg_put(312, relation->rel_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL); /* Msg312 View source for relation %s is not available. View BLR: */
|
|
display_blr(database, (SLONG*) &X.RDB$VIEW_BLR);
|
|
}
|
|
else {
|
|
ERRQ_msg_put(313, relation->rel_symbol->sym_string, NULL, NULL,
|
|
NULL, NULL); /* Msg313 Relation %s is a view defined as: */
|
|
show_text_blob(database, "\t", 0, (SLONG*) &X.RDB$VIEW_SOURCE, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
}
|
|
END_FOR;
|
|
}
|
|
|
|
|
|
static int show_views_detail( DBB database)
|
|
{
|
|
/**************************************
|
|
*
|
|
* s h o w _ v i e w s _ d e t a i l
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Show the view definitions. If none, return 0.
|
|
*
|
|
**************************************/
|
|
int count;
|
|
|
|
MET_meta_transaction(database, FALSE);
|
|
count = 0;
|
|
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_views])
|
|
X IN RDB$RELATIONS WITH X.RDB$VIEW_BLR NOT MISSING
|
|
SORTED BY X.RDB$RELATION_NAME
|
|
|
|
if (!count++)
|
|
ERRQ_msg_put(316, database->dbb_symbol->sym_string, NULL, NULL, NULL, NULL); /* Msg316 Views in database %s: */
|
|
|
|
truncate_string(X.RDB$RELATION_NAME);
|
|
ERRQ_msg_put(317, X.RDB$RELATION_NAME, NULL, NULL, NULL, NULL); /* Msg317 %s comprised of: */
|
|
FOR(REQUEST_HANDLE database->dbb_requests[REQ_show_view_rel])
|
|
V IN RDB$VIEW_RELATIONS
|
|
WITH V.RDB$VIEW_NAME = X.RDB$RELATION_NAME
|
|
SORTED BY V.RDB$RELATION_NAME
|
|
ib_printf(" %s\n", V.RDB$RELATION_NAME);
|
|
END_FOR;
|
|
|
|
END_FOR;
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
static int truncate_string( TEXT * string)
|
|
{
|
|
/**************************************
|
|
*
|
|
* t r u n c a t e _ s t r i n g
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Convert a blank filled string to
|
|
* a null terminated string without
|
|
* trailing blanks. Because some
|
|
* strings contain embedded blanks
|
|
* (e.g. query headers & edit strings)
|
|
* truncate from the back forward.
|
|
* Return the number of characters found,
|
|
* not including the terminating null.
|
|
*
|
|
**************************************/
|
|
TEXT *p;
|
|
|
|
for (p = string; *p; p++);
|
|
|
|
while (p > string && p[-1] == ' ')
|
|
--p;
|
|
|
|
*p = 0;
|
|
|
|
return (p - string);
|
|
}
|
|
|
|
|
|
static void view_info(
|
|
DBB dbb,
|
|
TEXT * view,
|
|
TEXT * base_field, SSHORT context, SSHORT level)
|
|
{
|
|
/**************************************
|
|
*
|
|
* v i e w _ i n f o
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
*
|
|
* field came from another relation.
|
|
* expand on this phenomenon.
|
|
*
|
|
**************************************/
|
|
TEXT *rt, spaces[64], *p, *end;
|
|
|
|
FOR(REQUEST_HANDLE dbb->dbb_requests[REQ_show_view_field] LEVEL level)
|
|
RFR IN RDB$RELATION_FIELDS CROSS VR IN RDB$VIEW_RELATIONS
|
|
WITH RFR.RDB$FIELD_NAME = base_field AND
|
|
RFR.RDB$RELATION_NAME = VR.RDB$RELATION_NAME AND
|
|
VR.RDB$VIEW_NAME = view AND
|
|
VR.RDB$VIEW_CONTEXT = context
|
|
truncate_string(RFR.RDB$RELATION_NAME);
|
|
|
|
/* create some space according to how many levels deep we are;
|
|
this is to avoid using %*s in the ib_printf, which doesn't work for OS/2 */
|
|
|
|
for (p = spaces, end =
|
|
spaces + MIN((level + 2) * 4, sizeof(spaces) - 1); p < end;)
|
|
*p++ = ' ';
|
|
*p = '\0';
|
|
|
|
if (RFR.RDB$BASE_FIELD.NULL)
|
|
ERRQ_msg_put(507, spaces, base_field, RFR.RDB$RELATION_NAME, NULL,
|
|
NULL);
|
|
/* Msg507 %s Based on field %s of relation %s */
|
|
else
|
|
ERRQ_msg_put(508, spaces, base_field, RFR.RDB$RELATION_NAME, NULL,
|
|
NULL);
|
|
/* Msg508 %s Based on field %s of view %s */
|
|
show_text_blob(dbb, "\t", 349, (SLONG*) &RFR.RDB$DESCRIPTION, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
|
|
if (!RFR.RDB$DESCRIPTION.NULL) {
|
|
ERRQ_msg_put(349, spaces, base_field, NULL, NULL, NULL); /* Msg349 %sBase field description for %s: */
|
|
show_text_blob(dbb, "\t\t", 0, (SLONG*) &RFR.RDB$DESCRIPTION, 0, (SLONG*) NULL_PTR,
|
|
FALSE);
|
|
}
|
|
|
|
if (!RFR.RDB$BASE_FIELD.NULL
|
|
&& (dbb->dbb_capabilities & DBB_cap_multi_trans)) {
|
|
truncate_string(RFR.RDB$BASE_FIELD);
|
|
view_info(dbb, RFR.RDB$RELATION_NAME, RFR.RDB$BASE_FIELD,
|
|
RFR.RDB$VIEW_CONTEXT, level + 1);
|
|
}
|
|
END_FOR;
|
|
}
|