From 2427b6d5c16abfd028c3af721bc6b669d23bf05f Mon Sep 17 00:00:00 2001 From: Jens Georg Date: Tue, 24 Aug 2010 16:59:12 +0300 Subject: [PATCH] media-export: Fix bgo#627243 String operators during Search() should be case insensitive --- .../media-export/rygel-media-export-database.vala | 44 ++++++++++++++++++++++ .../rygel-media-export-media-cache.vala | 21 +++++++++-- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/plugins/media-export/rygel-media-export-database.vala b/src/plugins/media-export/rygel-media-export-database.vala index 9eb7120..f53e12e 100644 --- a/src/plugins/media-export/rygel-media-export-database.vala +++ b/src/plugins/media-export/rygel-media-export-database.vala @@ -43,6 +43,40 @@ internal class Rygel.MediaExport.Database : Object { */ public delegate bool RowCallback (Sqlite.Statement stmt); + private static void utf8_like (Sqlite.Context context, + Sqlite.Value[] args) + requires (args.length == 2) { + if (args[1].to_text() == null) { + context.result_int (0); + + return; + } + + var pattern = Regex.escape_string (args[0].to_text ()); + pattern = pattern.replace("%", ".*").replace ("_", "."); + if (Regex.match_simple (pattern, + args[1].to_text (), + RegexCompileFlags.CASELESS)) { + context.result_int (1); + } else { + context.result_int (0); + } + } + + private static int utf8_collate (int alen, void* a, int blen, void* b) { + // unowned to prevent array copy + unowned uint8[] _a = (uint8[]) a; + _a.length = alen; + + unowned uint8[] _b = (uint8[]) b; + _b.length = blen; + + var str_a = ((string) _a).casefold (); + var str_b = ((string) _b).casefold (); + + return str_a.collate (str_b); + } + /** * Open a database in the user's cache directory as defined by XDG * @@ -67,6 +101,16 @@ internal class Rygel.MediaExport.Database : Object { this.db.exec ("PRAGMA synchronous = OFF"); this.db.exec ("PRAGMA temp_store = MEMORY"); this.db.exec ("PRAGMA count_changes = OFF"); + this.db.create_function ("like", + 2, + Sqlite.UTF8, + null, + Database.utf8_like, + null, + null); + this.db.create_collation ("CASEFOLD", + Sqlite.UTF8, + Database.utf8_collate); } /** diff --git a/src/plugins/media-export/rygel-media-export-media-cache.vala b/src/plugins/media-export/rygel-media-export-media-cache.vala index 0e38478..75aee0b 100644 --- a/src/plugins/media-export/rygel-media-export-media-cache.vala +++ b/src/plugins/media-export/rygel-media-export-media-cache.vala @@ -670,8 +670,11 @@ public class Rygel.MediaExport.MediaCache : Object { right_sql_string); } - private string? map_operand_to_column (string operand) throws Error { + private string? map_operand_to_column (string operand, + out string? collate = null) + throws Error { string column = null; + bool use_collation = false; switch (operand) { case "res": @@ -688,19 +691,23 @@ public class Rygel.MediaExport.MediaCache : Object { break; case "dc:title": column = "o.title"; + use_collation = true; break; case "upnp:artist": case "dc:creator": column = "m.author"; + use_collation = true; break; case "dc:date": column = "strftime(\"%Y\", m.date)"; break; case "upnp:album": column = "m.album"; + use_collation = true; break; case "dc:genre": column = "m.genre"; + use_collation = true; break; default: var message = "Unsupported column %s".printf (operand); @@ -708,6 +715,13 @@ public class Rygel.MediaExport.MediaCache : Object { throw new MediaCacheError.UNSUPPORTED_SEARCH (message); } + if (&collate != null) { + if (use_collation) { + collate = "COLLATE CASEFOLD"; + } else { + collate = ""; + } + } return column; } @@ -716,8 +730,9 @@ public class Rygel.MediaExport.MediaCache : Object { throws Error { string sql_function = null; GLib.Value? v = null; + string collate = null; - string column = map_operand_to_column (exp.operand1); + string column = map_operand_to_column (exp.operand1, out collate); switch (exp.op) { case SearchCriteriaOp.EXISTS: @@ -772,7 +787,7 @@ public class Rygel.MediaExport.MediaCache : Object { args.append (v); } - return "%s %s ?".printf (column, sql_function); + return "(%s %s ? %s)".printf (column, sql_function, collate); } public Gee.List get_meta_data_column_by_filter ( -- 2.7.4