]> pd.if.org Git - zpackage/blob - db.sql
bf6fd22a07c01b886d9d6e26a9dc1557d5132c03
[zpackage] / db.sql
1 begin;
2
3 PRAGMA application_id = 0x5a504442;
4 PRAGMA user_version = 1;
5
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
9 -- go here
10 CREATE TABLE files (
11         hash text primary key, -- sha256 of content
12         size integer, -- bigint?  certainly need > 2GB
13         compression text, -- always xz?
14         content blob
15 )
16 ;
17
18 -- information about packages
19 -- a package is identified by a package,version,release triple
20 create table packages (
21         -- primary key columns
22         package text not null,
23         version text not null, -- the upstream version string
24         release integer not null, -- the local release number
25 --      pkgid   text, -- the three above joined with '-'
26
27         -- metadata columns
28         description     text,
29         architecture    text,
30         url     text,
31         status  text,
32         licenses        text, -- hash of actual license?  need table for more than one?
33         packager        text,
34         build_time      integer default (strftime('%s', 'now')),
35         install_time    integer,
36         checksum        text, -- checksum of package contents.  null for incompleted packages
37         primary key (package,version,release),
38         check (typeof(package) = 'text'),
39         check (typeof(version) = 'text'),
40         check (typeof(release) = 'integer'),
41         check (release > 0)
42         -- TODO enforce name and version conventions
43         -- check(instr(version,'-') = 0)
44         -- check(instr(package,'/') = 0)
45         -- check(instr(package,'/') = 0)
46         -- check(instr(version,' ') = 0)
47         -- check(instr(package,' ') = 0)
48         -- check(instr(package,' ') = 0)
49         -- check(length(package) < 64)
50         -- check(length(version) < 32)
51 )
52 without rowid
53 ;
54
55 create view packages_pkgid as
56 select printf('%s-%s-%s', package, version, release) as pkgid, *
57 from packages;
58
59 create trigger packages_update_trigger instead of
60 update on packages_pkgid
61 begin
62         update packages
63         set package = NEW.package,
64         version = NEW.version,
65         release = NEW.release,
66         description = NEW.description,
67         architecture = NEW.architecture,
68         url = NEW.url,
69         status = NEW.status,
70         licenses = NEW.licenses,
71         packager = NEW.packager,
72         build_time = NEW.build_time,
73         install_time = NEW.install_time,
74         checksum = NEW.checksum
75         where package = OLD.package
76         and version = OLD.version
77         and release = OLD.release
78         ;
79 end
80 ;
81
82 -- handle package status history with a logging trigger.
83 create trigger logpkgstatus after update of status on packages
84 begin insert into zpmlog (action,target,info)
85         values (printf('status change %s %s', OLD.status, NEW.status),
86                 printf('%s-%s-%s', NEW.package, NEW.version, NEW.release),
87                 NULL); END;
88
89 create table packagetags (
90         -- package id triple
91         package text,
92         version text,
93         release integer,
94         tag     text,
95         set_time integer default (strftime('%s', 'now')),
96         primary key (package,version,release,tag),
97         foreign key (package,version,release) references packages (package,version,release) on delete cascade on update cascade
98 );
99
100 -- packagefile hash is columns as text, joined with null bytes, then
101 -- sha256 sum of that
102 -- package checksum is package columns as text, joined with null bytes,
103 -- other than the checksum and install_time column
104 -- then that hashed.  finally, that hash, plus the ascii sorted
105 -- hashes of the package files all joined with newlines, hashed.
106 -- really don't like this.
107
108 -- files contained in a package
109 create table packagefiles (
110         -- package id triple
111         package text,
112         version text,
113         release integer,
114
115         path    text, -- filesystem path
116         mode    text not null, -- perms, use text for octal rep?
117         username        text not null, -- name of owner
118         groupname       text not null, -- group of owner
119         uid     integer, -- numeric uid, generally ignored
120         gid     integer, -- numeric gid, generally ignored
121         configuration integer not null default 0, -- boolean if config file
122         filetype varchar not null default 'r',
123         -- r regular file
124         -- d directory
125         -- s symlink
126         -- h hard link -- not supported
127         -- c character special and b device special files add dev number column
128         -- b block special
129         -- p fifos (i.e. pipe)
130         target  text, -- link target for links
131         -- device file dev numbers, should probably be a separate table
132         devmajor        integer,
133         devminor        integer,
134         hash    text, -- null if no actual content, i.e. anything but a regular file
135         mtime   integer, -- seconds since epoch, finer resolution probably not needed
136         primary key (package,version,release,path),
137         foreign key (package,version,release) references packages (package,version,release) on delete cascade on update cascade,
138         check (not (filetype = 'l' and target is null)),
139         check (not (filetype = 'r' and hash is null)),
140         check (not (filetype = 'c' and (devmajor is null or devminor is null)))
141 )
142 without rowid
143 ;
144
145 create view packagefiles_pkgid as
146 select printf('%s-%s-%s', package, version, release) as pkgid, *
147 from packagefiles
148 ;
149
150 create view installed_ref_count as
151 select I.path, count(*) as refcount
152 from installedfiles I
153 group by I.path
154 ;
155
156 create view packagefiles_status as
157 select P.status, PF.*
158 from packagefiles_pkgid PF
159 left join packages_pkgid P on P.pkgid = PF.pkgid
160 ;
161
162 create view installedfiles as
163 select * from packagefiles_status
164 where status = 'installed'
165 ;
166
167 create view install_status as
168
169 select 'new' as op, PN.*
170 from packagefiles_status PN
171 left join installed_ref_count RC on RC.path = PN.path
172 where RC.refcount is null
173 and PN.status = 'installing'
174
175 union all
176
177 select 'update' as op, PN.*
178 from packagefiles_status PN
179 inner join installedfiles PI on PI.path = PN.path and PI.package = PN.package
180 left join installed_ref_count RC on RC.path = PN.path
181 where RC.refcount = 1
182 and PN.status = 'installing'
183 and PI.hash is not PN.hash
184
185 union all
186
187 select 'conflict' as op, PI.*
188 from packagefiles_status PN
189 inner join installedfiles PI on PI.path = PN.path and PI.package != PN.package
190 where PN.status = 'installing'
191
192 union all
193 select 'remove' as op, PI.*
194 from installedfiles PI
195 left join packagefiles_status PN
196     on PI.path = PN.path and PI.package = PN.package
197         and PI.pkgid != PN.pkgid
198 where PN.path is null
199 and PI.package in (select package from packages where status = 'installing')
200 ;
201
202 create table pathtags (
203         -- package id triple
204         package text,
205         version text,
206         release integer,
207
208         path    text, -- filesystem path
209         tag     text,
210         primary key (package,version,release,path,tag),
211         foreign key (package,version,release,path)
212         references packagefiles on delete cascade on update cascade
213 )
214 without rowid
215 ;
216
217 create table elfinfo (
218         file    text primary key, -- hash of blob
219         elftype text,
220         foreign key (file) references files on delete cascade
221 )
222 without rowid
223 ;
224
225 create table elfdeps (
226         file    text,
227         soname  text,
228         dependency text,
229         primary key (file, soname, dependency),
230         foreign key (file) references files on delete cascade
231 )
232 without rowid
233 ;
234
235 -- TODO just elf information?
236 -- and just hash, not package?
237 create table elflibraries (
238         file    text primary key,
239         soname  text,
240         foreign key (file) references files on delete cascade
241 )
242 without rowid
243 ;
244
245 create table elfneeded (
246         file    text,
247         needed  text, -- soname of dependency
248         primary key (file, needed),
249         foreign key (file) references files on delete cascade
250 )
251 without rowid
252 ;
253
254 -- package scripts: table of package, stage, file
255 create table scripts (
256         package text,
257         version text,
258         release integer,
259         stage   text,
260         hash    text,
261         primary key (package,version,release,stage),
262         foreign key (package,version,release) references packages (package,version,release) on delete cascade on update cascade
263 );
264
265 create view scripts_pkgid as
266 select printf('%s-%s-%s', package, version, release) as pkgid, *
267 from scripts
268 ;
269
270 -- package dependencies: table of package, dependency, dep type (package, soname)
271 create table packagedeps (
272         package text,
273         version text,
274         release integer,
275         requires text, -- package name (only)
276         minimum text,
277         maximum text,
278         primary key (package,version,release,package),
279         foreign key (package,version,release) references packages (package,version,release) on delete cascade on update cascade
280 );
281
282 -- capability labels
283 create table provides (
284         package text,
285         subpackage      text,
286         label   text -- a capability label
287 );
288
289 create table requires (
290         package text,
291         subpackage      text,
292         label   text -- a capability label
293 );
294
295 create table packagegroups (
296         package text,
297         "group" text
298 );
299
300 -- zpm actions
301 -- not sure how machine readable this needs to be,
302 -- do not at all for now, figure it out later
303 -- could be worth logging all commands in a history table,
304 -- the zpm driver could do that and capture the exit status
305 -- as well
306 -- might want the history table to note a "group" to tie together
307 -- sub-invocations, probably an environment variable set if not
308 -- already set by zpm, probably a uuid or a timestamp
309 create table zpmlog (
310         ts      text default (strftime('%Y-%m-%d %H:%M:%f', 'now')),
311         -- timestamp of action
312         action  text,
313         target  text, -- packagename, repo name, etc
314         info    text -- human readable
315 );
316
317 create table history (
318         ts      integer, -- again, probably needs timestamp sub second
319         cmd     text,
320         args    text,
321         status  integer
322 );
323
324 create table repository (
325         name    text primary key, -- our name for a repo
326         url     text not null,
327         priority        integer not null default 1,
328         refreshed       integer -- last refresh time
329 );
330
331 -- urls for downloading packages.  possibly unneeded
332 create table repository_packages (
333         repo    text,
334         pkg     text, -- glob pattern?  in which case others not needed
335         version text,
336         release text,
337         url     text
338 );
339
340 -- track which repository a package was cloned from, i.e. where we got it
341 create table packagesource (
342         name    text,
343         version text,
344         release integer,
345         repository      text references repository
346 );
347
348 commit;