]> git.donarmstrong.com Git - debbugs.git/commitdiff
add initial work on sql for debbugs
authorDon Armstrong <don@donarmstrong.com>
Sat, 24 Nov 2012 01:47:46 +0000 (17:47 -0800)
committerDon Armstrong <don@donarmstrong.com>
Sat, 24 Nov 2012 01:47:46 +0000 (17:47 -0800)
20 files changed:
Debbugs/DB.pm [new file with mode: 0644]
Debbugs/DB/Result/Arch.pm [new file with mode: 0644]
Debbugs/DB/Result/BinPkg.pm [new file with mode: 0644]
Debbugs/DB/Result/BinVer.pm [new file with mode: 0644]
Debbugs/DB/Result/Bug.pm [new file with mode: 0644]
Debbugs/DB/Result/BugBinpackage.pm [new file with mode: 0644]
Debbugs/DB/Result/BugBlock.pm [new file with mode: 0644]
Debbugs/DB/Result/BugMerged.pm [new file with mode: 0644]
Debbugs/DB/Result/BugPackage.pm [new file with mode: 0644]
Debbugs/DB/Result/BugSrcpackage.pm [new file with mode: 0644]
Debbugs/DB/Result/BugTag.pm [new file with mode: 0644]
Debbugs/DB/Result/BugVer.pm [new file with mode: 0644]
Debbugs/DB/Result/SrcPkg.pm [new file with mode: 0644]
Debbugs/DB/Result/SrcPkgAlias.pm [new file with mode: 0644]
Debbugs/DB/Result/SrcVer.pm [new file with mode: 0644]
Debbugs/DB/Result/Tag.pm [new file with mode: 0644]
bin/debbugs-loadsql [new file with mode: 0755]
sql/dbicdump.conf [new file with mode: 0644]
sql/dbicdump_command.sh [new file with mode: 0755]
sql/debbugs_schema.sql [new file with mode: 0644]

