libtabula

libtabula rocks

libtabula is a C++ wrapper for multiple C database APIs including those for SQLite, MariaDB, and MySQL. It is built around the same principles as the Standard C++ Library to make dealing with the database as easy as dealing with STL containers. In addition, libtabula provides facilities that let you avoid the most repetitive sorts of SQL within your own code, providing native C++ interfaces for these common tasks.

libtabula is basically “MySQL++ 4.0.” The name change reflects the fact that the library works with more than just MySQL now.

If you have any questions about this project, do not email us about it unless the question is inherently personal. The documentation answers most questions, and the old MySQL++ mailing list archives are a treasure trove of information:

The new mailing list is just getting started, but it will be the place to go for anything libtabula-specific. [Subscribe]

If you can’t find an answer in the documentation or the list archives, ask on the list. Everyone active in libtabula’s development monitors that mailing list, and the library’s primary maintainer responds to almost every question posted there. By posting to the mailing list, your question and any answers are archived for future developers to find, and you reach a wider audience than is possible with personal email.

Test Versions

We will likely be making some tarballs for public consumption before a first formal release. Keep an eye on the mailing list.

Latest Stable Version

Before upgrading from MySQL++ to libtabula, please read the “Incompatible Library Changes” chapter in the user manual. For more details without getting bogged down in the Fossil timeline, see the change log.

There have not yet been any releases of libtabula.

Linux Binary Packages

There have not yet been any releases of libtabula, hence no binary packages.

Old Versions

There are no old versions of libtabula yet.

Are you looking for an old version of MySQL++?

Documentation

The user and reference manuals are shipped in the source code tarball above. They are also available online.

Contributing to the Effort

The easiest thing to do if you want to help out with the libtabula development effort is to participate on the mailing list. We could use help answering questions, and it’s frequently helpful to have different voices contributing to discussions about the library’s future.

If you want to participate in the coding effort, the libtabula development project is hosted here. It is a Fossil repository, so you will probably need to install that first. Fossil is easy to build from source, but you may not need to as it has started to appear in many package repositories including Ubuntu, Cygwin, and Homebrew. There are also third-party RPMs.

If you have never used Fossil, it operates a lot like Subversion and shares a lot of commands with it — svn up and fossil up do the same thing, for instance — except that it is a DVCS like Git or Mercurial. If you turn off the autosync feature, Fossil behaves more like a traditional DVCS. The Fossil User Manual is a quick and easy read which will help you get started.

See the HACKERS.md file for more information on contributing patches to libtabula.

Before starting work on libtabula, check the wish list and the ticket system to see if the change you want to make is either already designed or implemented. This avoids duplicate design and coding work.

If you just want to keep up on the in-progress developments, you can subscribe to the libtabula timeline RSS feed. Between that and the mailing list traffic, you will know as much about libtabula’s development as anyone save the people actually working on it. :)

If you have a login on the libtabula Fossil repository, the checkout URL becomes http://MYUSER@libtabula.org/code. Fossil will prompt you for MYUSER’s password.

FAQs

What version of libtabula should I use?

If you’re writing new code, you should use the latest stable version.

If you are porting from MySQL++, you should bring your code base up to the last stable release of MySQL++ first. Don’t worry that you might end up doing some work over again. The changes needed to port to libtabula are additional to those needed to bring a MySQL++ based project up to date.

libtabula uses the standard major.minor.bug-fix version number scheme. A change in the library’s major version number denotes changes that will almost certainly require source code changes in your program. See the “Incompatible Library Changes” chapter of the user manual for details. A change in the minor version number indicates added features that don’t change existing library interfaces. If you don’t want to use those features, you should be able to install the new library without rebuilding your program. A change in the bug-fix number indicates internal bug fixes, which don’t affect the library interface at all, so such versions are always safe to install.

What platforms does it work on?

libtabula should work on any platform that has a Standard C++ compiler and the C API development files for your supported DBMS(es) of choice.

libtabula does have some conditional code to allow use of some C and C++ features that aren’t yet universally available, but all of this is optional.

In practice, libtabula works best on the platforms that get the most attention. On the most popular platforms, it normally works right out of the box with no futzing.

If your platform is over a decade old or is a marginal player in its segment of the market, you might have to do some hacking to get it working. We do not spend any effort to try and make libtabula work on BeOS, OS/2 and Symbian, but we will help you get it working, and will accept patches to fix the problems so long as they’re noninvasive.

What versions of SQLite does it work with?

libtabula ships with a copy of the latest stable version of SQLite 3.x at the time libtabula is released. We test this combination before every release.

You can build libtabula against an external copy of SQLite instead. The oldest version it is regularly tested against is 3.3.6.

We know of no reason it shouldn’t work with any 3.x version.

What versions of MySQL does it work with?

libtabula should work out of the box with MySQL versions going back to v4.1. If you can forego Unicode support, libtabula will work on 4.0 with minimal changes. libtabula can be made to build against MySQL 3.23, but it won’t do so out of the box.

