diff --git a/include/AppInfo.h b/include/AppInfo.h index dfca4c1..344cd53 100644 --- a/include/AppInfo.h +++ b/include/AppInfo.h @@ -38,7 +38,7 @@ #define SQLITE_APPVERSION_MAJOR "10" #define SQLITE_APPVERSION_MINOR "5" -#define COMPANY_COPYRIGHT "(c) 2001-2021 Webyog Inc." +#define COMPANY_COPYRIGHT "(c) 2001-2022 Webyog Inc." #define FILEVER MAJOR_VERSION_INT ## , ## MINOR_VERSION_INT ## , ## UPDATE_VERSION_INT ## , ## RELEASE_VERSION_INT #define STRFILEVER MAJOR_VERSION "." MINOR_VERSION "." STRINGIZE(UPDATE_VERSION_INT) "." STRINGIZE(RELEASE_VERSION_INT) diff --git a/include/CommonHelper.h b/include/CommonHelper.h index 9730e57..b124625 100644 --- a/include/CommonHelper.h +++ b/include/CommonHelper.h @@ -75,6 +75,8 @@ #define WAIT_TIMEOUT_SERVER "28800" #define PROCEDURE_FUNC_ERRMSG _("Unable to retrieve information. Please check your privileges. For routines (stored procedures and functions) you need SELECT privilege to mysql.proc if you are not the owner of the routines.") +#define AZURE_ENDPOINT "database.azure.com" + #define CPI_BIG5 950 #define CPI_CP850 850 #define CPI_KOI8R 20866 @@ -1010,6 +1012,8 @@ void RemovePattern(wyString &text, const wyChar* pattern); void SetSslAuthentication(MYSQL *mysql, ConnectionInfo *conninfo); +wyUInt32 GetConnectionId(Tunnel *tunnel, MYSQL *mysql); + //void DebugLog(const char *buffer); #ifdef _WIN32 void WriteLog(const wyChar* str); diff --git a/include/FrameWindowHelper.h b/include/FrameWindowHelper.h index 3fc7224..64febb5 100644 --- a/include/FrameWindowHelper.h +++ b/include/FrameWindowHelper.h @@ -428,7 +428,8 @@ All Files(*.*)\0*.*\0" #define SIZE_192 192 #define SIZE_256 256 #define SIZE_512 512 -#define SIZE_1024 1024 +#define SIZE_1024 1024 +#define SIZE_2048 2048 #define SIZE_5120 (20*1024) #define CURRENT_TIMESTAMP "CURRENT_TIMESTAMP" @@ -977,6 +978,16 @@ wyBool IsColumnSet(Tunnel * tunnel, MYSQL_RES * myfieldres, MYSQL_RES * res, co */ wyBool IsColumnPrimary(Tunnel * tunnel, MYSQL_RES * myfieldres, wyChar * column); +/// Searches for the column name in the virtual fields res +/** +@param tunnel : IN Mysql tunnel pointer +@param myfieldres : IN Mysql result set +@param column : IN Column name +@returns wyTrue if set else wyFalse +*/ +wyBool +IsFieldVirtual(Tunnel *tunnel, MYSQL_RES *myfieldres, wyString& column); + /// Whether there is a primary key for the table or not. /** @param tunnel : IN Tunnel Pointer. diff --git a/include/Global.h b/include/Global.h index 654d163..75fde1d 100644 --- a/include/Global.h +++ b/include/Global.h @@ -451,6 +451,9 @@ struct ConnectionInfo wyBool m_isInfoOpen; wyUInt32 m_isencrypted; + + wyBool m_isazuredb; + wyUInt32 m_connection_id; }; diff --git a/include/MDIWindow.h b/include/MDIWindow.h index 975c7fa..242dce6 100644 --- a/include/MDIWindow.h +++ b/include/MDIWindow.h @@ -981,6 +981,8 @@ class MDIWindow /// Stop query execution void StopQueryExecution(); + void ResetStopQueryExecution(); + ///CHecking if currenet execution stopped or not /** @return wyTrue if stopped/not executing anything, or return wyFalse diff --git a/include/Tunnel.h b/include/Tunnel.h index 3ca9c31..0713490 100644 --- a/include/Tunnel.h +++ b/include/Tunnel.h @@ -42,6 +42,7 @@ class Tunnel virtual void SetDB ( const char * db ) = 0; virtual void SetBatchEnd ( bool end ) = 0; virtual void EmptyQueryBuffer () = 0; + virtual void ClearXMLDoc() = 0; virtual bool GetMySQLVersion ( MYSQL * mysql ) = 0; virtual int mysql_real_query ( MYSQL * mysql, const char * q, unsigned long length, bool isbadforxml, bool batch = false, diff --git a/include/TunnelCommunity.h b/include/TunnelCommunity.h index b70a081..aa2957a 100644 --- a/include/TunnelCommunity.h +++ b/include/TunnelCommunity.h @@ -35,6 +35,7 @@ class TunnelCommunity : public Tunnel void SetDB ( const char * db ); void SetBatchEnd ( bool end ) {} void EmptyQueryBuffer (); + void ClearXMLDoc(); bool GetMySQLVersion ( MYSQL * mysql ); int mysql_real_query ( MYSQL * mysql, const char * q, unsigned long length, bool isbadforxml, diff --git a/include/Version.h b/include/Version.h index 4996519..843aaaf 100644 --- a/include/Version.h +++ b/include/Version.h @@ -1,5 +1,5 @@ #define MAJOR_VERSION_INT 13 -#define MINOR_VERSION_INT 1 -#define UPDATE_VERSION_INT 9 +#define MINOR_VERSION_INT 2 +#define UPDATE_VERSION_INT 0 #define RELEASE_VERSION_INT 0 #define EXTRAINFO "" diff --git a/src/CommonHelper.cpp b/src/CommonHelper.cpp index c20c190..2825516 100644 --- a/src/CommonHelper.cpp +++ b/src/CommonHelper.cpp @@ -1120,25 +1120,29 @@ CheckForOnUpdate(wyString &strcreate, wyInt32 fieldpos) free(create); return find; } + wyBool GetExpressionValue(wyChar * currentrow, wyString * expression) { -wyChar * find="AS"; -wyBool found=wyFalse; -const char *ptr = strstr(currentrow,find); -if(ptr) { - found=wyTrue; - int index = ptr - currentrow+2; - while(currentrow[index]!='S'&& currentrow[index]!='P'&& currentrow[index]!='V' ) - { - expression->AddSprintf("%c",currentrow[index]); - - index++; - } -} + wyString rowstr(currentrow); + wyChar * find = "AS"; + wyBool found = wyFalse; + int startpos = -1; + int endpos = -1; + + startpos = rowstr.FindI("AS"); + if (startpos == -1) + return found; -return found; + startpos = startpos + 3; //length of AS and space. + + if (((endpos = rowstr.FindI("VIRTUAL")) != -1) || ((endpos = rowstr.FindI("STORED")) != -1) || ((endpos = rowstr.FindI("PERSISTENT")) != -1)) { + expression->SetAs(rowstr.Substr(startpos, endpos - startpos)); + found = wyTrue; + } + return found; } + wyBool GetCheckConstraintValue(wyChar * currentrow, wyString * expression) { if (currentrow == NULL) @@ -4261,6 +4265,7 @@ InitConnectionDetails(ConnectionInfo *conn) conn->m_rgbfgconn = RGB(0, 0, 0); #endif + conn->m_no_ca = wyFalse; return; } @@ -4379,11 +4384,11 @@ IsDatatypeNumeric(wyString &datatype) } //Checks whether the datatype belongs to the deprecated numeric size datatypes or not +//We are not considering tinyint as MySQL returns display width for tinyint. It is an exceptional case. wyBool IsDatatypeDeprecatedSizeType(wyString &datatype) { - if (!( - datatype.CompareI("tinyint") == 0 || + if (!(datatype.CompareI("tinyint") == 0 || datatype.CompareI("smallint") == 0 || datatype.CompareI("mediumint") == 0 || datatype.CompareI("int") == 0 || @@ -4710,7 +4715,7 @@ RemovePattern(wyString &text, const wyChar* pattern) re = pcre_compile( pattern, /* the pattern */ - PCRE_UTF8 | PCRE_CASELESS | PCRE_NEWLINE_CR,/* default options */ //match is a case insensitive + PCRE_UTF8 | PCRE_CASELESS | PCRE_NEWLINE_CR,/* default options */ //match is a case insensitive &error, /* for error message */ &erroffset, /* for error offset */ NULL); /* use default character tables */ @@ -4747,9 +4752,9 @@ RemovePattern(wyString &text, const wyChar* pattern) } -void +void SetSslAuthentication(MYSQL *mysql, ConnectionInfo *conninfo) -{ +{ /// SSL Connection if ssl is selected if (conninfo->m_issslchecked == wyTrue) { @@ -4779,3 +4784,30 @@ SetSslAuthentication(MYSQL *mysql, ConnectionInfo *conninfo) } } } + +wyUInt32 +GetConnectionId(Tunnel *tunnel, MYSQL *mysql) +{ + MYSQL_RES *myres; + MYSQL_ROW myrow; + wyString query; + wyString idstr; + wyUInt32 conectionid = 0; + query.SetAs("SELECT CONNECTION_ID()"); + myres = SjaExecuteAndGetResult(tunnel, &mysql, query); + if (!myres) + { + //collation.SetAs("latin1"); + return wyFalse; + } + + myrow = sja_mysql_fetch_row(tunnel, myres); + + if (myrow[0]) + idstr.SetAs(myrow[0]); + + if (myres) + sja_mysql_free_result(tunnel, myres); + + return idstr.GetAsInt32(); +} diff --git a/src/ConnectionBase.cpp b/src/ConnectionBase.cpp index 79f6af4..5ba29c6 100644 --- a/src/ConnectionBase.cpp +++ b/src/ConnectionBase.cpp @@ -93,7 +93,7 @@ ConnectionBase::OnInitDialog(HWND hwnd, LPARAM lparam) // also sets the maximum text which can be entered into the value fields. SendMessage(GetDlgItem(hwnd, IDC_DLGCONNECT_HOST), EM_LIMITTEXT, 255, 0); SendMessage(GetDlgItem(hwnd, IDC_DLGCONNECT_USER), EM_LIMITTEXT, 255, 0); - SendMessage(GetDlgItem(hwnd, IDC_DLGCONNECT_PASSWORD), EM_LIMITTEXT, 255, 0); + SendMessage(GetDlgItem(hwnd, IDC_DLGCONNECT_PASSWORD), EM_LIMITTEXT, SIZE_2048, 0); SendMessage(GetDlgItem(hwnd, IDC_DLGCONNECT_PORT), EM_LIMITTEXT, 5, 0); SendMessage(GetDlgItem(hwnd, IDC_TIMEOUTEDIT), EM_LIMITTEXT, 6, 0); SendMessage(GetDlgItem(hwnd, IDC_PINGINTERVAL), EM_LIMITTEXT, 6, 0); @@ -1557,7 +1557,7 @@ ConnectionBase::GetInitialDetails(HWND hdlg) wyString timeout, conn, dirstr, pwdstr, tempstr, isencrypted; wyString codepage, userstr, hoststr, portstr, dbstr; wyWChar directory[MAX_PATH+1]={0}, *lpfileport=0; - wyChar pwd[SIZE_512]={0}; + wyChar pwd[SIZE_2048]={0}; wyBool decodepwd = wyTrue; wyUInt32 ret, usecompress = 1, isdefwaittimeout = 1, readonly = 0/*, usecleartext = 0*/; ConnectionInfo conninfo; @@ -2629,7 +2629,7 @@ void ConnectionBase::SaveServerDetails(HWND hwnd, const wyChar *conn, const wyChar *directory) { wyInt32 ret = 1, value = 1; - wyWChar temp[SIZE_1024] = {0}; + wyWChar temp[SIZE_2048] = {0}; wyString tempstr, isencrypted; // Server Host diff --git a/src/ConnectionCommunity.cpp b/src/ConnectionCommunity.cpp index d8a3797..8a641aa 100644 --- a/src/ConnectionCommunity.cpp +++ b/src/ConnectionCommunity.cpp @@ -380,7 +380,7 @@ ConnectionCommunity::ConnectToMySQL(HWND hdlg, ConnectionInfo *coninfo) wyUInt32 portno, client=0; wyInt32 ret; wyWChar host[SIZE_512]={0}, user[SIZE_512]={0}, timeout[32] = {0}; - wyWChar pwd[SIZE_512]={0}, port[10]={0}; + wyWChar pwd[SIZE_2048]={0}, port[10]={0}; MYSQL *mysql, *temp; wyString strinitcommand; @@ -396,7 +396,7 @@ ConnectionCommunity::ConnectToMySQL(HWND hdlg, ConnectionInfo *coninfo) ret = SendMessage(GetDlgItem(hdlg, IDC_DLGCONNECT_HOST), WM_GETTEXT,(WPARAM)SIZE_512-1, (LPARAM)host); ret = SendMessage(GetDlgItem(hdlg, IDC_DLGCONNECT_USER), WM_GETTEXT,(WPARAM)SIZE_512-1, (LPARAM)user); ret = SendMessage(GetDlgItem(hdlg, IDC_DLGCONNECT_PORT), WM_GETTEXT,(WPARAM)9, (LPARAM)port); - ret = SendMessage(GetDlgItem(hdlg, IDC_DLGCONNECT_PASSWORD), WM_GETTEXT,(WPARAM)SIZE_512-1, (LPARAM)pwd); + ret = SendMessage(GetDlgItem(hdlg, IDC_DLGCONNECT_PASSWORD), WM_GETTEXT,(WPARAM)SIZE_2048-1, (LPARAM)pwd); portno = _wtoi(port); @@ -488,7 +488,7 @@ ConnectionCommunity::OnConnect(HWND hwnd, ConnectionInfo * dbname) MYSQL *mysql; HWND lastfocus = GetFocus(); wyString conn, temp, dirnamestr; - wyWChar directory[MAX_PATH + 1] = {0}, *lpfileport = 0, pass[MAX_PATH + 1] = {0}; + wyWChar directory[MAX_PATH + 1] = {0}, *lpfileport = 0, pass[SIZE_2048] = {0}; HWND hwndcombo; wyInt32 count, storepwd, ret; @@ -567,7 +567,7 @@ ConnectionCommunity::OnConnect(HWND hwnd, ConnectionInfo * dbname) } else { - GetWindowText(GetDlgItem(hwnd, IDC_DLGCONNECT_PASSWORD), pass, MAX_PATH); + GetWindowText(GetDlgItem(hwnd, IDC_DLGCONNECT_PASSWORD), pass, SIZE_2048); temp.SetAs(pass); EncodePassword(temp); wyChar *encodestr = temp.EncodeBase64Password(); diff --git a/src/CustGrid.cpp b/src/CustGrid.cpp index c030b5b..0059be6 100644 --- a/src/CustGrid.cpp +++ b/src/CustGrid.cpp @@ -3249,7 +3249,7 @@ CCustGrid::DrawRowColumns(HDC hdcmem, PRECT rect, PRECT rectwin, wyUInt32 *totcx if(temprowlist) rect->right = rect->right + temprowlist->rowcx; } - else if(pgvcolnode && pgvcolnode->isshow == wyTrue) + else // if(pgvcolnode && pgvcolnode->isshow == wyTrue) { rect->top = rect->top + m_hight; rect->bottom = rect->top + m_hight; diff --git a/src/DataView.cpp b/src/DataView.cpp index 6b2f385..5dc7607 100644 --- a/src/DataView.cpp +++ b/src/DataView.cpp @@ -42,6 +42,7 @@ Author: Vishal P.R, Janani SriGuha extern PGLOBALS pGlobals; + //constructor for object represeting data MySQLDataEx::MySQLDataEx(MDIWindow* pmdi) { @@ -178,7 +179,6 @@ MySQLDataEx::Free() m_pmdi->m_tunnel->mysql_free_result(m_fieldres); } - //free key result if(m_keyres) { @@ -967,8 +967,7 @@ DataView::IsColumnReadOnly(wyInt32 col) wyInt32 DataView::IsColumnVirtual(wyInt32 col) { - wyString query,db, table,column; - MYSQL_RES *fieldres = NULL; + wyString query,db, table, column; if(! IsMySQL576Maria52(m_wnd->m_tunnel, &m_wnd->m_mysql)) return 0; @@ -982,34 +981,22 @@ DataView::IsColumnVirtual(wyInt32 col) else { - //get the db and table name - if(GetDBName(db, col) == wyTrue && GetTableName(table, col) == wyTrue && GetColumnName(column, col) == wyTrue) - { - query.Sprintf("show full fields from `%s`.`%s` WHERE FIELD='%s' AND (Extra LIKE '%%VIRTUAL%%' OR Extra LIKE '%%STORED%%' OR Extra LIKE '%%PERSISTENT%%')", db.GetString(), table.GetString(),column.GetString()); - fieldres = SjaExecuteAndGetResult(m_wnd->m_tunnel,&m_wnd->m_mysql,query); - - if(fieldres) + if (GetColumnName(column, col)) { + if (m_data->m_fieldres && IsFieldVirtual(m_wnd->m_tunnel, m_data->m_fieldres, column)) { - if(fieldres->row_count == 1) - { - m_data->m_colvirtual[col] = 1; - } - else - { - m_data->m_colvirtual[col] = 0; - } - - m_wnd->m_tunnel->mysql_free_result(fieldres); + m_data->m_colvirtual[col] = 1; + } + else + { + m_data->m_colvirtual[col] = 0; } - } return m_data->m_colvirtual[col]; } } - - else + else return 0; } @@ -5987,6 +5974,9 @@ DataView::GetViewData(wyBool selected) MYSQL_ROW myrow; MYSQL_FIELD* fields; +#ifndef COMMUNITY + m_wnd->m_tunnel->ClearXMLDoc(); +#endif COMMUNITY //get the total number of fields in the resultset. fields = m_data->m_datares->fields; numfields = m_data->m_datares->field_count; @@ -6026,7 +6016,7 @@ DataView::GetViewData(wyBool selected) esclen = strlen(fescape)+ strlen(lescape)+ 5; m_totalsize = GetTotalMemSize(&cesv, selected, esclen); - + if(m_totalsize <= 0) { return 0; @@ -6035,7 +6025,7 @@ DataView::GetViewData(wyBool selected) ret = OpenClipboard(m_hwndgrid); ret = EmptyClipboard(); ret = CloseClipboard(); - + hglbcopy = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, m_totalsize); // check whether so much pof memory has been allocated or not. @@ -6051,7 +6041,7 @@ DataView::GetViewData(wyBool selected) // can copy the data into the memory. lpstrcopy = (wyWChar*)GlobalLock(hglbcopy); nsize = 0; - //Add filednames if required + //Add fieldnames if required if(cesv.m_esch.m_isincludefieldnames) { for(i = 0; i < numfields; i++) @@ -6112,87 +6102,84 @@ DataView::GetViewData(wyBool selected) rowcount = m_data->m_rowarray->GetLength(); selectedrow = CustomGrid_GetCurSelRow(m_hwndgrid); - - for(j=0; jm_checkcount == 0) + if (selected == wyTrue && m_data->m_checkcount == 0) { - tj = j = selectedrow; + tj = j = selectedrow; copyselectedrow = wyTrue; } - //no need to copy unsaved rows.if it is an unsaved row IsNewRow(GetCurrentRow(GetBase(), j),j) will return wyTrue - else if((selected == wyTrue && m_data->m_rowarray->GetRowExAt(j)->m_ischecked == wyFalse && copyselectedrow == wyFalse) - || (m_data->m_rowarray->GetRowExAt(j)->IsNewRow() || j == m_data->m_modifiedrow)) + else if ((selected == wyTrue && m_data->m_rowarray->GetRowExAt(j)->m_ischecked == wyFalse && copyselectedrow == wyFalse) + || (m_data->m_rowarray->GetRowExAt(j)->IsNewRow() || j == m_data->m_modifiedrow)) { - continue; + continue; } // if we found any row in the result set that's been checked. isrowchecked = wyTrue; - myrow = m_data->m_rowarray->GetRowExAt(tj)->m_row; + myrow = m_data->m_rowarray->GetRowExAt(tj)->m_row; GetColLengthArray(myrow, numfields, len); length = len; - - for(i=0; i fields[i].name_length) { - nsize += fields[i].max_length * 2 + 1; + nsize += fields[i].max_length * sizeof(wyWChar) + 1; } else { - nsize += fields[i].name_length * 2 + 1; + nsize += fields[i].name_length * sizeof(wyWChar) + 1; } } else { if(fields[i].max_length == 0) { - nsize += strlen(fields[i].name) * 2 + 1; + nsize += strlen(fields[i].name) * sizeof(wyWChar) + 1; } else { - nsize += fields[i].max_length * 2 + 1; + nsize += fields[i].max_length * sizeof(wyWChar) + 1; } } } @@ -6257,6 +6245,9 @@ DataView::GetTotalMemSize(ExportCsv *cesv, wyBool selected, wyInt32 esclen) //if its selected i.e. user wants to copy only selected rows then //we have to allocate memory only for the selected rows selrowcount = m_data->m_checkcount; + if (selrowcount == 0 && selected) { + selrowcount = 1; + } if(selected == wyTrue) { @@ -6289,8 +6280,8 @@ DataView::VerifyMemory(HGLOBAL* hglobal, LPWSTR* buffer, wyUInt32 nsize, wyUInt3 //check for a potential buffer overrun if((nsize + sizetobeadded) * sizeof(wyWChar) > m_totalsize - 2) { - //reallocate the memory - m_totalsize += nsize + sizetobeadded + 2; + //reallocate the memory (m_totalsize is in bytes) + m_totalsize += (nsize + sizetobeadded) * sizeof(wyWChar) + 2; GlobalUnlock(*hglobal); htemp = GlobalReAlloc(*hglobal, m_totalsize, GMEM_MOVEABLE | GMEM_ZEROINIT); @@ -6538,7 +6529,7 @@ DataView::AddSelDataToClipBoard() SetCursor(hcursor); ShowCursor(1); - + if(!(OpenClipboard(m_hwndgrid))) { return wyFalse; @@ -7502,13 +7493,13 @@ DataView::GetTableDetails() return TE_STOPPED; } - //show any errors - if(!fieldres) - { - HandleErrors(query); - m_wnd->m_tunnel->mysql_free_result(myres); - return TE_ERROR; - } + //show any errors + if (!fieldres) + { + HandleErrors(query); + m_wnd->m_tunnel->mysql_free_result(myres); + return TE_ERROR; + } //get the key res @@ -7543,13 +7534,13 @@ DataView::GetTableDetails() m_data->m_createtablestmt.SetAs(myrow[1], m_wnd->m_ismysql41); m_wnd->m_tunnel->mysql_free_result(myres); - //free any existing fied res + //free any existing fields res if(m_data->m_fieldres) { m_wnd->m_tunnel->mysql_free_result(m_data->m_fieldres); } - //free any existing key res + //free any existing key res if(m_data->m_keyres) { m_wnd->m_tunnel->mysql_free_result(m_data->m_keyres); diff --git a/src/ExportAsSQL.cpp b/src/ExportAsSQL.cpp index 8960905..f9b3916 100644 --- a/src/ExportAsSQL.cpp +++ b/src/ExportAsSQL.cpp @@ -886,6 +886,16 @@ MySQLDump::ConnectToDataBaseNext() conn.m_clikey.SetAs(m_clikey); conn.m_cipher.SetAs(m_cipher); + //If CA-cert is not provided then m_no_ca = TRUE + if (conn.m_cacert.Compare("") == 0) + { + conn.m_no_ca = wyTrue; + } + else + { + conn.m_no_ca = wyFalse; + } + if(!m_tunnel->IsTunnel()) SetMySQLOptions(&conn, m_tunnel, &m_mysql, wyFalse); diff --git a/src/FrameWindowHelper.cpp b/src/FrameWindowHelper.cpp index 158780b..25bf4db 100644 --- a/src/FrameWindowHelper.cpp +++ b/src/FrameWindowHelper.cpp @@ -2552,6 +2552,38 @@ IsColumnPrimary(Tunnel *tunnel, MYSQL_RES *myfieldres, wyChar *column) return wyFalse; } +// function searches for the column name in the key res and finds if its part of a primary key column +wyBool +IsFieldVirtual(Tunnel *tunnel, MYSQL_RES *myfieldres, wyString& column) +{ + wyUInt32 count, field; + + MYSQL_ROW myrow; + + if (!myfieldres) + return wyFalse; + + if ((field = GetFieldIndex(myfieldres, "extra", tunnel)) == -1) + return wyFalse; + + for (count = 0; count < myfieldres->row_count; count++) + { + tunnel->mysql_data_seek(myfieldres, count); + + myrow = tunnel->mysql_fetch_row(myfieldres); + + if (column.Compare(myrow[0]) == 0 + && (strstr(myrow[field], "VIRTUAL") + || strstr(myrow[field], "STORED") + || strstr(myrow[field], "PERSISTENT") + ) + ) + return wyTrue; + } + + return wyFalse; +} + // Function reads the global .ini file and returns whether to warn user on update row // problem wyBool @@ -3145,7 +3177,16 @@ GetColLengthArray(MYSQL_ROW row, wyInt32 col, wyUInt32 *len) arr = len; // loop thru and get the length of each field - for (; ((INT)i) <= (col + 1); column++, arr++) + // Note that column is incremented to next after last column in the row to get the byte position exactly after end of last column + // and caclulate actual size of last column, that's why i starts from 0 and ends at <= col, not < col. When i is 0, no length is caclulated, + // as both column is at beginning of first column (row) and start is NULL. The first iteration is used to move the column pointer to second column + // (or position immediately after first column in case of 1 column row) and begin actual caclulating of bytes from this position to start position + // which is now in the beginning of first column. Next iterations column and start pointers move accordingly to calculate next columns until last one + // is calculated. There was a bug - the loop continued to i <= (col+1) which effectively makes the column and start pointers moving one more time after + // last column was calculated so start becomes the position after last column and column pointer points to sizeof(column) AFTER actual last column end byte. + // This meant that on last loop cycle a falacy column size was calculated in undefined memory space, which could be in process heap (nothing happens, except + // a fictional field size is saved as one more member of len array) or some other process or system memory space, which causes OS to immediately kill the app. + for (; ((INT)i) <= col; column++, arr++) { if (!*column) { diff --git a/src/GUIHelper.cpp b/src/GUIHelper.cpp index 4536a3d..59b9291 100644 --- a/src/GUIHelper.cpp +++ b/src/GUIHelper.cpp @@ -1692,6 +1692,7 @@ InitConInfo(ConnectionInfo &consrc, ConnectionInfo &contgt) contgt.m_issslchecked = consrc.m_issslchecked; contgt.m_issslauthchecked = consrc.m_issslauthchecked; + contgt.m_no_ca = consrc.m_no_ca; contgt.m_clicert.SetAs(consrc.m_clicert); contgt.m_clikey.SetAs(consrc.m_clikey); contgt.m_cacert.SetAs(consrc.m_cacert); @@ -1709,6 +1710,9 @@ InitConInfo(ConnectionInfo &consrc, ConnectionInfo &contgt) contgt.m_isglobalsqlmode = consrc.m_isglobalsqlmode; contgt.m_sqlmode.SetAs(consrc.m_sqlmode); contgt.m_initcommand.SetAs(consrc.m_initcommand); + + contgt.m_isazuredb = consrc.m_isazuredb; + contgt.m_connection_id = consrc.m_connection_id; } @@ -1742,6 +1746,7 @@ InitializeConnectionInfo(ConnectionInfo &con) // con.m_ispwdcleartext = wyFalse; con.m_isstorepwd = wyFalse; con.m_ishttp = wyFalse; + con.m_no_ca = wyFalse; } void @@ -9822,8 +9827,14 @@ wyBool GetSessionDetailsFromTable(wyWChar* path, ConnectionInfo *conninfo, wyInt colval = sqliteobj->GetText(&res , "CA"); - if(colval) + if (colval) { conninfo->m_cacert.SetAs(colval); + } + + if(conninfo->m_cacert.GetLength()) + conninfo->m_no_ca = wyFalse; + else + conninfo->m_no_ca = wyTrue; colval = sqliteobj->GetText(&res , "Cipher"); if(colval) diff --git a/src/MDIWindow.cpp b/src/MDIWindow.cpp index 091d752..695124a 100644 --- a/src/MDIWindow.cpp +++ b/src/MDIWindow.cpp @@ -166,6 +166,7 @@ MDIWindow::MDIWindow(HWND hwnd, ConnectionInfo * conninfo, wyString &dbname, wyS m_isfromsaveas = wyFalse; m_fromdirtytab = wyFalse; //m_tabposition = 0; + } MDIWindow::~MDIWindow() @@ -1908,6 +1909,7 @@ MDIWindow::StopQuery() MYSQL *mysql, *temp; wyWChar curdb[SIZE_512] = {0}; wyString currentdatabase; + wyInt32 thread_id; pGlobals->m_pcmainwin->GetCurrentSelDB(curdb, SIZE_512 - 1); @@ -1995,10 +1997,16 @@ MDIWindow::StopQuery() /* connection successful so now we need to kill the pid */ //DEBUG_LOG("StopQuery::mysql_kill"); - if(mysql_kill(mysql, m_mysql->thread_id)) + if (m_conninfo.m_isazuredb) + thread_id = m_conninfo.m_connection_id; + else + thread_id = m_mysql->thread_id; + + if(mysql_kill(mysql, thread_id)) { ShowMySQLError(m_hwnd, m_tunnel, &mysql, NULL, wyTrue); m_tunnel->mysql_close(temp); + ResetStopQueryExecution(); LeaveCriticalSection(&m_cs); return wyFalse; } @@ -2012,6 +2020,9 @@ MDIWindow::StopQuery() if(IsMySQL5010(m_tunnel, &m_mysql)) SetDefaultSqlMode(m_tunnel, &m_mysql, wyFalse); + if (m_conninfo.m_isazuredb) + m_conninfo.m_connection_id = GetConnectionId(m_tunnel, m_mysql); + //m_executing = wyFalse; LeaveCriticalSection(&m_cs); @@ -4488,6 +4499,16 @@ MDIWindow::StopQueryExecution() return ; } +void +MDIWindow::ResetStopQueryExecution() +{ + // Access the shared resource. + EnterCriticalSection(&m_cs); + m_stopquery = 0; + LeaveCriticalSection(&m_cs); + return; +} + wyBool MDIWindow::IsStopQueryVariableReset() { @@ -4555,7 +4576,10 @@ MDIWindow::ReConnect(Tunnel * tunnel, PMYSQL mysql, wyBool isssh, wyBool isimpor if(isprofile == wyTrue && currentdb.GetLength() && UseDatabase(currentdb, *mysql, tunnel) == wyFalse) return wyFalse; - + if (m_conninfo.m_isazuredb) { + m_conninfo.m_connection_id = GetConnectionId(tunnel, *mysql); + } + /* if its tunnel then we need the server version */ if(tunnel->IsTunnel()) { diff --git a/src/MySQLVersionHelper.cpp b/src/MySQLVersionHelper.cpp index d4dfece..2395072 100644 --- a/src/MySQLVersionHelper.cpp +++ b/src/MySQLVersionHelper.cpp @@ -311,8 +311,9 @@ wyBool IsMySQL800(PMYSQL mysql) { wyUInt32 me = mysql_get_server_version(*mysql);/* Only available from MySQLv8.0*/ + const char *dbString = mysql_get_server_info(*mysql); - if (me >= 80000) + if (me >= 80000 && !strstr(dbString, "MariaDB")) return wyTrue; else return wyFalse; diff --git a/src/ObjectInfo.cpp b/src/ObjectInfo.cpp index 557ef5c..ee4e9bf 100644 --- a/src/ObjectInfo.cpp +++ b/src/ObjectInfo.cpp @@ -3621,7 +3621,7 @@ ObjectInfo::FormatTextModeSQLStatement(MDIWindow* wnd, const wyChar* objectname, if(strtpos != -1) { - strcolumn.Replace(strtpos, strlen(tok) + 1, ""); + strcolumn.Replace(strtpos, strlen(tok) , ""); } tok = strtok(NULL, ","); diff --git a/src/TabIndexes.cpp b/src/TabIndexes.cpp index 690db5a..2e0f355 100644 --- a/src/TabIndexes.cpp +++ b/src/TabIndexes.cpp @@ -43,7 +43,6 @@ extern PGLOBALS pGlobals; #define UM_GRIDROWFOCUSCHANGE 4628 - IndexColumn::IndexColumn(FieldStructWrapper *value) { m_pcwrapobj = value; @@ -188,7 +187,7 @@ TabIndexes::FetchIndexValuesIntoWrapper() MYSQL_RES *myres; MYSQL_ROW myrow; wyString tblname(""), dbname(""); - wyString tobeignoredstr,colstr, indexname(""), indcolsstr(""), indexlength(""),indexcomment(""), indexorder(""), previndexvisibility(""), indexvisibility(""); + wyString tobeignoredstr,colstr, indexname(""), indcolsstr(""), indexlength(""),indexcomment(""), indexorder(""), indexvisibility(""); wyBool isunique = wyFalse, isfulltext = wyFalse; wyInt32 ind_keyname = -1, ind_colname = -1, ind_subpart = -1, ind_nonunique = -1, ind_indextype = -1,ind_indexcomment= -1, ind_indexorder=-1, ind_indexvis=-1; IndexesStructWrapper *cwrapobj = NULL; @@ -451,7 +450,7 @@ TabIndexes::FetchIndexValuesIntoWrapper() iindex->m_visible.SetAs(indexvisibility.GetString()); if(m_ismysql553) - iindex->m_indexcomment.SetAs(indexcomment.GetString()); + iindex->m_indexcomment.SetAs(indexcomment.GetString()); //..Sets the index type if(isunique) { @@ -562,7 +561,7 @@ TabIndexes::InitDlgGrid() //} // Just show order column if db supports ordering:: Note: - // MDB "accepts" asc/desc but does not uses it. as of 10.3.21 at least. + // MDB "accepts" asc/desc but does not use it. as of 10.3.21 at least. memset(&gvcol, 0, sizeof(gvcol)); @@ -2057,7 +2056,7 @@ TabIndexes::FillInitValues() CustomGrid_SetColumnReadOnly(m_hgridindexes, row, INDEXVISIBILITY, wyTrue); if(m_ismysql553) - CustomGrid_SetText(m_hgridindexes, row, INDEXCOMMENT,cwrapobj->m_oldval->m_indexcomment.GetString()); + CustomGrid_SetText(m_hgridindexes, row, INDEXCOMMENT,cwrapobj->m_oldval->m_indexcomment.GetString()); CustomGrid_SetRowLongData(m_hgridindexes, row, (LPARAM) cwrapobj); @@ -2697,7 +2696,8 @@ TabIndexes::GetNewAndModifiedIndexes(wyString &query, wyBool execute) visibilitystr.SetAs(""); if(m_ismysql553) - GetGridCellData(m_hgridindexes, row, INDEXCOMMENT, indexcomment); + GetGridCellData(m_hgridindexes, row, INDEXCOMMENT, indexcomment); + if(!indextypestr.GetLength()) indextypestr.SetAs("index"); else diff --git a/src/TabModule.cpp b/src/TabModule.cpp index 0227219..a455664 100644 --- a/src/TabModule.cpp +++ b/src/TabModule.cpp @@ -2559,8 +2559,7 @@ TabModule::SetTabRename(wyWChar *name, wyBool isedited,MDIWindow *wnd, wyBool is if (node2->tabtype == querytab) { //Fix to update sequence number from old and new session - s2.SetAs(newname.GetString()); - s2.SetAs(s2.Substr(0, 5)); + s2.SetAs(newname.Substr(0, 5)); s2.LTrim(); s2.RTrim(); diff --git a/src/TunnelCommunity.cpp b/src/TunnelCommunity.cpp index 88872bd..a265e8e 100644 --- a/src/TunnelCommunity.cpp +++ b/src/TunnelCommunity.cpp @@ -320,6 +320,11 @@ TunnelCommunity::EmptyQueryBuffer() VERIFY(false); } +void +TunnelCommunity::ClearXMLDoc() +{ + VERIFY(false); +} bool TunnelCommunity::CheckCorrectTunnelVersion(MYSQL * mysql) diff --git a/src/wyIni.cpp b/src/wyIni.cpp index 3f4db8e..46ec451 100644 --- a/src/wyIni.cpp +++ b/src/wyIni.cpp @@ -548,11 +548,11 @@ wyBool wyIni::LoadFile(const wyChar *filename, const wyChar* secname, const wyChar* keyname) { FILE *in_stream; - wyChar buffer[1024]; // earlier size is 255, then if it contains more than 255 then it is truncating. + wyChar buffer[2048]; // earlier size is 255, then if it contains more than 255 then it is truncating. Size increased to 2048 as password limit is set to 2048. wyChar comments[1024]; - wyChar current_section[1024]; + wyChar current_section[2048]; wyChar key[1024]; - wyChar value[1024]; + wyChar value[2048]; wyChar *pdest; wyInt32 index; wyInt32 c = 0; diff --git a/src/wyString.cpp b/src/wyString.cpp index 358845c..dce73cb 100644 --- a/src/wyString.cpp +++ b/src/wyString.cpp @@ -1578,7 +1578,7 @@ void wyString::EscapeNullFromPassword() void wyString::DecodeBase64Password(wyString &pwdstr) { wyChar *decodedstr = NULL; - decodedstr = AllocateBuff(512); + decodedstr = AllocateBuff(2048*2); wyInt32 len = DecodeBase64(pwdstr.GetString(), decodedstr); pwdstr.SetAsDirect(decodedstr, len); @@ -1588,7 +1588,7 @@ void wyString::DecodeBase64Password(wyString &pwdstr) wyChar* wyString::EncodeBase64Password() { - wyChar *encodestr = AllocateBuff(512); + wyChar *encodestr = AllocateBuff(2048*2); EncodeBase64(GetString(), GetLength(), &encodestr); return encodestr; } \ No newline at end of file