From 1465e86e80a44093e45eaa793f92822b192e41c0 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Wed, 27 Mar 2024 09:42:43 -0600 Subject: [PATCH 01/12] Fixed bug where updating PK field would cause the OSML to lose the DB object --- centrallix/osdrivers/objdrv_mysql.c | 64 ++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/centrallix/osdrivers/objdrv_mysql.c b/centrallix/osdrivers/objdrv_mysql.c index d776309fe..4a56858f0 100644 --- a/centrallix/osdrivers/objdrv_mysql.c +++ b/centrallix/osdrivers/objdrv_mysql.c @@ -1179,6 +1179,62 @@ mysd_internal_BuildAutoname(pMysdData inf, pMysdConn conn, pObjTrxTree oxt) return rval; } +/*** mysd_internal_UpdateName() - check an updated row and update the row if need be +***/ +int +mysd_internal_UpdateName(pMysdData data, char * newval, int col) + { + int i, j; + char *start, *end; + int curLen; + int newLen; + int fullLen; + int jump; + + /** If the updated value is part of a primary key, update the object name **/ + for(i = 0 ; i < data->TData->nKeys ; i++) + { + if(data->TData->KeyCols[i] == col && newval) + { + + fullLen = strlen(data->Objname); + /* find the start and end of the field to edit*/ + start = data->Objname; + for(j = 0 ; j < i ; j++) start = strchr(start, '|')+1; + end = strchr(start, '|'); + if(!end) end = data->Objname + fullLen - 1; /* make sure to account for if the string is at the end */ + end -= 1; + + /* check if new item will fit */ + curLen = end - start + 1; + newLen = strlen(newval); + if(fullLen - curLen + newLen >= sizeof(data->Objname)) + { + mssError(1,"MYSD","Cannot change object '%s' name to include '%s': name exceeds max length.", + data->Objname, newval); + return -1; + } + + /* shift over existing items to make room */ + jump = newLen - curLen; + if(jump > 0) + { + for(j = fullLen + jump ; j > (start - data->Objname) + (newLen - 1); j--) + data->Objname[j] = data->Objname[j-jump]; + } + else if(jump < 0) + { + for(j = start - data->Objname + 1 ; j < fullLen + jump + 1; j++) + data->Objname[j] = data->Objname[j-jump]; + } + + /* copy over the new value */ + for(j = 0 ; j < newLen ; j++) start[j] = newval[j]; + break; + } + } + return 0; + } /*** mysd_internal_UpdateRow() - update a given row ***/ @@ -2974,6 +3030,7 @@ mysdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr int type; DateTime dt; ObjData od; + char * valStr; type = mysdGetAttrType(inf, attrname, oxt); /** Choose the attr name **/ @@ -3072,13 +3129,16 @@ mysdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr } else if(datatype == DATA_T_DOUBLE || datatype == DATA_T_INTEGER) { - if(mysd_internal_UpdateRow(inf,mysd_internal_CxDataToMySQL(datatype,(ObjData*)val),i) < 0) return -1; + valStr = mysd_internal_CxDataToMySQL(datatype,(ObjData*)val); + if(mysd_internal_UpdateRow(inf,valStr,i) < 0) return -1; } else { - if(mysd_internal_UpdateRow(inf,mysd_internal_CxDataToMySQL(datatype,*(ObjData**)val),i) < 0) return -1; + valStr = mysd_internal_CxDataToMySQL(datatype,*(ObjData**)val); + if(mysd_internal_UpdateRow(inf,valStr,i) < 0) return -1; } } + mysd_internal_UpdateName(inf, valStr, i); } } } From 3171268e9d4b960f81c0cee4259e18296bde225a Mon Sep 17 00:00:00 2001 From: Noah Board Date: Wed, 27 Mar 2024 16:48:37 -0600 Subject: [PATCH 02/12] Updated the shift logic to avoid redundant work. Fixed bug when picking end ptr for the last key --- centrallix/osdrivers/objdrv_mysql.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/centrallix/osdrivers/objdrv_mysql.c b/centrallix/osdrivers/objdrv_mysql.c index 4a56858f0..5a71cc178 100644 --- a/centrallix/osdrivers/objdrv_mysql.c +++ b/centrallix/osdrivers/objdrv_mysql.c @@ -1201,9 +1201,8 @@ mysd_internal_UpdateName(pMysdData data, char * newval, int col) /* find the start and end of the field to edit*/ start = data->Objname; for(j = 0 ; j < i ; j++) start = strchr(start, '|')+1; - end = strchr(start, '|'); - if(!end) end = data->Objname + fullLen - 1; /* make sure to account for if the string is at the end */ - end -= 1; + end = strchr(start, '|') - 1; + if(end == (char*) -1) end = data->Objname + fullLen -1; /* make sure to account for if the string is at the end */ /* check if new item will fit */ curLen = end - start + 1; @@ -1219,12 +1218,16 @@ mysd_internal_UpdateName(pMysdData data, char * newval, int col) jump = newLen - curLen; if(jump > 0) { + /* shift data to the right working right to left. + Done once copied to the location right after where the new value will end */ for(j = fullLen + jump ; j > (start - data->Objname) + (newLen - 1); j--) data->Objname[j] = data->Objname[j-jump]; } else if(jump < 0) { - for(j = start - data->Objname + 1 ; j < fullLen + jump + 1; j++) + /* shift data to the left, working left to right. + Done once copied to the location where the full string will end */ + for(j = start - data->Objname + newLen ; j < fullLen + jump + 1; j++) data->Objname[j] = data->Objname[j-jump]; } From 91a13e66eb222e3cc00a1b65a202f066c495a3c1 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Thu, 11 Apr 2024 09:52:02 -0600 Subject: [PATCH 03/12] Fixed bug when updating PK field and any other field at same time. Changed how datetimes are added to path names. --- centrallix/osdrivers/objdrv_sybase.c | 89 ++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 4 deletions(-) diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 0c505eb69..d44a14d47 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -692,7 +692,7 @@ sybd_internal_GetCxType(int ut) if (ut == 11 || ut == 21) return DATA_T_MONEY; if (!CxGlobals.QuietInit) - mssError(1, "SYBD", "the usertype %d is not supported by Centrallix"); + mssError(1, "SYBD", "the usertype %d is not supported by Centrallix", ut); return -1; } @@ -1628,6 +1628,7 @@ sybd_internal_KeyToFilename(pSybdTableInf tdata, pSybdData inf) unsigned long long col64; ObjData val; MoneyType m; + DateTime dt; char* mstr; /** Get pointers to the key data. **/ @@ -1659,8 +1660,13 @@ sybd_internal_KeyToFilename(pSybdTableInf tdata, pSybdData inf) break; case 22: /** date value **/ case 12: /** date value **/ + /* convert to a more useable form */ memcpy(&col64, inf->ColPtrs[tdata->KeyCols[i]], 8); - snprintf(ptr,n_left,"%8.8llX",col64); + val.DateTime = &dt; + if(sybd_internal_GetCxValue(&col64, 22, &val, DATA_T_DATETIME) < 0) + return NULL; + mstr = objFormatDateTmp(val.DateTime, obj_default_date_fmt); + if (mstr) snprintf(ptr, n_left, "%s", mstr); break; case 7: /** INT **/ memcpy(&col, inf->ColPtrs[tdata->KeyCols[i]], 4); @@ -4411,6 +4417,73 @@ sybdGetFirstAttr(void* inf_v, pObjTrxTree* oxt) return ptr; } +int +sybd_internal_UpdateName(pSybdData inf, char* attrVal, int colInd, int type) + { + int newLen, oldLen; + int i; + int pkInd = -1; + char* start = inf->RowColPtr; + char* end; + + /** shouldn't be possible, but verify that the string is not null **/ + if(!attrVal) + { + mssError(1,"SYBD","Cannot update path: A PK value is being set to NULL"); + return -1; + } + + newLen = strlen(attrVal); + // if the name is too long, trim it down like it will be on insert; must match. + if(newLen > inf->TData->ColLengths[colInd] && type == DATA_T_STRING) + { + attrVal[inf->TData->ColLengths[colInd]] = '\0'; + newLen = inf->TData->ColLengths[colInd]; + } + + // find which key in pk this is + for(i = 0 ; i < inf->TData->nKeys ; i++) + { + if(colInd == inf->TData->KeyCols[i]) + { + pkInd = i; + break; + } + } + if(pkInd == -1) + { + mssError(1,"SYBD","Cannot update path: can not identify which part of PK is being changed"); + return -1; + } + + // get the start and end of the part that needs replaced + for(i = 0 ; i < pkInd ; i++) + { + start = strchr(start, '|') + 1; + if(start == (char*) 1) + { + mssError(1,"SYBD","Cannot update path: path contains fewer values than the table has keys"); + return -1; + } + } + end = strchr(start, '|'); + if(!end) end = start+strlen(start); + oldLen = (int) (end - start); + + // make sure has enough room to resize + if((strlen(inf->RowColPtr) - oldLen + newLen) + (inf->RowColPtr - inf->Pathname.Pathbuf) >= sizeof(inf->Pathname.Pathbuf)) + { + mssError(1,"SYBD","Cannot update path: Can not fit new key value in Pathbuf"); + return -1; + } + + // now shift things over + memmove(start+newLen, end, strlen(end)+1); //make sure it moves the null as well + // now copy in the new value + memcpy(start, attrVal, newLen); + + return 0; + } /*** sybdSetAttrValue - sets the value of an attribute. 'val' must *** point to an appropriate data type. @@ -4427,6 +4500,7 @@ sybdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr pXString xs; char* ptr; CS_INT restype = 0; + char * tempStr = NULL; /** Choose the attr name **/ if (!strcmp(attrname,"name")) @@ -4607,21 +4681,25 @@ sybdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr { xsPrintf(xs,"UPDATE %s SET %s=%s WHERE %s",inf->TablePtr, attrname,objDataToStringTmp(type,val,DATA_F_QUOTED | DATA_F_SYBQUOTE), ptr); + tempStr = objDataToStringTmp(type,val,0); // need to get value without quotes } else if (type == DATA_T_STRING) { /** objDataToString quotes strings **/ xsPrintf(xs,"UPDATE %s SET %s=%s WHERE %s",inf->TablePtr, attrname, objDataToStringTmp(type,*(void**)val,DATA_F_QUOTED | DATA_F_SYBQUOTE), ptr); + tempStr = objDataToStringTmp(type,*(void**)val,0); // need without quote } else if (type == DATA_T_MONEY) { + tempStr = objFormatMoneyTmp(*(void**)val, "0.0000"); xsPrintf(xs,"UPDATE %s SET %s=%s WHERE %s",inf->TablePtr, attrname, - objFormatMoneyTmp(*(void**)val, "0.0000"), ptr); + tempStr, ptr); } else if (type == DATA_T_DATETIME) { + tempStr = objFormatDateTmp(*(void**)val, obj_default_date_fmt); xsPrintf(xs,"UPDATE %s SET %s=\"%s\" WHERE %s",inf->TablePtr, attrname, - objFormatDateTmp(*(void**)val, obj_default_date_fmt), ptr); + tempStr, ptr); } /** Start the update. **/ @@ -4643,6 +4721,9 @@ sybdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr ** need to give feedback to the user on what other effects ** the update operation may have had. **/ + /* if it is a PK, need to change the object name so it can be located properly */ + if(is_key) sybd_internal_UpdateName(inf, tempStr, i, type); + if (sybd_internal_LookupRow(conn, inf) <= 0) { if (is_key) From 83a7688c5b0ec6aaa2a2ef353cba486084781d84 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Thu, 11 Apr 2024 13:38:11 -0600 Subject: [PATCH 04/12] Fixed bug where invalid key types would cause old values to appear in the path name --- centrallix/osdrivers/objdrv_sybase.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index d44a14d47..3b2f93d5f 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -1690,6 +1690,10 @@ sybd_internal_KeyToFilename(pSybdTableInf tdata, pSybdData inf) n--; snprintf(ptr,n_left,"%*.*s", n, n, inf->ColPtrs[tdata->KeyCols[i]]); break; + default: + mssError(1,"SYBD","Error - key/object type %d is not supported as a PK", tdata->ColTypes[tdata->KeyCols[i]]); + /* add a null to the end so the rest of the it can be generated properly */ + ptr[0] = '\0'; } } else From edf54a25b0f1314f2cda172d16d80202f7fd751e Mon Sep 17 00:00:00 2001 From: Noah Board Date: Thu, 11 Apr 2024 17:50:18 -0600 Subject: [PATCH 05/12] Updated mysql driver path rename to be less complex --- centrallix/osdrivers/objdrv_mysql.c | 94 +++++++++++++++-------------- 1 file changed, 48 insertions(+), 46 deletions(-) diff --git a/centrallix/osdrivers/objdrv_mysql.c b/centrallix/osdrivers/objdrv_mysql.c index 5a71cc178..34c099f2b 100644 --- a/centrallix/osdrivers/objdrv_mysql.c +++ b/centrallix/osdrivers/objdrv_mysql.c @@ -1182,60 +1182,62 @@ mysd_internal_BuildAutoname(pMysdData inf, pMysdConn conn, pObjTrxTree oxt) /*** mysd_internal_UpdateName() - check an updated row and update the row if need be ***/ int -mysd_internal_UpdateName(pMysdData data, char * newval, int col) +mysd_internal_UpdateName(pMysdData data, char * newval, int colInd, int type) { - int i, j; + int j; + int keyInd = -1; char *start, *end; - int curLen; - int newLen; - int fullLen; - int jump; + int oldLen, newLen, fullLen; - /** If the updated value is part of a primary key, update the object name **/ - for(i = 0 ; i < data->TData->nKeys ; i++) + /** find the PK index for the column. If it is not part of the pk, exit **/ + for(j = 0 ; j < data->TData->nKeys ; j++) { - if(data->TData->KeyCols[i] == col && newval) + if(data->TData->KeyCols[j] == colInd) { + keyInd = j; + break; + } + } + if (keyInd == -1 || !newval) return 0; - fullLen = strlen(data->Objname); - /* find the start and end of the field to edit*/ - start = data->Objname; - for(j = 0 ; j < i ; j++) start = strchr(start, '|')+1; - end = strchr(start, '|') - 1; - if(end == (char*) -1) end = data->Objname + fullLen -1; /* make sure to account for if the string is at the end */ - - /* check if new item will fit */ - curLen = end - start + 1; - newLen = strlen(newval); - if(fullLen - curLen + newLen >= sizeof(data->Objname)) - { - mssError(1,"MYSD","Cannot change object '%s' name to include '%s': name exceeds max length.", - data->Objname, newval); - return -1; - } + /* if it is a string and is too long, truncate it to match what will be stored */ + newLen = strlen(newval); + if(newLen > data->TData->ColLengths[colInd] && type == DATA_T_STRING) + { + newval[data->TData->ColLengths[colInd]] = '\0'; + newLen = data->TData->ColLengths[colInd]; + } - /* shift over existing items to make room */ - jump = newLen - curLen; - if(jump > 0) - { - /* shift data to the right working right to left. - Done once copied to the location right after where the new value will end */ - for(j = fullLen + jump ; j > (start - data->Objname) + (newLen - 1); j--) - data->Objname[j] = data->Objname[j-jump]; - } - else if(jump < 0) - { - /* shift data to the left, working left to right. - Done once copied to the location where the full string will end */ - for(j = start - data->Objname + newLen ; j < fullLen + jump + 1; j++) - data->Objname[j] = data->Objname[j-jump]; - } - - /* copy over the new value */ - for(j = 0 ; j < newLen ; j++) start[j] = newval[j]; - break; + fullLen = strlen(data->Objname); + /* find the start and end of the field to edit*/ + start = data->Objname; + for(j = 0 ; j < keyInd ; j++) + { + start = strchr(start, '|')+1; + if(start == (char*) 1) /* make sure has enough fields */ + { + mssError(1,"MYSD","Cannot change object '%s' name to include '%s': too few fields in name.", + data->Objname, newval); + return -1; } } + end = strchr(start, '|'); + if(!end) end = data->Objname + fullLen; /* make sure to account for if the string is at the end */ + + /* check if new item will fit */ + oldLen = end - start; + if(fullLen - oldLen + newLen >= sizeof(data->Objname)) + { + mssError(1,"MYSD","Cannot change object '%s' name to include '%s': name exceeds max length.", + data->Objname, newval); + return -1; + } + + /* shift over existing items to make room */ + memmove(start+newLen, end, strlen(end)+1); + /* copy over the new value */ + memcpy(start, newval, newLen); + return 0; } @@ -3141,7 +3143,7 @@ mysdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr if(mysd_internal_UpdateRow(inf,valStr,i) < 0) return -1; } } - mysd_internal_UpdateName(inf, valStr, i); + mysd_internal_UpdateName(inf, valStr, i, type); } } } From 829798647815dbbbf99faa3a61c28b7486c47d49 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Fri, 12 Apr 2024 16:48:03 -0600 Subject: [PATCH 06/12] cleaned up mysql code --- centrallix/osdrivers/objdrv_mysql.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/centrallix/osdrivers/objdrv_mysql.c b/centrallix/osdrivers/objdrv_mysql.c index 34c099f2b..df71614ff 100644 --- a/centrallix/osdrivers/objdrv_mysql.c +++ b/centrallix/osdrivers/objdrv_mysql.c @@ -1184,17 +1184,17 @@ mysd_internal_BuildAutoname(pMysdData inf, pMysdConn conn, pObjTrxTree oxt) int mysd_internal_UpdateName(pMysdData data, char * newval, int colInd, int type) { - int j; + int i; int keyInd = -1; char *start, *end; int oldLen, newLen, fullLen; /** find the PK index for the column. If it is not part of the pk, exit **/ - for(j = 0 ; j < data->TData->nKeys ; j++) + for(i = 0 ; i < data->TData->nKeys ; i++) { - if(data->TData->KeyCols[j] == colInd) + if(data->TData->KeyCols[i] == colInd) { - keyInd = j; + keyInd = i; break; } } @@ -1211,7 +1211,7 @@ mysd_internal_UpdateName(pMysdData data, char * newval, int colInd, int type) fullLen = strlen(data->Objname); /* find the start and end of the field to edit*/ start = data->Objname; - for(j = 0 ; j < keyInd ; j++) + for(i = 0 ; i < keyInd ; i++) { start = strchr(start, '|')+1; if(start == (char*) 1) /* make sure has enough fields */ From 67c5fe0f88504fa22211b811820d572f19212f35 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Mon, 15 Apr 2024 14:46:58 -0600 Subject: [PATCH 07/12] Fixed bug preventing inserts from running properly --- centrallix/osdrivers/objdrv_mysql.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/centrallix/osdrivers/objdrv_mysql.c b/centrallix/osdrivers/objdrv_mysql.c index df71614ff..d8026f113 100644 --- a/centrallix/osdrivers/objdrv_mysql.c +++ b/centrallix/osdrivers/objdrv_mysql.c @@ -3142,8 +3142,9 @@ mysdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr valStr = mysd_internal_CxDataToMySQL(datatype,*(ObjData**)val); if(mysd_internal_UpdateRow(inf,valStr,i) < 0) return -1; } - } + // make sure this does not run for inserts or other major transactions mysd_internal_UpdateName(inf, valStr, i, type); + } } } } From 9447b261e55f96daa8b71cf0262e9d4166171744 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Fri, 3 May 2024 12:35:28 -0600 Subject: [PATCH 08/12] Updated sybase driver to handle updating strings to be empty properly. Enabled sybase to properly set datetime cols that are part of primary keys --- centrallix/osdrivers/objdrv_sybase.c | 51 ++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 3b2f93d5f..014be2849 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -2955,6 +2955,8 @@ sybd_internal_InsertRow(pSybdData inf, pSybdConn conn, pObjTrxTree oxt) int colid; int holding_sem = 0; MoneyType m; + DateTime dt; + int result; /** Allocate a buffer for our insert statement. **/ insbuf = (pXString)nmMalloc(sizeof(XString)); @@ -3025,6 +3027,27 @@ sybd_internal_InsertRow(pSybdData inf, pSybdConn conn, pObjTrxTree oxt) } kptr[len] = tmpch; } + else if (ctype == DATA_T_DATETIME) + { + tmpch = kptr[len]; + kptr[len] = 0; + if (objDataToDateTime(DATA_T_STRING, kptr, &dt, obj_default_date_fmt) == 0) + { + tmpptr = objFormatDateTmp(&dt, obj_default_date_fmt); + if (!tmpptr) + tmpptr = " NULL "; + xsConcatPrintf(insbuf, " \"%s\" ", tmpptr); + } + kptr[len] = tmpch; + } + else + { + mssError(1,"SYBD","Cannot insert a primary key column with datatype %d", ctype); + xsDeInit(insbuf); + nmFree(insbuf,sizeof(XString)); + if (holding_sem) syPostSem(inf->TData->AutonameSem, 1, 0); + return -1; + } } else { @@ -4421,6 +4444,8 @@ sybdGetFirstAttr(void* inf_v, pObjTrxTree* oxt) return ptr; } +/*** sybd_internal_UpdateName - Update the object name to match new values + ***/ int sybd_internal_UpdateName(pSybdData inf, char* attrVal, int colInd, int type) { @@ -4436,16 +4461,22 @@ sybd_internal_UpdateName(pSybdData inf, char* attrVal, int colInd, int type) mssError(1,"SYBD","Cannot update path: A PK value is being set to NULL"); return -1; } - + newLen = strlen(attrVal); - // if the name is too long, trim it down like it will be on insert; must match. + /* if the name is too long, trim it down like it will be on insert; must match. */ if(newLen > inf->TData->ColLengths[colInd] && type == DATA_T_STRING) { attrVal[inf->TData->ColLengths[colInd]] = '\0'; newLen = inf->TData->ColLengths[colInd]; } + /* convert empty strings to a single space; sybase makes the same conversion */ + else if(type == DATA_T_STRING && newLen == 0) + { + attrVal = " "; + newLen = 1; + } - // find which key in pk this is + /* find which key in pk this is */ for(i = 0 ; i < inf->TData->nKeys ; i++) { if(colInd == inf->TData->KeyCols[i]) @@ -4460,7 +4491,7 @@ sybd_internal_UpdateName(pSybdData inf, char* attrVal, int colInd, int type) return -1; } - // get the start and end of the part that needs replaced + /* get the start and end of the part that needs replaced */ for(i = 0 ; i < pkInd ; i++) { start = strchr(start, '|') + 1; @@ -4474,16 +4505,16 @@ sybd_internal_UpdateName(pSybdData inf, char* attrVal, int colInd, int type) if(!end) end = start+strlen(start); oldLen = (int) (end - start); - // make sure has enough room to resize + /* make sure has enough room to resize */ if((strlen(inf->RowColPtr) - oldLen + newLen) + (inf->RowColPtr - inf->Pathname.Pathbuf) >= sizeof(inf->Pathname.Pathbuf)) { mssError(1,"SYBD","Cannot update path: Can not fit new key value in Pathbuf"); return -1; } - // now shift things over - memmove(start+newLen, end, strlen(end)+1); //make sure it moves the null as well - // now copy in the new value + /* now shift things over */ + memmove(start+newLen, end, strlen(end)+1); /* make sure it moves the null as well */ + /* now copy in the new value */ memcpy(start, attrVal, newLen); return 0; @@ -4685,13 +4716,13 @@ sybdSetAttrValue(void* inf_v, char* attrname, int datatype, pObjData val, pObjTr { xsPrintf(xs,"UPDATE %s SET %s=%s WHERE %s",inf->TablePtr, attrname,objDataToStringTmp(type,val,DATA_F_QUOTED | DATA_F_SYBQUOTE), ptr); - tempStr = objDataToStringTmp(type,val,0); // need to get value without quotes + tempStr = objDataToStringTmp(type,val,0); /* need to get value without quotes */ } else if (type == DATA_T_STRING) { /** objDataToString quotes strings **/ xsPrintf(xs,"UPDATE %s SET %s=%s WHERE %s",inf->TablePtr, attrname, objDataToStringTmp(type,*(void**)val,DATA_F_QUOTED | DATA_F_SYBQUOTE), ptr); - tempStr = objDataToStringTmp(type,*(void**)val,0); // need without quote + tempStr = objDataToStringTmp(type,*(void**)val,0); /* need without quote */ } else if (type == DATA_T_MONEY) { From 02c76d45d0fa5f430afd5de86421b1c1d3101c76 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Thu, 9 May 2024 17:13:56 -0600 Subject: [PATCH 09/12] changed how driver handles '' for string PKs to match how sybase handles it internally --- centrallix/osdrivers/objdrv_sybase.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 014be2849..13454d152 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -2815,6 +2815,11 @@ sybd_internal_BuildAutoname(pSybdData inf, pSybdConn conn, pObjTrxTree oxt) else { ptr = objDataToStringTmp(find_oxt->AttrType, find_oxt->AttrValue, 0); + if(ptr && strlen(ptr) == 0 && find_oxt->AttrType == DATA_T_STRING) + { + /* sybase will change "" to " ", so this keeps things consistent */ + ptr = " "; + } } key_values[j] = nmSysStrdup(ptr); if (!key_values[j]) From 88e00edbca65ef10c825a9126d14ea3f56ed0f73 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Tue, 4 Jun 2024 16:57:56 -0600 Subject: [PATCH 10/12] added fixmes for sybase driver case and date bugs --- centrallix/osdrivers/objdrv_sybase.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 13454d152..b21881727 100644 --- a/centrallix/osdrivers/objdrv_sybase.c +++ b/centrallix/osdrivers/objdrv_sybase.c @@ -731,6 +731,7 @@ sybd_internal_GetCxValue(void* ptr, int ut, pObjData val, int datatype) } else if (ut==22 || ut==12) { + /** FIXME: Datetime conversion will become a day off starting in 2101 **/ val->DateTime->Value = 0; /** datetime **/ @@ -2221,6 +2222,7 @@ sybd_internal_TreeToClause(pExpression tree, pSybdNode node, pSybdConn conn, pSy xsConcatenate(where_clause, " (", 2); sybd_internal_TreeToClause(subtree,node,conn,tdata,n_tdata,where_clause); xsConcatenate(where_clause, " ", 1); + /** FIXME: If the database uses a case insensitive colation the driver will be unable to detect case differences **/ if (tree->CompareType & MLX_CMP_LESS) xsConcatenate(where_clause,"<",1); if (tree->CompareType & MLX_CMP_GREATER) xsConcatenate(where_clause,">",1); if (tree->CompareType & MLX_CMP_EQUALS) xsConcatenate(where_clause,"=",1); From 72eebeda8a97136bafd6119c70e7ba9e9a9d4ba9 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Fri, 28 Jun 2024 15:53:38 -0600 Subject: [PATCH 11/12] added automated tests for sybase database driver --- centrallix-os/tests/Test_DB | 16 +++++++++ centrallix/test_db_setup.sh | 53 +++++++++++++++++++++++++++++ centrallix/tests/test_sybase_00.cmp | 4 +++ centrallix/tests/test_sybase_00.to | 17 +++++++++ centrallix/tests/test_sybase_01.cmp | 2 ++ centrallix/tests/test_sybase_01.to | 22 ++++++++++++ centrallix/tests/test_sybase_02.cmp | 6 ++++ centrallix/tests/test_sybase_02.to | 21 ++++++++++++ centrallix/tests/test_sybase_03.cmp | 16 +++++++++ centrallix/tests/test_sybase_03.to | 38 +++++++++++++++++++++ 10 files changed, 195 insertions(+) create mode 100644 centrallix-os/tests/Test_DB create mode 100755 centrallix/test_db_setup.sh create mode 100644 centrallix/tests/test_sybase_00.cmp create mode 100644 centrallix/tests/test_sybase_00.to create mode 100644 centrallix/tests/test_sybase_01.cmp create mode 100644 centrallix/tests/test_sybase_01.to create mode 100644 centrallix/tests/test_sybase_02.cmp create mode 100644 centrallix/tests/test_sybase_02.to create mode 100644 centrallix/tests/test_sybase_03.cmp create mode 100644 centrallix/tests/test_sybase_03.to diff --git a/centrallix-os/tests/Test_DB b/centrallix-os/tests/Test_DB new file mode 100644 index 000000000..5ed662be1 --- /dev/null +++ b/centrallix-os/tests/Test_DB @@ -0,0 +1,16 @@ +$Version=2$ +Kardia_DB "application/sybase" + { + server = ""; + database = "Test_DB"; + max_connections = 200; + annot_table = "ra"; + + // Use centrallix login credentials. + use_system_auth = "no"; + username = ""; + password = ""; + + // Migrate centrallix password to mysql password. + set_passwords = "no"; + } diff --git a/centrallix/test_db_setup.sh b/centrallix/test_db_setup.sh new file mode 100755 index 000000000..936eefec1 --- /dev/null +++ b/centrallix/test_db_setup.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +#### Centrallix Test Database Setup +#### +#### Copyright (C) 2024 by LightSys Technology Services, Inc. +#### +#### FREE SOFTWARE, NO WARRANTY: This program is Free Software, licensed +#### under version 2 of the GNU General Public License, or any later +#### version of the GNU GPL published by the Free Software Foundation, at +#### your option. This program is provided AS-IS and with ABSOLUTELY NO +#### WARRANTY. See the file 'COPYING' provided with this software for +#### more information about the rights granted to you under this license. +#### +#### +#### This script creates and intializes a database and two tables for use by the automated +#### tests for either the Sybase or MySQL driver. +#### This script relies on the following eviroment variables: +#### $DB_USER - the username for login. Must be a super user. +#### $DB_PASS - the password for login +#### $DB_TEST_USER - the user that will be granted permissions to the tables for testing +#### $DB_NAME - name of the database server (sybase only) +#### +#### to use it, simply run: +#### ./test_db_setup.sh + + +# check which database to use +if [ $# != 1 ] +then + echo "ERROR: Please enter exactly one database type to run this script against" + exit +fi + +if [ ${1,,} = "sybase" ]; then + # create the new database and add the tables + echo "running against Sybase" + printf "CREATE DATABASE Test_DB\ngo\n" | isql -U$DB_USER -P$DB_PASS -S$DB_NAME + printf "CREATE TABLE typeTests (dates datetime, monies money, ints int, strings varchar(30), bits bit, floats float NULL, PRIMARY KEY(dates, monies, ints, strings))\nGO\n"| isql -U$DB_USER -P$DB_PASS -S$DB_NAME -DTest_DB + printf "sp_adduser $DB_TEST_USER\nGRANT all ON typeTests TO $DB_TEST_USER\nGO\n" | isql -U$DB_USER -P$DB_PASS -S$DB_NAME -DTest_DB + printf "CREATE TABLE stringTests (a varchar(32), b varchar(32), c varchar(32), d varchar(32), PRIMARY KEY(a, b, c))\nGO\n" | isql -U$DB_USER -P$DB_PASS -S$DB_NAME -DTest_DB + printf "GRANT all ON stringTests TO $DB_TEST_USER\nGO\n" | isql -U$DB_USER -P$DB_PASS -S$DB_NAME -DTest_DB +elif [ ${1,,} = "mysql" ]; then + # create the new database and add the tables + echo "running against mysql" + mysql -u$DB_USER -p$DB_PASS -e 'CREATE DATABASE Test_DB' + mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'CREATE TABLE typeTests (dates datetime, monies decimal(14,4), ints int, strings varchar(30), bits bit, floats float NULL, PRIMARY KEY(dates, monies, ints, strings))' + mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'GRANT ALL ON typeTests TO $DB_TEST_USER' + mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'CREATE TABLE stringTests (a varchar(32), b varchar(32), c varchar(32), d varchar(32), PRIMARY KEY(a, b, c))' + mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'GRANT ALL ON stringTests TO $DB_TEST_USER' +else + echo "ERROR: cannot support database \"$1\". Please specify either sybase or mysql" + exit +fi diff --git a/centrallix/tests/test_sybase_00.cmp b/centrallix/tests/test_sybase_00.cmp new file mode 100644 index 000000000..2232e7241 --- /dev/null +++ b/centrallix/tests/test_sybase_00.cmp @@ -0,0 +1,4 @@ +"dates","monies","ints","strings","bits","floats" +30 Mar 2000 23:59,$3.3333,2000," ",0,-10000.0 +02 Feb 2020 00:00,$20.02,-1000,"two twos",0,22222.22222 +14 Mar 2024 01:59,$3.14,0,"pi",1,3.141593 diff --git a/centrallix/tests/test_sybase_00.to b/centrallix/tests/test_sybase_00.to new file mode 100644 index 000000000..2a36584e6 --- /dev/null +++ b/centrallix/tests/test_sybase_00.to @@ -0,0 +1,17 @@ +##NAME Sybase Basic Insert + +# make sure clean start +query delete from /tests/Test_DB/typeTests/rows + +# insert test values +query insert into /tests/Test_DB/typeTests/rows select dates = convert('datetime', '2020-02-02'), monies = convert('money', 20.0200), ints = -1000, strings = 'two twos', bits = 0, floats = 22222.22222 +query insert into /tests/Test_DB/typeTests/rows select dates = convert('datetime', '2024-03-14 01:59:26'), monies = convert('money', 3.14), ints = 0, strings = 'pi', bits = 1, floats = 3.14159265358979323846 +query insert into /tests/Test_DB/typeTests/rows select dates = convert('datetime', '2000-03-30 23:59:59'), monies = convert('money', 3.3333), ints = 2000, strings = '', bits = 0, floats = -10000.0 + + +# test that values inserted properly +csv select * from /tests/Test_DB/typeTests/rows + +# cleanup +query delete from /tests/Test_DB/typeTests/rows +csv select * from /tests/Test_DB/typeTests/rows diff --git a/centrallix/tests/test_sybase_01.cmp b/centrallix/tests/test_sybase_01.cmp new file mode 100644 index 000000000..aed987ae8 --- /dev/null +++ b/centrallix/tests/test_sybase_01.cmp @@ -0,0 +1,2 @@ +"dates","monies","ints","strings","bits","floats" +01 Sep 1991 00:00,$1991.0901,12,"this is a new string",1,19.91 diff --git a/centrallix/tests/test_sybase_01.to b/centrallix/tests/test_sybase_01.to new file mode 100644 index 000000000..b433cd8f4 --- /dev/null +++ b/centrallix/tests/test_sybase_01.to @@ -0,0 +1,22 @@ +##NAME Sybase Update One key + +# make sure clean start +query delete from /tests/Test_DB/typeTests/rows + +# insert test values +query insert into /tests/Test_DB/typeTests/rows select dates = convert('datetime', '2020-02-02'), monies = convert('money', 20.0200), ints = -1000, strings = 'two twos', bits = 0, floats = 22222.22222 + +# run updates +query update /tests/Test_DB/typeTests/rows set :dates = convert('datetime', '1991-09-01') +query update /tests/Test_DB/typeTests/rows set :monies = convert('money', 1991.0901) +query update /tests/Test_DB/typeTests/rows set :ints = 12 +query update /tests/Test_DB/typeTests/rows set :strings = 'this is a new string' +query update /tests/Test_DB/typeTests/rows set :bits = 1 +query update /tests/Test_DB/typeTests/rows set :floats = 19.91 + +# test that values updated properly +csv select * from /tests/Test_DB/typeTests/rows + +# cleanup +query delete from /tests/Test_DB/typeTests/rows +csv select * from /tests/Test_DB/typeTests/rows \ No newline at end of file diff --git a/centrallix/tests/test_sybase_02.cmp b/centrallix/tests/test_sybase_02.cmp new file mode 100644 index 000000000..a6be8ab50 --- /dev/null +++ b/centrallix/tests/test_sybase_02.cmp @@ -0,0 +1,6 @@ +"dates","monies","ints","strings","bits","floats" +01 Jan 2000 00:00,$12345.6789,-987654321,"This string is long enough tha",0,0.0 +"dates","monies","ints","strings","bits","floats" +01 Jan 2000 00:00,$1.2345,123,"B",0,0.0 +"dates","monies","ints","strings","bits","floats" +01 Jan 2000 00:00,$0.00,0," ",0,0.0 diff --git a/centrallix/tests/test_sybase_02.to b/centrallix/tests/test_sybase_02.to new file mode 100644 index 000000000..94610094f --- /dev/null +++ b/centrallix/tests/test_sybase_02.to @@ -0,0 +1,21 @@ +##NAME Sybase Update Multiple Keys + +# make sure clean start +query delete from /tests/Test_DB/typeTests/rows + +# insert test values +query insert into /tests/Test_DB/typeTests/rows select dates = convert('datetime', '2000-01-01'), monies = convert('money', 0.000), ints = 0, strings = 'A', bits = 0, floats = 0.0 + +# run updates +query update /tests/Test_DB/typeTests/rows set :monies = convert('money', 12345.6789), :strings = 'This string is long enough that it will need truncated', :ints = -987654321 +csv select * from /tests/Test_DB/typeTests/rows + +query update /tests/Test_DB/typeTests/rows set :monies = convert('money', 1.2345), :strings = 'B', :ints = 123 +csv select * from /tests/Test_DB/typeTests/rows + +query update /tests/Test_DB/typeTests/rows set :monies = convert('money', 0), :strings = '', :ints = 0 +csv select * from /tests/Test_DB/typeTests/rows + +# cleanup +query delete from /tests/Test_DB/typeTests/rows +csv select * from /tests/Test_DB/typeTests/rows diff --git a/centrallix/tests/test_sybase_03.cmp b/centrallix/tests/test_sybase_03.cmp new file mode 100644 index 000000000..9a85a8e3c --- /dev/null +++ b/centrallix/tests/test_sybase_03.cmp @@ -0,0 +1,16 @@ +"a","b","c","d" +"a much longer string that will e","b","c","test_1" +"a","b","c","d" +"a much longer string that will e","be it as it may, it is longer th","c","test_2" +"a","b","c","d" +"a much longer string that will e","be it as it may, it is longer th","see this sentence? It sounds lik","test_3" +"a","b","c","d" +"x","be it as it may, it is longer th","see this sentence? It sounds lik","test_4" +"a","b","c","d" +"x","y","see this sentence? It sounds lik","test_5" +"a","b","c","d" +"x","y","z","test_6" +"a","b","c","d" +"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB","CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC","test_7" +"a","b","c","d" +"a","b","c","test_8" diff --git a/centrallix/tests/test_sybase_03.to b/centrallix/tests/test_sybase_03.to new file mode 100644 index 000000000..51007d6cb --- /dev/null +++ b/centrallix/tests/test_sybase_03.to @@ -0,0 +1,38 @@ +##NAME Sybase Update with string key size changes + +# make sure clean start +query delete from /tests/Test_DB/stringTests/rows + +# insert test values +query insert into /tests/Test_DB/stringTests/rows select a = 'a', b = 'b', c = 'c', d = 'd' + +# grow each field +query update /tests/Test_DB/stringTests/rows set :a = 'a much longer string that will even be truncated', :d = 'test_1' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :b = 'be it as it may, it is longer than before', :d = 'test_2' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :c = 'see this sentence? It sounds like it starts with C, but alas does not', :d = 'test_3' +csv select * from /tests/Test_DB/stringTests/rows + +# shrink each field +query update /tests/Test_DB/stringTests/rows set :a = 'x', :d = 'test_4' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :b = 'y', :d = 'test_5' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :c = 'z', :d = 'test_6' +csv select * from /tests/Test_DB/stringTests/rows + +# expand and then shrink all at once +query update /tests/Test_DB/stringTests/rows set :a = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', :b = 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', :c = 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC', :d = 'test_7' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :a = 'a', :b = 'b', :c = 'c', :d = 'test_8' +csv select * from /tests/Test_DB/stringTests/rows + +# cleanup +query delete from /tests/Test_DB/stringTests/rows +csv select * from /tests/Test_DB/stringTests/rows From 45444c2b88a237a8fe8ec10298e49e7214667457 Mon Sep 17 00:00:00 2001 From: Noah Board Date: Fri, 28 Jun 2024 16:22:52 -0600 Subject: [PATCH 12/12] Added automated tests for mysql --- centrallix/test_db_setup.sh | 2 +- centrallix/tests/test_mysql_00.cmp | 4 ++++ centrallix/tests/test_mysql_00.to | 17 +++++++++++++ centrallix/tests/test_mysql_01.cmp | 2 ++ centrallix/tests/test_mysql_01.to | 23 ++++++++++++++++++ centrallix/tests/test_mysql_02.cmp | 4 ++++ centrallix/tests/test_mysql_02.to | 18 ++++++++++++++ centrallix/tests/test_mysql_03.cmp | 16 +++++++++++++ centrallix/tests/test_mysql_03.to | 38 ++++++++++++++++++++++++++++++ 9 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 centrallix/tests/test_mysql_00.cmp create mode 100644 centrallix/tests/test_mysql_00.to create mode 100644 centrallix/tests/test_mysql_01.cmp create mode 100644 centrallix/tests/test_mysql_01.to create mode 100644 centrallix/tests/test_mysql_02.cmp create mode 100644 centrallix/tests/test_mysql_02.to create mode 100644 centrallix/tests/test_mysql_03.cmp create mode 100644 centrallix/tests/test_mysql_03.to diff --git a/centrallix/test_db_setup.sh b/centrallix/test_db_setup.sh index 936eefec1..b7e8c5560 100755 --- a/centrallix/test_db_setup.sh +++ b/centrallix/test_db_setup.sh @@ -43,7 +43,7 @@ elif [ ${1,,} = "mysql" ]; then # create the new database and add the tables echo "running against mysql" mysql -u$DB_USER -p$DB_PASS -e 'CREATE DATABASE Test_DB' - mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'CREATE TABLE typeTests (dates datetime, monies decimal(14,4), ints int, strings varchar(30), bits bit, floats float NULL, PRIMARY KEY(dates, monies, ints, strings))' + mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'CREATE TABLE typeTests (dates datetime, monies decimal(14,4), ints int, strings varchar(30), bits bit, floats float NULL, blobs blob NULL, PRIMARY KEY(dates, monies, ints, strings))' mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'GRANT ALL ON typeTests TO $DB_TEST_USER' mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'CREATE TABLE stringTests (a varchar(32), b varchar(32), c varchar(32), d varchar(32), PRIMARY KEY(a, b, c))' mysql -u$DB_USER -p$DB_PASS -DTest_DB -e 'GRANT ALL ON stringTests TO $DB_TEST_USER' diff --git a/centrallix/tests/test_mysql_00.cmp b/centrallix/tests/test_mysql_00.cmp new file mode 100644 index 000000000..61180872c --- /dev/null +++ b/centrallix/tests/test_mysql_00.cmp @@ -0,0 +1,4 @@ +"dates","monies","ints","strings","bits","floats","blobs" +30 Mar 3333 01:59,$3.3333,2000,"",0,-10000.0,"!@#$%^&*()_-+=[{}]:;'""/?\|.,<>~`" +14 Mar 2024 01:59,$3.14,0,"pi",1,3.14159,"3.1415926535897932384626433832795028841971693993751058209749445923078, etc." +02 Feb 2020 00:00,$20.02,-1000,"two twos",0,22222.2,"just a longer string to test this" diff --git a/centrallix/tests/test_mysql_00.to b/centrallix/tests/test_mysql_00.to new file mode 100644 index 000000000..03f3ea22d --- /dev/null +++ b/centrallix/tests/test_mysql_00.to @@ -0,0 +1,17 @@ +##NAME MySQL Basic Insert + +# make sure clean start +query delete from /tests/Driver_DB/typeTests/rows + +# insert test values +query insert into /tests/Driver_DB/typeTests/rows select dates = '2020-02-02', monies = convert('money', 20.0200), ints = -1000, strings = 'two twos', bits = 0, floats = 22222.22222, blobs = 'just a longer string to test this' +query insert into /tests/Driver_DB/typeTests/rows select dates = '2024-03-14 01:59:26', monies = convert('money', 3.14), ints = 0, strings = 'pi', bits = 1, floats = 3.14159265358979323846, blobs = '3.1415926535897932384626433832795028841971693993751058209749445923078, etc.' +query insert into /tests/Driver_DB/typeTests/rows select dates = '3333-03-30 01:59:26', monies = convert('money', 3.3333), ints = 2000, strings = '', bits = 0, floats = -10000.0, blobs = '!@#$%^&*()_-+=[{}]:;\'"/?\\|.,<>~`' + + +# test that values inserted properly +csv select * from /tests/Driver_DB/typeTests/rows + +# cleanup +query delete from /tests/Driver_DB/typeTests/rows +csv select * from /tests/Driver_DB/typeTests/rows \ No newline at end of file diff --git a/centrallix/tests/test_mysql_01.cmp b/centrallix/tests/test_mysql_01.cmp new file mode 100644 index 000000000..b7ae543fa --- /dev/null +++ b/centrallix/tests/test_mysql_01.cmp @@ -0,0 +1,2 @@ +"dates","monies","ints","strings","bits","floats","blobs" +01 Sep 1991 00:00,$1991.0901,12,"this is a new string",1,19.91,"this works without a where because there is only one row" diff --git a/centrallix/tests/test_mysql_01.to b/centrallix/tests/test_mysql_01.to new file mode 100644 index 000000000..1e7f7e34f --- /dev/null +++ b/centrallix/tests/test_mysql_01.to @@ -0,0 +1,23 @@ +##NAME MySQL Update One key + +# make sure clean start +query delete from /tests/Driver_DB/typeTests/rows + +# insert test values +query insert into /tests/Driver_DB/typeTests/rows select dates = '2020-02-02', monies = convert('money', 20.0200), ints = -1000, strings = 'two twos', bits = 0, floats = 22222.22222, blobs = 'just a longer string to test this' + +# run updates +query update /tests/Driver_DB/typeTests/rows set :dates = '1991-09-01' +query update /tests/Driver_DB/typeTests/rows set :monies = convert('money', 1991.0901) +query update /tests/Driver_DB/typeTests/rows set :ints = 12 +query update /tests/Driver_DB/typeTests/rows set :strings = 'this is a new string' +query update /tests/Driver_DB/typeTests/rows set :bits = 1 +query update /tests/Driver_DB/typeTests/rows set :floats = 19.91 +query update /tests/Driver_DB/typeTests/rows set :blobs = 'this works without a where because there is only one row' + +# test that values updated properly +csv select * from /tests/Driver_DB/typeTests/rows + +# cleanup +query delete from /tests/Driver_DB/typeTests/rows +csv select * from /tests/Driver_DB/typeTests/rows \ No newline at end of file diff --git a/centrallix/tests/test_mysql_02.cmp b/centrallix/tests/test_mysql_02.cmp new file mode 100644 index 000000000..dd9e1230c --- /dev/null +++ b/centrallix/tests/test_mysql_02.cmp @@ -0,0 +1,4 @@ +"dates","monies","ints","strings","bits","floats","blobs" +01 Jan 2000 00:00,$12345.6789,-987654321,"This string is long enough tha",0,0.0,"confirm it worked" +"dates","monies","ints","strings","bits","floats","blobs" +01 Jan 2000 00:00,$1.2345,123,"B",0,0.0,"check once again" diff --git a/centrallix/tests/test_mysql_02.to b/centrallix/tests/test_mysql_02.to new file mode 100644 index 000000000..b044369d1 --- /dev/null +++ b/centrallix/tests/test_mysql_02.to @@ -0,0 +1,18 @@ +##NAME MySQL Update Multiple Keys + +# make sure clean start +query delete from /tests/Test_DB/typeTests/rows + +# insert test values +query insert into /tests/Test_DB/typeTests/rows select dates = '2000-01-01', monies = convert('money', 0.000), ints = 0, strings = 'A', bits = 0, floats = 0.0, blobs = 'A' + +# run updates +query update /tests/Test_DB/typeTests/rows set :monies = convert('money', 12345.6789), :strings = 'This string is long enough that it will need truncated', :ints = -987654321, :blobs='confirm it worked' +csv select * from /tests/Test_DB/typeTests/rows + +query update /tests/Test_DB/typeTests/rows set :monies = convert('money', 1.2345), :strings = 'B', :ints = 123, :blobs='check once again' +csv select * from /tests/Test_DB/typeTests/rows + +# cleanup +query delete from /tests/Test_DB/typeTests/rows +csv select * from /tests/Test_DB/typeTests/rows diff --git a/centrallix/tests/test_mysql_03.cmp b/centrallix/tests/test_mysql_03.cmp new file mode 100644 index 000000000..9a85a8e3c --- /dev/null +++ b/centrallix/tests/test_mysql_03.cmp @@ -0,0 +1,16 @@ +"a","b","c","d" +"a much longer string that will e","b","c","test_1" +"a","b","c","d" +"a much longer string that will e","be it as it may, it is longer th","c","test_2" +"a","b","c","d" +"a much longer string that will e","be it as it may, it is longer th","see this sentence? It sounds lik","test_3" +"a","b","c","d" +"x","be it as it may, it is longer th","see this sentence? It sounds lik","test_4" +"a","b","c","d" +"x","y","see this sentence? It sounds lik","test_5" +"a","b","c","d" +"x","y","z","test_6" +"a","b","c","d" +"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB","CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC","test_7" +"a","b","c","d" +"a","b","c","test_8" diff --git a/centrallix/tests/test_mysql_03.to b/centrallix/tests/test_mysql_03.to new file mode 100644 index 000000000..51007d6cb --- /dev/null +++ b/centrallix/tests/test_mysql_03.to @@ -0,0 +1,38 @@ +##NAME Sybase Update with string key size changes + +# make sure clean start +query delete from /tests/Test_DB/stringTests/rows + +# insert test values +query insert into /tests/Test_DB/stringTests/rows select a = 'a', b = 'b', c = 'c', d = 'd' + +# grow each field +query update /tests/Test_DB/stringTests/rows set :a = 'a much longer string that will even be truncated', :d = 'test_1' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :b = 'be it as it may, it is longer than before', :d = 'test_2' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :c = 'see this sentence? It sounds like it starts with C, but alas does not', :d = 'test_3' +csv select * from /tests/Test_DB/stringTests/rows + +# shrink each field +query update /tests/Test_DB/stringTests/rows set :a = 'x', :d = 'test_4' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :b = 'y', :d = 'test_5' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :c = 'z', :d = 'test_6' +csv select * from /tests/Test_DB/stringTests/rows + +# expand and then shrink all at once +query update /tests/Test_DB/stringTests/rows set :a = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA', :b = 'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB', :c = 'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC', :d = 'test_7' +csv select * from /tests/Test_DB/stringTests/rows + +query update /tests/Test_DB/stringTests/rows set :a = 'a', :b = 'b', :c = 'c', :d = 'test_8' +csv select * from /tests/Test_DB/stringTests/rows + +# cleanup +query delete from /tests/Test_DB/stringTests/rows +csv select * from /tests/Test_DB/stringTests/rows