-- -------------------------------------------------------------------------- -- Name : notification-subscriptions-migration.oracle.sql -- Author : Damien Metzler -- Description : Migrate the notifications from 6.0 to 7.10 scheme -- Ammedments : -- When Who What -- =========== =============== ========================================== -- 08-MAR-2016 Damien METZLER Initial Creation -- -------------------------------------------------------------------------- -- This methods need the conversion_api that can be found here : -- https://oracle-base.com/dba/miscellaneous/conversion_api.sql CREATE OR REPLACE FUNCTION RANDOM_STRING(l_size NUMBER) RETURN VARCHAR2 AS l_random VARCHAR2 (12); BEGIN l_random := ''; FOR i IN 1..l_size LOOP l_random := l_random || RPAD (conversion_api.to_hex (TRUNC (DBMS_RANDOM.VALUE (low => 1, high => 65535))),4,'0'); END LOOP; RETURN l_random; END; / CREATE OR REPLACE FUNCTION new_uuid RETURN VARCHAR2 AS BEGIN RETURN LOWER(RANDOM_STRING(2) || '-' || RANDOM_STRING(1) || '-' || RANDOM_STRING(1) || '-' || RANDOM_STRING(1) || '-' || RANDOM_STRING(3)); END; / CREATE OR REPLACE PROCEDURE nx_migrate_notif IS TOTALCNT PLS_INTEGER; CNT PLS_INTEGER; POS1 PLS_INTEGER; POS2 PLS_INTEGER; notif_uuid NOTIFICATIONENTRY.id%TYPE; l_seed BINARY_INTEGER; CURSOR NOTIFIEDDOC IS SELECT DISTINCT docid, mixintypes FROM usersubscription, hierarchy WHERE usersubscription.docid = hierarchy.id; BEGIN TOTALCNT := 0; DBMS_OUTPUT.put_line ( 'Migrating usersubscription table to document facet'); DBMS_OUTPUT.put_line ('Removing orphan notifications'); DELETE FROM usersubscription WHERE docid IN (SELECT DISTINCT usersubscription.docid FROM usersubscription LEFT OUTER JOIN hierarchy ON hierarchy.id = usersubscription.docid WHERE hierarchy.id IS NULL); FOR subscription IN NOTIFIEDDOC LOOP -- Add the 'Notifiable' facet if needed SELECT COUNT (*) INTO CNT FROM hierarchy WHERE hierarchy.ID = subscription.docid AND hierarchy.MIXINTYPES LIKE '%|Notifiable|%'; IF CNT = 0 THEN DBMS_OUTPUT.put_line ( 'Adding Notifiable facet to ' || subscription.docid); IF subscription.mixintypes IS NULL OR LENGTH (subscription.mixintypes) = 0 THEN UPDATE hierarchy SET mixintypes = '|Notifiable|' WHERE id = subscription.docid; ELSE UPDATE hierarchy SET mixintypes = mixintypes || ('Notifiable|') WHERE id = subscription.docid; END IF; END IF; SELECT MAX (POS) INTO POS1 FROM hierarchy WHERE hierarchy.id = subscription.docid AND hierarchy.name = 'notif:notifications' AND primaryType = 'notificationEntry'; IF POS1 IS NULL THEN POS1 := 0; END IF; DBMS_OUTPUT.put_line ( 'Migrating subscription on doc : ' || subscription.docid); FOR notification IN (SELECT DISTINCT usersubscription.notification FROM usersubscription WHERE docid = subscription.docid) LOOP -- For each notification on the doc we try to fetch if there are existing notificationEntry -- for this notification BEGIN SELECT DISTINCT notificationEntry.id INTO notif_uuid FROM hierarchy, notificationEntry WHERE notificationEntry.id = hierarchy.id AND hierarchy.parentId = subscription.docID AND notificationEntry.name = notification.notification; EXCEPTION WHEN NO_DATA_FOUND THEN notif_uuid := NULL; END; IF notif_uuid IS NULL THEN -- If not, we create the hierarchy node and its notificationEntry notif_uuid := new_uuid (); INSERT INTO hierarchy (id, parentid, pos, name, isproperty, primarytype) VALUES (notif_uuid, subscription.docid, POS1, 'notif:notifications', 1, 'notificationEntry'); INSERT INTO notificationEntry (id, name) VALUES (notif_uuid, notification.notification); ELSE DBMS_OUTPUT.put_line ( 'WARNING : Notification % already in hierachy' || notification.notification); END IF; -- Then we insert the usernames that are subscribed to this notification it they're not already subscribed SELECT MAX (POS) INTO POS2 FROM subscribers WHERE id = notif_uuid; IF POS2 IS NULL THEN POS2:=0; END IF; FOR username IN (SELECT DISTINCT userid FROM usersubscription WHERE docid = docid AND usersubscription.notification = notification.notification) LOOP SELECT COUNT (*) INTO CNT FROM subscribers WHERE id = notif_uuid AND item = username.userid; IF CNT = 0 THEN INSERT INTO subscribers (id, pos, item) VALUES (notif_uuid, POS2, username.userid); TOTALCNT := TOTALCNT + 1; POS2 := POS2 + 1; ELSE DBMS_OUTPUT.put_line ( 'WARNING : Username % already subscribed' || username.userid); END IF; END LOOP; POS1 := POS1 + 1; END LOOP; DELETE FROM usersubscription WHERE docid = subscription.docid; COMMIT; END LOOP; END; / EXECUTE nx_migrate_notif; DROP PROCEDURE nx_migrate_notif; DROP FUNCTION new_uuid;