2008/03/27

Shrinking an outsized KeePassX/KeePass database

There is an error in KeePassX (and there was a similar bug in KeePass, too) that can cause the database file to grow at a very rapid pace (I don't know what triggers this growth). To be precise, the database size doubles every time it is saved even if a very small change is made.

My database reached 256 MB. KeePass running on Windows XP could not open it (because of an Out of memory error) while KeePassX on Ubuntu could open it but it was taking a few minutes. But the main problem anyway was the fact that I couldn't add new entries or make any changes because the file would grow again.

I tried to shrink the file by saving it as a new database or exporting and then importing it, but it didn't work. I also tried to find a solution on the Internet, but I only found an information that there was such a bug and it was fixed in Windows version. So after a few days I downloaded the KeePass sources, spent half a day (it's been a long time since I last saw a C++ code :) first trying to make them compile (I didn't have a libboost_regex-vc80-mt-sgd-1_34_1.lib library file; I installed it with BoostPro Binary Installer for Visual C++ - take a look here and here) and then trying to find a place in the code where the individual entries get loaded. :)

Finally, it turned out that the problem was caused by an attachment which was taking almost all space in the database file (it had a few KB when I attached it some time ago).

So I placed a line responsible for loading the attachment inside a try... catch... block and added a message box.
try
{
pEntry->pszBinaryDesc = _UTF8ToString((UTF8_BYTE *)pData);
}
catch (...)
{
AfxMessageBox((CString)"There was a problem with reading pszBinaryDesc " 
+ (CString)"field of " + pEntry->pszTitle + (CString)" entry.\n"
+ (CString)"This data has been LOST. However, you can now save the "
+ (CString)"database as a new file and its size should be normal again.", 
MB_ICONEXCLAMATION);
}
Thanks to this if there is a broken (outsized) attachment in some entry, an exception is thrown (important: if you try to run KeePass on Linux using WINE, this exception will not be thrown) and KeePass skips loading it and informs the user that such a problem occurred. Be aware that I didn't find a way to restore a broken attachment so some data is lost, but the database can be opened and saved as a new database. The new database has a normal size.

If anyone has a similar problem, let me know - I can e-mail modified sources or a compiled EXE file.

UPDATE:

A tip from an anonymous reader:
I was able to get around the same issue and shrink my keepass database via "File" -> "Export To" -> "KeePass Database" in v1.14. Using "Save As" wouldn't do it, but exporting did the trick!

2008/03/03

Invalid 'Remote table-valued function calls are not allowed' message error

Assuming that [11.99.120.12] is a linked server created on a SQL Server 2005 computer and pointing to a SQL Server 2000 computer, executing a simple query like this:

  SELECT *
  FROM [11.99.120.12].SALES_DB.dbo.ORDERS (nolock)

will fail with the following error message:

  Server: Msg 4122, Level 16, State 1, Line 1
  Remote table-valued function calls are not allowed.

This error message is not correct, since ORDERS is a table and not a function.

This query will run correctly only if the WITH keyword is used before the (nolock) hint:

  SELECT *
  FROM [11.99.120.12].SALES_DB.dbo.ORDERS WITH (nolock)

This problem is also discussed here.