import
[web.mtrack] / schema / 4.xml
1 <schema version='4'>
2         <table name='projects'>
3                 <field name='projid' type='autoinc'/>
4                 <field name='ordinal' type='integer' nullable='0' default='5'>
5                         <comment>
6                                 used to order the project names
7                         </comment>
8                 </field>
9                 <field name='name' type='text' nullable='0'>
10                         <comment>
11                                 readable version of the name
12                         </comment>
13                 </field>
14                 <field name='shortname' type='varchar(16)' nullable='0'>
15                         <comment>
16                                 shorter name
17                         </comment>
18                 </field>
19                 <field name='notifyemail' type='varchar(320)'>
20                         <comment>
21                                 where email notifications are sent
22                         </comment>
23                 </field>
24                 <key>
25                         <field>projid</field>
26                 </key>
27                 <key type='unique'>
28                         <field>name</field>
29                 </key>
30         </table>
31
32         <table name='repos'>
33                 <field name='repoid' type='autoinc'/>
34                 <field name='shortname' type='varchar(16)' nullable='0'/>
35                 <field name='scmtype' type='varchar(32)' nullable='0'/>
36                 <field name='repopath' type='text' nullable='0'/>
37                 <field name='browserurl' type='text'>
38                         <comment>
39                         if defined, mtrack will use this as the base for links
40                         to changesets and repo browsing, otherwise it will
41                         handle it locally
42                         </comment>
43                 </field>
44                 <field name='browsertype' type='text'/>
45                 <field name='description' type='text'/>
46                 <field name='serverurl' type='text'>
47                         <comment>
48                                 The URL that SCM tools will use to checkout,
49                                 clone, push, pull or otherwise interact with
50                                 the repo.
51                         </comment>
52                 </field>
53                 <field name='parent' type='text' nullable='0' default=''>
54                         <comment>
55                         If NULL, this is a global repo.  Otherwise, parent is
56                         a string like 'user:wez' to indicate that it is owned
57                         by 'wez', or 'project:name' to indicate that it is owned
58                         by the 'name' project.
59                         </comment>
60                 </field>
61                 <field name='clonedfrom' type='integer'
62                         reftable='repos' refcol='repoid'>
63                         <comment>
64                                 If this was forked from another repo in the system,
65                                 then this field is set to its repoid
66                         </comment>
67                 </field>
68                 <key>
69                         <field>repoid</field>
70                 </key>
71                 <key type='unique'>
72                         <field>shortname</field>
73                         <field>parent</field>
74                 </key>
75         </table>
76
77         <table name='project_repo_link'>
78                 <comment>
79 Links a location within a repo to its "parent" project.
80 This allows multiple projects to exist within a repository
81 and also allows pre/post commit rules to determine whether
82 the location is a personal branch or scratch space, versus
83 a formal project branch.
84                 </comment>
85                 <field name='linkid' type='autoinc'/>
86                 <field name='projid' type='integer' reftable='projects' refcol='projid'
87                         nullable='0'/>
88                 <field name='repoid' type='integer' reftable='repos' refcol='repoid'
89                         nullable='0'/>
90                 <field name='repopathregex' type='text'/>
91                 <field name='is_scratch_space' type='integer' nullable='0' default='0'>
92                         <comment>
93                         May replace this with a reference to a workflow or other kind
94                         of ruleset to affect pre/post commit
95                         </comment>
96                 </field>
97                 <key>
98                         <field>linkid</field>
99                 </key>
100         </table>
101
102         <table name='components'>
103                 <field name='compid' type='autoinc'/>
104                 <field name='deleted' type='integer' nullable='0' default='0'/>
105                 <field name='name' type='text'/>
106                 <key>
107                         <field>compid</field>
108                 </key>
109                 <key type='unique'>
110                         <field>name</field>
111                 </key>
112         </table>
113
114         <table name='components_by_project'>
115                 <field name='projid' type='integer'/>
116                 <field name='compid' type='integer'
117                         reftable='components' refcol='compid' nullable='0'/>
118                 <key><field>projid</field><field>compid</field></key>
119         </table>
120
121         <table name='priorities'>
122                 <field name='priorityname' type='varchar(32)' nullable='0'/>
123                 <field name='deleted' type='integer' nullable='0' default='0'/>
124                 <field name='value' type='integer' nullable='0' default='5'/>
125                 <key><field>priorityname</field></key>
126         </table>
127
128         <table name='severities'>
129                 <field name='sevname' type='varchar(32)' nullable='0'/>
130                 <key><field>sevname</field></key>
131                 <field name='deleted' type='integer' nullable='0' default='0'/>
132                 <field name='ordinal' type='integer' nullable='0' default='5'/>
133         </table>
134
135         <table name='resolutions'>
136                 <field name='resname' type='varchar(32)' nullable='0'/>
137                 <key><field>resname</field></key>
138                 <field name='deleted' type='integer' nullable='0' default='0'/>
139                 <field name='ordinal' type='integer' nullable='0' default='5'/>
140         </table>
141         <table name='classifications'>
142                 <field name='classname' type='varchar(32)' nullable='0'/>
143                 <key><field>classname</field></key>
144                 <field name='deleted' type='integer' nullable='0' default='0'/>
145                 <field name='ordinal' type='integer' nullable='0' default='5'/>
146         </table>
147         <table name='ticketstates'>
148                 <field name='statename' type='varchar(32)' nullable='0'/>
149                 <key><field>statename</field></key>
150                 <field name='deleted' type='integer' nullable='0' default='0'/>
151                 <field name='ordinal' type='integer' nullable='0' default='5'/>
152         </table>
153         <table name='keywords'>
154                 <field name='kid' type='autoinc'/>
155                 <key><field>kid</field></key>
156                 <key type='unique'><field>keyword</field></key>
157                 <field name='keyword' type='text' nullable='0'/>
158         </table>
159         <table name='changes'>
160                 <field name='cid' type='autoinc'/>
161                 <field name='who' type='text'/>
162                 <field name='object' type='text'>
163                         <comment>
164                         usually tablename:id
165                         where id is a comma separated list of the primary key fields
166                         of the object that was edited
167                         </comment>
168                 </field>
169                 <field name='changedate' type='timestamp' nullable='0'
170                         default='CURRENT_TIMESTAMP'/>
171                 <field name='reason' type='text'>
172                         <comment>
173                                 commit/changelog message
174                         </comment>
175                 </field>
176                 <key><field>cid</field></key>
177                 <key type='multiple' name='idx_changes_object'><field>object</field></key>
178                 <key type='multiple' name='idx_changes_date'><field>changedate</field></key>
179         </table>
180
181         <table name='change_audit'>
182                 <field name='cid' type='integer' nullable='0'
183                         reftable='changes' refcol='cid'/>
184                 <field name='fieldname' type='text'/>
185                 <field name='action' type='varchar(16)'>
186                         <comment>
187         set, changed, deleted, added, removed.
188         set: filled in from a blank value
189         changed: changed existing value. value field has old value.
190         deleted: set value to blank, value field has old value
191         added: used for associated values (like keywords); the value field
192                lists out the primary keys of the added items, comma separated.
193         removed: used for associated values (like keywords); the value field
194                  lists out the primary keys of the removed items, comma separated
195                          </comment>
196                 </field>
197                 <field name='action' type='varchar(16)'/>
198                 <field name='oldvalue' type='text'/>
199                 <field name='value' type='text'/>
200         </table>
201
202         <table name='milestones'>
203                 <field name='mid' type='autoinc'/>
204                 <key><field>mid</field></key>
205                 <field name='name' type='text'/>
206                 <key type='unique'>
207                         <field>name</field>
208                 </key>
209                 <field name='description' type='text'/>
210                 <field name='startdate' type='timestamp'/>
211                 <field name='duedate' type='timestamp'/>
212                 <field name='completed' type='timestamp'/>
213                 <field name='deleted' type='integer' nullable='0' default='0'/>
214                 <field name='created' type='integer' nullable='0'
215                                 reftable='changes' refcol='cid'/>
216                 <field name='updated' type='integer' nullable='0'
217                                 reftable='changes' refcol='cid'/>
218                 <field name='pmid' type='integer' reftable='milestones' refcol='mid'>
219                         <comment>
220                                 parent milestone (for sprint support)
221                         </comment>
222                 </field>
223         </table>
224
225         <table name='tickets'>
226                 <field name='tid' type='char(32)' nullable='0'>
227                         <comment>unique identifier (short form UUID)</comment>
228                 </field>
229                 <field name='nsident' type='text' nullable='0'>
230                         <comment>
231         identifier assigned within a particular namespace
232         eg: when a ticket is accepted as a bug, will be assigned
233         a bug number for that project
234                         </comment>
235                 </field>
236         
237                 <field name='summary' type='text' nullable='0'>
238                         <comment>
239         -- one line summary
240         -- problem description in detail
241                         </comment>
242                 </field>
243                 <field name='description' type='text'/>
244
245                 <field name='changelog' type='text'>
246                         <comment>
247         -- end-user (or customer) facing summary, suitable for use in
248         -- a release notes or ChangeLog format
249                         </comment>
250                 </field>
251
252                 <field name='created' type='integer'
253                         nullable='0' reftable='changes' refcol='cid'/>
254                 <field name='updated' type='integer'
255                         nullable='0' reftable='changes' refcol='cid'/>
256
257                 <field name='owner' type='text'/>
258                 <field name='priority' type='text'/>
259                 <field name='severity' type='text'/>
260                 <field name='classification' type='text'/>
261                 <field name='resolution' type='text'/>
262                 <field name='cc' type='text'/>
263
264                 <field name='status' type='text' nullable='0'/>
265                 <field name='estimated' type='real'/>
266                 <field name='spent' type='real'/>
267
268                 <key><field>tid</field></key>
269                 <key type='unique'><field>nsident</field></key>
270         </table>
271
272         <table name='ticket_components'>
273                 <field name='tid' type='char(32)' nullable='0'
274                         reftable='tickets' refcol='tid'/>
275                 <field name='compid' type='integer' nullable='0'
276                         reftable='components' refcol='cid'/>
277         </table>
278
279         <table name='ticket_milestones'>
280                 <field name='tid' type='char(32)' nullable='0'
281                         reftable='tickets' refcol='tid'/>
282                 <field name='mid' type='integer' nullable='0'
283                         reftable='milestones' refcol='mid'/>
284         </table>
285
286         <table name='ticket_keywords'>
287                 <field name='tid' type='char(32)' nullable='0'
288                         reftable='tickets' refcol='tid'/>
289                 <field name='kid' type='integer' nullable='0'
290                         reftable='keywords' refcol='kid'/>
291         </table>
292                 
293         <table name='reports'>
294                 <field name='rid' type='autoinc'/>
295                 <field name='summary' type='text' nullable='0'/>
296                 <field name='description' type='text' nullable='0'/>
297                 <field name='query' type='text' nullable='0'/>
298                 <field name='changed' type='integer'
299                         nullable='0' reftable='changes' refcol='cid'/>
300                 <key><field>rid</field></key>
301                 <key type='unique'><field>summary</field></key>
302         </table>
303
304         <table name='effort'>
305                 <field name='eid' type='autoinc'/>
306                 <key><field>eid</field></key>
307                 <field name='tid' type='char(32)' nullable='0'/>
308                 <field name='cid' type='integer'
309                         nullable='0' reftable='changes' refcol='cid'/>
310                 <field name='expended' type='real'/>
311                 <field name='remaining' type='real'>
312                         <comment>revised estimate</comment>
313                 </field>
314                 <key type='multiple' name='idx_effort_ticket'><field>tid</field></key>
315         </table>
316
317         <table name='acl'>
318                 <comment>access control list</comment>
319                 <field name='objectid' type='text'/>
320                 <field name='cascade' type='integer' nullable='0'>
321                         <comment>
322         indicates whether the entry applies to this item or its children
323         sequence number allows explicit ordering for fine grained
324         permissions (exclude all members of a group, except a particular user)
325                         </comment>
326                 </field>
327                 <field name='seq' type='integer' nullable='0'/>
328                 <field name='role' type='text' nullable='0'>
329                         <comment>user or group name</comment>
330                 </field>
331                 <field name='action' type='text' nullable='0'>
332                         <comment>
333                 -- activity or action name ("read", "write")
334                 -- whether access is allowed
335                         </comment>
336                 </field>
337                 <field name='allow' type='integer' nullable='0'/>
338                 <key>
339                         <field>objectid</field>
340                         <field>seq</field>
341                         <field>cascade</field>
342                 </key>
343                 <key type='multiple' name='idx_acl_role'>
344                         <field>role</field>
345                 </key>
346         </table>
347
348         <table name='userinfo'>
349                 <field name='userid' type='text' nullable='0'>
350                         <comment>canonical user id</comment>
351                 </field>
352                 <key><field>userid</field></key>
353                 <field name='fullname' type='text'/>
354                 <field name='email' type='text'/>
355                 <field name='timezone' type='text'/>
356                 <field name='active' type='integer' nullable='0' default='1'/>
357                 <field name='sshkeys' type='text'/>
358         </table>
359
360         <table name='useraliases'>
361                 <field name='alias' type='text' nullable='0'/>
362                 <key><field>alias</field></key>
363                 <field name='userid' type='text' reftable='userinfo' refcol='userid'/>
364         </table>
365
366         <table name='attachments'>
367                 <field name='object' type='text' nullable='0'>
368                         <comment>
369                                 the object to which this is attached
370                                 sha1 hash of the contents of the attachment
371                         </comment>
372                 </field>
373                 <field name='hash' type='text' nullable='0'/>
374                 <field name='filename' type='text' nullable='0'/>
375                 <field name='size' type='integer' nullable='0'/>
376                 <field name='cid' type='integer'
377                         nullable='0' reftable='changes' refcol='cid'/>
378                 <field name='payload' type='blob'/>
379         </table>
380
381         <table name='last_notification'>
382                 <comment>last time that we procesed change notifications</comment>
383                 <field name='last_run' type='timestamp' nullable='0'/>
384                 <key><field>last_run</field></key>
385         </table>
386         <table name='search_engine_state'>
387                 <field name='last_run' type='timestamp' nullable='0'/>
388                 <key><field>last_run</field></key>
389         </table>
390
391         <table name='snippets'>
392                 <field name='snid' type='text' nullable='0'>
393                         <comment>snippet id</comment>
394                 </field>
395                 <field name='created' type='integer'
396                         nullable='0' reftable='changes' refcol='cid'/>
397                 <field name='updated' type='integer'
398                         nullable='0' reftable='changes' refcol='cid'/>
399                 <field name='description' type='text' nullable='0'>
400                         <comment>summary/blurb in wiki markup</comment>
401                 </field>
402                 <field name='lang' type='text' nullable='0'>
403                         <comment>what language?</comment>
404                 </field>
405                 <field name='snippet' type='text' nullable='0'>
406                         <comment>and the snippet itself</comment>
407                 </field>
408                 <key><field>snid</field></key>
409         </table>
410
411         <post driver="pgsql">
412 CREATE OR REPLACE FUNCTION _mtrack_group_concat(text, text)
413         RETURNS text as $$
414 SELECT CASE
415         WHEN $2 IS NULL THEN $1
416         WHEN $1 IS NULL THEN $2
417 ELSE
418         $1 operator(pg_catalog.||) ',' operator(pg_catalog.||) $2
419 END
420 $$ IMMUTABLE LANGUAGE SQL;
421
422 -- requires postgres 8.2 and higher
423 DROP AGGREGATE IF EXISTS mtrack_group_concat(text);
424
425 CREATE AGGREGATE mtrack_group_concat(
426         BASETYPE = text,
427         SFUNC = _mtrack_group_concat,
428         STYPE = text
429 );
430         </post>
431
432 </schema>