@@ -0,0 +1,1683 @@
+///////////////////////////////////////////////////////////////////////////////
+//
+// CegoClient.cc
+// -------------
+// Cego client program
+//
+// Design and Implementation by Bjoern Lemke
+//
+// (C)opyright 2000-2012 Bjoern Lemke
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+//
+// IMPLEMENTATION MODULE
+//
+// Class: main
+//
+// Description:
+//
+// Status: QG-2.6
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include <locale.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include <lfc/Chain.h>
+#include <lfc/Exception.h>
+#include <lfc/GetLongOpt.h>
+#include <lfc/File.h>
+#include <lfc/Timer.h>
+#include <lfc/Tokenizer.h>
+#include <lfc/Net.h>
+#include <lfc/SigHandler.h>
+#include <lfc/Tokenizer.h>
+
+#include <lfc/Element.h>
+#include <lfc/Document.h>
+#include <lfc/XMLSuite.h>
+
+#include "CegoOutput.h"
+#include "CegoViewObject.h"
+#include "CegoProcObject.h"
+#include "CegoKeyObject.h"
+#include "CegoDbHandler.h"
+#include "CegoModule.h"
+#include "CegoNet.h"
+#include "CegoXMLdef.h"
+
+#include "CegoDefs.h"
+
+
+#define USAGE "Usage: cgclt --user=<user>/<password>\n\
+ [ --server=<host>]\n\
+ [ --port=<port> ]\n\
+ [ --protocol={serial|xml} ]\n\
+ [ --tableset=<tableset> ]\n\
+ [ --batchfile=<batchfile> ]\n\
+ [ --dumpfile=<dumpfile> ]\n\
+ [ --structure ]\n\
+ [ --cmd=<command> ]\n\
+ [ --logfile=<logfile> ]\n\
+ [ --raw ]\n\
+ [ --ignore ]\n\
+ [ --profile=<pid> ]\n\
+ [ --debug ] [ --version ] [ --help ]"
+
+
+#define DEFAULTPORT 2200
+#define DEFAULTSERVER "localhost"
+#define DEFAULTPROTOCOL "xml"
+
+#define HISTFILE ".cgclt_history"
+#define PROMPT "CGCLT > "
+#define PROMPT2 "> "
+
+#define CGPROFILE ".cgprofile"
+
+#define LANGUAGE_ENV "LANG"
+#define LOCALE_CATEGORY LC_TIME
+
+#define MAXCMDLEN 5000
+
+enum RunMode { INTERACTIVE, BATCH, COMMAND, DUMP };
+
+extern char __lfcVersionString[];
+extern char __lfcxmlVersionString[];
+extern char __quoteEscapeFlag;
+
+bool flowCtl = false;
+int flowCount = 10;
+
+class AbortHandler : public SigHandler
+{
+
+public:
+
+ AbortHandler(const Chain& serverName,
+ int portNo,
+ const Chain& tableSet,
+ const Chain& user,
+ const Chain& password,
+ long tid,
+ CegoModule *pModule);
+ ~AbortHandler();
+ void sigCatch(int sig);
+
+ void setQueryAbort(bool doAbort);
+
+private:
+
+ long _tid;
+ bool _doAbort;
+ CegoModule *_pModule;
+ int _portNo;
+ Chain _serverName;
+ Chain _user;
+ Chain _password;
+ Chain _tableSet;
+};
+
+class ProfileEntry
+{
+
+public:
+
+ ProfileEntry();
+ ProfileEntry(const Chain& pid);
+ ProfileEntry(const Chain& pid,
+ const Chain& serverName,
+ int portNo,
+ const Chain& protocol,
+ const Chain& tableSet,
+ const Chain& auth,
+ const Chain& prompt);
+ ~ProfileEntry();
+
+ const Chain& getId() const;
+ const Chain& getServerName() const;
+ int getPortNo() const;
+ const Chain& getProtocol() const;
+ const Chain& getTableSet() const;
+ const Chain& getAuth() const;
+ const Chain& getPrompt() const;
+
+ ProfileEntry& operator = ( const ProfileEntry& ad);
+ bool operator == ( const ProfileEntry& ad);
+
+private:
+
+ Chain _pid;
+ int _portNo;
+ Chain _serverName;
+ Chain _protocol;
+ Chain _tableSet;
+ Chain _auth;
+ Chain _prompt;
+};
+
+int execute();
+bool dispatchCmd(CegoDbHandler* pNetHandle, AbortHandler* pAH, Chain cmd, bool outMode, int& exitCode, Chain& msg);
+void loadProfile(const Chain& rcFileName, ListT<ProfileEntry>& pfeList);
+void dumpTableSet(CegoNet *pCegoNet, const Chain& dumpFileName, bool isStructure);
+void dumpCounter(CegoNet *pCegoNet, File *pDF);
+void dumpTable(CegoNet *pCegoNet, File *pDF, bool isStructure);
+void dumpIndex(CegoNet *pCegoNet, File *pDF);
+void dumpKey(CegoNet *pCegoNet, File *pDF);
+void dumpCheck(CegoNet *pCegoNet, File *pDF);
+void dumpView(CegoNet *pCegoNet, File *pDF);
+void dumpProcedure(CegoNet *pCegoNet, File *pDF);
+
+Chain user;
+Chain password;
+Chain serverName;
+Chain tableSet;
+int portNo;
+Chain authString;
+Chain promptString;
+bool rawMode = false;
+bool ignoreError = false;
+bool isStructure = false;
+Chain batchFileName;
+Chain dumpFileName;
+Chain command;
+Chain logFile;
+RunMode runMode = INTERACTIVE;
+bool debug=false;
+CegoModule *pModule = 0;
+unsigned long modId;
+Chain homeDir;
+Chain histPath;
+CegoDbHandler::ProtocolType protType;
+
+int main(int argc, char **argv)
+{
+
+ GetLongOpt longOpt(argc, argv);
+
+ longOpt.addOpt("version");
+ longOpt.addOpt("help");
+ longOpt.addOpt("logfile");
+ longOpt.addOpt("tableset");
+ longOpt.addOpt("user");
+ longOpt.addOpt("cmd");
+ longOpt.addOpt("batchfile");
+ longOpt.addOpt("dumpfile");
+ longOpt.addOpt("structure");
+ longOpt.addOpt("qescmode");
+ longOpt.addOpt("debug");
+ longOpt.addOpt("raw");
+ longOpt.addOpt("ignore");
+ longOpt.addOpt("server", DEFAULTSERVER);
+ longOpt.addOpt("protocol", DEFAULTPROTOCOL);
+ longOpt.addOpt("port", Chain(DEFAULTPORT));
+ longOpt.addOpt("profile");
+
+ try
+ {
+ longOpt.parseOpt();
+ }
+ catch ( Exception e )
+ {
+ Chain msg;
+ e.pop(msg);
+ cerr << msg << endl;
+ cerr << USAGE << endl;
+ exit(1);
+ }
+
+
+#ifdef HAVE_MINGW32
+ homeDir = getenv("HOMEPATH");
+ histPath = homeDir + "\\" + Chain(HISTFILE);
+#else
+ Chain homeDir(getenv("HOME"));
+ Chain histPath = homeDir + "/" + Chain(HISTFILE);
+#endif
+
+ if ( longOpt.isSet("debug") )
+ debug=true;
+
+ if ( longOpt.isSet("qescmode") )
+ __quoteEscapeFlag=1;
+ else
+ __quoteEscapeFlag=0;
+
+
+ if ( longOpt.isSet("raw") )
+ rawMode=true;
+
+ if ( longOpt.isSet("ignore") )
+ ignoreError=true;
+
+
+ if ( longOpt.isSet("structure") )
+ isStructure=true;
+
+ if ( longOpt.isSet( Chain("help") ) )
+ {
+ cerr << USAGE << endl;
+ exit(0);
+ }
+
+ if ( longOpt.isSet( Chain("version") ) )
+ {
+ cout << CEGO_PRODUCT << " (" << sizeof(long) * 8 << " bit), Version " << CEGO_VERSION
+ << " [ lfc : " << __lfcVersionString
+ << ", lfcxml : " << __lfcxmlVersionString << " ]" << endl;
+ cout << CEGO_COPYRIGHT << endl;
+ exit(0);
+ }
+
+
+ ListT<ProfileEntry> pfeList;
+
+ try
+ {
+ loadProfile(homeDir + "/" + Chain(CGPROFILE), pfeList);
+ }
+ catch ( Exception e )
+ {
+ Chain msg;
+ e.pop(msg);
+ cerr << msg << endl;
+ exit(1);
+ }
+
+ logFile = longOpt.getOptValue("logfile");
+
+ if ( longOpt.isSet("batchfile") )
+ {
+ runMode = BATCH;
+ batchFileName = longOpt.getOptValue("batchfile");
+ }
+ if ( longOpt.isSet("dumpfile") )
+ {
+ runMode = DUMP;
+ dumpFileName = longOpt.getOptValue("dumpfile");
+ }
+ else if ( longOpt.isSet("cmd") )
+ {
+ runMode = COMMAND;
+ command = longOpt.getOptValue("cmd");
+ }
+
+
+ if ( longOpt.isSet("profile") )
+ {
+ Chain profile;
+ profile = longOpt.getOptValue("profile");
+
+ ProfileEntry *pE;
+ if ( ( pE = pfeList.Find( ProfileEntry(profile))) != 0 )
+ {
+ serverName = pE->getServerName();
+ tableSet = pE->getTableSet();
+ portNo = pE->getPortNo();
+ authString = pE->getAuth();
+ promptString = pE->getPrompt();
+ }
+ else
+ {
+ cerr << "Profile entry " << profile << " not found" << endl;
+ exit(1);
+ }
+ }
+ else
+ {
+ serverName = longOpt.getOptValue("server");
+ tableSet = longOpt.getOptValue("tableset");
+ portNo = longOpt.getOptValue("port").asInteger();
+ authString = longOpt.getOptValue("user");
+ promptString = Chain(PROMPT);
+ }
+
+ Tokenizer authTok(authString, Chain("/"));
+ authTok.nextToken(user);
+ authTok.nextToken(password);
+
+ if ( user.length() == 0 )
+ {
+ cerr << "User not set" << endl;
+ exit (1);
+ }
+ if ( password.length() == 0 )
+ {
+ cerr << "Password not set" << endl;
+ exit (1);
+ }
+ if ( tableSet.length() == 0 )
+ {
+ cerr << "Tableset not set" << endl;
+ exit (1);
+ }
+
+ Chain prot = longOpt.getOptValue("protocol");
+
+ if ( prot == Chain("serial") )
+ {
+ protType = CegoDbHandler::SERIAL;
+ }
+ else if ( prot == Chain("xml") )
+ {
+ protType = CegoDbHandler::XML;
+ }
+ else
+ {
+ cerr << "Invalid protocol " << prot;
+ exit (1);
+ }
+
+ // for localization
+ char* lang = 0;
+ if ( ( lang = getenv(LANGUAGE_ENV) ) != 0)
+ {
+ if ( setlocale(LOCALE_CATEGORY, lang) == 0)
+ {
+ Chain msg = Chain("Cannot set locale ") + Chain(lang);
+ cerr << msg << endl;
+ exit(1);
+ }
+ }
+
+ if ( logFile.length() > 0 )
+ pModule = new CegoModule(logFile);
+ else
+ pModule = new CegoModule;
+
+
+ modId = pModule->getModId("CegoClient");
+
+ if ( debug )
+ {
+ pModule->logModule(modId, "CegoClient", Logger::DEBUG);
+ unsigned long id = pModule->getModId("CegoDbHandler");
+ pModule->logModule(id, "CegoDbHandler", Logger::DEBUG);
+ }
+ else
+ {
+ pModule->logModule(modId, "CegoClient", Logger::NOTICE);
+ unsigned long id = pModule->getModId("CegoDbHandler");
+ pModule->logModule(id, "CegoDbHandler", Logger::NOTICE);
+ }
+
+ int exitCode = execute();
+
+ delete pModule;
+ exit(exitCode);
+}
+
+int execute()
+{
+ int exitCode = 0;
+
+ switch ( runMode )
+ {
+
+ case COMMAND:
+ {
+
+ Net n ( NETMNG_MSG_BUFLEN, NETMNG_SIZEBUFLEN );
+ NetHandler* pN;
+
+ try
+ {
+ pN = n.connect(serverName, portNo);
+ }
+ catch ( Exception e )
+ {
+ cerr << "Cannot connect to database" << endl;
+ return 1;
+ }
+
+ CegoDbHandler* pSH = new CegoDbHandler(pN, protType, pModule);
+
+ CegoDbHandler::ResultType res = pSH->requestSession(tableSet, user, password);
+ if ( res != CegoDbHandler::DB_OK )
+ {
+ Chain msg = pSH->getMsg();
+ delete pSH;
+ cerr << msg << endl;
+ return 1;
+ }
+
+ Chain msg;
+ dispatchCmd(pSH, 0, command, rawMode, exitCode, msg);
+
+ pSH->closeSession();
+
+ delete pSH;
+ delete pN;
+
+ break;
+
+ }
+ case BATCH:
+ {
+ int lineNo=0;
+
+ Net n ( NETMNG_MSG_BUFLEN, NETMNG_SIZEBUFLEN );
+ NetHandler* pN;
+
+ try
+ {
+ pN = n.connect(serverName, portNo);
+ }
+ catch ( Exception e )
+ {
+ cerr << "Cannot connect to database" << endl;
+ return 1;
+ }
+
+ CegoDbHandler* pSH = new CegoDbHandler(pN, protType, pModule);
+
+ CegoDbHandler::ResultType res = pSH->requestSession(tableSet, user, password);
+ if ( res != CegoDbHandler::DB_OK )
+ {
+ Chain msg = pSH->getMsg();
+ delete pSH;
+ cerr << msg << endl;
+ return 1;
+ }
+
+ File cmdFile(batchFileName);
+ if ( cmdFile.exists() == false )
+ {
+ cerr << "File " << batchFileName << " does not exist" << endl;
+ return 1;
+ }
+
+ try
+ {
+ cmdFile.open(File::READ);
+ }
+ catch ( Exception e)
+ {
+ cout << "Cannot open batchfile " + batchFileName << endl;
+ return 1;
+ }
+
+ try
+ {
+
+ Chain cmd;
+ Chain line;
+ bool disableDelimiter=false;
+ bool goOn = true;
+
+ while (goOn && cmdFile.readLine(line, MAXCMDLEN))
+ {
+ lineNo++;
+ line = line.cutTrailing(" \t");
+
+ bool isCommentLine = false;
+
+ if ( line.length() >= 2 )
+ {
+ if (line.cutTrailing(" \t").subChain(1, 2) == Chain("--"))
+ {
+ isCommentLine = true;
+ }
+ }
+
+ if ( ! isCommentLine )
+ {
+
+ if ( line == Chain("@") )
+ {
+ if ( disableDelimiter == false )
+ disableDelimiter=true;
+ else
+ disableDelimiter=false;
+ }
+ else
+ {
+ // cmd = line;
+ cmd = cmd + Chain(" ") + line;
+ cmd = cmd.cutTrailing(" \t");
+ }
+
+ if ( cmd.length() > 0 )
+ {
+
+ if (cmd.subChain(cmd.length()-1, cmd.length()) == Chain(";")
+ && disableDelimiter==false)
+ {
+
+ // send command to server here
+
+ Timer t(6,3);
+ t.start();
+
+ Chain msg;
+ goOn = dispatchCmd(pSH, 0, cmd, rawMode, exitCode, msg);
+
+ t.stop();
+
+ if ( exitCode != 0 )
+ {
+ cerr << "Line Number " + Chain(lineNo) + " : " << msg << endl;
+ }
+ else
+ {
+ cout << msg << endl;
+ cout << "ok ( " << t << " s )" << endl;
+ }
+
+ if ( exitCode != 0 && ignoreError )
+ goOn = true;
+
+ cmd = Chain("");
+
+ }
+ }
+ }
+ }
+ if ( cmd.length() > 1 )
+ {
+ cout << "Incomplete command ..<" << cmd << ">" << endl;
+ }
+
+ cmdFile.close();
+
+ pSH->closeSession();
+
+ delete pSH;
+ delete pN;
+
+ }
+ catch ( Exception e)
+ {
+ Chain msg;
+ e.pop(msg);
+ cerr << msg << endl;
+ return 1;
+ }
+
+ break;
+
+ }
+ case DUMP:
+ {
+
+ Chain logMode("notice");
+ if ( debug )
+ logMode=Chain("debug");
+
+ CegoNet *pCegoNet = new CegoNet( protType, logFile, logMode );
+
+ try
+ {
+ pCegoNet->connect(serverName, portNo, tableSet, user, password);
+ }
+ catch ( Exception e )
+ {
+ cerr << "Cannot connect to database" << endl;
+ delete pCegoNet;
+ return 1;
+ }
+
+ dumpTableSet(pCegoNet, dumpFileName, isStructure);
+
+ delete pCegoNet;
+
+ exitCode = 0;
+ break;
+
+ }
+ case INTERACTIVE:
+ {
+
+ Net n ( NETMNG_MSG_BUFLEN, NETMNG_SIZEBUFLEN );
+ NetHandler* pN;
+
+ try
+ {
+ pN = n.connect(serverName, portNo);
+ }
+ catch ( Exception e )
+ {
+ cerr << "Cannot connect to database" << endl;
+ return 1;
+ }
+
+ CegoDbHandler* pSH = new CegoDbHandler(pN, protType, pModule);
+
+#ifdef DEBUG
+ pModule->log(modId, Logger::DEBUG, Chain("Requesting session ..."));
+#endif
+
+ CegoDbHandler::ResultType res = pSH->requestSession(tableSet, user, password);
+ if ( res != CegoDbHandler::DB_OK )
+ {
+ Chain msg = pSH->getMsg();
+ delete pSH;
+ cerr << msg << endl;
+ return 1;
+ }
+
+
+ try
+ {
+
+ long tid = pSH->getTid();
+
+ AbortHandler *pAH = new AbortHandler(serverName, portNo, tableSet, user, password, tid, pModule);
+
+#ifdef DEBUG
+ pModule->log(modId, Logger::DEBUG, Chain("Got session ..."));
+#endif
+
+ read_history((char*)histPath);
+
+ bool goOn = true;
+ while ( goOn )
+ {
+
+ char *pC = 0;
+
+ Chain cs;
+
+ pC = readline(promptString);
+
+ if (pC)
+ {
+ cs = Chain(pC);
+
+ bool stmtComplete = false;
+ while (! stmtComplete )
+ {
+ add_history(pC);
+
+ if (pC)
+ free(pC);
+
+ cs = cs.cutTrailing(Chain(" \t"));
+
+ if ( cs.length() > 1)
+ {
+ if ( cs[cs.length()-2] == ';')
+ stmtComplete = true;
+ }
+
+ if ( ! stmtComplete )
+ {
+ if ( cs.length() > 1 )
+ {
+ pC = readline(PROMPT2);
+ }
+ else
+ {
+ pC = readline(promptString);
+ }
+ if (pC)
+ cs = cs + Chain(" ") + Chain(pC);
+ }
+
+ }
+
+ Timer t(6,3);
+ t.start();
+
+ Chain msg;
+ goOn = dispatchCmd(pSH, pAH, cs, rawMode, exitCode, msg);
+
+ t.stop();
+
+ if ( exitCode != 0 )
+ {
+ cerr << "Error : " << msg << endl;
+ cerr << "Query failed" << endl;
+ goOn = true;
+ }
+ else
+ {
+ cout << msg << endl;
+ cout << "ok ( " << t << " s )" << endl;
+ }
+ write_history((char*)histPath);
+ }
+ else
+ {
+ cout << "Bye" << endl;
+ goOn=false;
+ }
+ }
+
+ pSH->closeSession();
+
+ delete pSH;
+ delete pN;
+ delete pAH;
+
+ }
+ catch ( Exception e)
+ {
+ Chain msg;
+ e.pop(msg);
+ cerr << msg << endl;
+ return 1;
+ }
+
+ break;
+
+ }
+ }
+ return exitCode;
+}
+
+
+bool dispatchCmd(CegoDbHandler *pSH, AbortHandler *pAH, Chain cmd, bool outMode, int& exitCode, Chain& msg)
+{
+
+ exitCode = 0;
+
+ if ( cmd.cutTrailing(" ;") == Chain("quit") )
+ {
+ msg = Chain("Goodbye");
+ return false;
+ }
+
+ Tokenizer tok(cmd, Chain(" ;"));
+ Chain flowTok;
+ if ( tok.nextToken(flowTok) )
+ {
+
+ if ( flowTok == Chain("flowctl") )
+ {
+ Chain flowOpt;
+ if ( tok.nextToken(flowOpt) )
+ {
+ if ( flowOpt == Chain("off") )
+ {
+ flowCtl=false;
+ cout << "Flow control disabled" << endl;
+ }
+ else
+ {
+ flowCtl=true;
+ if ( flowOpt.asInteger() > 0 )
+ flowCount=flowOpt.asInteger();
+ cout << "Flow control enabled" << endl;
+ }
+ }
+ return true;
+ }
+ }
+
+ CegoDbHandler::ResultType res;
+
+ if ( pAH )
+ pAH->setQueryAbort(true);
+
+ res = pSH->reqQueryOp(cmd);
+
+ if ( pAH )
+ pAH->setQueryAbort(false);
+
+
+ if ( res == CegoDbHandler::DB_OK )
+ {
+ msg = pSH->getMsg();
+ long affCount = pSH->getAffected();
+
+ // if ( msg == Chain("Goodbye") )
+ // return true;
+
+ // cout << msg << endl; // " ( " << affCount << " affected )" << endl;
+
+ }
+ else if ( res == CegoDbHandler::DB_FIN )
+ {
+ msg = Chain("No rows");
+ }
+ else if ( res == CegoDbHandler::DB_INFO )
+ {
+
+ CegoObject::ObjectType objType = pSH->getObjType();
+
+ switch ( objType )
+ {
+ case CegoObject::SYSTEM:
+ case CegoObject::TABLE:
+ case CegoObject::PINDEX:
+ case CegoObject::UINDEX:
+ case CegoObject::INDEX:
+ {
+ CegoTableObject to;
+ to.putElement( pSH->getObjElement() );
+ cout << to.getFormatted();
+ break;
+ }
+ case CegoObject::VIEW:
+ {
+ CegoViewObject vo;
+ vo.putElement( pSH->getObjElement() );
+ cout << vo.getFormatted();
+ break;
+ }
+ case CegoObject::PROCEDURE:
+ {
+ CegoProcObject po;
+ po.putElement( pSH->getObjElement() );
+ cout << po.getFormatted();
+ break;
+ }
+ case CegoObject::FKEY:
+ {
+ CegoKeyObject ko;
+ ko.putElement( pSH->getObjElement() );
+ cout << ko.getFormatted();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if ( res == CegoDbHandler::DB_DATA )
+ {
+ ListT<CegoField> schema;
+ Chain format;
+
+ schema = pSH->getSchema();
+ format = pSH->getFormat();
+
+ CegoOutput output(schema, format);
+
+ output.setRawMode(outMode);
+
+ output.headOut();
+
+ // CegoDbHandler::QuerySync querySync;
+
+ // querySync=CegoDbHandler::QUERY_MOREDATA;
+
+ ListT<CegoFieldValue> fvl;
+ long count=0;
+
+ while ( ( res = pSH->receiveTableData(schema, fvl) ) == CegoDbHandler::DB_DATA )
+ {
+ count++;
+
+ output.rowOut(fvl);
+ fvl.Empty();
+
+ if ( flowCtl )
+ {
+ if ( count % flowCount == 0 )
+ {
+ cout << "Next, Reset, Abort ? ( n, r, a ) ";
+ char resp;
+ cin >> resp;
+ if ( resp == 'a' )
+ {
+ pSH->abortQuery();
+ break;
+ }
+ if ( resp == 'r' )
+ {
+ pSH->resetQuery();
+ }
+ else
+ {
+ // nothing
+ }
+ }
+ }
+
+ }
+ output.tailOut();
+ msg=Chain(count) + Chain(" tuples");
+ }
+ if ( res == CegoDbHandler::DB_ERROR )
+ {
+ msg = pSH->getMsg();
+ // cerr << msg << endl;
+ // cout << "Query failed" << endl;
+ exitCode = 1;
+ return false;
+ }
+
+ return true;
+}
+
+void dumpTableSet(CegoNet *pCegoNet, const Chain& dumpFileName, bool isStructure)
+{
+
+ File* pDF = new File(dumpFileName);
+ pDF->open(File::WRITE);
+
+ try
+ {
+ dumpCounter(pCegoNet, pDF);
+ dumpTable(pCegoNet, pDF, isStructure);
+ dumpIndex(pCegoNet, pDF);
+ dumpKey(pCegoNet, pDF);
+ dumpCheck(pCegoNet, pDF);
+ dumpView(pCegoNet, pDF);
+ dumpProcedure(pCegoNet, pDF);
+ }
+ catch ( Exception e)
+ {
+ Chain msg;
+ e.pop(msg);
+ cerr << msg << endl;
+ }
+
+ pDF->close();
+ delete pDF;
+
+}
+
+void dumpCounter(CegoNet *pCegoNet, File *pDF)
+{
+
+ long res;
+ res = pCegoNet->doQuery(Chain("list counter;"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain counterName = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain counterValue = pFV->valAsChain();
+
+ Chain cmd;
+
+ cmd=Chain("drop if exists counter ") + counterName + Chain(";\n");
+ pDF->writeChain(cmd);
+
+
+ cmd=Chain("create counter ") + counterName + Chain(";\n");
+ pDF->writeChain(cmd);
+ cmd=Chain("set counter ") + counterName + Chain(" to ") + counterValue + Chain(";\n");
+ pDF->writeChain(cmd);
+ fvl.Empty();
+ }
+}
+
+void dumpTable(CegoNet *pCegoNet, File *pDF, bool isStructure)
+{
+
+ long res;
+ res = pCegoNet->doQuery(Chain("list table;"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<Chain> tableList;
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain tableName = pFV->valAsChain();
+ tableList.Insert(tableName);
+ fvl.Empty();
+ }
+
+ Chain *pTable = tableList.First();
+ while ( pTable )
+ {
+ res = pCegoNet->doQuery(Chain("desc table ") + *pTable + Chain(";"));
+
+ Chain cmd;
+
+ cmd=Chain("drop if exists table ") + *pTable + Chain(";\n");
+ pDF->writeChain(cmd);
+
+ cmd=Chain("create table ") + *pTable + Chain("(");
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<CegoFieldValue> fvl;
+ bool isFirst=true;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ if ( isFirst == false )
+ cmd += Chain(", ");
+ isFirst=false;
+
+ CegoFieldValue *pFV = fvl.First();
+ Chain attrName = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain attrType = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain attrSize = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain attrDef = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain attrNull = pFV->valAsChain();
+
+ cmd += attrName + Chain(" ") + attrType;
+ if ( attrType == Chain(XML_STRING_VALUE)
+ || attrType == Chain(XML_BIGINT_VALUE)
+ || attrType == Chain(XML_DECIMAL_VALUE)
+ || attrType == Chain(XML_FIXED_VALUE))
+ cmd += Chain("(") + attrSize + Chain(")");
+ if ( attrDef != Chain(XML_NULL_VALUE))
+ cmd += Chain(" default ") + attrDef;
+ if ( attrNull == Chain("no"))
+ cmd += Chain(" not null");
+ fvl.Empty();
+ }
+
+ cmd += Chain(");\n");
+ pDF->writeChain(cmd);
+
+
+ if ( isStructure == false )
+ {
+ // dump table content
+ res = pCegoNet->doQuery(Chain("select * from ") + *pTable + Chain(";"));
+
+ schema.Empty();
+ fvl.Empty();
+
+ pCegoNet->getSchema(schema);
+
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ Chain cmd=Chain("insert into ") + *pTable + Chain(" values (");
+
+ CegoFieldValue *pFV = fvl.First();
+ while ( pFV )
+ {
+ Chain val = pFV->toChain();
+ cmd += val;
+ pFV = fvl.Next();
+
+ if ( pFV )
+ cmd += Chain(", ");
+ }
+ cmd += Chain(");\n");
+ pDF->writeChain(cmd);
+ fvl.Empty();
+ }
+ }
+
+ pTable = tableList.Next();
+ }
+}
+
+
+void dumpIndex(CegoNet *pCegoNet, File *pDF)
+{
+
+ long res;
+ res = pCegoNet->doQuery(Chain("list index;"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<Chain> indexList;
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain indexName = pFV->valAsChain();
+ indexList.Insert(indexName);
+ fvl.Empty();
+ }
+
+ Chain *pIndex = indexList.First();
+ while ( pIndex )
+ {
+ res = pCegoNet->doQuery(Chain("desc index ") + *pIndex + Chain(";"));
+
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ Chain tableName;
+ Chain indexType;
+ ListT<Chain> attrList;
+
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain attrName = pFV->valAsChain();
+ attrList.Insert(attrName);
+ pFV = fvl.Next();
+ tableName = pFV->valAsChain();
+ pFV = fvl.Next();
+ indexType = pFV->valAsChain();
+
+ fvl.Empty();
+ }
+
+ Chain cmd;
+
+ cmd=Chain("drop if exists index ") + *pIndex + Chain(";\n");
+ pDF->writeChain(cmd);
+
+ if ( indexType == Chain(XML_PINDEX_VALUE) )
+ cmd=Chain("create primary index ");
+ else if ( indexType == Chain(XML_UINDEX_VALUE) )
+ cmd=Chain("create unique index ") + *pIndex;
+ else
+ cmd=Chain("create index ") + *pIndex;
+
+ cmd += Chain(" on ") + tableName + Chain("(");
+
+ Chain *pAttr = attrList.First();
+ bool isFirst=true;
+ while ( pAttr )
+ {
+ if ( isFirst == false )
+ cmd += Chain(",");
+ isFirst=false;
+
+ cmd += *pAttr;
+ pAttr = attrList.Next();
+ }
+
+ cmd += Chain(");\n");
+ pDF->writeChain(cmd);
+
+ pIndex = indexList.Next();
+ }
+}
+
+
+void dumpKey(CegoNet *pCegoNet, File *pDF)
+{
+
+ long res;
+ res = pCegoNet->doQuery(Chain("list key;"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<Chain> keyList;
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain keyName = pFV->valAsChain();
+ keyList.Insert(keyName);
+ fvl.Empty();
+ }
+
+ Chain *pKey = keyList.First();
+ while ( pKey )
+ {
+ res = pCegoNet->doQuery(Chain("desc key ") + *pKey + Chain(";"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ Chain keyTable;
+ Chain refTable;
+ ListT<Chain> keyAttrList;
+ ListT<Chain> refAttrList;
+
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+
+ CegoFieldValue *pFV = fvl.First();
+
+ Chain tableName = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain attrName = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain attrType = pFV->valAsChain();
+
+ if ( attrType == Chain("key") )
+ {
+ keyTable=tableName;
+ keyAttrList.Insert(attrName);
+ }
+ else if ( attrType == Chain("reference") )
+ {
+ refTable=tableName;
+ refAttrList.Insert(attrName);
+ }
+
+ fvl.Empty();
+ }
+
+ Chain cmd;
+
+ cmd=Chain("drop if exists foreign key ") + *pKey + Chain(";\n");
+ pDF->writeChain(cmd);
+
+
+ cmd=Chain("alter table ") + keyTable + Chain(" add foreign key ") + *pKey + Chain("(");
+ Chain *pKeyAttr = keyAttrList.First();
+ while ( pKeyAttr )
+ {
+ cmd += *pKeyAttr;
+ pKeyAttr = keyAttrList.Next();
+ if ( pKeyAttr )
+ cmd += Chain(",");
+ }
+
+ cmd+=Chain(") references ") + refTable + Chain("(");
+ Chain *pRefAttr = refAttrList.First();
+ while ( pRefAttr )
+ {
+ cmd += *pRefAttr;
+ pRefAttr = refAttrList.Next();
+ if ( pRefAttr )
+ cmd += Chain(",");
+ }
+
+ cmd += Chain(");\n");
+ pDF->writeChain(cmd);
+
+ pKey = keyList.Next();
+ }
+}
+
+void dumpCheck(CegoNet *pCegoNet, File *pDF)
+{
+
+ long res;
+ res = pCegoNet->doQuery(Chain("list check;"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<Chain> checkList;
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain checkName = pFV->valAsChain();
+ checkList.Insert(checkName);
+ fvl.Empty();
+ }
+
+ Chain *pCheck = checkList.First();
+ while ( pCheck )
+ {
+ res = pCegoNet->doQuery(Chain("desc check ") + *pCheck + Chain(";"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<CegoFieldValue> fvl;
+ bool isFirst=true;
+ while ( pCegoNet->fetchData(schema, fvl) );
+
+ CegoFieldValue *pFV = fvl.First();
+ Chain checkTable = pFV->valAsChain();
+ pFV = fvl.Next();
+ Chain checkCondition = pFV->valAsChain();
+
+ fvl.Empty();
+
+ Chain cmd;
+
+ cmd=Chain("drop if exists check ") + *pCheck + Chain(";\n");
+ pDF->writeChain(cmd);
+
+ cmd=Chain("alter table ") + checkTable + Chain(" add check ") + *pCheck + Chain(" on ") + checkCondition + Chain(";\n");
+ pDF->writeChain(cmd);
+
+ pCheck = checkList.Next();
+ }
+}
+
+void dumpView(CegoNet *pCegoNet, File *pDF)
+{
+
+ long res;
+ res = pCegoNet->doQuery(Chain("list view;"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<Chain> viewList;
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain viewName = pFV->valAsChain();
+ viewList.Insert(viewName);
+ fvl.Empty();
+ }
+
+ Chain *pView = viewList.First();
+ while ( pView )
+ {
+ res = pCegoNet->doQuery(Chain("show view ") + *pView + Chain(";"));
+
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<CegoFieldValue> fvl;
+ bool isFirst=true;
+ Chain viewText;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ viewText = pFV->valAsChain();
+ fvl.Empty();
+ }
+
+ Chain cmd;
+
+ cmd=Chain("drop if exists view ") + *pView + Chain(";\n");
+ pDF->writeChain(cmd);
+
+ cmd=Chain("create ") + viewText;
+ cmd += Chain("\n");
+ pDF->writeChain(cmd);
+
+ pView = viewList.Next();
+ }
+}
+
+void dumpProcedure(CegoNet *pCegoNet, File *pDF)
+{
+
+ long res;
+ res = pCegoNet->doQuery(Chain("list procedure;"));
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<Chain> procList;
+ ListT<CegoFieldValue> fvl;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ Chain procName = pFV->valAsChain();
+ procList.Insert(procName);
+ fvl.Empty();
+ }
+
+ Chain *pProc = procList.First();
+ while ( pProc )
+ {
+ res = pCegoNet->doQuery(Chain("show procedure ") + *pProc + Chain(";"));
+
+
+ ListT<CegoField> schema;
+ pCegoNet->getSchema(schema);
+
+ ListT<CegoFieldValue> fvl;
+ Chain procText;
+ while ( pCegoNet->fetchData(schema, fvl) )
+ {
+ CegoFieldValue *pFV = fvl.First();
+ procText = pFV->valAsChain();
+ fvl.Empty();
+ }
+
+ Chain cmd;
+
+ cmd=Chain("drop if exists procedure ") + *pProc + Chain(";\n");
+ pDF->writeChain(cmd);
+
+ cmd=Chain("@\ncreate ") + procText;
+ cmd += Chain("\n@\n");
+ pDF->writeChain(cmd);
+
+ pProc = procList.Next();
+ }
+}
+
+void loadProfile(const Chain& rcFileName, ListT<ProfileEntry>& pfeList)
+{
+ File rcFile(rcFileName);
+ if ( rcFile.exists() )
+ {
+
+ rcFile.open(File::READ);
+
+ Chain rcLine;
+ while ( rcFile.readLine(rcLine) )
+ {
+ Tokenizer tok(rcLine, Chain(":"));
+
+ Chain pid;
+ Chain serverName;
+ Chain portNo;
+ Chain protocol;
+ Chain tableSet;
+ Chain prompt;
+ Chain user;
+ Chain pwd;
+
+ if ( tok.nextToken(pid) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+ if ( tok.nextToken(serverName) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+ if ( tok.nextToken(portNo) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+ if ( tok.nextToken(protocol) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+ if ( tok.nextToken(tableSet) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+ if ( tok.nextToken(prompt) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+ if ( tok.nextToken(user) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+ if ( tok.nextToken(pwd) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
+
+ Chain auth = user + Chain("/") + pwd;
+ ProfileEntry pfe(pid, serverName, portNo.asInteger(), protocol, tableSet, auth, prompt);
+ pfeList.Insert(pfe);
+
+ }
+ }
+}
+
+AbortHandler::AbortHandler(const Chain& serverName,
+ int portNo,
+ const Chain& tableSet,
+ const Chain& user,
+ const Chain& password,
+ long tid,
+ CegoModule *pModule) : SigHandler()
+{
+ init();
+ install(SIGINT);
+#ifndef HAVE_MINGW32
+ install(SIGPIPE);
+#endif
+ _tid = tid;
+ _pModule = pModule;
+ _portNo = portNo;
+ _tableSet = tableSet;
+ _user = user;
+ _password = password;
+ _serverName = serverName;
+}
+
+AbortHandler::~AbortHandler()
+{
+}
+
+void AbortHandler::sigCatch(int sig)
+{
+
+ try {
+ install(SIGINT);
+#ifndef HAVE_MINGW32
+ install(SIGPIPE);
+#endif
+
+ if ( _doAbort )
+ {
+
+ cout << endl << "Aborting query .." << endl;
+
+
+ Net n ( NETMNG_MSG_BUFLEN, NETMNG_SIZEBUFLEN );
+ NetHandler* pN;
+
+ pN = n.connect(_serverName, _portNo);
+
+ CegoDbHandler* pSH = new CegoDbHandler(pN, protType, _pModule);
+
+ CegoDbHandler::ResultType res = pSH->requestSession(_tableSet, _user, _password);
+ if ( res != CegoDbHandler::DB_OK )
+ {
+ Chain msg = pSH->getMsg();
+ throw Exception(EXLOC, msg);
+ }
+
+ Chain msg;
+
+ res = pSH->reqQueryAbort(_tid);
+
+ if ( res == CegoDbHandler::DB_OK )
+ {
+ Chain msg = pSH->getMsg();
+ }
+
+ pSH->closeSession();
+
+ delete pSH;
+ delete pN;
+
+ }
+ else
+ {
+ cout << "Use quit to quit" << endl;
+ }
+ }
+ catch ( Exception e)
+ {
+ Chain msg;
+ e.pop(msg);
+ cout << "Error : " << msg << endl;
+ }
+
+}
+
+void AbortHandler::setQueryAbort(bool doAbort)
+{
+ _doAbort = doAbort;
+}
+
+
+ProfileEntry::ProfileEntry()
+{
+}
+
+ProfileEntry::ProfileEntry(const Chain& pid)
+{
+ _pid = pid;
+}
+
+ProfileEntry::ProfileEntry(const Chain& pid,
+ const Chain& serverName,
+ int portNo,
+ const Chain& protocol,
+ const Chain& tableSet,
+ const Chain& auth,
+ const Chain& prompt)
+{
+ _pid = pid;
+ _serverName = serverName;
+ _portNo = portNo;
+ _protocol = protocol;
+ _tableSet = tableSet;
+ _auth = auth;
+ _prompt = prompt;
+}
+
+ProfileEntry::~ProfileEntry()
+{
+}
+
+
+const Chain& ProfileEntry::getId() const
+{
+ return _pid;
+}
+
+const Chain& ProfileEntry::getServerName() const
+{
+ return _serverName;
+}
+
+int ProfileEntry::getPortNo() const
+{
+ return _portNo;
+}
+
+const Chain& ProfileEntry::getProtocol() const
+{
+ return _protocol;
+}
+
+const Chain& ProfileEntry::getTableSet() const
+{
+ return _tableSet;
+}
+
+const Chain& ProfileEntry::getAuth() const
+{
+ return _auth;
+}
+
+const Chain& ProfileEntry::getPrompt() const
+{
+ return _prompt;
+}
+
+ProfileEntry& ProfileEntry::operator = ( const ProfileEntry& pe)
+{
+ _pid = pe._pid;
+ _serverName = pe._serverName;
+ _portNo = pe._portNo;
+ _protocol = pe._protocol;
+ _tableSet = pe._tableSet;
+ _auth = pe._auth;
+ _prompt = pe._prompt;
+ return (*this);
+}
+
+bool ProfileEntry::operator == ( const ProfileEntry& pe)
+{
+ if ( _pid == pe._pid )
+ return true;
+ return false;
+}
|
@@ -145,6 +145,7 @@
ProfileEntry(const Chain& pid,
const Chain& serverName,
int portNo,
+ const Chain& protocol,
const Chain& tableSet,
const Chain& auth,
const Chain& prompt);
@@ -153,6 +154,7 @@
const Chain& getId() const;
const Chain& getServerName() const;
int getPortNo() const;
+ const Chain& getProtocol() const;
const Chain& getTableSet() const;
const Chain& getAuth() const;
const Chain& getPrompt() const;
@@ -165,6 +167,7 @@
Chain _pid;
int _portNo;
Chain _serverName;
+ Chain _protocol;
Chain _tableSet;
Chain _auth;
Chain _prompt;
@@ -1457,6 +1460,7 @@
Chain pid;
Chain serverName;
Chain portNo;
+ Chain protocol;
Chain tableSet;
Chain prompt;
Chain user;
@@ -1474,6 +1478,10 @@
{
throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
}
+ if ( tok.nextToken(protocol) == false)
+ {
+ throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
+ }
if ( tok.nextToken(tableSet) == false)
{
throw Exception(EXLOC, Chain("Incomplete profile entry <") + rcLine + Chain(">"));
@@ -1492,7 +1500,7 @@
}
Chain auth = user + Chain("/") + pwd;
- ProfileEntry pfe(pid, serverName, portNo.asInteger(), tableSet, auth, prompt);
+ ProfileEntry pfe(pid, serverName, portNo.asInteger(), protocol, tableSet, auth, prompt);
pfeList.Insert(pfe);
}
@@ -1601,6 +1609,7 @@
ProfileEntry::ProfileEntry(const Chain& pid,
const Chain& serverName,
int portNo,
+ const Chain& protocol,
const Chain& tableSet,
const Chain& auth,
const Chain& prompt)
@@ -1608,6 +1617,7 @@
_pid = pid;
_serverName = serverName;
_portNo = portNo;
+ _protocol = protocol;
_tableSet = tableSet;
_auth = auth;
_prompt = prompt;
@@ -1633,6 +1643,11 @@
return _portNo;
}
+const Chain& ProfileEntry::getProtocol() const
+{
+ return _protocol;
+}
+
const Chain& ProfileEntry::getTableSet() const
{
return _tableSet;
@@ -1653,6 +1668,7 @@
_pid = pe._pid;
_serverName = pe._serverName;
_portNo = pe._portNo;
+ _protocol = pe._protocol;
_tableSet = pe._tableSet;
_auth = pe._auth;
_prompt = pe._prompt;
|