📄 isql++.cpp.svn-base
字号:
// if shrinkFactor is negative will use a minimal width int w; for(int i=0; i < (int)widths.size(); i++) { switch( md->getColumnType(i+1) ) { case Types::CHAR: case Types::VARCHAR: // cout << "Column " << md->getColumnName(i+1) // << "; shrinked from " << widths[i] << flush; w = (int)( ((float)widths[i]) * shrinkFactor); widths[i] = ( w > MIN_COL_WIDTH_ON_SCREEN ) ? w : MIN_COL_WIDTH_ON_SCREEN; // cout << " to " << widths[i] << endl; break; default: break; } } } } //now we have all widths, print column names cout << OUTER_SEPARATOR << flush; for(int i=1; i<=md->getColumnCount(); i++) { int w=widths[i-1]; string colName=md->getColumnName(i); //fix the width colName.resize(w,SPACE); if(i>1) { cout << INNER_SEPARATOR << flush; } cout << colName << flush; } cout << OUTER_SEPARATOR << endl; //print a line cout << OUTER_SEPARATOR << flush; for(int i=1; i<=md->getColumnCount(); i++) { int w=widths[i-1]; string s; s.resize(w,LINE_CHAR); if(i>1) { cout << INNER_SEPARATOR << flush; } cout << s << flush; } cout << OUTER_SEPARATOR << endl; //and finally, actually print the results while(rs->next()) { cnt++; cout << OUTER_SEPARATOR << flush; for(int i=1; i<=md->getColumnCount(); i++) { int w=widths[i-1]; string val=rs->getString(i); if(rs->wasNull()) { val=NULL_FIELD; } val.resize(w,SPACE); if(i>1) { cout << INNER_SEPARATOR << flush; } cout << val << flush; } cout << OUTER_SEPARATOR << endl; } cout << endl << OUTER_SEPARATOR << cnt << " rows fetched." << endl;} Isql::StatementTypeIsql::extractStatement(string& out){ // clear out out=""; if(buffer_.length()==0) { return STATEMENT_NONE; } //first, find the first non-whitespace char string::size_type first= buffer_.find_first_not_of(WS); if(first==string::npos) { return STATEMENT_NONE; } StatementType st=STATEMENT_NONE; string::size_type firstEnd= buffer_.find_first_of(WS,first); if(firstEnd!=string::npos || buffer_.length()-1>first) { // we need to check whether we brought an ; with us string::size_type eosp=buffer_.find_first_of (END_OF_STATEMENT,first); if(eosp!=string::npos && (firstEnd==string::npos || firstEnd>eosp)) { firstEnd=eosp; } string cmd=buffer_.substr(first,firstEnd-first); CmdMap::iterator i; if((i=commands_.find(cmd))!=commands_.end()) { st = STATEMENT_COMMAND; } } if(st==STATEMENT_NONE) { // our only choice now st=STATEMENT_SQL; } //ok, we know what we have in there. //now, let's search for a terminator const char* str=buffer_.c_str(); int inQ=0; //this is either '\'', '"' or 0 while iterating int i=0; while(str[i]!=0) { char c=str[i]; switch(c) { case '\'': if(inQ==0) { inQ='\''; } else if(inQ=='\'') { inQ=0; } break; case '"': if(inQ==0) { inQ='"'; } else if(inQ=='"') { inQ=0; } break; case END_OF_STATEMENT: if(inQ==0) { out=buffer_.substr(0,(string::size_type)i); if(str[i+1]!=0) { buffer_=buffer_.substr((string::size_type)i+1); } else { buffer_=""; } return st; } break; default: break; }; i++; } return STATEMENT_NONE;}void Isql::executeCommand(const string& cmd){ // we need to split up cmd into tokens vector<string> tokens=splitString(cmd,WS); if(tokens.size()==0) { cout << "Whoops: 0 tokens for executeCommand() " << endl; return; } vector<string>::iterator i=tokens.begin(); string name=*i; vector<string> args; while((++i)!=tokens.end()) { args.push_back(*i); } CmdMap::iterator cmdi=commands_.find(name); if(cmdi!=commands_.end()) { Command cmd=(*cmdi).second; (this->*cmd)(args); }}void Isql::setCmd(const vector<string>& args){ if(args.size()!=2) { throw CommandException ("invalid number of arguments to 'set'"); } string name=toLowerCase(args[0]); string value=args[1]; if(name=="maxrows") { int i=stringToInt(value); if(i<0) { throw CommandException ("maxrows must be >= 0"); } maxRows_=i; } else if(name=="catalog") { con_->setCatalog(value); } else if(name=="autocommit") { string v=toLowerCase(value); bool ac=(v=="on"?true:false); con_->setAutoCommit(ac); } else if(name=="trace") { string v=toLowerCase(value); bool t=(v=="on"?true:false); con_->setTrace(t); } else if(name=="tracefile") { con_->setTraceFile(value); } else { throw CommandException ("set: unknown variable '"+name+"'"); }}void Isql::showCmd(const vector<string>& args){ if(args.size()!=1) { throw CommandException ("invalid number of arguments to 'show'"); } string name=toLowerCase(args[0]); string value; if(name=="maxrows") { value=intToString(maxRows_); } else if(name=="catalog") { value=con_->getCatalog(); } else if(name=="autocommit") { value=(con_->getAutoCommit()?"on":"off"); } else if(name=="trace") { value=(con_->getTrace()?"on":"off"); } else if(name=="tracefile") { value=(con_->getTraceFile()); } else if(name=="types") { this->showTypesCmd(); return; } else { throw CommandException ("show: unknown variable '"+name+"'"); } cout << name << " is " << value << endl;}void Isql::showTypesCmd(){ DatabaseMetaData* md=con_->getMetaData(); try { ResultSet* rs=md->getTypeInfo(); Deleter<ResultSet> _rs(rs); if(rs->next()) { int nameLen=25; int odbcTypeLen=13; int maxLenLen=15; int paramsLen=20; int nullableLen=4; int searchableLen=12; string nameTitle="Name"; string odbcTypeTitle="ODBC Type"; string maxLenTitle="Max size"; string paramsTitle="Create with"; string nullableTitle="Null"; string searchableTitle="Searchable"; nameTitle.resize(nameLen,SPACE_CHAR); odbcTypeTitle.resize(odbcTypeLen,SPACE_CHAR); maxLenTitle.resize(maxLenLen,SPACE_CHAR); paramsTitle.resize(paramsLen,SPACE_CHAR); nullableTitle.resize(nullableLen,SPACE_CHAR); searchableTitle.resize(searchableLen,SPACE_CHAR); cout << OUTER_SEPARATOR << nameTitle << INNER_SEPARATOR << odbcTypeTitle << INNER_SEPARATOR << maxLenTitle << INNER_SEPARATOR << paramsTitle << INNER_SEPARATOR << nullableTitle << INNER_SEPARATOR << searchableTitle << OUTER_SEPARATOR << endl; string t; t.resize(nameLen,LINE_CHAR); cout << OUTER_SEPARATOR << t; t.resize(odbcTypeLen,LINE_CHAR); cout << INNER_SEPARATOR << t; t.resize(maxLenLen,LINE_CHAR); cout << INNER_SEPARATOR << t; t.resize(paramsLen,LINE_CHAR); cout << INNER_SEPARATOR << t; t.resize(nullableLen,LINE_CHAR); cout << INNER_SEPARATOR << t; t.resize(searchableLen,LINE_CHAR); cout << INNER_SEPARATOR << t << OUTER_SEPARATOR << endl; do { string name=rs->getString(1); string odbcType=getTypeName(rs->getShort(2)); string params=rs->getString(6); if(rs->wasNull()) { params=""; } int ml=rs->getInt(3); string maxLen; if(!rs->wasNull()) { maxLen=intToString(ml); } string nullable; switch(rs->getShort(7)) { case DatabaseMetaData::typeNoNulls: nullable="No"; break; case DatabaseMetaData::typeNullable: nullable="Yes"; break; case DatabaseMetaData::typeNullableUnknown: default: nullable="?"; break; } string searchable; switch(rs->getShort(9)) { case DatabaseMetaData::typePredChar: searchable="LIKE only"; break; case DatabaseMetaData::typePredBasic: searchable="except LIKE"; break; case DatabaseMetaData::typeSearchable: searchable="Yes"; break; case DatabaseMetaData::typePredNone: default: searchable="No"; break; } name.resize(nameLen,SPACE_CHAR); odbcType.resize(odbcTypeLen,SPACE_CHAR); maxLen.resize(maxLenLen,SPACE_CHAR); params.resize(paramsLen,SPACE_CHAR); nullable.resize(nullableLen,SPACE_CHAR); searchable.resize(searchableLen,SPACE_CHAR); cout << OUTER_SEPARATOR << name << INNER_SEPARATOR << odbcType << INNER_SEPARATOR << maxLen << INNER_SEPARATOR << params << INNER_SEPARATOR << nullable << INNER_SEPARATOR << searchable << OUTER_SEPARATOR << endl; } while(rs->next()); } } catch(SQLException& e) { cout << e.getMessage() << endl; }}void Isql::commitCmd(const vector<string>& args){ //we don't care about arguments, there are like 20 different //commit syntaxes try { con_->commit(); cout << "Transaction committed." << endl; } catch(SQLException& e) { cout << e.getMessage() << endl; }}void Isql::rollbackCmd(const vector<string>& args){ //same here try { con_->rollback(); cout << "Transaction rolled back." << endl; } catch(SQLException& e) { cout << e.getMessage() << endl; }}void Isql::describeCmd(const vector<string>& args){ if(args.size()!=1) { throw CommandException ("Invalid number of arguments to 'describe'"); } string arg=args[0]; DatabaseMetaData* md=con_->getMetaData(); string catalog; string schema; string name; this->splitIdentifier(arg,catalog,schema,name); vector<string> tableTypes; // fetch a list of all table types { ResultSet* rs=md->getTableTypes(); Deleter<ResultSet> _rs(rs); while(rs->next()) { tableTypes.push_back(rs->getString("TABLE_TYPE")); } } // first, we check for a table or view bool wasTable; { ResultSet* tableRs=md->getTables(catalog,schema,name,tableTypes); Deleter<ResultSet> _tableRs(tableRs); if((wasTable=tableRs->next())) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -