mysql调用libmysql.dll让我的应用程序在mysql超时后自动重新连接

问题描述:

我正在使用autohotkey进行mysql调用。 mysql接口通过引用一个可视化的基本API来解密。mysql调用libmysql.dll让我的应用程序在mysql超时后自动重新连接

我使用的连接mysql在这篇文章中引用的呼叫:http://www.autohotkey.com/forum/viewtopic.php?t=12482

我想补充一个dllcall复制此perl的呼叫的mysql_options ...

mysql_options(mysql, MYSQL_OPT_RECONNECT, &true); 

据我的理解,这个调用将使我的程序在标准的8小时mysql超时后正常地重新连接到mysql。我希望我的申请无限期地保持。

这是我的代码。关于Google代码库源代码库的参考文献表明,重新连接常量为20.除mysql_opt_reconnect调用外,一切正常。

任何人都可以帮助我确定正确的调用libmysql.dll让我的应用程序在MySQL超时发生后自动重新连接?

;============================================================ 
; mysql.ahk 
; 
; Provides a set of functions to connect and query a mysql database 
;============================================================ 

FileInstall, libmysql.dll, %A_AppData%\libmysql.dll, 1 

;============================================================ 
; Connect to mysql database and return db handle 
; 
; host = DTWRO-WS0061 
; user = alan 
; password = ******* 
; database = rush 
;============================================================ 

dbConnect(host,user,password,database){ 

    if (A_IsCompiled) { 
     ExternDir := A_AppData 
    } else { 
     ExternDir := A_WorkingDir 
    } 

    hModule := DllCall("LoadLibrary", "Str", ExternDir "\libmySQL.dll") 

    If (hModule = 0) 
    { 
     MsgBox 16, MySQL Error 233, Can't load libmySQL.dll from directory %ExternDir% 
     ExitApp 
    } 

    db := DllCall("libmySQL.dll\mysql_init", "UInt", 0) 

    If (db = 0) 
    { 
     MsgBox 16, MySQL Error 445, Not enough memory to connect to MySQL 
     ExitApp 
    } 

    ; figure out how to turn on reconnect call! 
    ; mysql_options(mysql, MYSQL_OPT_RECONNECT, &true); 
    value := DllCall("libmySQL.dll\mysql_options" 
      , "UInt", db 
      , "UInt", 20 ; is this the correct constant which represents MYSQL_OPT_RECONNECT?... see below 
      , "UInt", 1) ; true 

    connection := DllCall("libmySQL.dll\mysql_real_connect" 
     , "UInt", db 
     , "Str", host  ; host name 
     , "Str", user  ; user name 
     , "Str", password ; password 
     , "Str", database ; database name 
     , "UInt", 3306 ; port 
     , "UInt", 0 ; unix_socket 
     , "UInt", 0) ; client_flag 

    If (connection = 0) 
    { 
     HandleMySQLError(db, "Cannot connect to database") 
     Return 
    } 

    serverVersion := DllCall("libmySQL.dll\mysql_get_server_info", "UInt", db, "Str") 



    ;MsgBox % "Ping database: " . DllCall("libmySQL.dll\mysql_ping", "UInt", db) . "`nServer version: " . serverVersion 

    return db 

} 

;============================================================ 
; mysql error handling 
;============================================================ 

HandleMySQLError(db, message, query="") {  ; the equal sign means optional 
    errorCode := DllCall("libmySQL.dll\mysql_errno", "UInt", db) 
    errorStr := DllCall("libmySQL.dll\mysql_error", "UInt", db, "Str") 
    MsgBox 16, MySQL Error: %message%, Error %errorCode%: %errorStr%`n`n%query% 
    Return 
} 

;============================================================ 
; mysql get address 
;============================================================ 

GetUIntAtAddress(_addr, _offset) 
{ 
    local addr 

    addr := _addr + _offset * 4 

    Return *addr + (*(addr + 1) << 8) + (*(addr + 2) << 16) + (*(addr + 3) << 24) 
} 

;============================================================ 
; process query 
;============================================================ 

dbQuery(_db, _query) 
{ 
    local resultString, result, requestResult, fieldCount 
    local row, lengths, length, fieldPointer, field 

    query4error := RegExReplace(_query , "\t", " ") ; convert tabs to spaces so error message formatting is legible 
    result := DllCall("libmySQL.dll\mysql_query", "UInt", _db , "Str", _query) 

    If (result != 0) { 
     errorMsg = %_query% 
     HandleMySQLError(_db, "dbQuery Fail", query4error) 
     Return 
    } 

    requestResult := DllCall("libmySQL.dll\mysql_store_result", "UInt", _db) 

    if (requestResult = 0) { ; call must have been an insert or delete ... a select would return results to pass back 
     return 
    } 

    fieldCount := DllCall("libmySQL.dll\mysql_num_fields", "UInt", requestResult) 

    Loop 
    { 
     row := DllCall("libmySQL.dll\mysql_fetch_row", "UInt", requestResult) 
     If (row = 0 || row == "") 
      Break 

     ; Get a pointer on a table of lengths (unsigned long) 
     lengths := DllCall("libmySQL.dll\mysql_fetch_lengths" , "UInt", requestResult) 

     Loop %fieldCount% 
     { 
      length := GetUIntAtAddress(lengths, A_Index - 1) 
      fieldPointer := GetUIntAtAddress(row, A_Index - 1) 
      VarSetCapacity(field, length) 
      DllCall("lstrcpy", "Str", field, "UInt", fieldPointer) 
      resultString := resultString . field 
      If (A_Index < fieldCount) 
       resultString := resultString . "|"  ; seperator for fields 
     } 

     resultString := resultString . "`n"   ; seperator for records 

    } 

    ; remove last newline from resultString 
    resultString := RegExReplace(resultString , "`n$", "")  

    Return resultString 
} 
+0

AHHH ...我发现别的东西可以解决我的重新连接问题...我添加了“重新连接”到my.ini mysql配置文件的[mysql]部分并重新启动了mysql服务器。 我必须等待一段时间才能确定这是否正常工作。我会发现,当我发现。 – panofish 2011-03-18 19:06:17

甚至更​​好......我使用了一个oop类来保留mysql连接参数,以便当mysql连接超时并创建一个新的mysql调用时,它可以自动重新连接。

我花了一段时间去思考,但终于找到了一个很好的解决方案。

我只是在8小时后添加了一个settimer命令重新连接到mysql数据库。 8小时是默认的数据库连接超时。

现在AHK应用程序可以保持无限期运行,并始终连接到数据库!

+0

这工作,但不是最好的解决方案,我上面发布。 – panofish 2012-05-23 18:30:32