create view syncinfo as with -- paths to libraries we need to keep around preserve as ( select PFL.* from packagefiles PFL join elflibraries EL on EL.file = PFL.hash join elfneeded EN on EN.needed = EL.soname join packagefiles PFN on EN.file = PFN.hash join packages PN on PFN.package = PN.package and PFN.version = PN.version and PFN.release = PN.release where PN.status = 'installing' or PN.status = 'installed' and not (PFN.package = PFL.package and PFN.version = PFN.version and PFN.release = PFL.release) ), waspreserved as ( select PF.path from packagefiles PF join elflibraries EL on EL.file = PF.hash join elfneeded EN on EN.needed = EL.soname join packagefiles PL on EN.file = PL.hash join packages P on PL.path = P.package and PL.version = P.version and PL.release = P.release where P.status = 'removing' or P.status = 'installed' or P.status = 'updating' ) -- every path in 'installing' is either new or update, or no-op -- but we have to calculate them separately I think. -- once for new, once for update, and once for no-op, might be able -- to combine update and no-op select 'new' as op, printf('%s-%s-%s', PFI.package, PFI.version, PFI.release) as pkgid, PFI.path, PFI.username, PFI.uid, PFI.groupname, PFI.gid, PFI.mode, PFI.filetype, PFI.mtime, PFI.hash, PFI.configuration -- + case when PFC.configuration = 1 then 2 else 0 end as configuration, PFI.target, PFI.device, null as ohash, printf('%s:%s:%s:%s', PFI.filetype, PFI.mode, PFI.username, PFI.groupname) as mds, --printf('%s:%s:%s:%s', PFC.filetype, PFC.mode, PFC.username, PFC.groupname) as omds null as omds from packagefiles PFI join packages PI on PFI.package = PI.package and PFI.version = PI.version and PFI.release = PI.release /* left join packagefiles PFC on PFI.path = PFC.path left join packages PC on (PFI.package is not PC.package or PFI.release is not PC.release or PC.version is not PFI.version) and PC.status in ('installed','removing','updating') and PFC.package = PC.package and PFC.version = PC.version and PFC.release = PC.release */ where PI.status = 'installing' and not exists (select PFC.path from packagefiles PFC join packages PC on PFC.package = PC.package and PFC.version = PC.version and PFC.release = PC.release where PFC.path = PFI.path and PC.status in ('installed','removing','updating') ) /* (PFC.path is null or PC.status not in ('installed','removing','updating') ) */ union select case when PFI.filetype is PFC.filetype and PFI.mode is PFC.mode and PFI.username is PFC.username and PFI.groupname is PFC.groupname and PFI.hash is PFC.hash then 'noop' when PC.status = 'installed' then 'md conflict' else 'update' end as op, printf('%s-%s-%s', PFI.package, PFI.version, PFI.release) as pkgid, PFI.path, PFI.username, PFI.uid, PFI.groupname, PFI.gid, PFI.mode, PFI.filetype, PFI.mtime, PFI.hash, PFI.configuration + case when PFC.configuration = 1 then 2 else 0 end as configuration, PFI.target, PFI.device, PFC.hash as ohash, printf('%s:%s:%s:%s', PFI.filetype, PFI.mode, PFI.username, PFI.groupname) as mds, printf('%s:%s:%s:%s', PFC.filetype, PFC.mode, PFC.username, PFC.groupname) as omds from packagefiles PFI join packages P on PFI.package = P.package and PFI.version = P.version and PFI.release = P.release join packagefiles PFC on PFI.path = PFC.path join packages PC on (PFI.package is not PC.package or PFI.release is not PC.release or PC.version is not PFI.version) -- er, no, it's a conflict if it's in installed and it doesn't match and PC.status in ('installed','updating','removing') and PFC.package = PC.package and PFC.version = PC.version and PFC.release = PC.release where P.status = 'installing' --and PFC.path is not null -- every path in updating and removing is either remove or no-op -- not true, could be an update, but should be handled above union select 'remove', printf('%s-%s-%s', PFR.package, PFR.version, PFR.release) as pkgid, PFR.path, PFR.username, PFR.uid, PFR.groupname, PFR.gid, PFR.mode, PFR.filetype, PFR.mtime, PFR.hash, PFR.configuration, --PFR.target, coalesce(P.status, ' null status '), --PFR.device, -- PFI.path, coalesce(PFI.status, ' null status '), --PFR.device, PFR.target, PFR.device, null as ohash, --PFI.package, printf('%s:%s:%s:%s', PFR.filetype, PFR.mode, PFR.username, PFR.groupname) as mds, null as omds from packagefiles PFR join packages PU on PFR.package = PU.package and PFR.version = PU.version and PFR.release = PU.release and PU.status in ('removing','updating') where not exists (select path from packagefiles PFI join packages P on PFI.package = P.package and PFI.version = P.version and PFI.release = P.release and P.status in ('installing','installed') where PFI.path = PFR.path ) and path not in (select path from preserve) -- paths in 'installed' or 'updated' are no-ops union select 'preserve', printf('%s-%s-%s', PFP.package, PFP.version, PFP.release) as pkgid, PFP.path, PFP.username, PFP.uid, PFP.groupname, PFP.gid, PFP.mode, PFP.filetype, PFP.mtime, PFP.hash, PFP.configuration as configuration, PFP.target, PFP.device, null as ohash, printf('%s:%s:%s:%s', PFP.filetype, PFP.mode, PFP.username, PFP.groupname) as mds, null as omds from preserve PFP -- TODO don't include installed or installing -- left join packages P on P.package = PFP.package ... -- where P.status not in ('installed','installing') ;