MQL4 + SQLite3 Wrapper works in a script, but not an EA

 

Hello,

I'm using MT4 build 1330 from Oanda. I'm using this SQLite wrapper so I can work with a SQLite database: https://github.com/Shmuma/sqlite3-mt4-wrapper

I slightly modified the example code just to see if I can understand the code a bit. Here's what I have currently:


The working script file called sqlite_testJN.mq4:

#property strict


#include <sqlite.mqh>


bool do_check_table_exists (string db, string table)

{

    int res = sqlite_table_exists (db, table + "");


    if (res < 0) {

        PrintFormat ("Check for table existence failed with code %d", res);

        return (false);

    }


    return (res > 0);

}


void do_exec (string db, string exp)

{

    int res = sqlite_exec (db, exp + "");

    

    if (res != 0)

        PrintFormat ("Expression '%s' failed with code %d", exp, res);

}


int OnInit()

{

    if (!sqlite_init()) {

        return INIT_FAILED;

    }


    return INIT_SUCCEEDED;

}


void OnDeinit(const int reason)

{

    sqlite_finalize();

}


void OnStart ()

{

    string db = "test.db";


    string path = sqlite_get_fname (db);

    Print ("Dest DB path: " + path);


    if (!do_check_table_exists (db, "test")) {

        Print ("DB not exists, create schema");

        do_exec (db, "create table test (name text)");

        do_exec (db, "insert into test (name) values ('test1')");

        do_exec (db, "insert into test (name) values ('test2')");

        do_exec (db, "insert into test (name) values ('test3')");

        do_exec (db, "insert into test (name) values ('test4')");

    }


    int cols[1];

    int handle = sqlite_query (db, "select * from test", cols);


    Print ("Handle = " + handle);

    Print ("Some data = " + sqlite_next_row(handle));

    

    // It seems that if you touch/use/whatever the 'handle' variable in any way, it doesn't want to be 'used' again, so

    // you have to run the below line once again in order to iterate through the data (the while loop below it)

    handle = sqlite_query (db, "select * from test", cols); // yes, need to run this line again in order to actually loop through the data now


    while (sqlite_next_row (handle) == 1) {

        for (int i = 0; i < cols[0]; i++)

            Print (sqlite_get_col (handle, i));

    }


    sqlite_free_query (handle);


    return;

}

So as I mentioned, this runs fine...but just one time (as expected from this script).


But I want my code to loop over and over and run as an EA, so this is what I have so far:

My EA file called 'Signal Service Trade Monitor.mq4':

//+------------------------------------------------------------------+

//|                                 Signal Service Trade Monitor.mq4 |

//|                                                    Jamie Navarro |

//|                                             www.jamienavarro.com |

//+------------------------------------------------------------------+


#property copyright "Jamie Navarro"

#property link      "www.jamienavarro.com"

#property version   "1.00"

#property strict



#include <sqlite.mqh>




int OnInit()

{

    if (!sqlite_init()) {

        return INIT_FAILED;

    }

    

    

   myStupidLoop();

   

   

    return INIT_SUCCEEDED;

}




void OnDeinit(const int reason)

{

    sqlite_finalize();

}








void myStupidLoop()

{



   string db = "trades.db";

   string path = sqlite_get_fname (db);


   Comment ("Open position ticket numbers: ", TicketNumbersOfOpenOrders(), " db path = ", path);

   

 

   

   int cols[1];

   int handle = sqlite_query (db, "select * from test", cols);


   //Print ("HandleMyButt = " + handle);

   //Print ("Something = " + sqlite_next_row(handle));

    

   // It seems that if you touch/use/whatever the 'handle' variable in any way, it doesn't want to be 'used' again, so

   // you have to run the below line once again in order to iterate through the data (the while loop below it)

   //handle = sqlite_query (db, "select * from test", cols); // yes, need to run this line again in order to actually loop through the data now


   while (sqlite_next_row (handle) == 1) {

       for (int i = 0; i < cols[0]; i++)

           Print (sqlite_get_col (handle, i));

   }


   sqlite_free_query (handle);

   

   //void Sleep(1000);

   //sqlite_finalize();



}






void OnTick()

{

// myStupidLoop();

}








string TicketNumbersOfOpenOrders()

{

   //int TicketNumbers = 0;

   string TicketNumbers = "";

   

   for (int i=OrdersTotal()-1; i>= 0; i--)

   {

      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);

      

      if (OrderType()==OP_BUY || OrderType()==OP_SELL)

         {

         //TicketNumbers = TicketNumbers + ", " + OrderTicket();

         //TicketNumbers = OrderTicket();

         string tmpstrng = IntegerToString(OrderTicket(), 1, ' ');           // https://docs.mql4.com/convert/integertostring

         TicketNumbers = tmpstrng + " " + TicketNumbers;

         }

   }

 

   return TicketNumbers;

      

}










bool do_check_table_exists (string db, string table)

{

    int res = sqlite_table_exists (db, table + "");


    if (res < 0) {

        PrintFormat ("Check for table existence failed with code %d", res);

        return (false);

    }


    return (res > 0);

}


void do_exec (string db, string exp)

{

    int res = sqlite_exec (db, exp + "");

    

    if (res != 0)

        PrintFormat ("Expression '%s' failed with code %d", exp, res);

}


What happens when I try to run the EA, is I get the following error in the 'Experts' tab of MT4:

2021.05.06 07:30:50.282 Access violation read to 0x00000003 in 'C:\Users\jamie\AppData\Roaming\MetaQuotes\Terminal\3212703ED955F10C7534BE8497B221F4\MQL4\Libraries\sqlite3_wrapper.dll'

I've also tried running my 'myStupidLoop()' function in 'OnTick()' but get the same error. That's where I had it originally and thought OK, maybe it's trying to access the .db file too many times too fast, but I don't think that's the problem since I'm getting the same error in the 'OnInit()' function?


I'm not sure if it's an actual 'bug', but I did notice on the Github page that there are a few other people getting the same error, but I have no idea of their configuration/code/circumstance:

https://github.com/Shmuma/sqlite3-mt4-wrapper/issues/10


Ultimately what I'm trying to do here (in my limited coding ability) is code a 'Signal Service' for myself so that when I take a trade it will alert my Telegram channel. What my plan was is to have an EA monitor my trading account and enter any 'new' trade that it detects into a SQLite database and flag the record as 'new'. It would know that it is a 'new' trade by comparing all open trades (if any) to what's already in the database. Then I would have a separate Python script that monitors this database for anything that is flagged as 'new', and send out the signal to my Telegram channel, then update the record in the database as not new.

Maybe this is a terrible way of doing it? The thing is I don't know C/C++. I can do a bit of Python, I only know the basics of MQL4, I know Visual Basic.Net a bit, but this is all.

So beyond help with this actual error, I'm open to hearing other suggestions/ideas/thoughts on what I'm trying to do.


Shmuma/sqlite3-mt4-wrapper
Shmuma/sqlite3-mt4-wrapper
  • Shmuma
  • github.com
Database file is by default stored to . If you specify a full path as database filename, it's used. Terminal data path TERMINAL_DATA_PATH can be known by the following instruction. Open MT4 Open [File] menu Click "Open Data Folder" Sample Many sample scripts in under . Precautions Argument mess MT4 build 610 has a weird bug when dll function...
 

I figured it out!


I had the wrong (non-existent in my database) table name in my select statement! 

Also, I think the table name can't be the same as the database name, but I'm not 100% sure about that one, but I'd imagine it's probably not good practice to have them be the same, so I would make sure they're different anyway!

I wish that 'access read violation' error was more clear/specific, but oh well!

Hope this helps someone!

Reason: