ct_send_data

Description

Send a chunk of text or image data to the server.

Syntax

CS_RETCODE ct_send_data(cmd, buffer, buflen)
 
 CS_COMMAND     *cmd;
 CS_VOID               *buffer;
 CS_INT                  buflen;

Parameters

cmd

A pointer to the CS_COMMAND structure managing a client/server operation.

buffer

A pointer to the value to write to the server.

buflen

The length, in bytes, of *buffer.

CS_NULLTERM is not a legal value for buflen.

Returns

ct_send_data returns the following values:

Return value

Meaning

CS_SUCCEED

The routine completed successfully.

CS_FAIL

The routine failed.

CS_CANCELED

The send data operation was canceled.

CS_PENDING

Asynchronous network I/O is in effect. See “Asynchronous programming”.

CS_BUSY

An asynchronous operation is already pending for this connection. See “Asynchronous programming”.

Examples

Example 1

The following fragment illustrates the call sequence to build and send a send-data command:

          /*
           ** UpdateTextData()
           */
          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
                */
                ...CODE DELETED.....
               /*
                ** 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 that 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() 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_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 type”);
                          /* 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.
                */
                ...CODE DELETED.....
               return retcode;
           }

This code excerpt is from the getsend.c sample program.

Example 2

The following fragment illustrates the call sequence to send partial update data:

/*
** UpdateTextData()
*/
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
   */
   ...CODE DELETED.....
   /*
   ** 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;
   /*
   **  Insert newdata at offset 20.
   */
   textdata->iodesc.iotype = CS_IOPARTIAL;
   textdata->iodesc.offset = 20;
   textdata->iodesc.delete_length = 0;
   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 that 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() 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_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 type”);
            /* 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.
   */
   ...CODE DELETED.....
   return retcode;
}

This code excerpt is from the uctext.c sample program.

Usage


Suppressing commands

To update a text or image column, a client application typically calls the ct_command routine to initiate a send-data command. The client then calls the ct_data_info command to retrieve the CS_IODESC and determine the appropriate SQL command to generate (update or writetext) in a subsequent call to the ct_send_data routine.

To simplify this process and potentially improve performance, a client can suppress the generation of the SQL command (update or writetext) and send data directly to the server bulk handler. To do this, the client must initiate the send-data command by calling the ct_command routine with the type parameter set to CS_SEND_DATA_NOCMD. The client application can then use send-data commands to send only text or image data to the server bulk handler. When a bulk event occurs at the server, a 4-byte field is sent indicating the total number of bytes to be sent, followed by the text or image data. The bulk handler reads the total number of bytes expected using srv_text_info and the data using srv_get_data.

The server must define a stored procedure, sp_mda, to indicate whether or not it supports the ct_send_data routine sending only text or image data without a SQL command. The server sp_mda procedure is called only if the client application sets certain properties—for example, ct_con_props(CS_SENDDATA_NOCMD)—before the ct_connect routine is called. If any of these properties (such as CS_PARTIAL_TEXT or the CS_SENDDATA_NOCMD connection property) is set, the server sp_mda procedure is called during execution of ct_connect. If sp_mda indicates that the server does not support the ct_send_data routine sending only text or image data without a SQL command, any calls to the ct_command routine with the type parameter set to CS_SEND_DATA_NOCMD fail.

If the server can receive text or image data without a SQL command, sp_mda returns:

Parameter

Value

mdinfo

“SENDDATA_NOCMD”

querytype

2

query

senddata no cmd

NoteAdaptive Server cannot receive image or text data without a SQL command.

See also

ct_data_info, ct_get_data, “text and image data handling”