blob: 9eff6ea83b557a889038043eee3a9228cba5cedc [file] [log] [blame]
/********************************************************************
//
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
********************************************************************/
/* -*-C++-*-
*****************************************************************************
*
* File: SqlciUsage.cpp
* Description: Methods to return table and module usage info.
*
*
* Created: 1/15/2003
* Language: C++
* Status:
*
*
*
*
*****************************************************************************
*/
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#define ACCESS access
#define RW_ACCESS 6
#include <errno.h>
#include "Platform.h"
#include "ComCextdecs.h"
#include "str.h"
#include "NAString.h"
#include "sqlcmd.h"
#include "SqlciError.h"
extern volatile Int32 breakReceived;
Usage::Usage(char * module_dir, char * module, char * table,
NABoolean noe)
: SqlCmd(SqlCmd::USAGE_TYPE, NULL),
moduleDir_(NULL), module_(NULL), table_(NULL),
noe_(noe)
{
if (module_dir)
{
moduleDir_ = new char[strlen(module_dir)+1];
strcpy(moduleDir_, module_dir);
}
else
{
moduleDir_ = new char[strlen("c:/tdm_sqlmodules")+1];
strcpy(moduleDir_, "c:/tdm_sqlmodules");
}
if (module)
{
module_ = new char[strlen(module)+1];
strcpy(module_, module);
}
else
{
module_ = new char[strlen("*") + 1];
strcpy(module_, "*");
}
if (table)
{
table_ = new char[strlen(table)+1];
strcpy(table_, table);
}
else
{
table_ = NULL;
}
}
Usage::~Usage()
{
delete moduleDir_;
delete module_;
delete table_;
}
class ErrorModule
{
public:
ErrorModule(const char * modName, Int32 error);
~ErrorModule();
char * getModName() { return modName_; }
Int32 getError() { return error_;}
private:
char * modName_;
Int32 error_;
};
ErrorModule::ErrorModule(const char * modName, Int32 error)
: error_(error)
{
modName_ = new char[strlen(modName) + 1];
strcpy(modName_, modName);
}
ErrorModule::~ErrorModule()
{
delete modName_;
}
#pragma nowarn(1313) // warning elimination
static const char * moduleUsageQuery[] =
{
" select distinct ",
" case ",
" when operator = 'FILE_SCAN' ",
" then 'Table: ' || substring(description FROM position('scan_type: file_scan ' IN description) + 21 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: file_scan ' IN description) + 21)) ",
" )) ",
" when operator = 'INDEX_SCAN' ",
" then 'Index: ' || substring(description FROM position('scan_type: index_scan ' IN description) + 22 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: index_scan ' IN description) + 22)) ",
" )) ",
" when operator = 'FILE_SCAN_UNIQUE' ",
" then 'Table: ' || substring(description FROM position('scan_type: file_scan_unique ' IN description) + 28 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: file_scan_unique ' IN description) + 28)) ",
" )) ",
" when operator = 'INDEX_SCAN_UNIQUE' ",
" then 'Index: ' || substring(description FROM position('scan_type: index_scan_unique ' IN description) + 29 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: index_scan_unique ' IN description) + 29)) ",
" )) ",
" when operator = 'UNIQUE_UPDATE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then 'Index: ' || substring(description from position('iud_type: index_unique_update ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_unique_update ' IN description) + 30)))) ",
" else 'Table: ' || substring(description from position('iud_type: unique_update ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: unique_update ' IN description) + 24)))) ",
" end ",
" when operator = 'CURSOR_UPDATE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then 'Index: ' || substring(description from position('iud_type: index_cursor_update ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_cursor_update ' IN description) + 30)))) ",
" else 'Table: ' || substring(description from position('iud_type: cursor_update ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: cursor_update ' IN description) + 24)))) ",
" end ",
" when operator = 'SUBSET_UPDATE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then 'Index: ' || substring(description from position('iud_type: index_subset_update ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_subset_update ' IN description) + 30)))) ",
" else 'Table: ' || substring(description from position('iud_type: subset_update ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: subset_update ' IN description) + 24)))) ",
" end ",
" when operator = 'UNIQUE_DELETE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then 'Index: ' || substring(description from position('iud_type: index_unique_delete ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_unique_delete ' IN description) + 30)))) ",
" else 'Table: ' || substring(description from position('iud_type: unique_delete ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: unique_delete ' IN description) + 24)))) ",
" end ",
" when operator = 'CURSOR_DELETE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then 'Index: ' || substring(description from position('iud_type: index_cursor_delete ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_cursor_delete ' IN description) + 30)))) ",
" else 'Table: ' || substring(description from position('iud_type: cursor_delete ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: cursor_delete ' IN description) + 24)))) ",
" end ",
" when operator = 'SUBSET_DELETE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then 'Index: ' || substring(description from position('iud_type: index_subset_delete ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_subset_delete ' IN description) + 30)))) ",
" else 'Table: ' || substring(description from position('iud_type: subset_delete ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: subset_delete ' IN description) + 24)))) ",
" end ",
" when operator = 'INSERT' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then 'Index: ' || substring(description from position('iud_type: index_insert ' IN description) + 23 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_insert ' IN description) + 23)))) ",
" else 'Table: ' || substring(description from position('iud_type: insert ' IN description) + 17 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: insert ' IN description) + 17)))) ",
" end ",
" end ",
" from table(explain('%s', '%%')) ",
" where operator in ('FILE_SCAN', 'FILE_SCAN_UNIQUE', ",
" 'INDEX_SCAN', 'INDEX_SCAN_UNIQUE', ",
" 'UNIQUE_UPDATE', 'CURSOR_UPDATE', 'SUBSET_UPDATE', ",
" 'UNIQUE_DELETE', 'CURSOR_DELETE', 'SUBSET_DELETE', ",
" 'INSERT') ",
" order by 1;"
};
static const char * tableUsageQuery[] =
{
" select [first 1] operator ",
" from table(explain('%s', '%%')) ",
" where ",
" ( ",
" operator in ('INDEX_SCAN', 'INDEX_SCAN_UNIQUE') ",
" and ",
" ( ",
" case ",
" when operator = 'INDEX_SCAN' ",
" then substring(description FROM position('scan_type: index_scan ' IN description) + 22 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: index_scan ' IN description) + 22)) ",
" )) ",
" when operator = 'INDEX_SCAN_UNIQUE' ",
" then substring(description FROM position('scan_type: index_scan_unique ' IN description) + 29 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: index_scan_unique ' IN description) + 29)) ",
" )) ",
" end ",
" LIKE '%s(%%' ",
" or ",
" case ",
" when operator = 'INDEX_SCAN' ",
" then substring(description FROM position('scan_type: index_scan ' IN description) + 22 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: index_scan ' IN description) + 22)) ",
" )) ",
" when operator = 'INDEX_SCAN_UNIQUE' ",
" then substring(description FROM position('scan_type: index_scan_unique ' IN description) + 29 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: index_scan_unique ' IN description) + 29)) ",
" )) ",
" end ",
" LIKE '%%(%s)%%' ",
" ) ",
" ) ",
" or ",
" ( ",
" operator in ('FILE_SCAN', 'FILE_SCAN_UNIQUE', ",
" 'UNIQUE_UPDATE', 'CURSOR_UPDATE', 'SUBSET_UPDATE', ",
" 'UNIQUE_DELETE', 'CURSOR_DELETE', 'SUBSET_DELETE', ",
" 'INSERT') ",
" and ",
" case ",
" when operator = 'FILE_SCAN' ",
" then substring(description FROM position('scan_type: file_scan ' IN description) + 21 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: file_scan ' IN description) + 21)) ",
" )) ",
" when operator = 'FILE_SCAN_UNIQUE' ",
" then substring(description FROM position('scan_type: file_scan_unique ' IN description) + 28 ",
" FOR (position(' ' IN substring(description FROM position('scan_type: file_scan_unique ' IN description) + 28)) ",
" )) ",
" when operator = 'UNIQUE_UPDATE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then substring(description from position('iud_type: index_unique_update ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_unique_update ' IN description) + 30)))) ",
" else substring(description from position('iud_type: unique_update ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: unique_update ' IN description) + 24)))) ",
" end ",
" when operator = 'CURSOR_UPDATE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then substring(description from position('iud_type: index_cursor_update ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_cursor_update ' IN description) + 30)))) ",
" else substring(description from position('iud_type: cursor_update ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: cursor_update ' IN description) + 24)))) ",
" end ",
" when operator = 'SUBSET_UPDATE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then substring(description from position('iud_type: index_subset_update ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_subset_update ' IN description) + 30)))) ",
" else substring(description from position('iud_type: subset_update ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: subset_update ' IN description) + 24)))) ",
" end ",
" when operator = 'UNIQUE_DELETE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then substring(description from position('iud_type: index_unique_delete ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_unique_delete ' IN description) + 30)))) ",
" else substring(description from position('iud_type: unique_delete ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: unique_delete ' IN description) + 24)))) ",
" end ",
" when operator = 'CURSOR_DELETE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then substring(description from position('iud_type: index_cursor_delete ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_cursor_delete ' IN description) + 30)))) ",
" else substring(description from position('iud_type: cursor_delete ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: cursor_delete ' IN description) + 24)))) ",
" end ",
" when operator = 'SUBSET_DELETE' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then substring(description from position('iud_type: index_subset_delete ' IN description) + 30 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_subset_delete ' IN description) + 30)))) ",
" else substring(description from position('iud_type: subset_delete ' IN description) + 24 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: subset_delete ' IN description) + 24)))) ",
" end ",
" when operator = 'INSERT' ",
" then ",
" case ",
" when position('iud_type: index_' IN description) > 0 ",
" then substring(description from position('iud_type: index_insert ' IN description) + 23 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: index_insert ' IN description) + 23)))) ",
" else substring(description from position('iud_type: insert ' IN description) + 17 ",
" FOR (position(' ' IN substring(description FROM position('iud_type: insert ' IN description) + 17)))) ",
" end ",
" end ",
" = '%s' ",
" ) ",
" ;"
};
#pragma warn(1313) // warning elimination
short Usage::process(SqlciEnv * sqlci_env)
{
short retcode = 0;
Lng32 error = 0;
NAString cmd;
// a temporary file where the modules will be listed.
// The filename will be of the form: __mxci_usage__<juliantimestamp>
// This temp file will be created in /tmp, if it exists. If not, then
// it will be created in moduleDir_. If it cannot be written and read
// in one of these two dirs, an error will be returned.
NAString tempFile;
// check for RW access in /tmp dir.
tempFile = "/tmp";
Int32 rc = ACCESS(tempFile, RW_ACCESS);
if (rc == -1)
{
// now try module dir
tempFile = moduleDir_;
rc = ACCESS(tempFile, RW_ACCESS);
ErrorParam ep_tmp("/tmp");
ErrorParam ep_md(tempFile);
if (rc == -1)
{
SqlciError (2087,
&ep_tmp,
(ErrorParam *) 0
);
SqlciError (2087,
&ep_md,
(ErrorParam *) 0
);
return 0;
}
}
Int64 ts = NA_JulianTimestamp();
char tsBuf[100];
convertInt64ToAscii(ts, tsBuf);
// tempFile = NAString(moduleDir_) + "/" + "__mxci_usage__" + tsBuf;
tempFile = tempFile + "/" + "__mxci_usage__" + tsBuf;
// remove the temporary file, if it exists
cmd = "rm -f " + tempFile;
system(cmd);
// insert a backslash in front of any '$', single or double quote.
// We are not handling any quoted double/single quotes.
char * tempModule = new char[strlen(module_) * 2 + 1];
UInt32 i = 0;
Int32 j = 0;
while (i < strlen(module_))
{
if ((module_[i] == '"') ||
(module_[i] == '\'') ||
(module_[i] == '$'))
{
tempModule[j++] = '\\';
}
tempModule[j++] = module_[i++];
}
tempModule[j] = 0;
// 'ls' the modules.
NAString module(tempModule);
NAString modDir;
NABoolean modDirContainsWildcard = FALSE;
{
modDir = moduleDir_;
if (modDir.contains('*'))
modDirContainsWildcard = TRUE;
}
if ((module == "*") || (module == "*.*") || (module == "*.*.*"))
{
if (modDirContainsWildcard)
cmd = "find " + modDir + " -type f > " + tempFile;
else
cmd = "ls " + modDir + " > " + tempFile;
}
else
{
if (modDirContainsWildcard)
cmd = "find " + modDir + " -type f -name \"" + module + "\" > " + tempFile;
else
cmd = "ls " + modDir + "/" + module + " > " + tempFile;
}
system(cmd);
// read each module name from the temp file and process it.
FILE * file_stream = fopen(tempFile, "r");
if (! file_stream)
{
SqlciError (SQLCI_OBEY_FOPEN_ERROR,
new ErrorParam (errno),
new ErrorParam (tempFile),
(ErrorParam *) 0
);
return 0;
}
char buf[2000];
char * ok;
char outBuf[200];
Logfile *log = sqlci_env->get_logfile();
SqlciList<ErrorModule> * errModList = new SqlciList<ErrorModule>;
Int32 maxModNameLen = 0;
NABoolean displayObjectName = TRUE;
NABoolean done = FALSE;
NABoolean usageInfoFound = FALSE;
while (NOT done)
{
ok = fgets(buf, 2000, file_stream);
if (feof(file_stream))
{
done = TRUE;
continue;
}
if (! ok)
{
SqlciError (SQLCI_OBEY_FOPEN_ERROR,
new ErrorParam (errno),
new ErrorParam (tempFile),
(ErrorParam *) 0
);
delete errModList;
return 0;
}
// nuke the EOL character.
buf[strlen(buf)-1]=0;
//soln:10-050829-0917
NAString modName;
// if module parameter is omitted, then the names are displayed with
// "ls <dir>" command. This command will NOT prepend the dir name.
// So no need to skip the dirname out of the name returned in 'buf'.
if ((module == '*') || (module == "*.*") || (module == "*.*.*") ||
(modDirContainsWildcard))
modName = buf;
else
modName = &buf[strlen(moduleDir_) + 1];
// do not read files of length 0 or any file which starts with
// "__mxci_usage__". The latter are internal temp files.
if ((strlen(buf) <= 0) ||
(strncmp(modName.data(), "__mxci_usage__", strlen("__mxci_usage__") == 0)))
continue;
//soln:10-050829-0917 Begin
// if the modName is not a 3-part name, skip this file. It is
// not a module name.
size_t pos = 0;
Int32 noOfDots = 0;
while (pos != NA_NPOS)
{
pos = modName.index(".", pos);
if (pos != NA_NPOS)
{
noOfDots++;
pos++;
}
}
if (noOfDots != 2)
continue;
// create a new context in which the embedded statement will be
// loaded and DUO'ed from.
SQLCTX_HANDLE ctxtHandle;
error = SQL_EXEC_CreateContext(&ctxtHandle,
NULL, // char *sqlAuthId
0 // Int32 suppressAutoXact
);
if (error)
{
HandleCLIError(error, sqlci_env);
return 0;
}
SQLCTX_HANDLE prevCtxtHandle;
error = SQL_EXEC_SwitchContext(ctxtHandle, &prevCtxtHandle);
if (error)
{
HandleCLIError(error, sqlci_env);
return 0;
}
//soln:10-050829-0917 End
Int32 usage_query_size = 0;
Int32 usage_qry_array_size = 0;
if (table_)
usage_qry_array_size =
sizeof(tableUsageQuery) / sizeof(char*);
else
usage_qry_array_size =
sizeof(moduleUsageQuery) / sizeof(char*);
const char ** usageQuery = NULL;
if (table_)
usageQuery = tableUsageQuery;
else
usageQuery = moduleUsageQuery;
Int32 i = 0;
for (i = 0; i < usage_qry_array_size; i++)
{
Int32 j = 0;
const char * usage_frag = usageQuery[i];
#pragma warning (disable : 4018) //warning elimination
while ((j < strlen(usageQuery[i])) &&
(usage_frag[j] == ' '))
j++;
if (j < strlen(usageQuery[i]))
usage_query_size += strlen(&usage_frag[j]);
#pragma warning (default : 4018) //warning elimination
}
char * source_fmt = new char[usage_query_size + 100];
source_fmt[0] = 0;
for (i = 0; i < usage_qry_array_size; i++)
{
Int32 j = 0;
const char * usage_frag = usageQuery[i];
#pragma warning (disable : 4018) //warning elimination
while ((j < strlen(usageQuery[i])) &&
(usage_frag[j] == ' '))
j++;
if (j < strlen(usageQuery[i]))
strcat(source_fmt, &usage_frag[j]);
#pragma warning (default : 4018) //warning elimination
}
char * sqlStrBuf = NULL;
NAString fullyQualifiedModName;
if (modDirContainsWildcard)
fullyQualifiedModName = modName;
else
fullyQualifiedModName = modName;
if (table_)
sqlStrBuf = new char[usage_query_size + strlen(fullyQualifiedModName.data()) + 3 * strlen(table_) + 50];
else
sqlStrBuf = new char[usage_query_size + strlen(fullyQualifiedModName.data()) + 50];
if (table_)
sprintf(sqlStrBuf, source_fmt, fullyQualifiedModName.data(), table_, table_, table_);
else
sprintf(sqlStrBuf, source_fmt, fullyQualifiedModName.data());
SqlCmd sqlCmd(SqlCmd::DML_TYPE, sqlStrBuf);
PrepStmt * prepStmt = new PrepStmt("__MXCI_USAGE__");
sqlCmd.clearCLIDiagnostics();
retcode = sqlCmd.do_prepare(sqlci_env, prepStmt, get_sql_stmt(),
FALSE);
Logfile *log = sqlci_env->get_logfile();
Int32 numParams = 0;
char * paramArray[10];
retcode = sqlCmd.doExec(sqlci_env,
prepStmt->getStmt(),
prepStmt,
numParams,
paramArray,
NULL,
FALSE);
if (retcode < 0)
{
if ((retcode == -8834) ||
(retcode == -8808) ||
(retcode == -8809) ||
((retcode <= -8860) &&
(retcode >= -8866)))
{
ErrorModule * em = new ErrorModule(modName.data(), retcode);
errModList->append(em);
#pragma warning (disable : 4018) //warning elimination
if (strlen(modName.data()) > maxModNameLen)
#pragma nowarn(1506) // warning elimination
maxModNameLen = strlen(modName.data());
#pragma warn(1506) // warning elimination
#pragma warning (default : 4018) //warning elimination
}
else
{
error = retcode;
HandleCLIError(error, sqlci_env);
SqlciError (15992, (ErrorParam *) 0);
}
}
// retcode = SQL_Success;
NABoolean displayModuleName = TRUE;
NABoolean firstTime = TRUE;
while ((retcode >= 0) &&
(retcode != SQL_Eof))
{
retcode = sqlCmd.doFetch(sqlci_env,
prepStmt->getStmt(),
prepStmt,
FALSE);
if (retcode < 0)
{
if ((retcode == -8834) ||
(retcode == -8808) ||
(retcode == -8809) ||
((retcode <= -8860) &&
(retcode >= -8866)))
{
ErrorModule * em = new ErrorModule(modName.data(), retcode);
errModList->append(em);
#pragma warning (disable : 4018) //warning elimination
if (strlen(modName.data()) > maxModNameLen)
#pragma nowarn(1506) // warning elimination
maxModNameLen = strlen(modName.data());
#pragma warn(1506) // warning elimination
#pragma warning (default : 4018) //warning elimination
}
else
{
error = retcode;
HandleCLIError(error, sqlci_env);
SqlciError (15992, (ErrorParam *) 0);
}
}
else if ((firstTime) &&
(retcode == SQL_Eof))
{
//SqlciError (-15992, (ErrorParam *) 0);
}
firstTime = FALSE;
if ((retcode != SQL_Eof) &&
(retcode >= 0))
{
usageInfoFound = TRUE;
if (table_)
{
if (displayObjectName)
{
displayObjectName = FALSE;
sprintf(outBuf, "\n \nObject: %s\n", table_);
log->WriteAll(outBuf);
}
sqlCmd.displayRow(sqlci_env, prepStmt);
NAString oper(prepStmt->outputBuf());
oper = oper.strip();
char format[100];
if ((oper == "FILE_SCAN") ||
(oper == "FILE_SCAN_UNIQUE"))
{
sprintf(format, " Table: %%-" PFSZ "s Module: %%s", strlen(table_));
sprintf(outBuf, format, table_, modName.data());
}
else if ((oper == "INDEX_SCAN") ||
(oper == "INDEX_SCAN_UNIQUE"))
{
sprintf(format, " Index: %%-" PFSZ "s Module: %%s", strlen(table_));
sprintf(outBuf, format, table_, modName.data());
}
else
{
sprintf(format, " Object: %%-" PFSZ "s Module: %%s", strlen(table_));
sprintf(outBuf, format, table_, modName.data());
}
log->WriteAll(outBuf);
}
else
{
if (displayModuleName)
{
displayModuleName = FALSE;
sprintf(outBuf, "\n \nModule: %s\n", modName.data());
log->WriteAll(outBuf);
}
sqlCmd.displayRow(sqlci_env, prepStmt);
NAString inTableName(prepStmt->outputBuf());
NAString outTableName;
size_t start = 0;
size_t end = 0;
if (inTableName.index("Table: ", 0) == 0)
{
start = inTableName.index(" ");
outTableName = inTableName(start+1, inTableName.length() - start -1);
end = outTableName.index(" ");
outTableName = outTableName(0, end);
outTableName = " Table: " + outTableName;
}
else if (inTableName.index("Index: ") == 0)
{
start = inTableName.index(" ");
outTableName = inTableName(start+1, inTableName.length() - start -1);
end = outTableName.index(")");
if (end != NA_NPOS)
{
outTableName = outTableName(0, end+1);
}
else
{
size_t lParen = outTableName.index("(");
end = outTableName.index(" ");
outTableName = outTableName(0, end);
if (lParen != NA_NPOS)
outTableName += ")";
}
outTableName = " Index: " + outTableName;
}
else
{
outTableName = " Object: " + inTableName;
}
log->WriteAll(outTableName.data());
} // else
}
} // while (retcode >= 0)
if (retcode >= 0)
retcode = (short)SQL_EXEC_CloseStmt(prepStmt->getStmt());
if (prepStmt)
sqlCmd.deallocate(sqlci_env, prepStmt);
delete sqlStrBuf;
if (breakReceived)
done = TRUE;
// switch back to original context.
error = SQL_EXEC_SwitchContext(prevCtxtHandle, NULL);
if (error < 0)
{
HandleCLIError(error, sqlci_env);
}
// and drop the new context that was created
error = SQL_EXEC_DropContext(ctxtHandle);
if (error < 0)
{
HandleCLIError(error, sqlci_env);
}
} // while (NOT done)
if ((retcode >= 0) &&
(NOT usageInfoFound))
SqlciError (-15992, (ErrorParam *) 0); // issue a warning.
// print out the modules which got errors
ErrorModule * em = errModList->getFirst();
if (em)
{
sprintf(outBuf, "\n\nModules not loaded:\n");
log->WriteAll(outBuf);
}
char format[100];
sprintf(format, " Module: %%-%ds Error: %%d", maxModNameLen);
while (em)
{
sprintf(outBuf, format, em->getModName(), em->getError());
log->WriteAll(outBuf);
em = errModList->getNext();
}
log->WriteAll("");
fclose(file_stream);
// remove the temporary file
cmd = "rm -f " + tempFile;
system(cmd);
delete errModList;
return 0;
}