Adjuntar MySQL a MQ4 - página 5

 
sergeev:

Sí, todo funciona perfectamente, pero hasta ahora sólo lo he hecho para MQL5

un ejemplo de cómo funciona desde arriba en mi post


Puedes enviarme un trozo de código relativo a mysql_fetch_row, no queda claro en tu ejemplo cómo obtener celdas cuando el resultado consta de varias filas y columnas.
 
Graff:

Puedes enviar un trozo de código referente a mysql_fetch_row, no queda claro en tu ejemplo cómo obtener celdas cuando el resultado consta de varias filas y columnas.

de manera similar.

1. tomar mysql_num_rows, mysql_num_fields

2. obtener un puntero a una matriz de punteros a la siguiente cadena mysql_fetch_row, y un puntero a las longitudes de los campos mysql_fetch_lengths

3. sacamos estas longitudes del array de longitudes a nuestro propio array (mediante memcpy).

4. A partir de un puntero a un array de punteros de campo, sacar este array de punteros de campo (ya que conocemos mysql_num_fields).

5. Conociendo las longitudes de los campos (array de longitudes obtenidas de fetch_lengths) y los punteros a los propios campos estamos sacando datos en el array uchar de cada campo con memcpy

6. volver a la cláusula 2.

 
HIDDEN:
He dado vueltas y vueltas en ambos sentidos, nada me ha funcionado en la 4. A veces el terminal incluso se bloquea por completo.

Kirill, todo funciona en MQL4. Lo he probado en la build 409 .

Este es un ejemplo para obtener una cadena

#import "libmysql.dll"
    int mysql_get_client_info(); // функция вернула char*
#import "msvcrt.dll"
    int strcpy(string strDestination, int strSource); // копируем NULL-строку из source в байтовый массив 
#import

void start()
{
    int ptr; string data="123456789"; 
    ptr=mysql_get_client_info(); // получили указатель на строку
    strcpy(data, ptr); // скопировали его в массив
    Print("client_info="+data); // вывели на печать
}

Resultado
sql USDCHF,M30: client_info=6.0.0

lo mismo para una matriz de enteros
sustituir por

    int strcpy(int &strDestination[], int strSource); // копируем NULL-строку из source в байтовый массив 
 
sergeev:

Kirill, todo funciona en MQL4. Lo he probado en la build 409 .

aquí hay un ejemplo para obtener la cadena

resultado
sql USDCHF,M30: client_info=6.0.0

lo mismo si lo haces para un array
sustituir por

Tengo la misma construcción, pero mi terminal se bloquea.... Tengo que probarlo en diferentes terminales de diferentes empresas de corretaje.

Aunque puede depender del sistema, estoy probando con win7 x64.

 

HIDDEN:


xp/32

A continuación, descifra las diferentes opciones de llamada y ponte en contacto con el Servicio de Atención al Cliente sobre el fallo.

Tal vez le aconsejen qué hacer.

 
sergeev:

de manera similar.

1. tomar mysql_num_rows, mysql_num_fields

2. obtener un puntero a una matriz de punteros a la siguiente cadena mysql_fetch_row, y un puntero a las longitudes de los campos mysql_fetch_lengths

3. sacamos estas longitudes del array de longitudes a nuestro propio array (mediante memcpy).

4. A partir de un puntero a un array de punteros de campo, sacar este array de punteros de campo (ya que conocemos mysql_num_fields).

5. Conociendo las longitudes de los campos (array de longitudes obtenidas de fetch_lengths) y los punteros a los propios campos estamos sacando datos en el array uchar de cada campo con memcpy

6. Vuelve al paso 2.



Ya casi está. En esta fase, sólo podemos obtener la primera celda de cada fila. memcpy por alguna razón sólo copia el primer elemento en mis arrays. Mató una tarde entera. ¿Qué estoy haciendo mal?

Fuente, volcado, registro en el apéndice.

Archivos adjuntos:
 
Graff:


Casi lo tengo. En este momento, sólo puedo obtener la primera celda de cada fila. memcpy copia sólo el primer elemento en mis arrays por alguna razón. Mató una tarde entera. ¿Qué estoy haciendo mal?

Código fuente, volcado, registro en el apéndice.


hay comentarios

1. No es necesario utilizar las funciones UNICODE2ANSI en absoluto. Para ello tienes CharArrayToStr y ShortArrayToStr.

