Globalization Support

Berkeley DB globalization support allows you to translate error and informational message text to the language of your choosing, and then use the translated text instead of the default English text. This section describes Berkeley DB’s globalization support. Berkeley DB’s error and informational message text is captured in the Berkeley DB Message Reference Guide.

Message Format

By default, Berkeley DB messages are comprised of a message number followed by message text in English. For example:

  1. BDB1001 illegal record number size

It is possible to build Berkeley DB with stripped messages. When messages are stripped, the message text is removed from the library, leaving behind only the message number. When building a stripped library, there is no message text available so localization will not work.

If localization is enabled, the translated message is substituted for the original message text.

Enable Globalization Support

To output messages in a language other than the default English, follow the steps below:

  1. Provide an i18n component containing a localization function used to translate messages, and translation files that map existing messages to localized messages. The localization function can be added to the current Berkeley DB project, or as a dynamic library that is called at run time.

  2. Add the name of the localization function as the prefix for “(msg)” when HAVE_LOCALIZATION is defined in build_unix/db_int.in on *nux, or in build_windows/db_int.h on Windows.

  3. On *nix, specify -DHAVE_LOCALIZATION to CFLAGS. On Windows, specify /D HAVE_LOCALIZATION to the C/C++ Additional Options in the db project properties.

  4. Within your application code, use DB_ENV->set_errcall() or DB->set_errcall() to print the messages.

Note that Berkeley DB supports only UTF-8 for its message text. If your localization requires UTF-16 Unicode, the UTF-16 characters must be converted to UTF-8 Unicode by your localization function. If necessary, the error reporting function you specify to DB_ENV->set_errcall() or DB->set_errcall() can be used to revert the UTF-8 Unicode back to the UTF-16 Unicode.

Localization Example

The following example walks you through providing localization support for a single Berkeley DB error message:

  • Make the resource bundles. These provide the actual text translation:

    es.txt:

    1. es {
    2. BDB1002 illegal record number of 0 {"BDB1002 illegal record number of 0"}
    3. }

    de_CH.txt:

    1. de_CH {
    2. BDB1002 illegal record number of 0 {"BDB1002 illegale Rekordzahl von 0"}
    3. }

    root.txt:

    1. root {
    2. BDB1002 illegal record number of 0 {"BDB1002 illegal record number of 0"}
    3. }
  • Write and compile your localization functions: Note that the “es”, “de_CH” and “root” tags are used as the locale name in ures_open().

    Also notice that because ures_getStringByKey() returns UTF-16 Unicode, its output is converted to UTF-8 using ucnv_fromUChars().

    1. UConverter *conv;
    2. UResourceBundle *rhandle;
    3. char *mbuf;
    4. initialize() {
    5. /* Open ICU resource, specify the locale. */
    6. rhandle = ures_open(resource, "de_CH", &status);
    7. /* Open an ICU converter. */
    8. conv = ucnv_open("iso-8859-3", &status);
    9. mbuf = malloc(len * sizeof(char));
    10. memset(mbuf, 0, 100 * sizeof(char));
    11. }
    12. translate() {
    13. const UChar *wmsg;
    14. /* Get the translated message from the resource. */
    15. wmsg = ures_getStringByKey(rhandle, src, &len, &status);
    16. /* Convert UChar * to char. */
    17. len = ucnv_fromUChars(conv, wmsg, 100, , -1, &status);
    18. }
    19. close() {
    20. ucnv_close(conv);
    21. ures_close(rhandle);
    22. free(mbuf);
    23. }
  • Update db_int.h so that _(msg) is defined to use the translate() that we created in the previous step.

    1. #ifdef HAVE_LOCALIZATION
    2. #define _(msg) translate(msg)
    3. #else
    4. #define _(msg) msg
    5. #endif
  • Rebuild Berkeley DB, making sure to specify the HAVE_LOCALIZATION compile option.

  • Specify the error callback.

    1. dbp->set_errcall(dbp, print_err);
    2. print_err() {
    3. const UChar *wmsg;
    4. len = ucnv_toUChars(conv, wmsg, 100, src, len, &status);
    5. u_stdout = u_finit(stdout, NULL, NULL);
    6. u_file_write((UChar *)wmsg, len, u_stdout);
    7. }

The result of this is if you input an incorrect recno and reach the error 1002, the message “BDB1002 illegale Rekordzahl von 0” is output.