Udf programming in mysql: non-blocking timeout retransmission bitsCN.com
The User-Defined Function of MySQL is similar to an API. you can use C/C ++ (or C-language) according to certain specifications) compile a set of functions (UDFs), compile them into a dynamic link library, and load and unload UDFs using the drop function statement. After a UDF is loaded, it can be called like a built-in MySQL function, and the server automatically loads the existing UDF at startup.
# Ifdef STANDARD/* STANDARD is defined, don't use any mysql functions */
# Include
# Include
# Include
# Ifdef _ WIN __
Typedef unsigned _ int64 ulonglong;/* Microsofts 64 bit types */
Typedef _ int64 longlong;
# Else
Typedef unsigned long ulonglong;
Typedef long longlong;
# Endif/* _ WIN __*/
# Else
# Include
# Include
# If defined (MYSQL_SERVER)
# Include /* To get strmov ()*/
# Else
/* When compiled as standalone */
# Include
# Endif
# Endif
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Ifdef HAVE_DLOPEN
My_bool http_post_init (UDF_INIT * initid, UDF_ARGS * args, char * message );
Void http_post_deinit (UDF_INIT * initid );
Longlong http_post (UDF_INIT * initid, UDF_ARGS * args, char * is_null, char * error );
/*************************************** **********************************
** Example of init function
** Arguments:
** Initid Points to a structure that the init function shoshould fill.
** Char * ptr; A pointer that the function can use.
** Message Error message
** RETURN This function shocould return 1 if something goes wrong. In this case
**************************************** **********************************/
My_bool http_post_init (UDF_INIT * initid, UDF_ARGS * args, char * message)
{
If (args-> arg_count <3)
{
Strcpy (message, "Wrong arguments to http_post ;");
Return 1;
}
If (args-> arg_count = 4 & args-> args [3]! = NULL)
{
Int flexibleLength = strlen (args-> args [3]);
If (flexibleLength & gt; 160000)
{
Int allocLength = 200 + flexibleLength;
If (! (Initid-> ptr = (char *) malloc (allocLength )))
{
Strcpy (message, "Couldn't allocate memory in http_post_init ");
Return 1;
}
Return 0;
}
Else
{
Initid-> ptr = NULL;
}
}
Return 0;
}
/*************************************** *************************************
** Deinit function. This shoshould all resources allocated
** This function.
** Arguments:
** Initid Return value from xxxx_init
**************************************** ************************************/
Void http_post_deinit (UDF_INIT * initid)
{
If (initid! = NULL & initid-> ptr! = NULL)
{
Free (initid-> ptr );
Initid-> ptr = NULL;
}
}
/*************************************** ************************************
** UDF string function.
** Arguments:
** Initid Structure filled by xxx_init
** Args The same structure as to xxx_init. This structure
** This function shocould return a pointer to the result string.
** Normally this is 'result' but may also be an alloced string.
**************************************** ***********************************/
Longlong http_post (UDF_INIT * initid, UDF_ARGS * args,
Char * is_null _ attribute _ (unused )),
Char * error _ attribute _ (unused )))
{
Int sockfd = 0;
Int numbytes = 0;
Int flags = 0;
Int cycletimes = 0;
Char * sendBuffer = NULL;
Fd_set wset;
Struct timeval tval;
Tval. TV _sec = 0;
Tval. TV _usec = 300000;
If (initid-> ptr = NULL)
{
Char sendArray [160000] = "/0 ";
SendBuffer = sendArray;
}
Else
{
SendBuffer = initid-> ptr;
}
Struct sockaddr_in serv_addr;
Serv_addr.sin_family = AF_INET;
Serv_addr.sin_port = htons (atoi (args-> args [1]);
Serv_addr.sin_addr.s_addr = inet_addr (args-> args [0]);
Bzero (& (serv_addr.sin_zero), 8 );
If (args-> arg_count = 4 & (args-> args [3]! = NULL ))
{
Int argsNum = strlen (args-> args [3]);
Sprintf (sendBuffer, "POST /? % S HTTP/1.1/r/nContent-Length: % d/r/n % s ", args-> args [2], argsNum, args-> args [3]);
}
Else
{
Sprintf (sendBuffer, "POST /? % S HTTP/1.1/r/n ", args-> args [2]);
}
If (sockfd = socket (AF_INET, SOCK_STREAM, 0) =-1)
{
Close (sockfd );
Return 2;
}
Flags = fcntl (sockfd, F_GETFL, 0 );
Fcntl (sockfd, F_SETFL, flags | O_NONBLOCK); // Set to non-blocking
Do
{
Connect (sockfd, (struct sockaddr *) & serv_addr, sizeof (struct sockaddr ));
FD_ZERO (& wset );
FD_SET (sockfd, & wset );
If (select (sockfd + 1, NULL, & wset, NULL, & tval) <= 0 & cycletimes = 5)
{
Close (sockfd );
Return 5;
}
Numbytes = send (sockfd, sendBuffer, strlen (sendBuffer), 0 );
If (numbytes <0)
{
Usleep (20000 );
}
Cycletimes ++;
} While (numbytes <0 & cycletimes! = 5 );
If (numbytes <0)
{
Close (sockfd );
Return 4;
}
Close (sockfd );
Return 0;
}
# Endif/* HAVE_DLOPEN */
BitsCN.com