From f79dbc93cb1a8c0b183b1b81fa1518191d6ca07d Mon Sep 17 00:00:00 2001 From: Kai Elwert Date: Sun, 29 Aug 2010 10:21:35 +0200 Subject: [PATCH] Introduce DAAP-specific collation function for SQLite --- src/db.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/db.c b/src/db.c index eb57dd8a..b8bce20b 100644 --- a/src/db.c +++ b/src/db.c @@ -1,5 +1,6 @@ /* * Copyright (C) 2009-2010 Julien BLACHE + * Copyright (C) 2010 Kai Elwert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +27,11 @@ #include #include #include +#include + +#include +#include +#include #include @@ -3699,6 +3705,54 @@ db_daap_songalbumid_xfunc(sqlite3_context *pv, int n, sqlite3_value **ppv) sqlite3_result_int64(pv, result); } +static int +db_daap_unicode_xcollation(void *notused, int llen, const void *left, int rlen, const void *right) +{ + ucs4_t lch; + ucs4_t rch; + int lalpha; + int ralpha; + int rpp; + int ret; + + /* Extract first utf-8 character */ + ret = u8_mbtoucr(&lch, (const uint8_t *)left, llen); + if (ret < 0) + { + DPRINTF(E_LOG, L_DB, "DAAP collation: error %d in u8_mbtoucr (left)\n", ret); + + return 0; + } + + ret = u8_mbtoucr(&rch, (const uint8_t *)right, rlen); + if (ret < 0) + { + DPRINTF(E_LOG, L_DB, "DAAP collation: error %d in u8_mbtoucr (right)\n", ret); + + return 0; + } + + /* Ensure digits and other non-alphanum sort to tail */ + lalpha = uc_is_alpha(lch); + ralpha = uc_is_alpha(rch); + + if (!lalpha && ralpha) + return 1; + else if (lalpha && !ralpha) + return -1; + + /* Compare case and normalization insensitive */ + ret = u8_casecmp((const uint8_t *)left, llen, (const uint8_t*)right, rlen, NULL, UNINORM_NFD, &rpp); + if (ret < 0) + { + DPRINTF(E_LOG, L_DB, "DAAP collation: error in u8_casecmp: %s\n", strerror(errno)); + + return 0; + } + + return rpp; +} + int db_perthread_init(void) @@ -3723,6 +3777,15 @@ db_perthread_init(void) return -1; } + ret = sqlite3_create_collation(hdl, "DAAP", SQLITE_UTF8, NULL, db_daap_unicode_xcollation); + if (ret != SQLITE_OK) + { + DPRINTF(E_LOG, L_DB, "Could not create sqlite3 custom collation DAAP: %s\n", sqlite3_errmsg(hdl)); + + sqlite3_close(hdl); + return -1; + } + return 0; }