[rygel] media-export: Fix bgo#627243



commit 2427b6d5c16abfd028c3af721bc6b669d23bf05f
Author: Jens Georg <mail jensge org>
Date:   Tue Aug 24 16:59:12 2010 +0300

    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<string> get_meta_data_column_by_filter (



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]