📄 getsend.c
字号:
return retcode;
}
/*
** Set up the command to select from the table.
*/
sprintf(cmdbuf, "select * from %s", Ex_tabname);
retcode = ct_command(cmd, CS_LANG_CMD, cmdbuf, CS_NULLTERM, CS_UNUSED);
if (retcode != CS_SUCCEED)
{
ex_error("RetrieveData: ct_command() failed");
free(cmdbuf);
return retcode;
}
free(cmdbuf);
/*
** Send the command to the server
*/
if (ct_send(cmd) != CS_SUCCEED)
{
ex_error("RetrieveData: ct_send() failed");
return retcode;
}
/*
** Process the results of the command
*/
while ((retcode = ct_results(cmd, &res_type)) == CS_SUCCEED)
{
switch ((int)res_type)
{
case CS_ROW_RESULT:
/*
** Handle the expected row results.
*/
retcode = FetchResults(cmd, textdata);
if (retcode != CS_SUCCEED)
{
ex_error("RetrieveData: FetchResults() failed");
/*
** Something failed so cancel all results.
*/
ct_cancel(NULL, cmd, CS_CANCEL_ALL);
return retcode;
}
break;
case CS_CMD_SUCCEED:
case CS_CMD_DONE:
/*
** This means that the command succeeded or is
** finished.
*/
break;
case CS_CMD_FAIL:
/*
** The server encountered an error while
** processing our command.
*/
ex_error("RetrieveData: ct_result() returned CS_CMD_FAIL");
return CS_FAIL;
break;
default:
/*
** We got something unexpected.
*/
ex_error("RetrieveData: ct_results() returned unexpected result typ");
/*
** Cancel all results.
*/
ct_cancel(NULL, cmd, CS_CANCEL_ALL);
break;
}
}
/*
** We're done processing results. Let's check the
** return value of ct_results() to see if everything
** went ok.
*/
switch ((int)retcode)
{
case CS_END_RESULTS:
/*
** Everything went fine.
*/
retcode = CS_SUCCEED;
break;
case CS_FAIL:
/*
** ct_results() call failed.
*/
ex_error("RetrieveData: ct_results() failed");
break;
default:
/*
** We got an unexpected return value.
*/
ex_error("RetrieveData: ct_results() returned unexpected result");
break;
}
return retcode;
}
/*
** FetchResults()
**
** Type of function:
** getsend program internal api
**
** Purpose:
** This function retrieves the results expected
** for this example. It demonstrates retrieving
** a text column intermixed with columns of
** other data types.
**
** Parameters:
** cmd - Pointer to CS_COMMAND structure.
** textdata - Pointer to a TEXT_DATA structure to fill.
**
** Return:
** CS_SUCCEED if text was fetched correctly.
** Otherwise a Client-Library failure code.
*/
CS_STATIC CS_RETCODE
FetchResults(cmd, textdata)
CS_COMMAND *cmd;
TEXT_DATA *textdata;
{
CS_RETCODE retcode;
CS_DATAFMT fmt;
CS_INT firstcol;
CS_TEXT *txtptr;
CS_FLOAT floatitem;
CS_INT count;
CS_INT len;
/*
** All binds must be of columns prior to the columns
** to be retrieved by ct_get_data().
** To demonstrate this, bind the first column returned.
*/
memset(&fmt, 0, sizeof(CS_DATAFMT));
fmt.datatype = CS_INT_TYPE;
fmt.maxlength = sizeof(CS_INT);
fmt.count = 1;
fmt.format = CS_FMT_UNUSED;
retcode = ct_bind(cmd, 1, &fmt, &firstcol, NULL, NULL);
if (retcode != CS_SUCCEED)
{
ex_error("FetchResults: ct_bind() failed");
return retcode;
}
/*
** Retrieve and display the results.
*/
while(((retcode = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED,
&count)) == CS_SUCCEED) || (retcode == CS_ROW_FAIL) )
{
/*
** Check for a recoverable error.
*/
if (retcode == CS_ROW_FAIL)
{
ex_error("FetchResults: ct_fetch() returned CS_ROW_FAIL");
continue;
}
/*
** Get the text data item in the second column.
** Loop until we have all the data for this item.
** The text used for this example could be retrieved
** in one ct_get_data call, but data could be too large
** for this to be the case. Instead, the data would have to
** be retrieved in chunks. The example will retrieve
** the text in 5 byte increments to demonstrate retrieving
** data items in chunks.
*/
txtptr = textdata->textbuf;
textdata->textlen = 0;
do
{
retcode = ct_get_data(cmd, 2, txtptr, 5, &len);
textdata->textlen += len;
/*
** Protect against overflowing the string buffer.
*/
if ((textdata->textlen + 5) > (EX_MAX_TEXT - 1))
{
break;
}
txtptr += len;
} while (retcode == CS_SUCCEED);
if (retcode != CS_END_ITEM)
{
ex_error("FetchResults: ct_get_data() failed");
return retcode;
}
/*
** Retrieve the descriptor of the text data. It is
** available while retrieving results of a select query.
** The information will be needed for later updates.
*/
retcode = ct_data_info(cmd, CS_GET, 2, &textdata->iodesc);
if (retcode != CS_SUCCEED)
{
ex_error("FetchResults: cs_data_info() failed");
return retcode;
}
/*
** Get the float data item in the third column.
*/
retcode = ct_get_data(cmd, 3, (CS_VOID *)&floatitem,
sizeof (floatitem), &len);
if (retcode != CS_END_ITEM)
{
ex_error("FetchResults: ct_get_data() failed");
return(retcode);
}
/*
** When using ct_get_data to process results, it is not
** required to get all the columns in the row. To illustrate
** this, the last column of the result set is not retrieved.
*/
}
/*
** We're done processing rows. Check the
** final return value of ct_fetch().
*/
if (retcode == CS_END_DATA)
{
/*
** Succeeded in retrieving data.
*/
retcode = CS_SUCCEED;
}
else
{
/*
** Something unexpected happened.
*/
ex_error("FetchResults: ct_fetch() failed");
}
return retcode;
}
/*
** UpdateTextData()
**
** Type of function:
** getsend program internal api
**
** Purpose:
** This function updates the text column
** with the specified text, and calls ProcessResults()
** to retrieve the new timestamp for the updated
** text column.
**
** Parameters:
** connection - Pointer to CS_CONNECTION structure.
** textdata - Pointer to a TEXT_DATA structure to fill.
** newdata - Pointer to new data to send.
**
** Returns:
** CS_SUCCEED if text was updated correctly.
** Otherwise a Client-Library failure code.
*/
CS_STATIC CS_RETCODE
UpdateTextData(connection, textdata, newdata)
CS_CONNECTION *connection;
TEXT_DATA *textdata;
char *newdata;
{
CS_RETCODE retcode;
CS_INT res_type;
CS_COMMAND *cmd;
CS_INT i;
CS_TEXT *txtptr;
CS_INT txtlen;
/*
** Allocate a command handle to send the text with
*/
if ((retcode = ct_cmd_alloc(connection, &cmd)) != CS_SUCCEED)
{
ex_error("UpdateTextData: ct_cmd_alloc() failed");
return retcode;
}
/*
** Inform Client-Library the next data sent will be
** used for a text or image update.
*/
if ((retcode = ct_command(cmd, CS_SEND_DATA_CMD, NULL, CS_UNUSED,
CS_COLUMN_DATA)) != CS_SUCCEED)
{
ex_error("UpdateTextData: ct_command() failed");
return retcode;
}
/*
** Fill in the description information for the update
** and send it to Client-Library.
*/
txtptr = (CS_TEXT *)newdata;
txtlen = strlen(newdata);
textdata->iodesc.total_txtlen = txtlen;
textdata->iodesc.log_on_update = CS_TRUE;
retcode = ct_data_info(cmd, CS_SET, CS_UNUSED, &textdata->iodesc);
if (retcode != CS_SUCCEED)
{
ex_error("UpdateTextData: ct_data_info() failed");
return retcode;
}
/*
** Send the text one byte at a time. This is not the best thing to do
** for performance reasons, but does demonstrate the ct_send_data()
** can handle arbitrary amounts of data.
*/
for (i = 0; i < txtlen; i++, txtptr++)
{
retcode = ct_send_data(cmd, txtptr, (CS_INT)1);
if (retcode != CS_SUCCEED)
{
ex_error("UpdateTextData: ct_send_data() failed");
return retcode;
}
}
/*
** ct_send_data() does writes to internal network buffers. To insure
** that all the data is flushed to the server, a ct_send() is done.
*/
if ((retcode = ct_send(cmd)) != CS_SUCCEED)
{
ex_error("UpdateTextData: ct_send() failed");
return retcode;
}
/*
** Process the results of the command
*/
while ((retcode = ct_results(cmd, &res_type)) == CS_SUCCEED)
{
switch ((int)res_type)
{
case CS_PARAM_RESULT:
/*
** Retrieve a description of the parameter data.
** Only timestamp data is expected in this example.
*/
retcode = ProcessTimestamp(cmd, textdata);
if (retcode != CS_SUCCEED)
{
ex_error("UpdateTextData: ProcessTimestamp() failed");
/*
** Something failed so cancel all results.
*/
ct_cancel(NULL, cmd, CS_CANCEL_ALL);
return retcode;
}
break;
case CS_STATUS_RESULT:
/*
** Not expecting CS_STATUS_RESULT in this example,
** but if received results will be pending. Therefore,
** cancel the current result set.
*/
retcode = ct_cancel(NULL, cmd, CS_CANCEL_CURRENT);
if (retcode != CS_SUCCEED)
{
ex_error("UpdateTextData: ct_cancel() failed");
return retcode;
}
break;
case CS_CMD_SUCCEED:
case CS_CMD_DONE:
/*
** This means that the command succeeded or is
** finished.
*/
break;
case CS_CMD_FAIL:
/*
** The server encountered an error while
** processing our command.
*/
ex_error("UpdateTextData: ct_results() returned CS_CMD_FAIL");
break;
default:
/*
** We got something unexpected.
*/
ex_error("UpdateTextData: ct_results() returned unexpected result typ");
/*
** Cancel all results.
*/
ct_cancel(NULL, cmd, CS_CANCEL_ALL);
break;
}
}
/*
** We're done processing results. Let's check the
** return value of ct_results() to see if everything
** went ok.
*/
switch ((int)retcode)
{
case CS_END_RESULTS:
/*
** Everything went fine.
*/
retcode = CS_SUCCEED;
break;
case CS_FAIL:
/*
** ct_results() call failed.
*/
ex_error("UpdateTextData: ct_results() failed");
break;
default:
/*
** We got an unexpected return value.
*/
ex_error("UpdateTextData: ct_results() returned unexpected result");
break;
}
return retcode;
}
/*
** ProcessTimestamp()
**
** Purpose:
** This function retrieves the new timestamp for
** the updated text column into the CS_IODESC
** structure.
**
** Parameters:
** cmd - Pointer to a CS_COMMAND structure.
** textdata - Pointer to a TEXT_DATA structure to fill.
**
** Returns:
** CS_SUCCEED if text was updated correctly.
** Otherwise a Client-Library failure code.
*/
CS_STATIC CS_RETCODE
ProcessTimestamp(cmd, textdata)
CS_COMMAND *cmd;
TEXT_DATA *textdata;
{
CS_RETCODE retcode;
CS_INT count;
CS_DATAFMT datafmt;
retcode = ct_describe(cmd, 1, &datafmt);
if (retcode != CS_SUCCEED)
{
ex_error("ProcessTimestamp: ct_describe() failed");
return retcode;
}
/*
** Check if the data is a timestamp. If so, save it
** to the CS_IODESC structure for future text updates.
*/
if (!(datafmt.status & CS_TIMESTAMP))
{
/*
** Unexpected parameter data was received.
*/
ex_error("ProcessTimestamp: unexpected parameter data received");
return CS_FAIL;
}
/*
** Bind the timestamp field of the io descriptor
** to assign the new timestamp from the parameter
** results.
*/
datafmt.maxlength = sizeof(textdata->iodesc.timestamp);
datafmt.format = CS_FMT_UNUSED;
if ((retcode = ct_bind(cmd, 1, &datafmt, (CS_VOID *)textdata->iodesc.timestamp,
&textdata->iodesc.timestamplen,
NULL)) != CS_SUCCEED)
{
ex_error("ProcessTimestamp: ct_bind() failed");
return retcode;
}
/*
** Retrieve the parameter result containing the timestamp.
*/
retcode = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count);
if (retcode != CS_SUCCEED)
{
ex_error("ProcessTimestamp: ct_fetch() failed");
return retcode;
}
/*
** The timestamp was retrieved, so cancel the
** rest of the result set.
*/
retcode = ct_cancel(NULL, cmd, CS_CANCEL_CURRENT);
if (retcode != CS_SUCCEED)
{
ex_error("ProcessTimestamp: ct_cancel() failed");
}
return retcode;
}
/*
** ValidateTxt()
**
** Type of function:
** getsend program internal api
**
** Purpose:
** This function validates that the retrieved
** text is the value that was expected.
**
** Parameters:
** textdata - Pointer to a TEXT_DATA structure to use.
** valid_str - Pointer to the expected text.
**
** Return:
** Nothing.
*/
CS_STATIC CS_VOID
ValidateTxt(textdata, valid_str)
TEXT_DATA *textdata;
char *valid_str;
{
char buf[EX_MAX_TEXT + 1];
/*
** Add a null terminator at the end of the text for comparing.
*/
memcpy(buf, textdata->textbuf, textdata->textlen);
buf[textdata->textlen] = '\0';
if (strcmp(buf, valid_str) == 0)
{
fprintf(stdout, "The retrieved text is the expected value.\n");
}
else
{
fprintf(stdout, "The retrieved text is NOT the expected value\n");
}
fflush(stdout);
}
/*
** DisplayData()
**
** Type of function:
** getsend program internal api
**
** Purpose:
** This function displays the text data last retrieved from the database.
**
** Parameters:
** textdata - Pointer to a TEXT_DATA structure to use.
**
** Return:
** Nothing.
*/
CS_STATIC CS_VOID
DisplayData(textdata)
TEXT_DATA *textdata;
{
char buf[EX_MAX_TEXT + 1];
/*
** Add a null terminator at the end of the
** text for displaying the value.
*/
memcpy(buf, textdata->textbuf, textdata->textlen);
buf[textdata->textlen] = '\0';
fprintf(stdout, "\nThe text data retrieved is: \n\t%s\n", buf);
fflush(stdout);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -