Thursday, July 24, 2008

Embedded mysql in C++ under windows

Embedding mysql into a C++ application is not that complicated, it's just badly documented. A few things are needed:
  1. The embedded library, libmysqld.lib. This should be residing in %mysql_dir%/lib/opt. Do not confuse it with libmysql.lib, those are two different things. Most probably, you won't see a libmysqld.lib in there. I'm not entirely clear on the details, but it seems that it was removed from recent installations. I think 4.1 has it, but I'm positive both 5.0 and 5.1rc don't. You can try scavenging the web to find it somewhere, but it is a lot easier to build it from source. If you happen to have it bundled with your installation, skip this part.
    • Download the source as a tgz archive for the current version (5.0.51b as of this writing) and extract it.
    • Follow the instructions in INSTALL-WIN-SOURCE, they are quite thorough. Note that you will need to install CMake, but it is painless.
    • After building mysql, look in libmysqld\debug and you will find libmysqld.lib and libmysqld.dll.
    You need to link your application against libmysqld.lib and copy libmysqld.dll to your application's folder (or make it accessible in other ways).
  2. Try this sample:
    static char *server_options[] =
    { "mysql_test", "--datadir=c:/somewhere/data", "--language=c:/somewhere/english", 0};
    int num_elements = (sizeof(server_options) / sizeof(char *)) - 1;
    
    static char *server_groups[] = { "libmysqld_server", NULL };
    
    int main()
    {
      mysql_library_init(num_elements, server_options, server_groups);
      MYSQL* handle = mysql_init(0);
      mysql_options(handle, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
      mysql_real_connect(handle, 0, 0, 0, 0, 0, 0, 0);
    
      // from this point, use 'handle' as if you were using
      // it before
    
      mysql_close(handle);
      mysql_library_end();
    }
    Be careful though: as this bug is saying, passing the wrong options to mysql_library_init() will probably crash your application. Concerning the hardcoded paths, I'm still working on that. Obviously, even if the server is embedded in the application, the database needs to be stored somewhere and the path needs to be specified. I guess the best way is, under Windows, to add the install path in the registry and use it. You could also use the current working directory (might be dangerous) or lookup the executable's path (GetModuleFileName()).
  3. I've also had problems with creating stored procedure. Mysql was complaining that it couldn't find the table mysql.proc. The mysql database is created automatically when you install the server. Because your embedded server starts completely empty, it seems that there are things you cannot do. I temporarily solved this problem by copying the mysql folder from my server installation to the data folder of the embedded server.

No comments: