2017-04-04 70 views
0

我想從用C寫成的UDF內連接到本地主機上的MySQL數據庫。我創建了一個用戶定義的函數,將它提供給MySQL DB作爲共享對象的插件文件夾,並提供了UDF:如何從CentOS上的C UDF連接到MySQL數據庫

CREATE FUNCTION test_udf RETURNS INTEGER SONAME 'test_udf.so'; 

這意味着我可以使用:

SELECT test_udf(); 

由於test_udf()被調用時,它應該從數據庫連接到數據庫在本地主機上,SELECT數據,處理da ta併成功返回一個整數值。

這工作完全在Mac OSX,但沒有機會,我的CentOS 7下一旦得到這個工作作爲UDF嘗試連接到數據庫在本地主機上我得到的錯誤:

Can't connect to MySQL server on 'localhost'

當然,我做了一個適當的設置my.cnf並關心防火牆設置。

有沒有人有想法?有沒有人試過這樣的東西?

此代碼編譯都在Mac和CentOS完全使用gcc。

gcc $(mysql_config —cflags —include —libs) -shared -fPIC -o test_udf.so test_udf.c 
/// DEBUG MODE FOR IDE (comment out if UDF need´s to be compiled using gcc from commandline) /////////////////////////// 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 
//#define DEBUG                           //<---------- COMMENT OUT IF COMPILATION AS SHARED OBJECT 
//#define LINUX 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 


/*********************************************************************************************************************** 
* MySQL udf function prototypes 
* 
* for STRING functions: 
* ++++++++++++++++++++++ 
* char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length,char *is_null, 
*   char *error); 
* 
* for INTEGER functions: 
* ++++++++++++++++++++++ 
* long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 
* 
* for REAL functions: 
* ++++++++++++++++++++++ 
* double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); 
* 
* for DECIMAL functions: 
* ++++++++++++++++++++++ 
* DECIMAL functions return string values and should be declared the same way as STRING functions. 
* ROW functions are not implemented. 
* 
* Initialization/Deinitialization 
* +++++++++++++++++++++++++++++++++ 
* The initialization and deinitialization functions are declared like this: 
* my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message); 
* void xxx_deinit(UDF_INIT *initid); 
* 
***********************************************************************************************************************/ 


/*********************************************************************************************************************** 
* UDF global defines (needed for debug & UDF BOTH!) 
***********************************************************************************************************************/ 
#define QUERY_1 "SELECT * FROM test_table" 


/*********************************************************************************************************************** 
* UDF global defines (needed for debug & UDF) 
***********************************************************************************************************************///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

#ifdef DEBUG 
#define DEBUG_ON 1          // Debugging mode is on -> for testing in IDE 
#else 
/*********************************************************************************************************************** 
* automatic UDF function name generation 
***********************************************************************************************************************/ 
#define DEBUG_ON 0          // Debugging mode is of when compiled as shared object 
#define UDF_RETURN_TYPE my_ulonglong     // the return value type          <---------- TYPE IN RETURN VALUE TYPE 
#define UDF_FCT_NAME test_udf       // the UDF function name          <---------- TYPE IN UDF FUNCTION NAME 
#define INIT_FCT_NAME test_udf_init      // the UDF init function name         <---------- TYPE IN UDF INIT FUNCTION NAME 
#define DEINIT_FCT_NAME test_udf_deinit     // the UDF deinit function name         <---------- TYPE IN UDF DEINIT FUNCTION NAME 

#endif 