We do most of the development against MySQL 5.x, but we stick only to GA versions. If you run across a problem getting it to work with a bleeding-edge version of MySQL, we’re happy to help you fix the problem, and will almost certainly accept a patch for the problem.

Does it build against MariaDB?

It seems to work perfectly, using both the 5.5 and 10.0 versions. We base that on the fact that libtabula passes its own test suite. If you know of a regression, please let us know on the mailing list.

What software license does libtabula use? Is it free?

libtabula is free software, licensed under the GNU LGPL v2.1.

What does the LGPL license mean to me, as far as libtabula goes?

The common wisdom regarding LGPL’d libraries is that you can use them with a program using almost any software license as long as you’re willing to link dynamically. Think of the GNU C library (glibc) on Linux: it’s LGPL’d and linked to almost everything on a Linux system, at least indirectly. If your program’s software license allows dynamic linking to glibc, it should allow you to use libtabula dynamically, too.

If you link to libtabula statically, you trigger the “viral” provisions of the LGPL. Practically speaking, it means your program must be licensed under the LGPL or something compatible with it, such as the GPL. This rules out static linking when you want to keep your source code closed, and even rules out static linking with some open source licenses, since not all of them are compatible with LGPL at that level.

There’s no practical way of avoiding this. libtabula’s licensing history is tangled, what with the numerous changes of maintainership and the lack of a copyright assignment system for third-party contributions. It would simply be impractical to contact all of the past contributors and get them to agree on the licensing changes needed to make this happen.

Doesn’t the MySQL C API library’s GPL license override libtabula’s LGPL license?

The MySQL C API library is available under two different licenses, not one.

The default license for MySQL (including its C API library) is GPL with the FOSS license exception. This is what you get if you got MySQL for free, such as by downloading it from mysql.com or as part of your Linux distro. The less liberal distribution terms of the C API library’s GPL do override the less restrictive ones of libtabula’s LGPL license. This matters if you want to distribute your program as a binary only, keeping the source to yourself.

If you need to be able to distribute closed-source programs, Oracle will happily sell you a commercial distribution license for their C API library.

This issue really has nothing to do with libtabula. The same restriction applies if you write your program directly against the C API library. The only reason I even put this here is because people keep asking the question. Please work out the licensing with Oracle. Having settled that, the previous FAQ item applies.

You may also be able to get around this sort of problem by switching to MariaDB.

How does libtabula compare to MySQL++?

The main thing libtabula brings to the table relative to MySQL++ is that it supports multiple back-end database engines. It also adds the SSQLS v2 feature, which is basically an ORM for C++.

How does libtabula compare to other C++ database libraries?

These days, there are several other C++ database libraries: Connector/C++, SOCI, DbiXX.... Why choose libtabula?

The main reason libtabula exists in the face of all that competition is that its predecessor, MySQL++, is considerably older than all of them, having started in 1998. Perhaps you are like me and have a big legacy of MySQL++ code and experience that you want to keep. Or, perhaps you are new to libtabula and are interested in a library with more features than these young upstarts; just check out the relative size of their documentation.

I believe libtabula is the most idiomatic C++ library of the bunch. Connector/C++ purposely mimics Java’s JDBC API, whereas DbiXX and SOCI are based on a kind of SQL-in-C++ DSL that is neither SQL nor C++, exactly. libtabula is based on concepts you’ve already pounded into your hands’ muscle memory, like the STL. As you read through the tutorial, it should strike you as regular everyday C++, rather than something alien.

One good reason to use SOCI or DbiXX over libtabula is that they support more RDBMSes. If you need more than MariaDB, MySQL and SQLite, and you don’t want to contribute a driver for your RDBMS of choice to libtabula, you’ll want to look elsehwere.

Connector/C++, for obvious reasons, only supports MySQL.

Will it build under GCC?

Yes, with GCC version 3.0 and up, except on MinGW, which requires 3.4.5 at minimum.

Will it build under Visual C++?

Yes, it works out of the box with Visual C++ 2005 and newer.

Will it build on Mac OS X?

Yes, it builds just fine, both from within the Xcode environment and at the command line. We currently test only on OS X 10.8 and up, but if you find a breakage on an older platform, we can probably fix it going back to 10.3 or so. Beyond that, C++ support on OS X gets old enough that it’s not likely to build libtabula without a lot of hackery.

Will it build under Cygwin?

Yes, it’s pretty much as easy as on Linux.

Beware of Cygwin’s licensing: any program linked to cygwin1.dll is subject to the GPL, unless you’ve purchased ($$) a commercial license for Cygwin from Red Hat. If that’s not a problem for you, see the Cygwin README file.

If you are making a closed-source program, we recommend using Visual C++ or MinGW instead.

Will it build under MinGW?

Yes, as long as it has GCC 3.4.5 or newer. GCC 4.x also fixes a lot of things on MinGW.

Will it build under Solaris?

Yes, we have reports of people building it successfully on versions as old as Solaris 8. It may also work with Sun CC, but it’s been long enough since we got a success report about that that we are now unsure that it still works.

g++ simple1.cpp -o simple1 ?

No!

You’re probably missing a -I flag for the libtabula headers, and you’re certainly missing correct link flags.

