SELECT count(*) FROM t_inodes WHERE ipnfsid='000000000000000000000000000000000001' Create lost+found directory UPDATE t_inodes SET inlink=inlink+1,ictime=now(),imtime=now() WHERE ipnfsid='000000000000000000000000000000000000' Move lost links to lost+found UPDATE t_dirs SET iparent='000000000000000000000000000000000001',iname=ipnfsid WHERE NOT EXISTS (SELECT 1 FROM t_inodes WHERE ipnfsid=iparent); UPDATE t_inodes SET inlink=2+(SELECT count(*) FROM t_dirs WHERE iparent='000000000000000000000000000000000001') WHERE ipnfsid='000000000000000000000000000000000001'; Move unlinked files and directories to lost+found UPDATE t_inodes i SET inlink=1 WHERE itype != 16384 AND NOT EXISTS (SELECT 1 FROM t_dirs d WHERE d.ipnfsid=i.ipnfsid); INSERT INTO t_dirs (SELECT '000000000000000000000000000000000001',ipnfsid,ipnfsid FROM t_inodes i WHERE ipnfsid!='000000000000000000000000000000000000' AND NOT EXISTS (SELECT 1 FROM t_dirs d WHERE d.ipnfsid=i.ipnfsid)); UPDATE t_inodes SET inlink=2+(SELECT count(*) FROM t_dirs WHERE iparent='000000000000000000000000000000000001') WHERE ipnfsid='000000000000000000000000000000000001'; Correct link count on directories UPDATE t_inodes i SET inlink=2+(SELECT count(*) FROM t_dirs d WHERE d.iparent=i.ipnfsid) WHERE itype=16384 AND inlink!=2+(SELECT count(*) FROM t_dirs d WHERE d.iparent=i.ipnfsid); Add inumber identity field Update f_create_inode stored procedure to return inumber CREATE OR REPLACE FUNCTION f_create_inode(parent bigint, name varchar, id varchar, type integer, mode integer, nlink integer, uid integer, gid int, size bigint, io integer, now timestamp) RETURNS bigint AS $$ DECLARE newid bigint; BEGIN INSERT INTO t_inodes VALUES (id,type,mode,nlink,uid,gid,size,io,now,now,now,now,0) RETURNING inumber INTO newid; INSERT INTO t_dirs VALUES (parent, newid, name); UPDATE t_inodes SET inlink=inlink+1,imtime=now,ictime=now,igeneration=igeneration+1 WHERE inumber = parent; RETURN newid; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION f_create_inode(parent varchar, name varchar, id varchar, type integer, mode integer, nlink integer, uid integer, gid int, size bigint, io integer, now timestamp) RETURNS void AS $$ BEGIN INSERT INTO t_inodes VALUES (id,type,mode,nlink,uid,gid,size,io,now,now,now,now,0); INSERT INTO t_dirs VALUES (parent, name, id); UPDATE t_inodes SET inlink=inlink+1,imtime=now,ictime=now,igeneration=igeneration+1 WHERE ipnfsid=parent; END; $$ LANGUAGE plpgsql; Rewrite t_tags to use inumber as foreign key insert into t_tags (inumber, itagid, isorign, itagname) (select i.inumber, t.itagid, t.isorign, t.itagname from t_tags2 t join t_inodes i on t.ipnfsid = i.ipnfsid) insert into t_tags (ipnfsid, itagname, itagid, isorign) (select i.ipnfsid, t.itagname, t.itagid, t.isorign from t_tags2 t join t_inodes i on t.inumber = i.inumber) Replace ipnfsid by inumber as foreign key in t_dirs insert into t_dirs (select p.inumber, c.inumber, d.iname from t_dirs_old d join t_inodes p on d.iparent = p.ipnfsid join t_inodes c on d.ipnfsid = c.ipnfsid) insert into t_dirs (select p.ipnfsid, d.iname, c.ipnfsid from t_dirs_new d join t_inodes p on d.iparent = p.inumber join t_inodes c on d.ichild = c.inumber) Replace ipndsid by inumber as foreign key in t_inodes_data insert into t_inodes_data (inumber,ifiledata) (select i.inumber,d.ifiledata from t_inodes_data2 d join t_inodes i on d.ipnfsid = i.ipnfsid) insert into t_inodes_data (ipnfsid,ifiledata) (select i.ipnfsid,d.ifiledata from t_inodes_data2 d join t_inodes i on d.inumber = i.inumber) Update stored procedures for inumber changes in t_dirs CREATE OR REPLACE FUNCTION path2inumber(root bigint, path varchar) RETURNS bigint AS $$ DECLARE id bigint := root; elements varchar[] := string_to_array(path, '/'); child bigint; type int; link varchar; BEGIN FOR i IN 1..array_upper(elements,1) LOOP CASE WHEN elements[i] = '.' THEN child := id; WHEN elements[i] = '..' THEN SELECT iparent INTO child FROM t_dirs WHERE ichild = id; IF NOT FOUND THEN child := id; END IF; ELSE SELECT d.ichild, c.itype INTO child, type FROM t_dirs d JOIN t_inodes c ON d.ichild = c.inumber WHERE d.iparent = id AND d.iname = elements[i]; IF type = 40960 THEN SELECT encode(ifiledata,'escape') INTO link FROM t_inodes_data WHERE inumber = child; IF link LIKE '/%' THEN child := path2inumber(pnfsid2inumber('000000000000000000000000000000000000'), substring(link from 2)); ELSE child := path2inumber(id, link); END IF; END IF; END CASE; IF child IS NULL THEN RETURN NULL; END IF; id := child; END LOOP; RETURN id; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION path2inodes(root bigint, path varchar, OUT inode t_inodes) RETURNS SETOF t_inodes AS $$ DECLARE dir bigint; elements text[] := string_to_array(path, '/'); inodes t_inodes[]; parent t_inodes; link varchar; BEGIN -- Find the inode of the root SELECT * INTO inode FROM t_inodes WHERE inumber = root; IF NOT FOUND THEN RETURN; END IF; -- We build an array of the inodes for the path inodes := ARRAY[inode]; -- For each path element FOR i IN 1..array_upper(elements,1) LOOP -- Return empty set if not a directory IF inode.itype != 16384 THEN RETURN; END IF; -- The ID of the directory dir := inode.inumber; -- Lookup the next path element CASE WHEN elements[i] = '.' THEN CONTINUE; WHEN elements[i] = '..' THEN SELECT p.* INTO parent FROM t_inodes p JOIN t_dirs d ON p.inumber = d.iparent WHERE d.ichild = dir; IF FOUND THEN inode := parent; ELSE CONTINUE; END IF; ELSE SELECT c.* INTO inode FROM t_inodes c JOIN t_dirs d ON c.inumber = d.ichild WHERE d.iparent = dir AND d.iname = elements[i]; -- Return the empty set if not found IF NOT FOUND THEN RETURN; END IF; END CASE; -- Append the inode to the result set inodes := array_append(inodes, inode); -- If inode is a symbolic link IF inode.itype = 40960 THEN -- Read the link SELECT encode(ifiledata,'escape') INTO STRICT link FROM t_inodes_data WHERE inumber = inode.inumber; -- If absolute path then resolve from the file system root IF link LIKE '/%' THEN dir := pnfsid2inumber('000000000000000000000000000000000000'); link := substring(link from 2); -- Call recursively and add inodes to result set FOR inode IN SELECT * FROM path2inodes(dir, link) LOOP inodes := array_append(inodes, inode); END LOOP; ELSE -- Call recursively and add inodes to result set; skip -- first inode as it is the inode of dir FOR inode IN SELECT * FROM path2inodes(dir, link) OFFSET 1 LOOP inodes := array_append(inodes, inode); END LOOP; END IF; -- Return empty set if link could not be resolved IF NOT FOUND THEN RETURN; END IF; -- Continue from the inode pointed to by the link inode = inodes[array_upper(inodes,1)]; END IF; END LOOP; -- Output all inodes FOR i IN 1..array_upper(inodes,1) LOOP inode := inodes[i]; RETURN NEXT; END LOOP; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION inumber2path(bigint) RETURNS varchar AS $$ DECLARE inumber bigint := $1; path varchar := ''; entry record; BEGIN LOOP SELECT * INTO entry FROM t_dirs WHERE ichild = inumber; IF FOUND AND entry.iparent != inumber THEN path := '/' || entry.iname || path; inumber := entry.iparent; ELSE EXIT; END IF; END LOOP; RETURN path; END; $$ LANGUAGE 'plpgsql'; CREATE OR REPLACE FUNCTION pnfsid2inumber(varchar) RETURNS bigint AS $$ SELECT inumber FROM t_inodes WHERE ipnfsid = $1; $$ LANGUAGE SQL; CREATE OR REPLACE FUNCTION inumber2pnfsid(bigint) RETURNS varchar AS $$ SELECT ipnfsid FROM t_inodes WHERE inumber = $1; $$ LANGUAGE SQL; CREATE OR REPLACE FUNCTION inode2path(varchar) RETURNS varchar AS $$ SELECT inumber2path(pnfsid2inumber($1)); $$ LANGUAGE SQL; CREATE OR REPLACE FUNCTION path2inode(root varchar, path varchar) RETURNS varchar AS $$ SELECT inumber2pnfsid(path2inumber(pnfsid2inumber($1), $2)); $$ LANGUAGE SQL; DROP FUNCTION path2inodes(root varchar, path varchar, OUT inode t_inodes) CREATE OR REPLACE FUNCTION path2inode(root varchar, path varchar) RETURNS varchar AS $$ DECLARE id varchar := root; elements varchar[] := string_to_array(path, '/'); child varchar; itype INT; link varchar; BEGIN FOR i IN 1..array_upper(elements,1) LOOP CASE WHEN elements[i] = '.' THEN child := id; WHEN elements[i] = '..' THEN IF id = '000000000000000000000000000000000000' THEN child := id; ELSE SELECT iparent INTO child FROM t_dirs WHERE ipnfsid=id; END IF; ELSE SELECT dir.ipnfsid, inode.itype INTO child, itype FROM t_dirs dir, t_inodes inode WHERE dir.ipnfsid = inode.ipnfsid AND dir.iparent=id AND dir.iname=elements[i]; IF itype=40960 THEN SELECT encode(ifiledata,'escape') INTO link FROM t_inodes_data WHERE ipnfsid=child; IF link LIKE '/%' THEN child := path2inode('000000000000000000000000000000000000', substring(link from 2)); ELSE child := path2inode(id, link); END IF; END IF; END CASE; IF child IS NULL THEN RETURN NULL; END IF; id := child; END LOOP; RETURN id; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION path2inodes(root varchar, path varchar, OUT inode t_inodes) RETURNS SETOF t_inodes AS $$ DECLARE dir varchar; elements text[] := string_to_array(path, '/'); inodes t_inodes[]; link varchar; BEGIN -- Find the inode of the root SELECT * INTO inode FROM t_inodes WHERE ipnfsid = root; IF NOT FOUND THEN RETURN; END IF; -- We build an array of the inodes for the path inodes := ARRAY[inode]; -- For each path element FOR i IN 1..array_upper(elements,1) LOOP -- Return empty set if not a directory IF inode.itype != 16384 THEN RETURN; END IF; -- The PNFS ID of the directory dir := inode.ipnfsid; -- Lookup the next path element CASE WHEN elements[i] = '.' THEN CONTINUE; WHEN elements[i] = '..' THEN IF dir = '000000000000000000000000000000000000' THEN CONTINUE; ELSE SELECT t_inodes.* INTO inode FROM t_inodes, t_dirs WHERE t_inodes.ipnfsid = t_dirs.iparent AND t_dirs.ipnfsid = dir; END IF; ELSE SELECT t_inodes.* INTO inode FROM t_inodes, t_dirs WHERE t_inodes.ipnfsid = t_dirs.ipnfsid AND t_dirs.iparent = dir AND iname = elements[i]; END CASE; -- Return the empty set if not found IF NOT FOUND THEN RETURN; END IF; -- Append the inode to the result set inodes := array_append(inodes, inode); -- If inode is a symbolic link IF inode.itype = 40960 THEN -- Read the link SELECT encode(ifiledata,'escape') INTO STRICT link FROM t_inodes_data WHERE ipnfsid = inode.ipnfsid; -- If absolute path then resolve from the file system root IF link LIKE '/%' THEN dir := '000000000000000000000000000000000000'; link := substring(link from 2); -- Call recursively and add inodes to result set FOR inode IN SELECT * FROM path2inodes(dir, link) LOOP inodes := array_append(inodes, inode); END LOOP; ELSE -- Call recursively and add inodes to result set; skip -- first inode as it is the inode of dir FOR inode IN SELECT * FROM path2inodes(dir, link) OFFSET 1 LOOP inodes := array_append(inodes, inode); END LOOP; END IF; -- Return empty set if link could not be resolved IF NOT FOUND THEN RETURN; END IF; -- Continue from the inode pointed to by the link inode = inodes[array_upper(inodes,1)]; END IF; END LOOP; -- Output all inodes FOR i IN 1..array_upper(inodes,1) LOOP inode := inodes[i]; RETURN NEXT; END LOOP; END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION inode2path(varchar) RETURNS varchar AS $$ DECLARE inode VARCHAR := $1; ipath varchar := ''; ichain RECORD; BEGIN LOOP SELECT INTO ichain * FROM t_dirs WHERE ipnfsid=inode AND iname != '.' AND iname != '..'; IF FOUND AND ichain.iparent != inode THEN ipath := '/' || ichain.iname || ipath; inode := ichain.iparent; ELSE EXIT; END IF; END LOOP; RETURN ipath; END; $$ LANGUAGE 'plpgsql'; DROP FUNCTION inumber2path(BIGINT); DROP FUNCTION path2inodes(root bigint, path varchar, OUT inode t_inodes); DROP FUNCTION path2inumber(root bigint, path varchar); DROP FUNCTION pnfsid2inumber(varchar); DROP FUNCTION inumber2pnfsid(bigint); Replace ipndsid by inumber as foreign key in t_inodes_checksum insert into t_inodes_checksum (inumber, itype, isum) (select i.inumber,c.itype,c.isum from t_inodes_checksum2 c join t_inodes i on c.ipnfsid=i.ipnfsid) insert into t_inodes_checksum (ipnfsid, itype, isum) (select i.ipnfsid,c.itype,c.isum from t_inodes_checksum2 c join t_inodes i on c.inumber=i.inumber) Replace ipndsid by inumber as foreign key in t_storageinfo insert into t_storageinfo (inumber,ihsmname,istoragegroup,istoragesubgroup) (select i.inumber,s.ihsmname,s.istoragegroup,s.istoragesubgroup from t_storageinfo2 s join t_inodes i on s.ipnfsid=i.ipnfsid) insert into t_storageinfo (ipnfsid,ihsmname,istoragegroup,istoragesubgroup) (select i.ipnfsid,s.ihsmname,s.istoragegroup,s.istoragesubgroup from t_storageinfo2 s join t_inodes i on s.inumber=i.inumber) DROP TRIGGER tgr_locationinfo_trash; DROP TRIGGER tgr_locationinfo_trash2; CREATE TRIGGER tgr_locationinfo_trash AFTER DELETE ON t_locationinfo REFERENCING OLD ROW old FOR EACH ROW WHEN (NOT EXISTS (SELECT 1 FROM t_inodes WHERE ipnfsid = old.ipnfsid)) INSERT INTO t_locationinfo_trash VALUES (old.ipnfsid, old.itype, old.ilocation, old.ipriority, old.ictime, old.iatime, old.istate) CREATE TRIGGER tgr_locationinfo_trash2 AFTER DELETE ON t_inodes REFERENCING OLD ROW old FOR EACH ROW INSERT INTO t_locationinfo_trash VALUES (old.ipnfsid, 2, '', 0, now(), now(), 1) Replace ipndsid by inumber as foreign key in t_locationinfo insert into t_locationinfo (inumber,itype,ipriority,ictime,iatime,istate,ilocation) (select i.inumber,l.itype,l.ipriority,l.ictime,l.iatime,l.istate,l.ilocation from t_locationinfo2 l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_locationinfo (ipnfsid,itype,ilocation,ipriority,ictime,iatime,istate) (select i.ipnfsid,l.itype,l.ilocation,l.ipriority,l.ictime,l.iatime,l.istate from t_locationinfo2 l join t_inodes i on l.inumber=i.inumber) Update stored procedures for inumber changes in t_locationinfo DROP TRIGGER IF EXISTS tgr_locationinfo_trash ON t_inodes; -- -- store location of deleted inodes in trash table -- CREATE OR REPLACE FUNCTION f_locationinfo2trash() RETURNS TRIGGER AS $t_inodes_trash$ BEGIN IF (TG_OP = 'DELETE') THEN INSERT INTO t_locationinfo_trash SELECT OLD.ipnfsid, itype, ilocation, ipriority, ictime, iatime, istate FROM t_locationinfo WHERE inumber = OLD.inumber UNION SELECT OLD.ipnfsid, 2, '', 0, now(), now(), 1; END IF; RETURN OLD; END; $t_inodes_trash$ LANGUAGE plpgsql; -- -- trigger to store removed inodes -- CREATE TRIGGER tgr_locationinfo_trash BEFORE DELETE ON t_inodes FOR EACH ROW EXECUTE PROCEDURE f_locationinfo2trash(); DROP TRIGGER IF EXISTS tgr_locationinfo_trash ON t_inodes; -- -- store location of deleted inodes in trash table -- -- stores a old values into the trash table except last access time, -- which replaced with a time, when the trigger was running -- CREATE OR REPLACE FUNCTION f_locationinfo2trash() RETURNS TRIGGER AS $t_inodes_trash$ BEGIN IF (TG_OP = 'DELETE') THEN INSERT INTO t_locationinfo_trash SELECT ipnfsid , itype, ilocation , ipriority, ictime , iatime , istate FROM t_locationinfo WHERE ipnfsid = OLD.ipnfsid UNION SELECT OLD.ipnfsid, 2, '', 0, now(), now(), 1; END IF; RETURN OLD; END; $t_inodes_trash$ LANGUAGE plpgsql; -- -- trigger to store removed inodes -- CREATE TRIGGER tgr_locationinfo_trash BEFORE DELETE ON t_inodes FOR EACH ROW EXECUTE PROCEDURE f_locationinfo2trash(); Replace ipndsid by inumber as foreign key in t_level_1 insert into t_level_1 (inumber,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.inumber,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_1_old l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_level_1 (ipnfsid,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.ipnfsid,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_1_old l join t_inodes i on l.inumber=i.inumber) Replace ipndsid by inumber as foreign key in t_level_2 insert into t_level_2 (inumber,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.inumber,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_2_old l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_level_2 (ipnfsid,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.ipnfsid,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_2_old l join t_inodes i on l.inumber=i.inumber) Replace ipndsid by inumber as foreign key in t_level_3 insert into t_level_3 (inumber,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.inumber,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_3_old l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_level_3 (ipnfsid,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.ipnfsid,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_3_old l join t_inodes i on l.inumber=i.inumber) Replace ipndsid by inumber as foreign key in t_level_4 insert into t_level_4 (inumber,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.inumber,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_4_old l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_level_4 (ipnfsid,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.ipnfsid,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_4_old l join t_inodes i on l.inumber=i.inumber) Replace ipndsid by inumber as foreign key in t_level_5 insert into t_level_5 (inumber,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.inumber,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_5_old l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_level_5 (ipnfsid,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.ipnfsid,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_5_old l join t_inodes i on l.inumber=i.inumber) Replace ipndsid by inumber as foreign key in t_level_6 insert into t_level_6 (inumber,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.inumber,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_6_old l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_level_6 (ipnfsid,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.ipnfsid,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_6_old l join t_inodes i on l.inumber=i.inumber) Replace ipndsid by inumber as foreign key in t_level_7 insert into t_level_7 (inumber,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.inumber,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_7_old l join t_inodes i on l.ipnfsid=i.ipnfsid) insert into t_level_7 (ipnfsid,imode,inlink,iuid,igid,isize,ictime,iatime,imtime,ifiledata) (select i.ipnfsid,l.imode,l.inlink,l.iuid,l.igid,l.isize,l.ictime,l.iatime,l.imtime,l.ifiledata from t_level_7_old l join t_inodes i on l.inumber=i.inumber) Fix trigger on insert or update on t_level_4 -- -- populate t_storageinfo from information in t_level_4 -- CREATE OR REPLACE FUNCTION "public"."enstore2chimera" () RETURNS void AS $$ DECLARE ichain RECORD; istring text[]; igroup text; istore text; l_entries text[]; ilocation text; BEGIN FOR ichain IN SELECT * FROM t_level_4 LOOP ilocation = f_enstore2uri(encode(ichain.ifiledata,'escape')); IF ilocation IS NULL THEN raise warning 'ilocation is NULL %',ichain.inumber; CONTINUE; ELSE BEGIN INSERT INTO t_locationinfo VALUES ( ichain.inumber, 0, ilocation, 10, NOW(), NOW(), 1); EXCEPTION WHEN unique_violation THEN -- do nothing RAISE NOTICE 'Tape location for % aready exist.', ichain.inumber; CONTINUE; END; l_entries = string_to_array(encode(ichain.ifiledata,'escape'), E'\n'); BEGIN INSERT INTO t_storageinfo VALUES (ichain.inumber,'enstore','enstore',l_entries[4]); EXCEPTION WHEN unique_violation THEN -- do nothing RAISE NOTICE 'Storage info for % aready exist.', ichain.inumber; CONTINUE; END; END IF; END LOOP; END; $$ LANGUAGE 'plpgsql'; DROP TRIGGER IF EXISTS tgr_enstore_location ON t_level_4; CREATE OR REPLACE FUNCTION f_enstorelevel2locationinfo() RETURNS TRIGGER AS $$ DECLARE l_entries text[]; location text; file_data varchar; BEGIN IF (TG_OP = 'INSERT') THEN location := f_enstore2uri(encode(NEW.ifiledata,'escape')); IF location IS NULL THEN -- encp only creates empty layer 4 file -- so NEW.ifiledata is null INSERT INTO t_locationinfo VALUES (NEW.inumber,0,'enstore:',10,NOW(),NOW(),1); INSERT INTO t_storageinfo VALUES (NEW.inumber,'enstore','enstore','enstore'); ELSE l_entries = string_to_array(encode(NEW.ifiledata,'escape'), E'\n'); INSERT INTO t_locationinfo VALUES (NEW.inumber,0,location,10,NOW(),NOW(),1); INSERT INTO t_storageinfo VALUES (NEW.inumber,'enstore','enstore',l_entries[4]); END IF; -- -- we assume all files coming through level4 to be CUSTODIAL-NEARLINE -- -- the block below is needed for files written directly by encp -- BEGIN UPDATE t_inodes SET iaccess_latency = 0, iretention_policy = 0 WHERE inumber = NEW.inumber; END; ELSEIF (TG_OP = 'UPDATE') THEN file_data := encode(NEW.ifiledata, 'escape'); IF ( file_data = E'\n') THEN UPDATE t_locationinfo SET ilocation = file_data WHERE inumber = NEW.inumber and itype=0; ELSE location := f_enstore2uri(file_data); IF location IS NOT NULL THEN UPDATE t_locationinfo SET ilocation = f_enstore2uri(file_data) WHERE inumber = NEW.inumber and itype=0; l_entries = string_to_array(file_data, E'\n'); UPDATE t_storageinfo SET istoragesubgroup=l_entries[4] WHERE inumber = NEW.inumber; END IF; END IF; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER tgr_enstore_location BEFORE INSERT OR UPDATE ON t_level_4 FOR EACH ROW EXECUTE PROCEDURE f_enstorelevel2locationinfo(); -- -- populate t_storageinfo from information in t_level_4 -- CREATE OR REPLACE FUNCTION "public"."enstore2chimera" () RETURNS void AS $$ DECLARE ichain RECORD; istring text[]; igroup text; istore text; l_entries text[]; ilocation text; BEGIN FOR ichain IN SELECT * FROM t_level_4 LOOP ilocation = f_enstore2uri(encode(ichain.ifiledata,'escape')); IF ilocation IS NULL THEN raise warning 'ilocation is NULL %',ichain.ipnfsid; CONTINUE; ELSE BEGIN INSERT INTO t_locationinfo VALUES ( ichain.ipnfsid, 0, ilocation, 10, NOW(), NOW(), 1); EXCEPTION WHEN unique_violation THEN -- do nothing RAISE NOTICE 'Tape location for % aready exist.', ichain.ipnfsid; CONTINUE; END; l_entries = string_to_array(encode(ichain.ifiledata,'escape'), E'\n'); BEGIN INSERT INTO t_storageinfo VALUES (ichain.ipnfsid,'enstore','enstore',l_entries[4]); EXCEPTION WHEN unique_violation THEN -- do nothing RAISE NOTICE 'Storage info for % aready exist.', ichain.ipnfsid; CONTINUE; END; END IF; END LOOP; END; $$ LANGUAGE 'plpgsql'; DROP TRIGGER IF EXISTS tgr_enstore_location ON t_level_4; CREATE OR REPLACE FUNCTION f_enstorelevel2locationinfo() RETURNS TRIGGER AS $$ DECLARE l_entries text[]; location text; file_data varchar; BEGIN IF (TG_OP = 'INSERT') THEN location := f_enstore2uri(encode(NEW.ifiledata,'escape')); IF location IS NULL THEN -- encp only creates empty layer 4 file -- so NEW.ifiledata is null INSERT INTO t_locationinfo VALUES (NEW.ipnfsid,0,'enstore:',10,NOW(),NOW(),1); INSERT INTO t_storageinfo VALUES (NEW.ipnfsid,'enstore','enstore','enstore'); ELSE l_entries = string_to_array(encode(NEW.ifiledata,'escape'), E'\n'); INSERT INTO t_locationinfo VALUES (NEW.ipnfsid,0,location,10,NOW(),NOW(),1); INSERT INTO t_storageinfo VALUES (NEW.ipnfsid,'enstore','enstore',l_entries[4]); END IF; -- -- we assume all files coming through level4 to be CUSTODIAL-NEARLINE -- -- the block below is needed for files written directly by encp -- BEGIN UPDATE t_inodes SET iaccess_latency = 0, iretention_policy = 0 WHERE ipnfsid = NEW.ipnfsid; END; ELSEIF (TG_OP = 'UPDATE') THEN file_data := encode(NEW.ifiledata, 'escape'); IF ( file_data = E'\n') THEN UPDATE t_locationinfo SET ilocation = file_data WHERE ipnfsid = NEW.ipnfsid and itype=0; ELSE location := f_enstore2uri(file_data); IF location IS NOT NULL THEN UPDATE t_locationinfo SET ilocation = f_enstore2uri(file_data) WHERE ipnfsid = NEW.ipnfsid and itype=0; l_entries = string_to_array(file_data, E'\n'); UPDATE t_storageinfo SET istoragesubgroup=l_entries[4] WHERE ipnfsid = NEW.ipnfsid; END IF; END IF; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER tgr_enstore_location BEFORE INSERT OR UPDATE ON t_level_4 FOR EACH ROW EXECUTE PROCEDURE f_enstorelevel2locationinfo(); Replace ipndsid by inumber as foreign key in t_acl insert into t_acl (inumber,ace_order,rs_type,type,access_msk,who,who_id,flags) (select i.inumber,a.ace_order,a.rs_type,a.type,a.access_msk,a.who,a.who_id,a.flags from t_acl2 a join t_inodes i on a.rs_id=i.ipnfsid) insert into t_acl (rs_id,rs_type,type,flags,access_msk,who,who_id,ace_order) (select i.ipnfsid,a.rs_type,a.type,a.flags,a.access_msk,a.who,a.who_id,a.ace_order from t_acl2 a join t_inodes i on a.inumber=i.inumber)