diff --git a/Debbugs/DB.pm b/Debbugs/DB.pm
new file mode 100644 (file)
index 0000000..f44e185
--- /dev/null
@@ -0,0 +1,20 @@
+use utf8;
+package Debbugs::DB;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Schema';
+
+__PACKAGE__->load_namespaces;
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 10:25:29
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:wiMg1t5hFUhnyufL3yT5fQ
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/Arch.pm b/Debbugs/DB/Result/Arch.pm
new file mode 100644 (file)
index 0000000..bc50ae4
--- /dev/null
@@ -0,0 +1,113 @@
+use utf8;
+package Debbugs::DB::Result::Arch;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::Arch
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<arch>
+
+=cut
+
+__PACKAGE__->table("arch");
+
+=head1 ACCESSORS
+
+=head2 id
+
+  data_type: 'integer'
+  is_auto_increment: 1
+  is_nullable: 0
+  sequence: 'arch_id_seq'
+
+=head2 arch
+
+  data_type: 'text'
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "id",
+  {
+    data_type         => "integer",
+    is_auto_increment => 1,
+    is_nullable       => 0,
+    sequence          => "arch_id_seq",
+  },
+  "arch",
+  { data_type => "text", is_nullable => 0 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<arch_arch_key>
+
+=over 4
+
+=item * L</arch>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("arch_arch_key", ["arch"]);
+
+=head1 RELATIONS
+
+=head2 bin_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BinVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bin_vers",
+  "Debbugs::DB::Result::BinVer",
+  { "foreign.arch_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-11-23 17:41:43
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:kL57i2SauNRCt/bK6ACRKg
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BinPkg.pm b/Debbugs/DB/Result/BinPkg.pm
new file mode 100644 (file)
index 0000000..1635c1e
--- /dev/null
@@ -0,0 +1,128 @@
+use utf8;
+package Debbugs::DB::Result::BinPkg;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BinPkg
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bin_pkg>
+
+=cut
+
+__PACKAGE__->table("bin_pkg");
+
+=head1 ACCESSORS
+
+=head2 id
+
+  data_type: 'integer'
+  is_auto_increment: 1
+  is_nullable: 0
+  sequence: 'bin_pkg_id_seq'
+
+=head2 pkg
+
+  data_type: 'text'
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "id",
+  {
+    data_type         => "integer",
+    is_auto_increment => 1,
+    is_nullable       => 0,
+    sequence          => "bin_pkg_id_seq",
+  },
+  "pkg",
+  { data_type => "text", is_nullable => 0 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bin_pkg_pkg_key>
+
+=over 4
+
+=item * L</pkg>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bin_pkg_pkg_key", ["pkg"]);
+
+=head1 RELATIONS
+
+=head2 bin_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BinVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bin_vers",
+  "Debbugs::DB::Result::BinVer",
+  { "foreign.bin_pkg_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_binpackages
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugBinpackage>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_binpackages",
+  "Debbugs::DB::Result::BugBinpackage",
+  { "foreign.bin_pkg_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 21:09:18
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:yA4czi38S+fA2P6aKn+UAw
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BinVer.pm b/Debbugs/DB/Result/BinVer.pm
new file mode 100644 (file)
index 0000000..432cbb1
--- /dev/null
@@ -0,0 +1,157 @@
+use utf8;
+package Debbugs::DB::Result::BinVer;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BinVer
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bin_ver>
+
+=cut
+
+__PACKAGE__->table("bin_ver");
+
+=head1 ACCESSORS
+
+=head2 bin_pkg_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 src_ver_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 arch_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 ver
+
+  data_type: 'text'
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bin_pkg_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "src_ver_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "arch_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "ver",
+  { data_type => "text", is_nullable => 0 },
+);
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bin_ver_bin_pkg_id_arch_idx>
+
+=over 4
+
+=item * L</bin_pkg_id>
+
+=item * L</arch_id>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bin_ver_bin_pkg_id_arch_idx", ["bin_pkg_id", "arch_id"]);
+
+=head2 C<bin_ver_src_ver_id_arch_idx>
+
+=over 4
+
+=item * L</src_ver_id>
+
+=item * L</arch_id>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bin_ver_src_ver_id_arch_idx", ["src_ver_id", "arch_id"]);
+
+=head1 RELATIONS
+
+=head2 arch
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Arch>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "arch",
+  "Debbugs::DB::Result::Arch",
+  { id => "arch_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 bin_pkg
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::BinPkg>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bin_pkg",
+  "Debbugs::DB::Result::BinPkg",
+  { id => "bin_pkg_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 src_ver
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcVer>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "src_ver",
+  "Debbugs::DB::Result::SrcVer",
+  { id => "src_ver_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 10:25:29
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0AnavpmoUrdrgChtyIBRBg
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/Bug.pm b/Debbugs/DB/Result/Bug.pm
new file mode 100644 (file)
index 0000000..71ea251
--- /dev/null
@@ -0,0 +1,327 @@
+use utf8;
+package Debbugs::DB::Result::Bug;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::Bug
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug>
+
+=cut
+
+__PACKAGE__->table("bug");
+
+=head1 ACCESSORS
+
+=head2 id
+
+  data_type: 'integer'
+  is_nullable: 0
+
+=head2 creation
+
+  data_type: 'timestamp with time zone'
+  default_value: current_timestamp
+  is_nullable: 0
+  original: {default_value => \"now()"}
+
+=head2 log_modified
+
+  data_type: 'timestamp with time zone'
+  default_value: current_timestamp
+  is_nullable: 0
+  original: {default_value => \"now()"}
+
+=head2 last_modified
+
+  data_type: 'timestamp with time zone'
+  default_value: current_timestamp
+  is_nullable: 0
+  original: {default_value => \"now()"}
+
+=head2 archived
+
+  data_type: 'boolean'
+  default_value: false
+  is_nullable: 0
+
+=head2 unarchived
+
+  data_type: 'timestamp with time zone'
+  is_nullable: 1
+
+=head2 forwarded
+
+  data_type: 'text'
+  default_value: (empty string)
+  is_nullable: 0
+
+=head2 summary
+
+  data_type: 'text'
+  default_value: (empty string)
+  is_nullable: 0
+
+=head2 outlook
+
+  data_type: 'text'
+  default_value: (empty string)
+  is_nullable: 0
+
+=head2 subject
+
+  data_type: 'text'
+  is_nullable: 0
+
+=head2 done
+
+  data_type: 'text'
+  default_value: (empty string)
+  is_nullable: 0
+
+=head2 owner
+
+  data_type: 'text'
+  default_value: (empty string)
+  is_nullable: 0
+
+=head2 unknown_packages
+
+  data_type: 'text'
+  default_value: (empty string)
+  is_nullable: 0
+
+=head2 severity
+
+  data_type: 'enum'
+  default_value: 'normal'
+  extra: {custom_type_name => "bug_severity",list => ["wishlist","minor","normal","important","serious","grave","critical"]}
+  is_nullable: 1
+
+=cut
+
+__PACKAGE__->add_columns(
+  "id",
+  { data_type => "integer", is_nullable => 0 },
+  "creation",
+  {
+    data_type     => "timestamp with time zone",
+    default_value => \"current_timestamp",
+    is_nullable   => 0,
+    original      => { default_value => \"now()" },
+  },
+  "log_modified",
+  {
+    data_type     => "timestamp with time zone",
+    default_value => \"current_timestamp",
+    is_nullable   => 0,
+    original      => { default_value => \"now()" },
+  },
+  "last_modified",
+  {
+    data_type     => "timestamp with time zone",
+    default_value => \"current_timestamp",
+    is_nullable   => 0,
+    original      => { default_value => \"now()" },
+  },
+  "archived",
+  { data_type => "boolean", default_value => \"false", is_nullable => 0 },
+  "unarchived",
+  { data_type => "timestamp with time zone", is_nullable => 1 },
+  "forwarded",
+  { data_type => "text", default_value => "", is_nullable => 0 },
+  "summary",
+  { data_type => "text", default_value => "", is_nullable => 0 },
+  "outlook",
+  { data_type => "text", default_value => "", is_nullable => 0 },
+  "subject",
+  { data_type => "text", is_nullable => 0 },
+  "done",
+  { data_type => "text", default_value => "", is_nullable => 0 },
+  "owner",
+  { data_type => "text", default_value => "", is_nullable => 0 },
+  "unknown_packages",
+  { data_type => "text", default_value => "", is_nullable => 0 },
+  "severity",
+  {
+    data_type => "enum",
+    default_value => "normal",
+    extra => {
+      custom_type_name => "bug_severity",
+      list => [
+        "wishlist",
+        "minor",
+        "normal",
+        "important",
+        "serious",
+        "grave",
+        "critical",
+      ],
+    },
+    is_nullable => 1,
+  },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 RELATIONS
+
+=head2 bug_binpackages
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugBinpackage>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_binpackages",
+  "Debbugs::DB::Result::BugBinpackage",
+  { "foreign.bug_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_blocks_blocks
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugBlock>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_blocks_blocks",
+  "Debbugs::DB::Result::BugBlock",
+  { "foreign.blocks" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_blocks_bugs
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugBlock>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_blocks_bugs",
+  "Debbugs::DB::Result::BugBlock",
+  { "foreign.bug_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_merged_bugs
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugMerged>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_merged_bugs",
+  "Debbugs::DB::Result::BugMerged",
+  { "foreign.bug_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_srcpackages
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugSrcpackage>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_srcpackages",
+  "Debbugs::DB::Result::BugSrcpackage",
+  { "foreign.bug_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_tags
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugTag>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_tags",
+  "Debbugs::DB::Result::BugTag",
+  { "foreign.bug_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_vers",
+  "Debbugs::DB::Result::BugVer",
+  { "foreign.bug_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bugs_merged_merged
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugMerged>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bugs_merged_merged",
+  "Debbugs::DB::Result::BugMerged",
+  { "foreign.merged" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 21:09:18
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:k+98VF0kOIp6OReqNNVXDg
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BugBinpackage.pm b/Debbugs/DB/Result/BugBinpackage.pm
new file mode 100644 (file)
index 0000000..022994f
--- /dev/null
@@ -0,0 +1,113 @@
+use utf8;
+package Debbugs::DB::Result::BugBinpackage;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BugBinpackage
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug_binpackage>
+
+=cut
+
+__PACKAGE__->table("bug_binpackage");
+
+=head1 ACCESSORS
+
+=head2 bug_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 bin_pkg_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bug_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "bin_pkg_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+);
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bug_binpackage_id_pkg_id>
+
+=over 4
+
+=item * L</bug_id>
+
+=item * L</bin_pkg_id>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bug_binpackage_id_pkg_id", ["bug_id", "bin_pkg_id"]);
+
+=head1 RELATIONS
+
+=head2 bin_pkg
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::BinPkg>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bin_pkg",
+  "Debbugs::DB::Result::BinPkg",
+  { id => "bin_pkg_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 bug
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bug",
+  "Debbugs::DB::Result::Bug",
+  { id => "bug_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 21:09:18
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:Nu0491VeKbUCBLaDIFAWwA
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BugBlock.pm b/Debbugs/DB/Result/BugBlock.pm
new file mode 100644 (file)
index 0000000..074b29b
--- /dev/null
@@ -0,0 +1,113 @@
+use utf8;
+package Debbugs::DB::Result::BugBlock;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BugBlock
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug_blocks>
+
+=cut
+
+__PACKAGE__->table("bug_blocks");
+
+=head1 ACCESSORS
+
+=head2 bug_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 blocks
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bug_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "blocks",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+);
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bug_blocks_bug_id_blocks_idx>
+
+=over 4
+
+=item * L</bug_id>
+
+=item * L</blocks>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bug_blocks_bug_id_blocks_idx", ["bug_id", "blocks"]);
+
+=head1 RELATIONS
+
+=head2 block
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "block",
+  "Debbugs::DB::Result::Bug",
+  { id => "blocks" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 bug
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bug",
+  "Debbugs::DB::Result::Bug",
+  { id => "bug_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 10:25:29
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:adv4v35ZqedSG4L0CFNPMg
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BugMerged.pm b/Debbugs/DB/Result/BugMerged.pm
new file mode 100644 (file)
index 0000000..8c38428
--- /dev/null
@@ -0,0 +1,113 @@
+use utf8;
+package Debbugs::DB::Result::BugMerged;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BugMerged
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug_merged>
+
+=cut
+
+__PACKAGE__->table("bug_merged");
+
+=head1 ACCESSORS
+
+=head2 bug_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 merged
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bug_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "merged",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+);
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bug_merged_bug_id_merged_idx>
+
+=over 4
+
+=item * L</bug_id>
+
+=item * L</merged>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bug_merged_bug_id_merged_idx", ["bug_id", "merged"]);
+
+=head1 RELATIONS
+
+=head2 bug
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bug",
+  "Debbugs::DB::Result::Bug",
+  { id => "bug_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 merged
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "merged",
+  "Debbugs::DB::Result::Bug",
+  { id => "merged" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 10:25:29
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xCalzFeFWcT0PGF/+82yvA
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BugPackage.pm b/Debbugs/DB/Result/BugPackage.pm
new file mode 100644 (file)
index 0000000..2d85e1d
--- /dev/null
@@ -0,0 +1,77 @@
+use utf8;
+package Debbugs::DB::Result::BugPackage;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BugPackage
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug_package>
+
+=cut
+
+__PACKAGE__->table("bug_package");
+
+=head1 ACCESSORS
+
+=head2 bug_id
+
+  data_type: 'integer'
+  is_nullable: 1
+
+=head2 pkg_id
+
+  data_type: 'integer'
+  is_nullable: 1
+
+=head2 pkg_type
+
+  data_type: 'text'
+  is_nullable: 1
+
+=head2 package
+
+  data_type: 'text'
+  is_nullable: 1
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bug_id",
+  { data_type => "integer", is_nullable => 1 },
+  "pkg_id",
+  { data_type => "integer", is_nullable => 1 },
+  "pkg_type",
+  { data_type => "text", is_nullable => 1 },
+  "package",
+  { data_type => "text", is_nullable => 1 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 21:09:18
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4ELLjuEEq63Ca0PeqFEfsg
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BugSrcpackage.pm b/Debbugs/DB/Result/BugSrcpackage.pm
new file mode 100644 (file)
index 0000000..c733f17
--- /dev/null
@@ -0,0 +1,113 @@
+use utf8;
+package Debbugs::DB::Result::BugSrcpackage;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BugSrcpackage
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug_srcpackage>
+
+=cut
+
+__PACKAGE__->table("bug_srcpackage");
+
+=head1 ACCESSORS
+
+=head2 bug_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 src_pkg_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bug_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "src_pkg_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+);
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bug_srcpackage_id_pkg_id>
+
+=over 4
+
+=item * L</bug_id>
+
+=item * L</src_pkg_id>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bug_srcpackage_id_pkg_id", ["bug_id", "src_pkg_id"]);
+
+=head1 RELATIONS
+
+=head2 bug
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bug",
+  "Debbugs::DB::Result::Bug",
+  { id => "bug_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 src_pkg
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcPkg>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "src_pkg",
+  "Debbugs::DB::Result::SrcPkg",
+  { id => "src_pkg_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 21:09:18
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ukA5dsM3UFiuOoDauTZN/A
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BugTag.pm b/Debbugs/DB/Result/BugTag.pm
new file mode 100644 (file)
index 0000000..ca6541f
--- /dev/null
@@ -0,0 +1,113 @@
+use utf8;
+package Debbugs::DB::Result::BugTag;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BugTag
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug_tag>
+
+=cut
+
+__PACKAGE__->table("bug_tag");
+
+=head1 ACCESSORS
+
+=head2 bug_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 tag_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bug_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "tag_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+);
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bug_tag_bug_tag_id>
+
+=over 4
+
+=item * L</bug_id>
+
+=item * L</tag_id>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("bug_tag_bug_tag_id", ["bug_id", "tag_id"]);
+
+=head1 RELATIONS
+
+=head2 bug
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bug",
+  "Debbugs::DB::Result::Bug",
+  { id => "bug_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 tag
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Tag>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "tag",
+  "Debbugs::DB::Result::Tag",
+  { id => "tag_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 10:25:29
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:CscnquDh4dh3f4LNgRn1Ew
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/BugVer.pm b/Debbugs/DB/Result/BugVer.pm
new file mode 100644 (file)
index 0000000..e8d9da2
--- /dev/null
@@ -0,0 +1,194 @@
+use utf8;
+package Debbugs::DB::Result::BugVer;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::BugVer
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<bug_ver>
+
+=cut
+
+__PACKAGE__->table("bug_ver");
+
+=head1 ACCESSORS
+
+=head2 bug_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 ver_string
+
+  data_type: 'text'
+  is_nullable: 1
+
+=head2 src_pkg_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 1
+
+=head2 src_ver_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 1
+
+=head2 found
+
+  data_type: 'boolean'
+  default_value: true
+  is_nullable: 0
+
+=head2 creation
+
+  data_type: 'timestamp with time zone'
+  default_value: current_timestamp
+  is_nullable: 0
+  original: {default_value => \"now()"}
+
+=head2 last_modified
+
+  data_type: 'timestamp with time zone'
+  default_value: current_timestamp
+  is_nullable: 0
+  original: {default_value => \"now()"}
+
+=cut
+
+__PACKAGE__->add_columns(
+  "bug_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "ver_string",
+  { data_type => "text", is_nullable => 1 },
+  "src_pkg_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
+  "src_ver_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
+  "found",
+  { data_type => "boolean", default_value => \"true", is_nullable => 0 },
+  "creation",
+  {
+    data_type     => "timestamp with time zone",
+    default_value => \"current_timestamp",
+    is_nullable   => 0,
+    original      => { default_value => \"now()" },
+  },
+  "last_modified",
+  {
+    data_type     => "timestamp with time zone",
+    default_value => \"current_timestamp",
+    is_nullable   => 0,
+    original      => { default_value => \"now()" },
+  },
+);
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<bug_ver_bug_id_ver_string_found_idx>
+
+=over 4
+
+=item * L</bug_id>
+
+=item * L</ver_string>
+
+=item * L</found>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint(
+  "bug_ver_bug_id_ver_string_found_idx",
+  ["bug_id", "ver_string", "found"],
+);
+
+=head1 RELATIONS
+
+=head2 bug
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::Bug>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "bug",
+  "Debbugs::DB::Result::Bug",
+  { id => "bug_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 src_pkg
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcPkg>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "src_pkg",
+  "Debbugs::DB::Result::SrcPkg",
+  { id => "src_pkg_id" },
+  {
+    is_deferrable => 1,
+    join_type     => "LEFT",
+    on_delete     => "CASCADE",
+    on_update     => "CASCADE",
+  },
+);
+
+=head2 src_ver
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcVer>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "src_ver",
+  "Debbugs::DB::Result::SrcVer",
+  { id => "src_ver_id" },
+  {
+    is_deferrable => 1,
+    join_type     => "LEFT",
+    on_delete     => "CASCADE",
+    on_update     => "CASCADE",
+  },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-11-23 17:41:43
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JMDsn7GGxoQ001KYUOyyTw
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/SrcPkg.pm b/Debbugs/DB/Result/SrcPkg.pm
new file mode 100644 (file)
index 0000000..66d6268
--- /dev/null
@@ -0,0 +1,194 @@
+use utf8;
+package Debbugs::DB::Result::SrcPkg;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::SrcPkg
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<src_pkg>
+
+=cut
+
+__PACKAGE__->table("src_pkg");
+
+=head1 ACCESSORS
+
+=head2 id
+
+  data_type: 'integer'
+  is_auto_increment: 1
+  is_nullable: 0
+  sequence: 'src_pkg_id_seq'
+
+=head2 pkg
+
+  data_type: 'text'
+  is_nullable: 0
+
+=head2 pseduopkg
+
+  data_type: 'boolean'
+  default_value: false
+  is_nullable: 1
+
+=head2 alias_of
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 1
+
+=cut
+
+__PACKAGE__->add_columns(
+  "id",
+  {
+    data_type         => "integer",
+    is_auto_increment => 1,
+    is_nullable       => 0,
+    sequence          => "src_pkg_id_seq",
+  },
+  "pkg",
+  { data_type => "text", is_nullable => 0 },
+  "pseduopkg",
+  { data_type => "boolean", default_value => \"false", is_nullable => 1 },
+  "alias_of",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<src_pkg_pkg_key>
+
+=over 4
+
+=item * L</pkg>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("src_pkg_pkg_key", ["pkg"]);
+
+=head1 RELATIONS
+
+=head2 alias_of
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcPkg>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "alias_of",
+  "Debbugs::DB::Result::SrcPkg",
+  { id => "alias_of" },
+  {
+    is_deferrable => 1,
+    join_type     => "LEFT",
+    on_delete     => "CASCADE",
+    on_update     => "CASCADE",
+  },
+);
+
+=head2 bug_srcpackages
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugSrcpackage>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_srcpackages",
+  "Debbugs::DB::Result::BugSrcpackage",
+  { "foreign.src_pkg_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_vers",
+  "Debbugs::DB::Result::BugVer",
+  { "foreign.src_pkg_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 src_pkgs
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::SrcPkg>
+
+=cut
+
+__PACKAGE__->has_many(
+  "src_pkgs",
+  "Debbugs::DB::Result::SrcPkg",
+  { "foreign.alias_of" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 src_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::SrcVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "src_vers",
+  "Debbugs::DB::Result::SrcVer",
+  { "foreign.src_pkg_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-11-23 17:41:43
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:s3tqzD1crqO0a57NzVkWDg
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/SrcPkgAlias.pm b/Debbugs/DB/Result/SrcPkgAlias.pm
new file mode 100644 (file)
index 0000000..9d77fce
--- /dev/null
@@ -0,0 +1,123 @@
+use utf8;
+package Debbugs::DB::Result::SrcPkgAlias;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::SrcPkgAlias
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<src_pkg_alias>
+
+=cut
+
+__PACKAGE__->table("src_pkg_alias");
+
+=head1 ACCESSORS
+
+=head2 id
+
+  data_type: 'integer'
+  is_auto_increment: 1
+  is_nullable: 0
+  sequence: 'src_pkg_alias_id_seq'
+
+=head2 src_pkg_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 pkg_alias
+
+  data_type: 'text'
+  is_nullable: 0
+
+=cut
+
+__PACKAGE__->add_columns(
+  "id",
+  {
+    data_type         => "integer",
+    is_auto_increment => 1,
+    is_nullable       => 0,
+    sequence          => "src_pkg_alias_id_seq",
+  },
+  "src_pkg_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "pkg_alias",
+  { data_type => "text", is_nullable => 0 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<pkg_alias_src_pkg_id_idx>
+
+=over 4
+
+=item * L</pkg_alias>
+
+=item * L</src_pkg_id>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("pkg_alias_src_pkg_id_idx", ["pkg_alias", "src_pkg_id"]);
+
+=head1 RELATIONS
+
+=head2 src_pkg
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcPkg>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "src_pkg",
+  "Debbugs::DB::Result::SrcPkg",
+  { id => "src_pkg_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 10:25:29
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:y5PGSPakrgG4u/oXIau2pw
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/SrcVer.pm b/Debbugs/DB/Result/SrcVer.pm
new file mode 100644 (file)
index 0000000..e9125ba
--- /dev/null
@@ -0,0 +1,210 @@
+use utf8;
+package Debbugs::DB::Result::SrcVer;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::SrcVer
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<src_ver>
+
+=cut
+
+__PACKAGE__->table("src_ver");
+
+=head1 ACCESSORS
+
+=head2 id
+
+  data_type: 'integer'
+  is_auto_increment: 1
+  is_nullable: 0
+  sequence: 'src_ver_id_seq'
+
+=head2 src_pkg_id
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 0
+
+=head2 ver
+
+  data_type: 'text'
+  is_nullable: 0
+
+=head2 upload_date
+
+  data_type: 'timestamp with time zone'
+  default_value: current_timestamp
+  is_nullable: 0
+  original: {default_value => \"now()"}
+
+=head2 based_on
+
+  data_type: 'integer'
+  is_foreign_key: 1
+  is_nullable: 1
+
+=cut
+
+__PACKAGE__->add_columns(
+  "id",
+  {
+    data_type         => "integer",
+    is_auto_increment => 1,
+    is_nullable       => 0,
+    sequence          => "src_ver_id_seq",
+  },
+  "src_pkg_id",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+  "ver",
+  { data_type => "text", is_nullable => 0 },
+  "upload_date",
+  {
+    data_type     => "timestamp with time zone",
+    default_value => \"current_timestamp",
+    is_nullable   => 0,
+    original      => { default_value => \"now()" },
+  },
+  "based_on",
+  { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<src_ver_src_pkg_id_ver>
+
+=over 4
+
+=item * L</src_pkg_id>
+
+=item * L</ver>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("src_ver_src_pkg_id_ver", ["src_pkg_id", "ver"]);
+
+=head1 RELATIONS
+
+=head2 based_on
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcVer>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "based_on",
+  "Debbugs::DB::Result::SrcVer",
+  { id => "based_on" },
+  {
+    is_deferrable => 1,
+    join_type     => "LEFT",
+    on_delete     => "CASCADE",
+    on_update     => "CASCADE",
+  },
+);
+
+=head2 bin_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BinVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bin_vers",
+  "Debbugs::DB::Result::BinVer",
+  { "foreign.src_ver_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 bug_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_vers",
+  "Debbugs::DB::Result::BugVer",
+  { "foreign.src_ver_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+=head2 src_pkg
+
+Type: belongs_to
+
+Related object: L<Debbugs::DB::Result::SrcPkg>
+
+=cut
+
+__PACKAGE__->belongs_to(
+  "src_pkg",
+  "Debbugs::DB::Result::SrcPkg",
+  { id => "src_pkg_id" },
+  { is_deferrable => 1, on_delete => "CASCADE", on_update => "CASCADE" },
+);
+
+=head2 src_vers
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::SrcVer>
+
+=cut
+
+__PACKAGE__->has_many(
+  "src_vers",
+  "Debbugs::DB::Result::SrcVer",
+  { "foreign.based_on" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 17:10:22
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:sYRJ4htIIKwvuvbUemk90A
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/Debbugs/DB/Result/Tag.pm b/Debbugs/DB/Result/Tag.pm
new file mode 100644 (file)
index 0000000..567c2b5
--- /dev/null
@@ -0,0 +1,121 @@
+use utf8;
+package Debbugs::DB::Result::Tag;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Debbugs::DB::Result::Tag
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 COMPONENTS LOADED
+
+=over 4
+
+=item * L<DBIx::Class::InflateColumn::DateTime>
+
+=back
+
+=cut
+
+__PACKAGE__->load_components("InflateColumn::DateTime");
+
+=head1 TABLE: C<tag>
+
+=cut
+
+__PACKAGE__->table("tag");
+
+=head1 ACCESSORS
+
+=head2 id
+
+  data_type: 'integer'
+  is_auto_increment: 1
+  is_nullable: 0
+  sequence: 'tag_id_seq'
+
+=head2 tag
+
+  data_type: 'text'
+  is_nullable: 0
+
+=head2 obsolete
+
+  data_type: 'boolean'
+  default_value: false
+  is_nullable: 1
+
+=cut
+
+__PACKAGE__->add_columns(
+  "id",
+  {
+    data_type         => "integer",
+    is_auto_increment => 1,
+    is_nullable       => 0,
+    sequence          => "tag_id_seq",
+  },
+  "tag",
+  { data_type => "text", is_nullable => 0 },
+  "obsolete",
+  { data_type => "boolean", default_value => \"false", is_nullable => 1 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<tag_tag_key>
+
+=over 4
+
+=item * L</tag>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("tag_tag_key", ["tag"]);
+
+=head1 RELATIONS
+
+=head2 bug_tags
+
+Type: has_many
+
+Related object: L<Debbugs::DB::Result::BugTag>
+
+=cut
+
+__PACKAGE__->has_many(
+  "bug_tags",
+  "Debbugs::DB::Result::BugTag",
+  { "foreign.tag_id" => "self.id" },
+  { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07025 @ 2012-07-17 21:09:18
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:4ea1AINoa4KQxMnX4oZwmA
+
+
+# You can replace this text with custom code or comments, and it will be preserved on regeneration
+1;
diff --git a/bin/debbugs-loadsql b/bin/debbugs-loadsql
new file mode 100755 (executable)
index 0000000..849e27f
--- /dev/null
@@ -0,0 +1,278 @@
+#! /usr/bin/perl
+# debbugs-loadsql is part of debbugs, and is released
+# under the terms of the GPL version 2, or any later version, at your
+# option. See the file README and COPYING for more information.
+# Copyright 2012 by Don Armstrong <don@donarmstrong.com>.
+
+
+use warnings;
+use strict;
+
+use Getopt::Long qw(:config no_ignore_case);
+use Pod::Usage;
+
+=head1 NAME
+
+debbugs-loadsql -- load debbugs sql database
+
+=head1 SYNOPSIS
+
+debbugs-loadsql [options]
+
+ Options:
+  --quick, -q only load changed bugs
+  --service, -s service name
+  --sysconfdir, -c postgresql service config dir
+  --debug, -d debugging level (Default 0)
+  --help, -h display this help
+  --man, -m display manual
+
+=head1 OPTIONS
+
+=over
+
+=item B<--quick, -q>
+
+Only load changed bugs
+
+=item B<--service,-s>
+
+Postgreql service to use; defaults to debbugs
+
+=item B<--sysconfdir,-c>
+
+System configuration directory to use; if not set, defaults to the
+postgresql default. [Operates by setting PGSYSCONFDIR]
+
+=item B<--debug, -d
+
+Debug verbosity.
+
+=item B<--help, -h>
+
+Display brief useage information.
+
+=item B<--man, -m>
+
+Display this manual.
+
+=back
+
+
+=cut
+
+
+use vars qw($DEBUG);
+
+use Debbugs::Common qw(checkpid lockpid get_hashname getparsedaddrs getbugcomponent make_list);
+use Debbugs::Config qw(:config);
+use Debbugs::Status qw(read_bug split_status_fields);
+use Debbugs::Log;
+use Debbugs::DB;
+use DateTime;
+use File::stat;
+
+
+my %options = (debug           => 0,
+              help            => 0,
+              man             => 0,
+              verbose         => 0,
+              quiet           => 0,
+              quick           => 0,
+              service         => 'debbugs',
+             );
+
+
+GetOptions(\%options,
+          'quick|q',
+          'service|s',
+          'sysconfdir|c',
+          'spool_dir|spool-dir=s',
+          'debug|d+','help|h|?','man|m');
+
+pod2usage() if $options{help};
+pod2usage({verbose=>2}) if $options{man};
+
+$DEBUG = $options{debug};
+
+my @USAGE_ERRORS;
+$options{verbose} = $options{verbose} - $options{quiet};
+
+pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS;
+
+if (exists $options{sysconfdir}) {
+    if (not defined $options{sysconfdir} or not length $options{sysconfdir}) {
+       delete $ENV{PGSYSCONFDIR};
+    } else {
+       $ENV{PGSYSCONFDIR} = $options{sysconfdir};
+    }
+}
+
+if (exists $options{spool_dir} and defined $options{spool_dir}) {
+    $config{spool_dir} = $options{spool_dir};
+}
+chdir($config{spool_dir}) or die "chdir $config{spool_dir} failed: $!";
+
+my $verbose = $options{debug};
+
+my $initialdir = "db-h";
+
+if (defined $ARGV[0] and $ARGV[0] eq "archive") {
+    $initialdir = "archive";
+}
+
+if (not lockpid($config{spool_dir}.'/lock/debbugs-loadsql')) {
+     if ($options{quick}) {
+         # If this is a quick run, just exit
+         print STDERR "Another debbugs-loadsql is running; stopping\n" if $verbose;
+         exit 0;
+     }
+     print STDERR "Another debbugs-loadsql is running; stopping\n";
+     exit 1;
+}
+
+# connect to the database; figure out how to handle errors properly
+# here.
+my $schema = Debbugs::DB->connect('dbi:Pg:service='.$options{service}) or
+    die "Unable to connect to database: ";
+
+my $time = 0;
+my $start_time = time;
+
+
+my @dirs = ($initialdir);
+my $cnt = 0;
+my %tags;
+my %queue;
+while (my $dir = shift @dirs) {
+    printf "Doing dir %s ...\n", $dir if $verbose;
+
+    opendir(DIR, "$dir/.") or die "opendir $dir: $!";
+    my @subdirs = readdir(DIR);
+    closedir(DIR);
+
+    my @list = map { m/^(\d+)\.summary$/?($1):() } @subdirs;
+    push @dirs, map { m/^(\d+)$/ && -d "$dir/$1"?("$dir/$1"):() } @subdirs;
+
+    for my $bug (@list) {
+       print "Up to $cnt bugs...\n" if (++$cnt % 100 == 0 && $verbose);
+       my $stat = stat(getbugcomponent($bug,'summary',$initialdir));
+       if (not defined $stat) {
+           print STDERR "Unable to stat $bug $!\n";
+           next;
+       }
+       next if $stat->mtime < $time;
+       my $data = read_bug(bug => $bug,
+                           location => $initialdir);
+       load_bug($schema,split_status_fields($data),\%tags,\%queue);
+    }
+}
+hanlde_queue($schema,\%queue);
+
+sub load_bug {
+    my ($s,$data,$tags,$queue) = @_;
+    my $s_data = split_status_fields($data);
+    my @tags;
+    for my $tag (make_list($s_data->{keywords})) {
+       next unless defined $tag and length $tag;
+       # this allows for invalid tags. But we'll use this to try to
+       # find those bugs and clean them up
+       if (not exists $tags->{$tag}) {
+           $tags->{$tag} = $s->resultset('Tag')->find_or_create({tag => $tag});
+       }
+       push @tags, $tags->{$tag};
+    }
+    my $bug = {id => $data->{bug_num},
+              creation => DateTime->from_epoch(epoch => $data->{date}),
+              log_modified => DateTime->from_epoch(epoch => $data->{log_modified}),
+              last_modified => DateTime->from_epoch(epoch => $data->{last_modified}),
+              archived => $data->{archived},
+              (defined $data->{unarchived} and length($data->{unarchived}))?(unarchived => DateTime->from_epoch(epoch => $data->{unarchived})):(),
+              forwarded => $data->{forwarded} // '',
+              summary => $data->{summary} // '',
+              outlook => $data->{outlook} // '',
+              subject => $data->{subject} // '',
+              done => $data->{done} // '',
+              owner => $data->{owner} // '',
+              severity => length($data->{severity}) ? $data->{severity} : $config{default_severity},
+             };
+    $s->resultset('Bug')->update_or_create($bug);
+    $s->txn_do(sub {
+                  for my $ff (qw(found fixed)) {
+                      my @elements = $s->resultset('BugVer')->search({bug_id => $data->{bug_num},
+                                                                      found  => $ff eq 'found'?1:0,
+                                                                     });
+                      my %elements_to_delete = map {($elements[$_]->ver_string(),$_)} 0..$#elements;
+                      my @elements_to_add;
+                      for my $version (@{$data->{"${ff}_versions"}}) {
+                          if (exists $elements_to_delete{$version}) {
+                              delete $elements_to_delete{$version};
+                          } else {
+                              push @elements_to_add,$version;
+                          }
+                      }
+                      for my $element (keys %elements_to_delete) {
+                          $elements_to_delete{$element}->delete();
+                      }
+                      for my $element (@elements_to_add) {
+                          # find source package and source version id
+                          my $ne = $s->resultset('BugVer')->new_result({bug_id => $data->{bug_num},
+                                                                        ver_string => $element,
+                                                                        found => $ff eq 'found'?1:0,
+                                                                       }
+                                                                      );
+                          if (my ($src_pkg,$src_ver) = $element =~ m{^([^\/]+)/(.+)$}) {
+                              my $src_pkg_e = $s->resultset('SrcPkg')->single({pkg => $src_pkg});
+                              if (defined $src_pkg_e) {
+                                  $ne->src_pkg_id($src_pkg_e->id());
+                                  my $src_ver_e = $s->resultset('SrcVer')->single({src_pkg_id => $src_pkg_e->id(),
+                                                                                   ver => $src_ver
+                                                                                  });
+                                  $ne->src_ver_id($src_ver_e->id()) if defined $src_ver_e;
+                              }
+                          }
+                          $ne->insert();
+                      }
+                  }
+              });
+    $s->txn_do(sub {
+                  $s->resultset('BugTag')->search({bug_id => $data->{bug_num}})->delete();
+                  $s->populate(BugTag => [[qw(bug_id tag_id)], map {[$data->{bug_num}, $_->id()]} @tags]);
+              });
+    # because these bugs reference other bugs which might not exist
+    # yet, we can't handle them until we've loaded all bugs. queue
+    # them up.
+    $queue->{merged}{$data->{bug_num}} = [@{$data->{mergedwith}}];
+    $queue->{blocks}{$data->{bug_num}} = [@{$data->{blocks}}];
+
+    print STDERR "Handled $data->{bug_num}\n";
+    # still need to handle merges, versions, etc.
+}
+
+sub handle_queue{
+    my ($s,$queue) = @_;
+    my %queue_types =
+       (merged => {set => 'BugMerged',
+                   columns => [qw(bug_id merged)],
+                   bug_id => 'bug_id',
+                  },
+        blocks => {set => 'BugBlock',
+                   columns => [qw(bug_id blocks)],
+                   bug_id => 'bug_id',
+                  },
+       );
+    for my $queue_type (keys %queue_types) {
+       for my $bug (%{$queue->{$queue_type}}) {
+           my $qt = $queue_types{$queue_type};
+           $s->txn_do(sub {
+                          $s->resultset($qt->{set})->search({$qt->{bug_id},$bug})->delete();
+                          $s->populate($qt->{set},[[@{$qt->{columns}}],map {[$bug,$_]} @{$queue->{$queue_type}{$bug}}]) if
+                              @{$queue->{$queue_type}{$bug}};
+                      }
+                     );
+       }
+    }
+}
+
+
+__END__
diff --git a/sql/dbicdump.conf b/sql/dbicdump.conf
new file mode 100644 (file)
index 0000000..f9c2741
--- /dev/null
@@ -0,0 +1,12 @@
+schema_class Debbugs::DB::Schema
+
+lib .
+
+<connect_info>
+    dsn     dbi:Pg:service=snp
+</connect_info>
+
+<loader_options>
+    components  InflateColumn::DateTime
+    components  TimeStamp
+</loader_options>
\ No newline at end of file
diff --git a/sql/dbicdump_command.sh b/sql/dbicdump_command.sh
new file mode 100755 (executable)
index 0000000..b56ad68
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+if ! [ -d "sql" ] || ! [ -d "Debbugs" ]; then 
+    echo "In the wrong directory"
+    exit 1;
+fi;
+
+dbicdump -I. -o dump_directory=. \
+    -o components='["InflateColumn::DateTime"]' \
+    -o preserve_case=1 \
+    Debbugs::DB dbi:Pg:service=debbugs '' '';
+
diff --git a/sql/debbugs_schema.sql b/sql/debbugs_schema.sql
new file mode 100644 (file)
index 0000000..68db33d
--- /dev/null
@@ -0,0 +1,148 @@
+
+DROP TABLE bug_tag CASCADE;
+DROP TABLE tag CASCADE;
+DROP TABLE bug CASCADE;
+DROP TYPE bug_severity CASCADE;
+DROP TABLE src_pkg CASCADE;
+DROP TABLE bug_ver CASCADE;
+DROP TABLE src_pkg_alias CASCADE;
+DROP TABLE src_ver CASCADE;
+DROP TABLE arch CASCADE;
+DROP TABLE bin_ver CASCADE;
+DROP TABLE bin_pkg CASCADE;
+DROP TABLE bug_blocks CASCADE;
+DROP TABLE bug_merged CASCADE;
+DROP VIEW bug_package CASCADE;
+DROP TABLE bug_srcpackage CASCADE;
+DROP TABLE bug_binpackage CASCADE;
+-- severities
+CREATE TYPE bug_severity AS ENUM ('wishlist','minor','normal',
+       'important','serious','grave','critical');
+
+-- bugs table
+CREATE TABLE bug (
+       id INTEGER NOT NULL PRIMARY KEY,
+       creation TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+       log_modified TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+       last_modified TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+       archived BOOLEAN NOT NULL DEFAULT FALSE,
+       unarchived TIMESTAMP WITH TIME ZONE,
+       forwarded TEXT NOT NULL DEFAULT '',
+       summary TEXT NOT NULL DEFAULT '',
+       outlook TEXT NOT NULL DEFAULT '',
+       subject TEXT NOT NULL,
+       done TEXT NOT NULL DEFAULT '',
+       owner TEXT NOT NULL DEFAULT '',
+       unknown_packages TEXT NOT NULL DEfAULT '',
+       severity bug_severity DEFAULT 'normal'::bug_severity
+);
+
+CREATE TABLE bug_blocks (
+       bug_id INT NOT NULL REFERENCES bug,
+       blocks INT NOT NULL REFERENCES bug,
+       CONSTRAINT bug_doesnt_block_itself CHECK (bug_id <> blocks)
+);
+CREATE UNIQUE INDEX bug_blocks_bug_id_blocks_idx ON bug_blocks(bug_id,blocks);
+CREATE INDEX bug_blocks_bug_id_idx ON bug_blocks(bug_id);
+CREATE INDEX bug_blocks_blocks_idx ON bug_blocks(blocks);
+
+CREATE TABLE bug_merged (
+       bug_id INT NOT NULL REFERENCES bug,
+       merged INT NOT NULL REFERENCES bug,
+       CONSTRAINT bug_doesnt_merged_itself CHECK (bug_id <> merged)
+);
+CREATE UNIQUE INDEX bug_merged_bug_id_merged_idx ON bug_merged(bug_id,merged);
+CREATE INDEX bug_merged_bug_id_idx ON bug_merged(bug_id);
+CREATE INDEX bug_merged_merged_idx ON bug_merged(merged);
+
+CREATE TABLE src_pkg (
+       id SERIAL PRIMARY KEY,
+       pkg TEXT NOT NULL UNIQUE,
+       pseduopkg BOOLEAN DEFAULT FALSE,
+       alias_of INT REFERENCES src_pkg ON UPDATE CASCADE ON DELETE CASCADE
+       CONSTRAINT src_pkg_doesnt_alias_itself CHECK (id <> alias_of)
+);
+
+CREATE TABLE src_ver (
+       id SERIAL PRIMARY KEY,
+       src_pkg_id INT NOT NULL REFERENCES src_pkg
+            ON UPDATE CASCADE ON DELETE CASCADE,
+       ver TEXT NOT NULL,
+       upload_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+       based_on INT REFERENCES src_ver
+            ON UPDATE CASCADE ON DELETE CASCADE
+);
+CREATE UNIQUE INDEX src_ver_src_pkg_id_ver ON src_ver(src_pkg_id,ver);
+
+CREATE TABLE bug_ver (
+       bug_id INT NOT NULL REFERENCES bug
+         ON UPDATE CASCADE ON DELETE RESTRICT,
+       ver_string TEXT,
+       src_pkg_id INT REFERENCES src_pkg
+            ON UPDATE CASCADE ON DELETE SET NULL,
+       src_ver_id INT REFERENCES src_ver
+            ON UPDATE CASCADE ON DELETE SET NULL,
+       found BOOLEAN NOT NULL DEFAULT TRUE,
+       creation TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
+       last_modified TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
+);
+CREATE INDEX bug_ver_src_pkg_id_idx ON bug_ver(src_pkg_id);
+CREATE INDEX bug_ver_src_pkg_id_src_ver_id_idx ON bug_ver(src_pkg_id,src_ver_id);
+CREATE INDEX bug_ver_src_ver_id_idx ON bug_ver(src_ver_id);
+CREATE UNIQUE INDEX ON bug_ver(bug_id,ver_string,found);
+
+CREATE TABLE arch (
+       id SERIAL PRIMARY KEY,
+       arch TEXT NOT NULL UNIQUE
+);
+
+CREATE TABLE bin_pkg (
+       id SERIAL PRIMARY KEY,
+       pkg TEXT NOT NULL UNIQUE
+);
+
+CREATE TABLE bin_ver(
+       bin_pkg_id INT NOT NULL REFERENCES bin_pkg
+            ON UPDATE CASCADE ON DELETE CASCADE,
+       src_ver_id INT NOT NULL REFERENCES src_ver
+            ON UPDATE CASCADE ON DELETE CASCADE,
+       arch_id INT NOT NULL REFERENCES arch
+                   ON UPDATE CASCADE ON DELETE CASCADE,
+       ver TEXT NOT NULL
+);
+CREATE INDEX bin_ver_ver_idx ON bin_ver(ver);
+CREATE UNIQUE INDEX bin_ver_bin_pkg_id_arch_idx ON bin_ver(bin_pkg_id,arch_id);
+CREATE UNIQUE INDEX bin_ver_src_ver_id_arch_idx ON bin_ver(src_ver_id,arch_id);
+CREATE INDEX bin_ver_bin_pkg_id_idx ON bin_ver(bin_pkg_id);
+CREATE INDEX bin_ver_src_ver_id_idx ON bin_ver(src_ver_id);
+
+CREATE TABLE tag (
+       id SERIAL PRIMARY KEY,
+       tag TEXT NOT NULL UNIQUE,
+       obsolete BOOLEAN DEFAULT FALSE
+);
+
+CREATE TABLE bug_tag (
+       bug_id INT NOT NULL REFERENCES bug,
+       tag_id INT NOT NULL REFERENCES tag
+);
+
+CREATE UNIQUE INDEX bug_tag_bug_tag_id ON bug_tag (bug_id,tag_id);
+CREATE INDEX bug_tag_tag_id ON bug_tag (tag_id);
+CREATE INDEX bug_tag_bug_id ON bug_tag (bug_id);
+
+CREATE TABLE bug_binpackage (
+       bug_id INT NOT NULL REFERENCES bug,
+       bin_pkg_id INT NOT NULL REFERENCES bin_pkg
+);
+CREATE UNIQUE INDEX bug_binpackage_id_pkg_id ON bug_binpackage(bug_id,bin_pkg_id);
+
+CREATE TABLE bug_srcpackage (
+       bug_id INT NOT NULL REFERENCES bug,
+       src_pkg_id INT NOT NULL REFERENCES src_pkg ON UPDATE CASCADE ON DELETE CASCADE
+);
+CREATE UNIQUE INDEX bug_srcpackage_id_pkg_id ON bug_srcpackage(bug_id,src_pkg_id);
+
+CREATE VIEW bug_package (bug_id,pkg_id,pkg_type,package) AS
+       SELECT b.bug_id,b.bin_pkg_id,'binary',bp.pkg FROM bug_binpackage b JOIN bin_pkg bp ON bp.id=b.bin_pkg_id UNION
+              SELECT s.bug_id,s.src_pkg_id,'source',sp.pkg FROM bug_srcpackage s JOIN src_pkg sp ON sp.id=s.src_pkg_id;
\ No newline at end of file