Use only a single table for each bug tracker + add tracker for Globster

This commit is contained in:
Yorhel 2013-04-01 12:53:27 +02:00
parent 76bb10482a
commit ac3c5676d3
5 changed files with 43 additions and 47 deletions

59
Bug.pm
View file

@ -1,12 +1,7 @@
=head1 SQL Schema
CREATE TABLE ${p}issues (
issue SERIAL PRIMARY KEY,
latest integer NOT NULL
);
CREATE TABLE ${p}messages (
CREATE TABLE $p (
id SERIAL PRIMARY KEY,
issue integer NOT NULL,
date timestamptz NOT NULL DEFAULT NOW(),
@ -22,6 +17,9 @@
=head2 Update queries
ALTER TABLE ${p}messages RENAME TO $p;
DROP TABLE ${p}issues;
ALTER TABLE ${p}messages ADD COLUMN admin boolean NOT NULL DEFAULT false;
ALTER TABLE ${p}messages ADD COLUMN name varchar(200) NOT NULL DEFAULT '';
@ -36,7 +34,7 @@ use TUWF ':html', 'html_escape';
sub new {
my $class = shift;
return bless {
prefix => 'issue_',
table => 'issues',
types => [qw|bug feature docs other|],
default_type => 'other',
statusses => [qw|new accepted duplicate confirmed fixed wontfix worksforme|],
@ -58,20 +56,20 @@ sub dbListing {
$o{reverse} = 1 if !$o{sort};
my %where = (
$o{id} ? ('i.issue = ?' => $o{id}) : (),
$o{closed} != 2 ? ('!s m.closed' => !$o{closed} ? 'NOT' : '') : (),
'NOT EXISTS(SELECT 1 FROM !s im WHERE im.id > m.id AND im.issue = m.issue)' => $self->{table},
$o{id} ? ('issue = ?' => $o{id}) : (),
$o{closed} != 2 ? ('!s closed' => !$o{closed} ? 'NOT' : '') : (),
);
my $order = sprintf {
date => 'm.id %s',
date => 'id %s',
}->{$o{sort}||'date'}, $o{reverse} ? 'DESC' : 'ASC';
my($r, $np) = $TUWF::OBJ->dbPage(\%o, q{
SELECT i.issue, m.summary, to_char(m.date, 'YYYY-MM-DD') AS date, m.type, m.status, m.closed
FROM !sissues i
JOIN !smessages m ON m.id = i.latest
SELECT issue, summary, to_char(date, 'YYYY-MM-DD') AS date, type, status, closed
FROM !s m
!W
ORDER BY !s}, $self->{prefix}, $self->{prefix}, \%where, $order
ORDER BY !s}, $self->{table}, \%where, $order
);
return wantarray ? ($r, $np) : $r;
}
@ -80,29 +78,32 @@ sub dbListing {
sub dbItem {
my($self, $id) = @_;
return $TUWF::OBJ->dbAll(q{
SELECT m.issue, m.summary, to_char(m.date, 'YYYY-MM-DD HH24:MI:SS (tz)') AS date, m.type, m.status, m.closed, m.name, m.admin, m.message
FROM !smessages m
WHERE m.issue = ?
ORDER BY m.id}, $self->{prefix}, $id
SELECT issue, summary, to_char(date, 'YYYY-MM-DD HH24:MI:SS (tz)') AS date, type, status, closed, name, admin, message
FROM !s
WHERE issue = ?
ORDER BY id}, $self->{table}, $id
);
}
sub dbEmails {
my($self, $id) = @_;
return [ map $_->{email}, @{$TUWF::OBJ->dbAll(q|SELECT DISTINCT m.email FROM !smessages m WHERE m.issue = ? AND m.email <> ''|, $self->{prefix}, $id)} ];
return [ map $_->{email}, @{$TUWF::OBJ->dbAll(q|SELECT DISTINCT email FROM !s WHERE issue = ? AND email <> ''|, $self->{table}, $id)} ];
}
sub dbSave {
my($self, $id, $closed, @a) = @_;
$id = $TUWF::OBJ->dbRow('INSERT INTO !sissues (latest) VALUES (0) RETURNING issue', $self->{prefix})->{issue} if !$id;
my $latest = $TUWF::OBJ->dbRow(
'INSERT INTO !smessages (issue, closed, summary, name, email, type, status, message, admin) VALUES (?, ?, !l) RETURNING id',
$self->{prefix}, $id, $closed?1:0, \@a
)->{id};
$TUWF::OBJ->dbExec('UPDATE !sissues SET latest = ? WHERE issue = ?', $self->{prefix}, $latest, $id);
return $id;
# TODO: Issue ID allocation may currently cause two bug reports created at
# the same time to get the same id. It'd be better to use a PostgreSQL
# sequence...
my $issue = $id ? '?' : '(SELECT COALESCE(MAX(issue)+1, 1) FROM !s)';
return $TUWF::OBJ->dbRow(
"INSERT INTO !s (issue, closed, summary, name, email, type, status, message, admin) VALUES ($issue, ?, !l) RETURNING issue",
$self->{table}, $id || $self->{table}, $closed?1:0, \@a
)->{issue}
}
@ -232,7 +233,7 @@ sub htmlForm {
}
li class => 'bug_frm_message';
textarea name => 'bug_message';end; br;
lit 'Please use a <a href="http://p.blicky.net/">pastebin</a> if you want to include large chunks of code or program output.';
lit 'Please use a <a href="http://p.blicky.net/">pastebin</a> if you want to include chunks of code or program output.';
end;
li class => 'bug_frm_submit';
input type => 'submit', value => 'Submit';
@ -302,12 +303,12 @@ sub handleForm {
$TUWF::OBJ->mail(
"Hello!\n\n".
"A new reply has been posted to a bug you have previously shown\n".
"an interest in. You can find the reply at the following URL:\n".
"an interest in. You can find the reply at the following URL:\n\n".
" $base$u\n\n".
"If you do not wish to receive any more notifications for this (and\n".
"perhaps other) bugs, please reply to this email stating your intent.",
Subject => "Reply to $f->{bug_summary}",
To => "$_",
To => $_,
);
}
}

13
dat/doc
View file

@ -1,15 +1,8 @@
=pod
When programming stuff, I often come across a situation where I am not
happy with the documentation or articles available online, and feel the urge to
do something about this situation. Most of the time I resist this urge because
I otherwise won't get any programming done, but sometimes this urge is just too
hard to resist.
I don't really have a blog - at least not one that I take seriously - so I'll
just use this site to publish my articles. Since I've just started writing
these, this page is still quite empty. I'll add more as soon as my urge to
write an article surprasses my urge to get some programming done again.
I don't often write stuff. Certainly not enough to warrant a blog. But
sometimes I do feel the need to write down my thoughts. The results of those
rare occasions are published on this page.
=over

View file

@ -38,11 +38,11 @@ compiling and/or installing it, I also offer statically linked binaries:
=over
=item * L<Linux, 64-bit|http://dev.yorhel.nl/download/ncdc-linux-x86_64-1.15.tar.gz>
=item * L<Linux, 64-bit|http://dev.yorhel.nl/download/ncdc-linux-x86_64-1.16.1.tar.gz>
=item * L<Linux, 32-bit|http://dev.yorhel.nl/download/ncdc-linux-i486-1.15.tar.gz>
=item * L<Linux, 32-bit|http://dev.yorhel.nl/download/ncdc-linux-i486-1.16.1.tar.gz>
=item * L<Linux, ARM|http://dev.yorhel.nl/download/ncdc-linux-arm-1.15.tar.gz>
=item * L<Linux, ARM|http://dev.yorhel.nl/download/ncdc-linux-arm-1.16.1.tar.gz>
=back

View file

@ -99,10 +99,10 @@ TUWF::register(
qr{dump/grenamr} => sub { podpage(shift, 'dump-grenamr', 'dump', 'grenamr', 'GTK+ Mass File Renamer') },
qr{dump/nccolour} => sub { podpage(shift, 'dump-nccolour', 'dump', 'nccolour', 'Colours in NCurses') },
qr{feed\.atom} => \&atom,
qr{(ncdc|ncdu)/bug} => \&bug_list,
qr{(ncdc|ncdu)/bug/post} => \&bug_post,
qr{(ncdc|ncdu)/bug/new} => \&bug_new,
qr{(ncdc|ncdu)/bug/([1-9][0-9]*)} => \&bug_item,
qr{(ncdc|ncdu|globster)/bug} => \&bug_list,
qr{(ncdc|ncdu|globster)/bug/post} => \&bug_post,
qr{(ncdc|ncdu|globster)/bug/new} => \&bug_new,
qr{(ncdc|ncdu|globster)/bug/([1-9][0-9]*)} => \&bug_item,
);
TUWF::set(
@ -232,7 +232,7 @@ sub _bug_init {
$s->_load_module('TUWF::DB');
$s->{_TUWF}{db_login} = [ undef, undef, undef ];
$s->dbInit;
return TUWF::Bug->new(prefix => $p.'_', admins => [ $ENV{ISSUE_CODE} ]);
return TUWF::Bug->new(table => $p, admins => [ $ENV{ISSUE_CODE} ]);
}
@ -494,6 +494,7 @@ sub htmlMenu {
$m->('/globster/launch', 'globster-launch', $o{sec} eq 'launch', undef, 1);
});
$m->('/globster/api', 'API Doc', $o{sec} eq 'api');
$m->('/globster/bug', 'Bug tracker', $o{sec} eq 'bug');
} elsif($o{page} eq 'tuwf') {
$m->('/tuwf', 'Info', !$o{sec});
$m->('/tuwf/man', 'Manual', $o{sec} eq 'man', sub {

View file

@ -3,4 +3,5 @@ Disallow: /download
Disallow: /dat
Disallow: /ncdc/bug
Disallow: /ncdu/bug
Disallow: /globster/bug