[PATCH 3 of 4 saem_ref v2] [ark] Add PL/pgSQL function to generate qualified ARK identifier

Denis Laxalde denis.laxalde at logilab.fr
Thu Feb 15 15:04:05 CET 2018


# HG changeset patch
# User Denis Laxalde <denis.laxalde at logilab.fr>
# Date 1518702264 -3600
#      Thu Feb 15 14:44:24 2018 +0100
# Node ID a32231d4c7039692a87f9fa38ba527b732ebafc6
# Parent  97dd205f44f9ba98f5ed3d8960970e0602532f59
# Available At http://hg.logilab.org/review/cubes/saem_ref
#              hg pull http://hg.logilab.org/review/cubes/saem_ref -r a32231d4c703
# EXP-Topic ark/qualifiers
[ark] Add PL/pgSQL function to generate qualified ARK identifier

We add a gen_qualified_ark function taking an existing ARK record with
specified "name" attribute and produces a new ARK record with a randomly
generated "qualifier" and specified "name".

Related to extranet #46880051.

diff --git a/cubicweb_saem_ref/schema/ark.postgres.sql b/cubicweb_saem_ref/schema/ark.postgres.sql
--- a/cubicweb_saem_ref/schema/ark.postgres.sql
+++ b/cubicweb_saem_ref/schema/ark.postgres.sql
@@ -74,3 +74,31 @@ BEGIN
     END LOOP;
 END;
 $$ LANGUAGE plpgsql;
+
+-- Insert a record in "ark" table from a "base" identifier using a qualifier.
+CREATE OR REPLACE
+FUNCTION gen_qualified_ark(base TEXT, len INTEGER)
+RETURNS TEXT AS $$
+DECLARE
+    ark_qualifier TEXT;
+BEGIN
+    PERFORM 1 FROM ark WHERE ark.name = base AND ark.qualifier = '';
+    IF NOT FOUND THEN
+        RAISE 'no ark record matching name "%" found', base
+        USING ERRCODE = 'invalid_parameter_value';
+    END IF;
+    LOOP
+        BEGIN
+            INSERT INTO ark
+                VALUES (base, gen_ark_part(len, '', ''))
+                RETURNING qualifier INTO ark_qualifier;
+            RETURN ark_qualifier;
+        EXCEPTION
+            WHEN unique_violation THEN
+                -- Continue and try with another "name".
+                RAISE WARNING 'unique_violation';
+                NULL;
+        END;
+    END LOOP;
+END;
+$$ LANGUAGE plpgsql;
diff --git a/test/test_ark.py b/test/test_ark.py
--- a/test/test_ark.py
+++ b/test/test_ark.py
@@ -85,6 +85,28 @@ class ArkServiceTC(testlib.CubicWebTC):
             str(cm.exception),
         )
 
+    def test_generate_qualifier_no_name_existing(self):
+        with self.connect() as conn:
+            with conn.cursor() as cu:
+                with self.assertRaises(psycopg2.DataError) as cm:
+                    cu.execute("SELECT * FROM gen_qualified_ark(%s, %s);",
+                               ("doesnotexist", 3))
+        self.assertIn('no ark record matching name "doesnotexist" found',
+                      str(cm.exception))
+
+    def test_generate_qualifier_name_existing(self):
+        with self.connect() as conn:
+            with conn.cursor() as cu:
+                cu.execute("INSERT INTO ark VALUES (%s, DEFAULT);",
+                           ("exists", ))
+                cu.execute("SELECT * FROM gen_qualified_ark(%s, %s);",
+                           ("exists", 3))
+                cu.execute("SELECT * FROM ark"
+                           " WHERE ark.name = 'exists'"
+                           " AND NOT ark.qualifier = '';")
+                (_, qualifier), = cu.fetchall()
+        self.assertEqual(len(qualifier), 3, qualifier)
+
 
 if __name__ == '__main__':
     import unittest



More information about the saem-devel mailing list