/*********************************************************************************************************************** 
* Includes 
***********************************************************************************************************************/ 
#ifdef DEBUG 
#include <stdio.h> 
#include <stdlib.h> 
#ifndef LINUX 
#include "include/mysql.h" 
#else 
#include "mysql/mysql.h" 
#endif 
#include <string.h> 
#include "my_mysql_header.h" 
#else 
#include "my_mysql_header.h" 
#ifdef STANDARD 
/* STANDARD is defined, don't use any mysql functions */ 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#ifdef __WIN__ 
typedef unsigned __int64 ulonglong;/* Microsofts 64 bit types */ 
typedef __int64 longlong; 
#else 
typedef unsigned long long ulonglong; 
typedef long long longlong; 
#endif /*__WIN__*/ 
#else 
#include <my_global.h> 
#include <my_sys.h> 
#if defined(MYSQL_SERVER) 
#include <m_string.h>/* To get strmov() */ 
#else 
/* when compiled as standalone */ 
#include <string.h> 
#define strmov(a,b) stpcpy(a,b) 
#define bzero(a,b) memset(a,0,b) 
#define memcpy_fixed(a,b,c) memcpy(a,b,c) 
#endif 
#endif 
#include <mysql.h> 
#include <ctype.h> 
#endif 


//#endif 


#ifndef DEBUG 
/*********************************************************************************************************************** 
* MySQL UDF function prototypes 
***********************************************************************************************************************/ 
my_bool INIT_FCT_NAME(UDF_INIT *initid, UDF_ARGS *args, char *message); 
void DEINIT_FCT_NAME(UDF_INIT *initid __attribute__((unused))); 
UDF_RETURN_TYPE UDF_FCT_NAME(UDF_INIT* initid, 
       UDF_ARGS* args __attribute__((unused)), 
       char* is_null __attribute__((unused)), 
       char* error __attribute__((unused))); 
#endif 


/*********************************************************************************************************************** 
* Other function prototypes 
***********************************************************************************************************************/ 


/*********************************************************************************************************************** 
* Other functions 
***********************************************************************************************************************/ 
int finish_with_error(MYSQL *con) 
{ 
    mysql_close(con); 
    return 1; 
} 


/*********************************************************************************************************************** 
* MySQL udf function definitions 
***********************************************************************************************************************/ 
#ifdef DEBUG 
int main() 
{ 
#else 
my_bool INIT_FCT_NAME(UDF_INIT *initid, UDF_ARGS *args, char *message) 
{ 
    if(!(args->arg_count == 0)) { 
     strcpy(message, "No Arguments expected!"); 
     return 1; 
    } 
    return 0; 
} 


void DEINIT_FCT_NAME(UDF_INIT *initid __attribute__((unused))) 
{ 

} 



UDF_RETURN_TYPE UDF_FCT_NAME(UDF_INIT* initid, 
          UDF_ARGS* args __attribute__((unused)), 
          char* is_null __attribute__((unused)), 
          char* error __attribute__((unused))) 
{ 
#endif 

    MYSQL *con = mysql_init(NULL); 

    if (con == NULL) 
    { 
     fprintf(stderr, "%s\n", mysql_error(con)); 
     exit(1); 
    } 

    if (mysql_real_connect(con, ADDRESS, USER, PASSWORD, DATABASE, 0, NULL, 0) == NULL) 
    { 
     finish_with_error(con); 
    } 

    if (mysql_query(con, QUERY_1)) 
    { 
     finish_with_error(con); 
    } 

    MYSQL_RES *result = mysql_store_result(con); 

    if (result == NULL) 
    { 
     finish_with_error(con); 
    } 

    /* 
    * UDF CODE GOING HERE! 
    */ 

    mysql_free_result(result); 
    mysql_close(con); 

    return 0; 
} 
+0

上創建本地與CentOS7一個流浪漢框Mac和測試有 –

回答

0

好最後我想出如何得到這個工作。

1)增加的mysql_options前連接:從請求mysql_query更改

mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client"); 

2)mysql_real_query

mysql_real_query(&mysql, "select * from new_schema.new_table", 34); 

3)的my.cnf設置爲:

[client] 
    port=3306 
    socket=/var/lib/mysql/mysql.sock 

4)使用127.0.0.1而不是mysql_real_connect函數中的「localhost」,否則配置的套接字將不能使用