The user manual has a section that describes how to build a program based on libtabula.

It compiles, but it won’t link! Why?

To build any program using libtabula, at minimum you must link to the libtabula library and also to the C API library/libraries you need for the DBMSes you built libtabula against. The libtabula library is libtabula.so on Unixy systems, and libtabula.lib on Windows. The MySQL C API library is either libmysqlclient{_r}.{a,so} on Unixy systems and libmysql.lib on Windows.

Visual C++: An additional requirement with Visual C++ is that you must link to the same C Run-Time Library (RTL) for all modules throughout your project. The Visual C++ project files that come with libtabula use the multithreaded DLL version (/MD or /MDd) of the C RTL. If you link libtabula to a program or additional third party library that uses a different RTL, you will get link errors. Study the example projects’ settings to see how this is done. The instructions in the Visual C++ README file may also be helpful.

See Chapter 9, Using libtabula in Your Own Project in the libtabula User Manual for more on this.

Why is my program leaking memory?

The current version of libtabula has no known memory leaks. If you free all of the libtabula objects you allocate, it should not be leaking memory.

If you’re getting a report from a memory debugger about a leak, most likely you’re seeing memory that the MySQL C API library allocates for its own internal purposes. libtabula is built atop this library, so it can look like it’s libtabula leaking the memory. This underlying C library automatically allocates multiple blocks of memory in ways that are more or less outside libtabula’s control. If you feel you must plug these leaks, it is up to your code to call the relevant C API functions.

These “leaks” are all harmless in practice for most programs. A typical program using libtabula needs database access for its entire effective run time, and the size of the leak doesn’t increase over run time if you follow the instructions in the threads chapter of the User Manual. The OS automatically frees this memory when your program exits.

That said, it’s annoying to see leak reports in a memory debugger, particularly if leak checking is a regular part of your build and test process. You can placate the memory debugger by calling Connection::thread_end() from each thread that uses a database connection when that thread finishes using the database. In addition, after the last bit of code that uses libtabula stops, you need to call the MySQL C API function mysql_library_end(). If you’re using a ConnectionPool, you might put this last call in the destructor, since the pool object is typically the last libtabula object to be destroyed.

If you’ve done that and still think you really have a serious memory leak — one of those “the longer it runs, the more memory it uses” sorts of leak — you need to tie it to some unit of work. Does memory go up as a function of time? number of queries issued? count of rows retreived? Until you can establish this link, it’s premature to post to the libtabula mailing list claiming there’s a leak in libtabula. Even if you can establish such a link, it’s far more likely that you’re not releasing the libtabula objects you allocate than libtabula itself failing to release memory.

My program is crashing. Help!

The most common cause of crashes in libtabula is uncaught exceptions. The library throws exceptions when it detects errors, such as invalid SQL syntax, invalid login parameters, etc. Try running the example programs, since they all catch exceptions properly.

If the examples also crash and you’re using someone else’s binary RPMs, try rebuilding the RPMs from the source RPM. A binary RPM is fairly closely tied to the system it is built under, so it’s possible that RPMs you build on your system will work better than those built elsewhere.

Nothing’s working at all! Is it broken?

Maybe, but have you tried running the examples? Follow the instructions in the examples README file. If the examples work but your program doesn’t, chances are good that the error is in your program; study the examples, and read the manuals. If the examples also fail to work, post to the mailing list with a detailed failure report.

I’m sure I’ve found a bug. How do I submit a report?

We’ll want some code that demonstrates the bug. No doubt you’d rather not send us a copy of your database to demonstrate the problem, and to be frank, we don’t want your database, either. The best thing is to modify one of the libtabula examples so that it reproduces the problem you’re seeing. This lets the people that can help you reproduce the problem on their machines, without needing your database.

Once you have your problem boiled down to a simple example, send the source code to the mailing list along with a detailed report. We want to know what you expect the program to do, and what it actually does on your machine. Keep in mind, programs often behave differently on different systems. As a programmer yourself, you know what it is like to deal with vague user bug reports. Give us the sort of error report you’d like to receive for your programs.

How do I submit a change to libtabula?

This is covered in detail in the HACKERS file that accompanied libtabula.

But in brief:

  1. Clone the Fossil repository
  2. Open the clone
  3. Hack
  4. Say fossil diff > mychange.patch, and send that patch file to the or create a new ticket for it. If you are supplying a patch for an existing ticket, obviously you’d want to attach it to that ticket instead.

That is, we want a unified diff against the trunk of libtabula’s Fossil repo.

send it either to the mailing list, or to the bug tracker. We prefer that you only use the bug tracker for patches that are so trivial or obvious that they won’t need discussion.

When a patch is rejected, the most common reason is that it breaks the library’s binary interface (ABI), so that an old program can’t link to the changed library without recompiling. We only make such changes at major version transitions. These transitions are rare, and we can’t even promise that there will ever be another one, much less when it will occur. If you have a choice of two ways to get your desired effect and one of them doesn’t break the ABI, it will increase the chances that we accept your patch if you do it that way.

This space intentionally left blank. :)


  Go to my home page