📄 mysqlconnection.c
字号:
// don't attempt to bind beyond the number of // variables defined when the query was prepared if (bindcounter>bindcount) { return false; } bindvaluesize[bindcounter]=valuesize; if (*isnull) { bind[bindcounter].buffer_type=MYSQL_TYPE_NULL; bind[bindcounter].buffer=(void *)NULL; bind[bindcounter].buffer_length=0; bind[bindcounter].length=0; } else { bind[bindcounter].buffer_type=MYSQL_TYPE_LONG_BLOB; bind[bindcounter].buffer=(void *)value; bind[bindcounter].buffer_length=valuesize; bind[bindcounter].length=&bindvaluesize[bindcounter]; } bind[bindcounter].is_null=(my_bool *)isnull; bindcounter++; return true;}bool mysqlcursor::inputBindClob(const char *variable, uint16_t variablesize, const char *value, uint32_t valuesize, int16_t *isnull) { return inputBindBlob(variable,variablesize,value,valuesize,isnull);}#endifbool mysqlcursor::executeQuery(const char *query, uint32_t length, bool execute) { // initialize counts ncols=0; nrows=0;#ifdef HAVE_MYSQL_STMT_PREPARE if (!mysqlconn->fakebinds && usestmtprepare) { // handle binds if (bindcounter && mysql_stmt_bind_param(stmt,bind)) { return false; } // execute the query if ((queryresult=mysql_stmt_execute(stmt))) { return false; } checkForTempTable(query,length); // get the affected row count affectedrows=mysql_stmt_affected_rows(stmt); // get the column count ncols=mysql_stmt_field_count(stmt); // get the metadata mysqlresult=NULL; if (ncols) { mysqlresult=mysql_stmt_result_metadata(stmt); } // bind the fields if (ncols && mysql_stmt_bind_result(stmt,fieldbind)) { return false; } // store the result set if (mysql_stmt_store_result(stmt)) { return false; } // get the row count nrows=mysql_stmt_num_rows(stmt); } else {#else // if this if the first query of the session, do a commit first, // doing this will refresh this connection with any data // committed by other connections, which is what would happen // if a new client connected directly to mysql // (if HAVE_MYSQL_STMT_PREPARE is defined, // then this is done in prepareQuery()) if (mysqlconn->firstquery) { mysqlconn->commit(); mysqlconn->firstquery=false; }#endif // initialize result set mysqlresult=NULL; // execute the query if ((queryresult=mysql_real_query(&mysqlconn->mysql, query,length))) { return false; } checkForTempTable(query,length); // get the affected row count affectedrows=mysql_affected_rows(&mysqlconn->mysql); // store the result set if ((mysqlresult=mysql_store_result(&mysqlconn->mysql))== (MYSQL_RES *)NULL) { // if there was an error then return failure, otherwise // the query must have been some DML or DDL char *err=(char *)mysql_error(&mysqlconn->mysql); if (err && err[0]) { return false; } else { return true; } } // get the column count ncols=mysql_num_fields(mysqlresult); // get the row count nrows=mysql_num_rows(mysqlresult);#ifdef HAVE_MYSQL_STMT_PREPARE }#endif return true;}const char *mysqlcursor::errorMessage(bool *liveconnection) { *liveconnection=true; const char *err;#ifdef HAVE_MYSQL_STMT_PREPARE if (!mysqlconn->fakebinds && usestmtprepare) { err=mysql_stmt_error(stmt); } else {#endif err=mysql_error(&mysqlconn->mysql);#ifdef HAVE_MYSQL_STMT_PREPARE }#endif#if defined(HAVE_MYSQL_CR_SERVER_GONE_ERROR) || \ defined(HAVE_MYSQL_CR_SERVER_LOST) #ifdef HAVE_MYSQL_CR_SERVER_GONE_ERROR if (queryresult==CR_SERVER_GONE_ERROR) { *liveconnection=false; } else #endif #ifdef HAVE_MYSQL_CR_SERVER_LOST if (queryresult==CR_SERVER_LOST) { *liveconnection=false; } else #endif#endif if (!charstring::compare(err,"") || !charstring::compareIgnoringCase(err, "mysql server has gone away") || !charstring::compareIgnoringCase(err, "Can't connect to local MySQL",28) || !charstring::compareIgnoringCase(err, "Lost connection to MySQL server during query")) { *liveconnection=false; }if (!*liveconnection) { sleep(2);} return err;}uint32_t mysqlcursor::colCount() { return ncols;}const char * const * mysqlcursor::columnNames() { mysql_field_seek(mysqlresult,0); columnnames=new char *[ncols]; for (unsigned int i=0; i<ncols; i++) { columnnames[i]=mysql_fetch_field(mysqlresult)->name; } return columnnames;}bool mysqlcursor::knowsRowCount() { return true;}uint64_t mysqlcursor::rowCount() { return nrows;}bool mysqlcursor::knowsAffectedRows() { return true;}uint64_t mysqlcursor::affectedRows() { return affectedrows;}uint16_t mysqlcursor::columnTypeFormat() { return (uint16_t)COLUMN_TYPE_IDS;}void mysqlcursor::returnColumnInfo() { // for DML or DDL queries, return no column info if (!mysqlresult) { return; } // some useful variables uint16_t type; uint32_t length; // position ourselves at the first field mysql_field_seek(mysqlresult,0); // for each column... for (unsigned int i=0; i<ncols; i++) { // fetch the field mysqlfield=mysql_fetch_field(mysqlresult); // append column type to the header if (mysqlfield->type==FIELD_TYPE_STRING) { type=STRING_DATATYPE; length=(uint32_t)mysqlfield->length; } else if (mysqlfield->type==FIELD_TYPE_VAR_STRING) { type=CHAR_DATATYPE; length=(uint32_t)mysqlfield->length+1; } else if (mysqlfield->type==FIELD_TYPE_DECIMAL#ifdef HAVE_MYSQL_FIELD_TYPE_NEWDECIMAL || mysqlfield->type==FIELD_TYPE_NEWDECIMAL#endif ) { type=DECIMAL_DATATYPE; if (mysqlfield->decimals>0) { length=(uint32_t)mysqlfield->length+2; } else if (mysqlfield->decimals==0) { length=(uint32_t)mysqlfield->length+1; } if (mysqlfield->length<mysqlfield->decimals) { length=(uint32_t)mysqlfield->decimals+2; } } else if (mysqlfield->type==FIELD_TYPE_TINY) { type=TINYINT_DATATYPE; length=1; } else if (mysqlfield->type==FIELD_TYPE_SHORT) { type=SMALLINT_DATATYPE; length=2; } else if (mysqlfield->type==FIELD_TYPE_LONG) { type=INT_DATATYPE; length=4; } else if (mysqlfield->type==FIELD_TYPE_FLOAT) { type=FLOAT_DATATYPE; if (mysqlfield->length<=24) { length=4; } else { length=8; } } else if (mysqlfield->type==FIELD_TYPE_DOUBLE) { type=REAL_DATATYPE; length=8; } else if (mysqlfield->type==FIELD_TYPE_LONGLONG) { type=BIGINT_DATATYPE; length=8; } else if (mysqlfield->type==FIELD_TYPE_INT24) { type=MEDIUMINT_DATATYPE; length=3; } else if (mysqlfield->type==FIELD_TYPE_TIMESTAMP) { type=TIMESTAMP_DATATYPE; length=4; } else if (mysqlfield->type==FIELD_TYPE_DATE) { type=DATE_DATATYPE; length=3; } else if (mysqlfield->type==FIELD_TYPE_TIME) { type=TIME_DATATYPE; length=3; } else if (mysqlfield->type==FIELD_TYPE_DATETIME) { type=DATETIME_DATATYPE; length=8;#ifdef HAVE_MYSQL_FIELD_TYPE_YEAR } else if (mysqlfield->type==FIELD_TYPE_YEAR) { type=YEAR_DATATYPE; length=1;#endif#ifdef HAVE_MYSQL_FIELD_TYPE_NEWDATE } else if (mysqlfield->type==FIELD_TYPE_NEWDATE) { type=NEWDATE_DATATYPE; length=1;#endif } else if (mysqlfield->type==FIELD_TYPE_NULL) { type=NULL_DATATYPE;#ifdef HAVE_MYSQL_FIELD_TYPE_ENUM } else if (mysqlfield->type==FIELD_TYPE_ENUM) { type=ENUM_DATATYPE; // 1 or 2 bytes delepending on the # of enum values // (65535 max) length=2;#endif#ifdef HAVE_MYSQL_FIELD_TYPE_SET } else if (mysqlfield->type==FIELD_TYPE_SET) { type=SET_DATATYPE; // 1,2,3,4 or 8 bytes depending on the # of // members (64 max) length=8;#endif // For some versions of mysql, tinyblobs, mediumblobs and // longblobs all show up as FIELD_TYPE_BLOB despite field types // being defined for those types. tinyblobs have a length // of 255 though, so that can be used for something. medium // and long blobs both have the same length though. Go // figure. Also, the word TEXT and BLOB appear to be // interchangable. We'll use BLOB because it appears to be // more standard than TEXT. I wonder if this will be // changed in a future incarnation of mysql. I also wonder // what happens on a 64 bit machine. } else if (mysqlfield->type==FIELD_TYPE_TINY_BLOB || (mysqlfield->type==FIELD_TYPE_BLOB && mysqlfield->length<256)) { type=TINY_BLOB_DATATYPE; length=255; } else if (mysqlfield->type==FIELD_TYPE_BLOB && mysqlfield->length<65536) { type=BLOB_DATATYPE; length=65535; } else if (mysqlfield->type==FIELD_TYPE_MEDIUM_BLOB || (mysqlfield->type==FIELD_TYPE_BLOB && mysqlfield->length<16777216)) { type=MEDIUM_BLOB_DATATYPE; length=16777215; } else if (mysqlfield->type==FIELD_TYPE_LONG_BLOB || mysqlfield->type==FIELD_TYPE_BLOB) { type=LONG_BLOB_DATATYPE; length=2147483647; } else { type=UNKNOWN_DATATYPE; length=(int)mysqlfield->length; } // send column definition // for mysql, length is actually precision conn->sendColumnDefinition(mysqlfield->name, charstring::length(mysqlfield->name), type,length, mysqlfield->length, mysqlfield->decimals, !(IS_NOT_NULL(mysqlfield->flags)), IS_PRI_KEY(mysqlfield->flags), mysqlfield->flags&UNIQUE_KEY_FLAG, mysqlfield->flags&MULTIPLE_KEY_FLAG, mysqlfield->flags&UNSIGNED_FLAG, mysqlfield->flags&ZEROFILL_FLAG,#ifdef BINARY_FLAG mysqlfield->flags&BINARY_FLAG,#else 0,#endif#ifdef AUTO_INCREMENT_FLAG mysqlfield->flags&AUTO_INCREMENT_FLAG#else 0#endif ); }}bool mysqlcursor::noRowsToReturn() { // for DML or DDL queries, return no data return (!mysqlresult);}bool mysqlcursor::skipRow() { return fetchRow();}bool mysqlcursor::fetchRow() {#ifdef HAVE_MYSQL_STMT_PREPARE if (!mysqlconn->fakebinds && usestmtprepare) { return !mysql_stmt_fetch(stmt); } else {#endif return ((mysqlrow=mysql_fetch_row(mysqlresult))!=NULL && (mysqlrowlengths=mysql_fetch_lengths( mysqlresult))!=NULL);#ifdef HAVE_MYSQL_STMT_PREPARE }#endif}void mysqlcursor::returnRow() { for (unsigned int col=0; col<ncols; col++) {#ifdef HAVE_MYSQL_STMT_PREPARE if (!mysqlconn->fakebinds && usestmtprepare) { if (!isnull[col]) { conn->sendField(field[col],fieldlength[col]); } else { conn->sendNullField(); } } else {#endif if (mysqlrow[col]) { conn->sendField(mysqlrow[col], mysqlrowlengths[col]); } else { conn->sendNullField(); }#ifdef HAVE_MYSQL_STMT_PREPARE }#endif }}void mysqlcursor::cleanUpData(bool freeresult, bool freebinds) {#ifdef HAVE_MYSQL_STMT_PREPARE if (!mysqlconn->fakebinds && usestmtprepare) { if (freebinds) { bindcounter=0; rawbuffer::zero(&bind,sizeof(bind)); mysql_stmt_reset(stmt); } if (freeresult) { mysql_stmt_free_result(stmt); } }#endif if (freeresult && mysqlresult!=(MYSQL_RES *)NULL) { mysql_free_result(mysqlresult); mysqlresult=NULL;#ifdef HAVE_MYSQL_NEXT_RESULT while (!mysql_next_result(&mysqlconn->mysql)) { mysqlresult=mysql_store_result(&mysqlconn->mysql); if (mysqlresult!=(MYSQL_RES *)NULL) { mysql_free_result(mysqlresult); mysqlresult=NULL; } }#endif } delete[] columnnames; columnnames=NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -