📄 freetdsconnection.c
字号:
// if we're doing an rpc query, the result set should be a single // row of output parameter results, fetch it and populate the output // bind variables... if (isrpcquery && resultstype==CS_PARAM_RESULT) { if (ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED, &rowsread)!=CS_SUCCEED && !rowsread) { return false; } // copy data into output bind values CS_INT maxindex=outbindindex; if (ncols<outbindindex) { // this shouldn't happen... maxindex=ncols; } for (CS_INT i=0; i<maxindex; i++) { if (outbindtype[i]==CS_CHAR_TYPE) { CS_INT length=outbindstringlengths[i]; if (datalength[i][0]<length) { length=datalength[i][0]; } rawbuffer::copy(outbindstrings[i], data[i][0],length); } else if (outbindtype[i]==CS_INT_TYPE) { *outbindints[i]=charstring::toInteger( data[i][0]); } else if (outbindtype[i]==CS_FLOAT_TYPE) { *outbinddoubles[i]=charstring::toFloat( data[i][0]); } } discardResults(); ncols=0; } // return success only if no error was generated if (freetdsconn->errorstring) { return false; } return true;}const char *freetdscursor::errorMessage(bool *liveconnection) { if (freetdsconn->deadconnection) { *liveconnection=false; } else { *liveconnection=true; } if (freetdsconn->errorstring) { return freetdsconn->errorstring->getString(); } else { return NULL; }}bool freetdscursor::knowsRowCount() { return false;}uint64_t freetdscursor::rowCount() { return 0;}bool freetdscursor::knowsAffectedRows() { return knowsaffectedrows;}uint64_t freetdscursor::affectedRows() { return affectedrows;}uint32_t freetdscursor::colCount() { return ncols;}const char * const *freetdscursor::columnNames() { for (CS_INT i=0; i<ncols; i++) { if (ct_describe(cmd,i+1,&column[i])!=CS_SUCCEED) { break; } columnnames[i]=column[i].name; } return columnnames;}uint16_t freetdscursor::columnTypeFormat() { return (uint16_t)COLUMN_TYPE_IDS;}void freetdscursor::returnColumnInfo() { // unless the query was a successful select, send no header if (resultstype!=CS_ROW_RESULT &&#ifdef FREETDS_SUPPORTS_CURSORS resultstype!=CS_CURSOR_RESULT &&#endif resultstype!=CS_COMPUTE_RESULT) { return; } // gonna need this later int16_t type; // for each column... for (CS_INT i=0; i<ncols; i++) { // get the column description if (ct_describe(cmd,i+1,&column[i])!=CS_SUCCEED) { break; } // set the datatype uint16_t binary=0; if (column[i].datatype==CS_CHAR_TYPE) { type=CHAR_DATATYPE; } else if (column[i].datatype==CS_INT_TYPE) { type=INT_DATATYPE; } else if (column[i].datatype==CS_SMALLINT_TYPE) { type=SMALLINT_DATATYPE; } else if (column[i].datatype==CS_TINYINT_TYPE) { type=TINYINT_DATATYPE; } else if (column[i].datatype==CS_MONEY_TYPE) { type=MONEY_DATATYPE; } else if (column[i].datatype==CS_DATETIME_TYPE) { type=DATETIME_DATATYPE; } else if (column[i].datatype==CS_NUMERIC_TYPE) { type=NUMERIC_DATATYPE; } else if (column[i].datatype==CS_DECIMAL_TYPE) { type=DECIMAL_DATATYPE; } else if (column[i].datatype==CS_DATETIME4_TYPE) { type=SMALLDATETIME_DATATYPE; } else if (column[i].datatype==CS_MONEY4_TYPE) { type=SMALLMONEY_DATATYPE; } else if (column[i].datatype==CS_IMAGE_TYPE) { type=IMAGE_DATATYPE; binary=1; } else if (column[i].datatype==CS_BINARY_TYPE) { type=BINARY_DATATYPE; } else if (column[i].datatype==CS_BIT_TYPE) { type=BIT_DATATYPE; } else if (column[i].datatype==CS_REAL_TYPE) { type=REAL_DATATYPE; } else if (column[i].datatype==CS_FLOAT_TYPE) { type=FLOAT_DATATYPE; } else if (column[i].datatype==CS_TEXT_TYPE) { type=TEXT_DATATYPE; } else if (column[i].datatype==CS_VARCHAR_TYPE) { type=VARCHAR_DATATYPE; } else if (column[i].datatype==CS_VARBINARY_TYPE) { type=VARBINARY_DATATYPE; } else if (column[i].datatype==CS_LONGCHAR_TYPE) { type=LONGCHAR_DATATYPE; } else if (column[i].datatype==CS_LONGBINARY_TYPE) { type=LONGBINARY_DATATYPE; } else if (column[i].datatype==CS_LONG_TYPE) { type=LONG_DATATYPE; } else if (column[i].datatype==CS_ILLEGAL_TYPE) { type=ILLEGAL_DATATYPE; } else if (column[i].datatype==CS_SENSITIVITY_TYPE) { type=SENSITIVITY_DATATYPE; } else if (column[i].datatype==CS_BOUNDARY_TYPE) { type=BOUNDARY_DATATYPE; } else if (column[i].datatype==CS_VOID_TYPE) { type=VOID_DATATYPE; } else if (column[i].datatype==CS_USHORT_TYPE) { type=USHORT_DATATYPE; } else { type=UNKNOWN_DATATYPE; } // limit the column size if (column[i].maxlength>MAX_ITEM_BUFFER_SIZE) { column[i].maxlength=MAX_ITEM_BUFFER_SIZE; } // send the column definition conn->sendColumnDefinition(column[i].name, charstring::length(column[i].name), type, column[i].maxlength, column[i].precision, column[i].scale, (column[i].status&CS_CANBENULL), 0, 0, (column[i].status& (CS_KEY|CS_VERSION_KEY)), (type==USHORT_DATATYPE), 0, binary, (column[i].status&CS_IDENTITY)); }}bool freetdscursor::noRowsToReturn() { // unless the query was a successful select, send no data return (resultstype!=CS_ROW_RESULT &&#ifdef FREETDS_SUPPORTS_CURSORS resultstype!=CS_CURSOR_RESULT &&#endif resultstype!=CS_COMPUTE_RESULT);}bool freetdscursor::skipRow() { if (fetchRow()) { row++; return true; } return false;}bool freetdscursor::fetchRow() { if (row==FETCH_AT_ONCE) { row=0; } if (row>0 && row==maxrow) { return false; } if (!row) { if (ct_fetch(cmd,CS_UNUSED,CS_UNUSED,CS_UNUSED, &rowsread)!=CS_SUCCEED && !rowsread) { return false; } maxrow=rowsread; totalrows=totalrows+rowsread; } return true;}void freetdscursor::returnRow() { // send each row back for (CS_INT col=0; col<ncols; col++) { if (nullindicator[col][row]>-1 && datalength[col][row]) { conn->sendField(data[col][row],datalength[col][row]-1); } else { conn->sendNullField(); } } row++;}void freetdscursor::cleanUpData(bool freeresult, bool freebinds) { if (clean) { return; } if (freeresult) { discardResults(); discardCursor(); } clean=true;}void freetdscursor::discardResults() { // if there are any unprocessed result sets, process them if (results==CS_SUCCEED) { do { if (ct_cancel(NULL,cmd,CS_CANCEL_CURRENT)==CS_FAIL) { freetdsconn->deadconnection=true; // FIXME: call ct_close(CS_FORCE_CLOSE) // maybe return false } results=ct_results(cmd,&resultstype); } while (results==CS_SUCCEED); } if (results==CS_FAIL) { if (ct_cancel(NULL,cmd,CS_CANCEL_ALL)==CS_FAIL) { freetdsconn->deadconnection=true; // FIXME: call ct_close(CS_FORCE_CLOSE) // maybe return false } }}void freetdscursor::discardCursor() {#ifdef FREETDS_SUPPORTS_CURSORS if (cmd==cursorcmd) { if (ct_cursor(cursorcmd,CS_CURSOR_CLOSE,NULL,CS_UNUSED, NULL,CS_UNUSED,CS_DEALLOC)==CS_SUCCEED) { if (ct_send(cursorcmd)==CS_SUCCEED) { results=ct_results(cmd,&resultstype); discardResults(); } } }#endif}CS_RETCODE freetdsconnection::csMessageCallback(CS_CONTEXT *ctxt, CS_CLIENTMSG *msgp) { if (errorstring) { return CS_SUCCEED; } errorstring=new stringbuffer(); errorstring->append("Client Library error:\n"); errorstring->append(" severity(")-> append((int32_t)CS_SEVERITY(msgp->msgnumber))-> append(")\n"); errorstring->append(" layer(")-> append((int32_t)CS_LAYER(msgp->msgnumber))-> append(")\n"); errorstring->append(" origin(")-> append((int32_t)CS_ORIGIN(msgp->msgnumber))-> append(")\n"); errorstring->append(" number(")-> append((int32_t)CS_NUMBER(msgp->msgnumber))-> append(")\n"); errorstring->append("Error: ")->append(msgp->msgstring)-> append("\n"); if (msgp->osstringlen>0) { errorstring->append("Operating System Error:\n"); errorstring->append("\n ")->append(msgp->osstring)-> append("\n"); } //printf("csMessageCallback:\n%s\n",errorstring->getString()); // for a timeout message, set deadconnection to 1 if (CS_SEVERITY(msgp->msgnumber)==CS_SV_RETRY_FAIL && CS_LAYER(msgp->msgnumber)==63 && CS_ORIGIN(msgp->msgnumber)==63 && CS_NUMBER(msgp->msgnumber)==63) { deadconnection=true; // for a read from sql server failed message, set deadconnection to 1 } else if (CS_SEVERITY(msgp->msgnumber)==78 && CS_LAYER(msgp->msgnumber)==0 && CS_ORIGIN(msgp->msgnumber)==0 && (CS_NUMBER(msgp->msgnumber)==36 || CS_NUMBER(msgp->msgnumber)==38)) { deadconnection=true; } // FIXME: sybase connection has another case, do we need it? return CS_SUCCEED;}CS_RETCODE freetdsconnection::clientMessageCallback(CS_CONTEXT *ctxt, CS_CONNECTION *cnn, CS_CLIENTMSG *msgp) { if (errorstring) { return CS_SUCCEED; } errorstring=new stringbuffer(); errorstring->append("Client Library error:\n"); errorstring->append(" severity(")-> append((int32_t)CS_SEVERITY(msgp->msgnumber))-> append(")\n"); errorstring->append(" layer(")-> append((int32_t)CS_LAYER(msgp->msgnumber))-> append(")\n"); errorstring->append(" origin(")-> append((int32_t)CS_ORIGIN(msgp->msgnumber))-> append(")\n"); errorstring->append(" number(")-> append((int32_t)CS_NUMBER(msgp->msgnumber))-> append(")\n"); errorstring->append("Error: ")->append(msgp->msgstring)-> append("\n"); if (msgp->osstringlen>0) { errorstring->append("Operating System Error:\n"); errorstring->append("\n ")->append(msgp->osstring)-> append("\n"); } //printf("clientMessageCallback:\n%s\n",errorstring->getString()); // for a timeout message, set deadconnection to 1 if (CS_SEVERITY(msgp->msgnumber)==CS_SV_RETRY_FAIL && CS_LAYER(msgp->msgnumber)==63 && CS_ORIGIN(msgp->msgnumber)==63 && CS_NUMBER(msgp->msgnumber)==63) { deadconnection=true; // for a read from sql server failed message, set deadconnection to 1 } else if (CS_SEVERITY(msgp->msgnumber)==78 && CS_LAYER(msgp->msgnumber)==0 && CS_ORIGIN(msgp->msgnumber)==0 && (CS_NUMBER(msgp->msgnumber)==36 || CS_NUMBER(msgp->msgnumber)==38)) { deadconnection=true; } // FIXME: sybase connection has another case, do we need it? return CS_SUCCEED;}CS_RETCODE freetdsconnection::serverMessageCallback(CS_CONTEXT *ctxt, CS_CONNECTION *cnn, CS_SERVERMSG *msgp) { // This is a special case, for some reason, "use db" queries // throw a warning, ignore them. if ((CS_NUMBER(msgp->msgnumber)==5701 && (CS_SEVERITY(msgp->msgnumber)==10 || CS_SEVERITY(msgp->msgnumber)==0)) || (CS_NUMBER(msgp->msgnumber)==69 && CS_SEVERITY(msgp->msgnumber)==22)) { return CS_SUCCEED; } if (errorstring) { return CS_SUCCEED; } errorstring=new stringbuffer(); errorstring->append("Server message:\n"); errorstring->append(" severity(")-> append((int32_t)CS_SEVERITY(msgp->msgnumber))-> append(")\n"); errorstring->append(" number(")-> append((int32_t)CS_NUMBER(msgp->msgnumber))-> append(")\n"); errorstring->append(" state(")-> append((int32_t)msgp->state)->append(")\n"); errorstring->append(" line(")-> append((int32_t)msgp->line)->append(")\n"); errorstring->append("Server Name:\n")-> append(msgp->svrname)->append("\n"); errorstring->append("Procedure Name:\n")-> append(msgp->proc)->append("\n"); errorstring->append("Error: ")-> append(msgp->text)->append("\n"); //printf("serverMessageCallback:\n%s\n",errorstring->getString()); return CS_SUCCEED;}void freetdsconnection::dropTempTable(sqlrcursor_svr *cursor, const char *tablename) { stringbuffer dropquery; dropquery.append("drop table #")->append(tablename); if (cursor->prepareQuery(dropquery.getString(), dropquery.getStringLength())) { cursor->executeQuery(dropquery.getString(), dropquery.getStringLength(),1); } cursor->cleanUpData(true,true);}bool freetdsconnection::commit() { cleanUpAllCursorData(true,true); return sqlrconnection_svr::commit();}bool freetdsconnection::rollback() { cleanUpAllCursorData(true,true); return sqlrconnection_svr::rollback();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -