summaryrefslogtreecommitdiffstats
path: root/Bugzilla/DB
diff options
context:
space:
mode:
authormkanat%kerio.com <>2005-02-17 03:11:06 +0100
committermkanat%kerio.com <>2005-02-17 03:11:06 +0100
commit62b2ec349b01a454420eaadd22caad929521a76e (patch)
treeee6df46d3cb0df42a21791ead8b323e0e500116c /Bugzilla/DB
parentfc3aa3e7aa78106e8148b3ecbd92e65e5ad63985 (diff)
downloadbugzilla-62b2ec349b01a454420eaadd22caad929521a76e.tar.gz
bugzilla-62b2ec349b01a454420eaadd22caad929521a76e.tar.xz
Bug 237862: New database layer for cross-database compatibility
Patch By Tomas Kopal <Tomas.Kopal@altap.cz> r=mkanat, a=myk
Diffstat (limited to 'Bugzilla/DB')
-rw-r--r--Bugzilla/DB/Mysql.pm162
-rw-r--r--Bugzilla/DB/Pg.pm180
2 files changed, 342 insertions, 0 deletions
diff --git a/Bugzilla/DB/Mysql.pm b/Bugzilla/DB/Mysql.pm
new file mode 100644
index 000000000..d2204433b
--- /dev/null
+++ b/Bugzilla/DB/Mysql.pm
@@ -0,0 +1,162 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Netscape Communications
+# Corporation. Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s): Dave Miller <davem00@aol.com>
+# Gayathri Swaminath <gayathrik00@aol.com>
+# Jeroen Ruigrok van der Werven <asmodai@wxs.nl>
+# Dave Lawrence <dkl@redhat.com>
+# Tomas Kopal <Tomas.Kopal@altap.cz>
+
+=head1 NAME
+
+Bugzilla::DB::Mysql - Bugzilla database compatibility layer for MySQL
+
+=head1 DESCRIPTION
+
+This module overrides methods of the Bugzilla::DB module with MySQL specific
+implementation. It is instantiated by the Bugzilla::DB module and should never
+be used directly.
+
+For interface details see L<Bugzilla::DB> and L<DBI>.
+
+=cut
+
+package Bugzilla::DB::Mysql;
+
+use strict;
+
+use Bugzilla::Error;
+use Carp;
+
+# This module extends the DB interface via inheritance
+use base qw(Bugzilla::DB);
+
+sub new {
+ my ($class, $user, $pass, $host, $dbname, $port, $sock) = @_;
+
+ # construct the DSN from the parameters we got
+ my $dsn = "DBI:mysql:host=$host;database=$dbname;port=$port";
+ $dsn .= ";mysql_socket=$sock" if $sock;
+
+ my $self = $class->db_new($dsn, $user, $pass);
+
+ # all class local variables stored in DBI derived class needs to have
+ # a prefix 'private_'. See DBI documentation.
+ $self->{private_bz_tables_locked} = 0;
+
+ bless ($self, $class);
+
+ return $self;
+}
+
+# when last_insert_id() is supported on MySQL by lowest DBI/DBD version
+# required by Bugzilla, this implementation can be removed.
+sub bz_last_key {
+ my ($self) = @_;
+
+ my ($last_insert_id) = $self->selectrow_array('SELECT LAST_INSERT_ID()');
+
+ return $last_insert_id;
+}
+
+sub sql_regexp {
+ return "REGEXP";
+}
+
+sub sql_not_regexp {
+ return "NOT REGEXP";
+}
+
+sub sql_limit {
+ my ($self, $limit,$offset) = @_;
+
+ if (defined($offset)) {
+ return "LIMIT $offset, $limit";
+ } else {
+ return "LIMIT $limit";
+ }
+}
+
+sub sql_to_days {
+ my ($self, $date) = @_;
+
+ return "TO_DAYS($date)";
+}
+
+sub sql_date_format {
+ my ($self, $date, $format) = @_;
+
+ $format = "%Y.%m.%d %H:%i:%s" if !$format;
+
+ return "DATE_FORMAT($date, " . $self->quote($format) . ")";
+}
+
+sub sql_interval {
+ my ($self, $interval) = @_;
+
+ return "INTERVAL $interval";
+}
+
+sub bz_lock_tables {
+ my ($self, @tables) = @_;
+
+ # Check first if there was no lock before
+ if ($self->{private_bz_tables_locked}) {
+ carp("Tables already locked");
+ ThrowCodeError("already_locked");
+ } else {
+ $self->do('LOCK TABLE ' . join(', ', @tables));
+
+ $self->{private_bz_tables_locked} = 1;
+ }
+}
+
+sub bz_unlock_tables {
+ my ($self, $abort) = @_;
+
+ # Check first if there was previous matching lock
+ if (!$self->{private_bz_tables_locked}) {
+ # Abort is allowed even without previous lock for error handling
+ return if $abort;
+ carp("No matching lock");
+ ThrowCodeError("no_matching_lock");
+ } else {
+ $self->do("UNLOCK TABLES");
+
+ $self->{private_bz_tables_locked} = 0;
+ }
+}
+
+# As Bugzilla currently runs on MyISAM storage, which does not supprt
+# transactions, these functions die when called.
+# Maybe we should just ignore these calls for now, but as we are not
+# using transactions in MySQL yet, this just hints the developers.
+sub bz_start_transaction {
+ die("Attempt to start transaction on DB without transaction support");
+}
+
+sub bz_commit_transaction {
+ die("Attempt to commit transaction on DB without transaction support");
+}
+
+sub bz_rollback_transaction {
+ die("Attempt to rollback transaction on DB without transaction support");
+}
+
+1;
diff --git a/Bugzilla/DB/Pg.pm b/Bugzilla/DB/Pg.pm
new file mode 100644
index 000000000..a23c38666
--- /dev/null
+++ b/Bugzilla/DB/Pg.pm
@@ -0,0 +1,180 @@
+# -*- Mode: perl; indent-tabs-mode: nil -*-
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Netscape Communications
+# Corporation. Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s): Dave Miller <davem00@aol.com>
+# Gayathri Swaminath <gayathrik00@aol.com>
+# Jeroen Ruigrok van der Werven <asmodai@wxs.nl>
+# Dave Lawrence <dkl@redhat.com>
+# Tomas Kopal <Tomas.Kopal@altap.cz>
+
+=head1 NAME
+
+Bugzilla::DB::Pg - Bugzilla database compatibility layer for PostgreSQL
+
+=head1 DESCRIPTION
+
+This module overrides methods of the Bugzilla::DB module with PostgreSQL
+specific implementation. It is instantiated by the Bugzilla::DB module
+and should never be used directly.
+
+For interface details see L<Bugzilla::DB> and L<DBI>.
+
+=cut
+
+package Bugzilla::DB::Pg;
+
+use strict;
+
+use Bugzilla::Error;
+use Carp;
+
+# This module extends the DB interface via inheritance
+use base qw(Bugzilla::DB);
+
+sub new {
+ my ($class, $user, $pass, $host, $dbname, $port) = @_;
+
+ # construct the DSN from the parameters we got
+ my $dsn = "DBI:Pg:host=$host;dbname=$dbname;port=$port";
+
+ my $self = $class->db_new($dsn, $user, $pass);
+
+ # all class local variables stored in DBI derived class needs to have
+ # a prefix 'private_'. See DBI documentation.
+ $self->{private_bz_tables_locked} = 0;
+
+ bless ($self, $class);
+
+ return $self;
+}
+
+# if last_insert_id is supported on PostgreSQL by lowest DBI/DBD version
+# supported by Bugzilla, this implementation can be removed.
+sub bz_last_key {
+ my ($self, $table, $column) = @_;
+
+ my $seq = $table . "_" . $column . "_seq";
+ my ($last_insert_id) = $self->selectrow_array("SELECT CURRVAL('$seq')");
+
+ return $last_insert_id;
+}
+
+sub sql_regexp {
+ return "~";
+}
+
+sub sql_not_regexp {
+ return "!~"
+}
+
+sub sql_limit {
+ my ($self, $limit,$offset) = @_;
+
+ if (defined($offset)) {
+ return "LIMIT $limit OFFSET $offset";
+ } else {
+ return "LIMIT $limit";
+ }
+}
+
+sub sql_to_days {
+ my ($self, $date) = @_;
+
+ return "TO_CHAR($date, 'J')::int";
+}
+
+sub sql_date_format {
+ my ($self, $date, $format) = @_;
+
+ $format = "%Y.%m.%d %H:%i:%s" if !$format;
+
+ $format =~ s/\%Y/YYYY/g;
+ $format =~ s/\%y/YY/g;
+ $format =~ s/\%m/MM/g;
+ $format =~ s/\%d/DD/g;
+ $format =~ s/\%a/Dy/g;
+ $format =~ s/\%H/HH24/g;
+ $format =~ s/\%i/MI/g;
+ $format =~ s/\%s/SS/g;
+
+ return "TO_CHAR($date, " . $self->quote($format) . ")";
+}
+
+sub sql_interval {
+ my ($self, $interval) = @_;
+
+ return "INTERVAL '$interval'";
+}
+
+sub bz_lock_tables {
+ my ($self, @tables) = @_;
+
+ # Check first if there was no lock before
+ if ($self->{private_bz_tables_locked}) {
+ carp("Tables already locked");
+ ThrowCodeError("already_locked");
+ } else {
+ my %read_tables;
+ my %write_tables;
+ foreach my $table (@tables) {
+ $table =~ /^([\d\w]+)([\s]+AS[\s]+[\d\w]+)?[\s]+(WRITE|READ)$/i;
+ my $table_name = $1;
+ if ($3 =~ /READ/i) {
+ if (!exists $read_tables{$table_name}) {
+ $read_tables{$table_name} = undef;
+ }
+ }
+ else {
+ if (!exists $write_tables{$table_name}) {
+ $write_tables{$table_name} = undef;
+ }
+ }
+ }
+
+ # Begin Transaction
+ $self->bz_start_transaction();
+
+ Bugzilla->dbh->do('LOCK TABLE ' . join(', ', keys %read_tables) .
+ ' IN ROW SHARE MODE') if keys %read_tables;
+ Bugzilla->dbh->do('LOCK TABLE ' . join(', ', keys %write_tables) .
+ ' IN ROW EXCLUSIVE MODE') if keys %write_tables;
+ }
+}
+
+sub bz_unlock_tables {
+ my ($self, $abort) = @_;
+
+ # Check first if there was previous matching lock
+ if (!$self->{private_bz_tables_locked}) {
+ # Abort is allowed even without previous lock for error handling
+ return if $abort;
+
+ carp("No matching lock");
+ ThrowCodeError("no_matching_lock");
+ } else {
+ # End transaction, tables will be unlocked automatically
+ if ($abort) {
+ $self->bz_rollback_transaction();
+ } else {
+ $self->bz_commit_transaction();
+ }
+ }
+}
+
+1;