2. No he intentado utilizar la cadena en la función strcpy(cadena strDestino, int strFuente); todo se hizo a través de arrays. Si sabes lo que estás copiando de la codificación UTF, es mejor almacenar los datos en una matriz corta.

3. Aquí tienes un error técnico (por lo que todo va mal)
memcpy(alens,lens,num_fields);

No es un array de un solo byte como uchar. Necesito memcpy(alens,lens,num_fields*sizeof(int));

 
sergeev:

hay comentarios

1. No es necesario utilizar las funciones UNICODE2ANSI en absoluto. Para ello tienes CharArrayToStr y ShortArrayToStr.

2. No he intentado utilizar la cadena en la función strcpy(cadena strDestino, int strFuente); todo se hace a través de arrays. Si sabes lo que estás copiando de la codificación UTF, es mejor almacenar los datos en una matriz corta.

3. aquí es donde tienes un error técnico (que hace que todo vaya mal)
memcpy(alens,lens,num_fields);

no es un array de un solo byte como uchar. necesitas memcpy(alens,lens,num_fields*sizeof(int));



Gracias. Está funcionando. ¿Piensa lanzar una clase o biblioteca para trabajar con el músculo?
 
Graff:

Gracias. Está funcionando. ¿Hay algún plan para lanzar una clase o biblioteca para trabajar con musl?

Si hay necesidad, puedo hacerlo. Sólo que no necesito explicar lo que ya está claro...

Sólo hay 50 funciones en esta libmysql...

la mayoría de ellas son funciones puramente de servicio. diez de ellas son esenciales para el trabajo.

--------

¿Cómo ves realmente esta clase o biblioteca? ¿Qué funciones debería tener?

¿Simplemente hacer duplicados de las funciones api, o poner algunos conjuntos de acciones en una sola función?

 
sergeev:

Si hay necesidad, puedo hacerlo. Sólo que no necesito explicar lo que ya está claro...

Sólo hay 50 funciones en esta libmysql...

y la mayoría son funciones puramente de servicio. De las docenas que necesita.

--------

En general, ¿cómo ve esta clase o biblioteca? ¿Qué funciones debería tener?



Creo que no basta con describir las funciones de libmysql.dll. La clase debe permitir al usuario trabajar con la base de datos de forma sencilla y sin esfuerzo.

Ejemplo 1: Conexión a la base de datos. Para conectarse a la base de datos a través de mi débil clase, hay que llamar al constructor de la clase, aunque dentro de la clase se realizan toda una serie de acciones, no siempre necesarias o incluso requeridas.

CMYSQL2::CMYSQL2(const string host="localhost",const string user="root",const string password="",const string database="database",const uint port=3306)
  {
   uchar _host[],_user[],_password[],_database[],_socket[];
   StringToCharArray(host,_host);
   StringToCharArray(user,_user);
   StringToCharArray(password,_password);
   StringToCharArray(database,_database);
// Connecting
   mysql=mysql_init(NULL);
   uint conn=mysql_real_connect(mysql,_host,_user,_password,_database,port,_socket,0);
   if(mysql==NULL || conn==NULL || mysql!=conn){ Print(__FUNCTION__,"-> MySQL connetion failure.");}
  }

Ejemplo 2: obtener un resultado de varias líneas y columnas. Todo lo que el usuario necesita es alimentar la consulta y un array(estructura) para escribir el resultado.

//+------------------------------------------------------------------+
//|  Returns string array as sql_results struct param and rows count
//+------------------------------------------------------------------+
uint CMYSQL2::GetArray(string query,sql_results &out[])
  {
   Query2(query);
   StoreResult();
   uint rows=GetNumRows();
   uint fields=GetNumFields();
   ArrayResize(out,rows);

   for(uint r=0;r<rows;r++)
     {
      ArrayResize(out[r].value,fields);
      string fr_res=mysql_fetch_row(result);
      
      for(uint f=0;f<fields;f++)
        {
         out[r].value[f]=get_cell_u(fr_res,f);//Print("3,",f,",",fields);
        }
     }
   FreeLastResult();
   return(rows);
  }

^ este es un código antiguo, solo para tener la idea.

También podría haber muchos ejemplos sobre cómo añadir información a la base de datos.

Si sólo utilizas un conjunto de funciones sin comprobaciones, es muy fácil obtener una lectura de violación de acceso a 0x00000000 en 'libmysql.dll' y colapsar todo el sistema.

Dispuesto a considerar la posibilidad de crear una clase abierta para trabajar con el músculo.