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/osdrivers/objdrv_mysql.c b/centrallix/osdrivers/objdrv_mysql.c index d776309fe..d8026f113 100644 --- a/centrallix/osdrivers/objdrv_mysql.c +++ b/centrallix/osdrivers/objdrv_mysql.c @@ -1179,6 +1179,67 @@ 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 colInd, int type) + { + 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(i = 0 ; i < data->TData->nKeys ; i++) + { + if(data->TData->KeyCols[i] == colInd) + { + keyInd = i; + break; + } + } + if (keyInd == -1 || !newval) return 0; + + /* 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]; + } + + fullLen = strlen(data->Objname); + /* find the start and end of the field to edit*/ + start = data->Objname; + for(i = 0 ; i < keyInd ; i++) + { + 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; + } /*** mysd_internal_UpdateRow() - update a given row ***/ @@ -2974,6 +3035,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,12 +3134,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; } + // make sure this does not run for inserts or other major transactions + mysd_internal_UpdateName(inf, valStr, i, type); } } } diff --git a/centrallix/osdrivers/objdrv_sybase.c b/centrallix/osdrivers/objdrv_sybase.c index 0c505eb69..b21881727 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; } @@ -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 **/ @@ -1628,6 +1629,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 +1661,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); @@ -1684,6 +1691,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 @@ -2211,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); @@ -2805,6 +2817,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]) @@ -2945,6 +2962,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)); @@ -3015,6 +3034,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 { @@ -4411,6 +4451,81 @@ 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) + { + 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]; + } + /* 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 */ + 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 +4542,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 +4723,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 +4763,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) diff --git a/centrallix/test_db_setup.sh b/centrallix/test_db_setup.sh new file mode 100755 index 000000000..b7e8c5560 --- /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, 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' +else + echo "ERROR: cannot support database \"$1\". Please specify either sybase or mysql" + exit +fi 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 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