MySQL вызывает libmysql.dll, чтобы мое приложение автоматически переподключалось после тайм-аута MySQL - PullRequest
0 голосов
/ 08 марта 2011

Я использую autohotkey, чтобы делать вызовы mysql.Интерфейс mysql был расшифрован путем ссылки на Visual Basic API для mysql.

Я использую вызовы mysql connect, упоминаемые в этом посте: http://www.autohotkey.com/forum/viewtopic.php?t=12482

Я хотел бы добавить dllcall для репликацииэтот вызов perl для mysql_options ...

mysql_options(mysql, MYSQL_OPT_RECONNECT, &true);

Насколько я понимаю, этот вызов позволил бы моей программе изящно переподключиться к mysql после стандартного 8-часового тайм-аута mysql.Я хочу, чтобы мое приложение оставалось на неопределенный срок.

Вот мой код.Ссылка на библиотеку исходного кода googles предполагает, что константа повторного подключения равна 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
}

Ответы [ 2 ]

0 голосов
/ 05 мая 2012

Еще лучше ... Я использовал класс oop для сохранения параметров подключения mysql, чтобы после истечения времени ожидания подключения mysql и нового вызова mysql он мог автоматически переподключиться.

0 голосов
/ 10 мая 2011

Мне потребовалось время, чтобы мыслить нестандартно, но я наконец нашел решение, которое работает очень хорошо.

Я просто добавил команду settimer для повторного подключения к базе данных mysql через 8 часов.По умолчанию время подключения к базе данных составляет 8 часов.

Теперь приложение AHK может работать бесконечно долго и всегда подключено к базе данных!

...