3 PRAGMA application_id = 0x5a504442;
4 PRAGMA user_version = 1;
6 -- should be faster with rowid due to the blob content
7 -- these are really just blobs of data
8 -- TODO copyright and license information should probably
11 hash text primary key, -- sha256 of content
12 size integer, -- bigint? certainly need > 2GB
13 compression text, -- always xz?
18 create view filerefs as
19 select F.hash, count(PF.hash) + count(S.hash) + count(EL.file) as refcount
21 left join packagefiles PF on PF.hash = F.hash
22 left join scripts S on S.hash = F.hash
23 left join elflibraries EL on EL.file = F.hash
27 -- information about packages
28 -- a package is identified by a package,version,release triple
29 create table packages (
30 -- primary key columns
31 package text not null,
32 version text not null, -- the upstream version string
33 release integer not null, -- the local release number
40 licenses text, -- hash of actual license? need table for more than one?
42 build_time integer default (strftime('%s', 'now')),
44 hash text, -- see integ.c for package hash details
45 primary key (package,version,release),
46 check (typeof(package) = 'text'),
47 check (typeof(version) = 'text'),
48 check (typeof(release) = 'integer'),
50 -- enforce name and version conventions
51 check(instr(package,' ') = 0),
52 check(instr(package,'/') = 0),
53 check(instr(package,':') = 0),
54 check(instr(version,' ') = 0),
55 check(instr(version,'-') = 0),
56 check(instr(version,'/') = 0),
57 check(instr(version,':') = 0),
58 check(length(package) < 64),
59 check(length(package) > 0),
60 check(length(version) < 32),
61 check(length(version) > 0)
66 create index package_status_index on packages (status);
67 create index package_package_index on packages (package);
69 create view packages_pkgid as
70 select printf('%s-%s-%s', package, version, release) as pkgid, *
73 create trigger packages_delete_trigger instead of
74 delete on packages_pkgid
76 delete from packages where package = OLD.package
77 and version = OLD.version and release = OLD.release;
80 create trigger packages_update_trigger instead of
81 update on packages_pkgid
84 set package = NEW.package,
85 version = NEW.version,
86 release = NEW.release,
87 description = NEW.description,
88 architecture = NEW.architecture,
91 licenses = NEW.licenses,
92 packager = NEW.packager,
93 build_time = NEW.build_time,
94 install_time = NEW.install_time,
96 where package = OLD.package
97 and version = OLD.version
98 and release = OLD.release
103 -- handle package status history with a logging trigger.
104 create trigger logpkgstatus after update of status on packages
105 begin insert into zpmlog (action,target,info)
106 values (printf('status change %s %s', OLD.status, NEW.status),
107 printf('%s-%s-%s', NEW.package, NEW.version, NEW.release),
110 create table packagetags (
116 set_time integer default (strftime('%s', 'now')),
117 primary key (package,version,release,tag),
118 foreign key (package,version,release) references packages (package,version,release) on delete cascade on update cascade
121 -- files contained in a package
122 create table packagefiles (
128 path text, -- filesystem path
129 mode text not null, -- perms, use text for octal rep?
130 username text not null, -- name of owner
131 groupname text not null, -- group of owner
132 uid integer, -- numeric uid, generally ignored
133 gid integer, -- numeric gid, generally ignored
134 configuration integer not null default 0, -- boolean if config file
135 confhash text, -- last hash on disk
136 filetype varchar not null default 'r',
140 -- h hard link -- not supported
141 -- c character special -- not supported
142 -- b block special -- not supported
143 -- c and b device special files add dev number column
144 -- p fifos (i.e. pipe) -- not supported
145 -- s unix domain socket -- not supported
146 target text, -- link target for links
147 device integer, -- device file dev_t
148 hash text, -- null if not a regular file
149 mtime integer, -- seconds since epoch, finer resolution not needed
150 primary key (package,version,release,path),
151 foreign key (package,version,release)
152 references packages (package,version,release)
153 on delete cascade on update cascade,
154 check (not (filetype = 'l' and target is null)),
155 check (not (filetype = 'h' and target is null)),
156 check (target is null or length(target) between 1 and 4095),
157 check (hash is null or length(hash) between 1 and 1024),
158 check (not (filetype = 'r' and hash is null)),
159 check (not (filetype = 'c' and device is null)),
160 check (not (filetype = 'b' and device is null)),
161 check (filetype in ('r','d','l','h','c','b','p')),
162 check(length(username) between 1 and 256),
163 check(length(groupname) between 1 and 256),
164 check (configuration = 0 or configuration = 1)
169 create index packagefile_package_index on packagefiles (package);
170 create index packagefile_path_index on packagefiles (path);
171 create index packagefile_hash_index on packagefiles (hash);
173 create view packagefiles_pkgid as
174 select printf('%s-%s-%s', package, version, release) as pkgid, *,
175 printf('%s:%s:%s:%s', filetype, mode, username, groupname) as mds
179 create trigger packagefiles_update_trigger instead of
180 update on packagefiles_pkgid
183 set package = NEW.package,
184 version = NEW.version,
185 release = NEW.release,
188 username = NEW.username,
189 groupname = NEW.groupname,
192 configuration = NEW.configuration,
193 filetype = NEW.filetype,
198 where package = OLD.package
199 and version = OLD.version
200 and release = OLD.release
206 create trigger packagefiles_delete_trigger instead of
207 delete on packagefiles_pkgid
209 delete from packagefiles
210 where package = OLD.package
211 and version = OLD.version
212 and release = OLD.release
215 update packages set hash = null
216 where package = OLD.package
217 and version = OLD.version
218 and release = OLD.release
223 create view installed_ref_count as
224 select I.path, count(*) as refcount
225 from installedfiles I
229 create view sync_status_ref_count as
230 select path, status, count(*) as refcount
231 from packagefiles_status
232 where status in ('installed', 'installing', 'removing')
233 group by path, status
236 create view packagefiles_status as
237 select P.status, PF.*
238 from packagefiles_pkgid PF
239 left join packages_pkgid P on P.pkgid = PF.pkgid
242 create view installedfiles as
243 select * from packagefiles_status
244 where status = 'installed'
247 create table pathtags (
253 path text, -- filesystem path
255 primary key (package,version,release,path,tag),
256 foreign key (package,version,release,path)
257 references packagefiles on delete cascade on update cascade
262 create view elfdeps as
263 select PF.pkgid, PF.status, PF.path, N.needed as needs,
264 PL.path as library, PL.pkgid provider, PL.status as library_status
265 from packagefiles_status PF
266 join elfneeded N on N.file = PF.hash
267 left join elflibraries L on N.needed = L.soname
268 left join packagefiles_status PL on PL.hash = L.file
271 -- TODO just elf information?
272 -- and just hash, not package?
273 create table elflibraries (
274 file text primary key,
280 create table elfneeded (
282 needed text, -- soname of dependency
283 primary key (file, needed)
288 -- package scripts: table of package, stage, file
289 create table scripts (
295 primary key (package,version,release,stage),
296 foreign key (package,version,release) references packages (package,version,release) on delete cascade on update cascade
299 create view scripts_pkgid as
300 select printf('%s-%s-%s', package, version, release) as pkgid, *
304 -- package dependencies: table of package, dependency, dep type (package, soname)
305 create table packagedeps (
309 requires text, -- package name (only)
312 primary key (package,version,release,package),
313 foreign key (package,version,release) references packages (package,version,release) on delete cascade on update cascade
317 create table provides (
320 label text -- a capability label
323 create table requires (
326 label text -- a capability label
329 create table packagegroups (
335 -- not sure how machine readable this needs to be,
336 -- do not at all for now, figure it out later
337 -- could be worth logging all commands in a history table,
338 -- the zpm driver could do that and capture the exit status
340 -- might want the history table to note a "group" to tie together
341 -- sub-invocations, probably an environment variable set if not
342 -- already set by zpm, probably a uuid or a timestamp
343 create table zpmlog (
344 ts text default (strftime('%Y-%m-%d %H:%M:%f', 'now')),
345 -- timestamp of action
347 target text, -- packagename, repo name, etc
348 info text -- human readable
352 id integer primary key, -- rowid alias
353 ts text default (strftime('%Y-%m-%d %H:%M:%f', 'now')),
355 pkgid text, -- package
356 path text, -- file path involved
357 file text, -- hash of file
358 ack integer default 0
361 create table history (
362 ts integer, -- again, probably needs timestamp sub second
368 create table repository (
369 name text primary key, -- our name for a repo
371 priority integer not null default 1,
372 refreshed integer -- last refresh time
375 -- urls for downloading packages. possibly unneeded
376 create table repository_packages (
378 pkg text, -- glob pattern? in which case others not needed
384 -- track which repository a package was cloned from, i.e. where we got it
385 create table packagesource (
389 repository text references repository
392 create view syncconflicts as
395 select BASE.*, 'preserved' as rstatus
396 from packagefiles_status BASE
397 join elflibraries EL on EL.file = BASE.hash
399 BASE.status in ('removed', 'updated')
400 and BASE.hash in (select hash from packagefiles_status where
401 status in ('installed'))
404 select distinct BASE.*,
405 case when P.status = 'installing' and BASE.status = 'installed'
407 when BASE.status in ('removed','updated')
408 and BASE.path in (select path from preserved) then
413 from packagefiles_status BASE
414 left join packages P on P.package = BASE.package
415 and BASE.status in ('installed', 'removing')
416 and P.status = 'installing'
418 -- metadata different
420 select path, count(distinct mds) as mdcount,
421 count(distinct hash) as hashcount
423 where SS.rstatus in ('installing', 'installed')
425 having (count(distinct mds) > 1 or count(distinct hash) > 1)
427 select BASE.*, 'hash' as conflict
429 where path in (select path from md_conflict where hashcount > 1)
431 select BASE.*, 'md' as conflict
433 where path in (select path from md_conflict where mdcount > 1)
436 create view syncinfo as
439 select BASE.*, 'preserved' as rstatus
440 from packagefiles_status BASE
441 join elflibraries EL on EL.file = BASE.hash
443 BASE.status in ('removed', 'updated')
444 and BASE.hash in (select hash from packagefiles_status where
445 status in ('installed'))
448 select distinct BASE.*,
449 case when P.status = 'installing' and BASE.status = 'installed'
451 when BASE.status in ('removed','updated')
452 and BASE.path in (select path from preserved) then
457 from packagefiles_status BASE
458 left join packages P on P.package = BASE.package
459 and BASE.status in ('installed', 'removing')
460 and P.status = 'installing'
462 -- new file: in installing, not in installed or updating or removing
465 path,username,uid,groupname,gid,mode,filetype,mtime,hash,
466 configuration,target,device, null as ohash
468 where path not in (select path from syncstatus where
469 rstatus in ('installed', 'updating', 'removing')
471 and rstatus in ('installing')
473 -- modified: retained, but with different metadata
477 SS.username, SS.uid, SS.groupname, SS.gid, SS.mode, SS.filetype,
478 SS.mtime, SS.hash, SS.configuration, SS.target, SS.device,
479 OS.hash as ohash, SS.mds, OS.mds as omds
482 on SS.path = OS.path and SS.pkgid is not OS.pkgid
484 and OS.rstatus in ('installed','updating','removing')
485 and (SS.mds is not OS.mds or SS.hash is not OS.hash)
487 SS.rstatus in ('installing')
489 -- preserve: libraries needed by something in installed or installing
494 where status in ('installed', 'installing')
495 and library is not null
499 path,username,uid,groupname,gid,mode,filetype,mtime,hash,
500 configuration,target,device, null as ohash
502 where path in (select library from needed)
503 and SS.rstatus in ('removing', 'removed')
505 -- remove: cur, not preserved, not in final set
508 path,username,uid,groupname,gid,mode,filetype,mtime,hash,
509 configuration,target,device, null as ohash
512 select path from syncstatus where
513 rstatus in ('installed', 'installing')
515 and path not in (select path from preserve)
516 and rstatus in ('removing', 'updating')
518 -- expired: libraries that had been preserved, but aren't needed now
521 path,username,uid,groupname,gid,mode,filetype,mtime,hash,
522 configuration,target,device, null as ohash
524 where hash in (select file from elflibraries where file is not null)
525 and path not in (select path from preserve)
526 and rstatus in ('removed','updated')
528 select 'update' as op, *
529 ,(select group_concat(pkgid, ' ')
531 where SS.rstatus = 'installing' and SS.path = M.path
535 select 'remove' as op, *, null, null, null from remove
537 select 'obsolete' as op, *, null, null, null from expired
539 select 'new' as op, *, null, null, null from newfiles
541 select 'preserve' as op, *, null, null, null from preserve