Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions centrallix-os/tests/Test_DB
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$Version=2$
Kardia_DB "application/sybase"
{
server = "<SERVER-NAME>";
database = "Test_DB";
max_connections = 200;
annot_table = "ra";

// Use centrallix login credentials.
use_system_auth = "no";
username = "<TEST_USER>";
password = "<TEST_PASS>";

// Migrate centrallix password to mysql password.
set_passwords = "no";
}
70 changes: 68 additions & 2 deletions centrallix/osdrivers/objdrv_mysql.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
***/
Expand Down Expand Up @@ -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 **/
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
131 changes: 127 additions & 4 deletions centrallix/osdrivers/objdrv_sybase.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 **/
Expand Down Expand Up @@ -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. **/
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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
{
Expand Down Expand Up @@ -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.
Expand All @@ -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"))
Expand Down Expand Up @@ -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. **/
Expand All @@ -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)
Expand Down
Loading