Provide a faster I18N stored proc and teach cstore et al to use it. user/miker/faster-i18n
authorMike Rylander <mrylander@gmail.com>
Mon, 8 May 2017 17:17:10 +0000 (13:17 -0400)
committerMike Rylander <mrylander@gmail.com>
Mon, 8 May 2017 17:17:10 +0000 (13:17 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/c-apps/oils_sql.c
Open-ILS/src/sql/Pg/002.functions.config.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.function.faster-i18n.sql [new file with mode: 0644]

index c33a3af..9104237 100644 (file)
@@ -4530,10 +4530,10 @@ char* SELECT (
                                                        i18n = osrfHashGet( field_def, "i18n" );
 
                                                if( str_is_true( i18n ) ) {
-                                                       buffer_fadd( select_buf, " oils_i18n_xlate('%s', '%s', '%s', "
-                                                               "'%s', \"%s\".%s::TEXT, '%s') AS \"%s\"",
+                                                       buffer_fadd( select_buf, " COALESCE(oils_i18n_xlate('%s', '%s', '%s', "
+                                                               "'%s', \"%s\".%s::TEXT, '%s'),%s) AS \"%s\"",
                                                                class_tname, cname, col_name, class_pkey,
-                                                               cname, class_pkey, locale, col_name );
+                                                               cname, class_pkey, locale, col_name, col_name );
                                                } else {
                                                        buffer_fadd( select_buf, " \"%s\".%s AS \"%s\"",
                                                                cname, col_name, col_name );
@@ -4654,10 +4654,10 @@ char* SELECT (
 
                                                        if( str_is_true( i18n ) ) {
                                                                buffer_fadd( select_buf,
-                                                                       " oils_i18n_xlate('%s', '%s', '%s', '%s', "
-                                                                       "\"%s\".%s::TEXT, '%s') AS \"%s\"",
+                                                                       " COALESCE(oils_i18n_xlate('%s', '%s', '%s', '%s', "
+                                                                       "\"%s\".%s::TEXT, '%s'),%s) AS \"%s\"",
                                                                        class_tname, cname, col_name, class_pkey, cname,
-                                                                       class_pkey, locale, _alias );
+                                                                       class_pkey, locale, col_name, _alias );
                                                        } else {
                                                                buffer_fadd( select_buf, " \"%s\".%s AS \"%s\"",
                                                                        cname, col_name, _alias );
@@ -5500,9 +5500,9 @@ static char* buildSELECT ( const jsonObject* search_hash, jsonObject* rest_of_qu
                                        char* pkey = osrfHashGet( idlClass, "primarykey" );
                                        char* tname = osrfHashGet( idlClass, "tablename" );
 
-                                       buffer_fadd( select_buf, " oils_i18n_xlate('%s', '%s', '%s', "
-                                                       "'%s', \"%s\".%s::TEXT, '%s') AS \"%s\"",
-                                                       tname, cname, fname, pkey, cname, pkey, locale, fname );
+                                       buffer_fadd( select_buf, " COALESCE(oils_i18n_xlate('%s', '%s', '%s', "
+                                                       "'%s', \"%s\".%s::TEXT, '%s'),%s) AS \"%s\"",
+                                                       tname, cname, fname, pkey, cname, pkey, locale, fname, fname );
                                } else {
                                        buffer_fadd( select_buf, " \"%s\".%s", cname, fname );
                                }
index 7eaed4c..95bdfe6 100644 (file)
@@ -283,45 +283,27 @@ $$ LANGUAGE SQL IMMUTABLE;
 
 
 
-CREATE OR REPLACE FUNCTION oils_i18n_xlate ( keytable TEXT, keyclass TEXT, keycol TEXT, identcol TEXT, keyvalue TEXT, raw_locale TEXT ) RETURNS TEXT AS $func$
-DECLARE
-    locale      TEXT := REGEXP_REPLACE( REGEXP_REPLACE( raw_locale, E'[;, ].+$', '' ), E'_', '-', 'g' );
-    language    TEXT := REGEXP_REPLACE( locale, E'-.+$', '' );
-    result      config.i18n_core%ROWTYPE;
-    fallback    TEXT;
-    keyfield    TEXT := keyclass || '.' || keycol;
-BEGIN
+CREATE OR REPLACE FUNCTION oils_i18n_xlate (text, text, text, text, text, text) RETURNS TEXT AS $$
+
+WITH
+    wlocale AS (
+        SELECT REGEXP_REPLACE( REGEXP_REPLACE( $6, E'[;, ].+$', '' ), E'_', '-', 'g' ) AS value
+    ),
+    wlanguage AS (
+        SELECT REGEXP_REPLACE( wlocale.value, E'-.+$', '' ) AS value FROM wlocale
+    )
 
-    -- Try the full locale
-    SELECT  * INTO result
-      FROM  config.i18n_core
-      WHERE fq_field = keyfield
-            AND identity_value = keyvalue
-            AND translation = locale;
-
-    -- Try just the language
-    IF NOT FOUND THEN
-        SELECT  * INTO result
-          FROM  config.i18n_core
-          WHERE fq_field = keyfield
-                AND identity_value = keyvalue
-                AND translation = language;
-    END IF;
-
-    -- Fall back to the string we passed in in the first place
-    IF NOT FOUND THEN
-       EXECUTE
-            'SELECT ' ||
-                keycol ||
-            ' FROM ' || keytable ||
-            ' WHERE ' || identcol || ' = ' || quote_literal(keyvalue)
-                INTO fallback;
-        RETURN fallback;
-    END IF;
-
-    RETURN result.string;
-END;
-$func$ LANGUAGE PLPGSQL STABLE;
+    SELECT  string
+      FROM  config.i18n_core,
+            wlocale,
+            wlanguage
+      WHERE fq_field = $2 || '.' || $3
+            AND translation IN (wlanguage.value, wlanguage.value)
+            AND identity_value = $5
+      ORDER BY LENGTH(translation) DESC
+      LIMIT 1
+
+$$ LANGUAGE SQL STABLE;
 
 -- Functions for marking translatable strings in SQL statements
 -- Parameters are: primary key, string, class hint, property
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.function.faster-i18n.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.function.faster-i18n.sql
new file mode 100644 (file)
index 0000000..67a8ed1
--- /dev/null
@@ -0,0 +1,29 @@
+BEGIN;
+
+DROP FUNCTION oils_i18n_xlate (text, text, text, text, text, text);
+
+CREATE OR REPLACE FUNCTION oils_i18n_xlate (text, text, text, text, text, text) RETURNS TEXT AS $$
+
+WITH
+    wlocale AS (
+        SELECT REGEXP_REPLACE( REGEXP_REPLACE( $6, E'[;, ].+$', '' ), E'_', '-', 'g' ) AS value
+    ),
+    wlanguage AS (
+        SELECT REGEXP_REPLACE( wlocale.value, E'-.+$', '' ) AS value FROM wlocale
+    )
+
+    SELECT  string
+      FROM  config.i18n_core,
+            wlocale,
+            wlanguage
+      WHERE fq_field = $2 || '.' || $3
+            AND translation IN (wlanguage.value, wlanguage.value)
+            AND identity_value = $5
+      ORDER BY LENGTH(translation) DESC
+      LIMIT 1
+
+$$ LANGUAGE SQL STABLE;
+
+COMMIT;
+
+