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)