From 35210c061e2ef7831624eafbc69cdbae08dc3d57 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Sat, 1 Feb 2020 16:39:08 +0100 Subject: [PATCH] [Bug 1592129] Add a shortcut for quoting identifiers in strings. The Bugzilla::DB object has a qi attribute which returns a special hashref that can be used inside double-quoted strings to quote database identifiers. ```perl my $q = Bugzilla->dbh->qi; Bugzilla->dbh->do("SELECT COUNT(*) FROM $q->{groups}"); ``` --- Bugzilla/DB.pm | 10 +++++ Bugzilla/DB/QuoteIdentifier.pm | 71 ++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 Bugzilla/DB/QuoteIdentifier.pm diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 7262cf888c..c1f7461716 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -24,6 +24,7 @@ use Bugzilla::Install::Localconfig; use Bugzilla::Util; use Bugzilla::Error; use Bugzilla::DB::Schema; +use Bugzilla::DB::QuoteIdentifier; use Bugzilla::Version; use Scalar::Util qw(blessed); @@ -32,6 +33,15 @@ use Storable qw(dclone); has [qw(dsn user pass attrs)] => (is => 'ro', required => 1,); +has 'qi' => (is => 'lazy'); + +sub _build_qi { + my ($self) = @_; + my %q; + tie %q, 'Bugzilla::DB::QuoteIdentifier', db => $self; + + return \%q; +} # Install proxy methods to the DBI object. # We can't use handles() as DBIx::Connector->dbh has to be called each diff --git a/Bugzilla/DB/QuoteIdentifier.pm b/Bugzilla/DB/QuoteIdentifier.pm new file mode 100644 index 0000000000..b3957d163f --- /dev/null +++ b/Bugzilla/DB/QuoteIdentifier.pm @@ -0,0 +1,71 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::DB::QuoteIdentifier; + +use 5.10.1; +use Moo; + +has 'db' => ( + is => 'ro', + weak_ref => 1, + required => 1, +); + +sub TIEHASH { + my ($class, @args) = @_; + + return $class->new(@args); +} + +sub FETCH { + my ($self, $key) = @_; + + return $self->db->quote_identifier($key); +} + +sub FIRSTKEY { + return; +} + +sub FIRSTVALUE { + return; +} + +sub EXISTS { + return 1 +} + +sub DELETE { + return 1 +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::DB::QuoteIdentifier + +=head1 SYNOPSIS + + my %q; + tie %q, 'Bugzilla::DB::QuoteIdentifier', db => Bugzilla->dbh; + + is("this is $q{something}", 'this is ' . Bugzilla->dbh->quote_identifier('something')); + +=head1 DESCRIPTION + +Bugzilla has many strings with bare sql column names or table names. Sometimes, +as in the case of MySQL 8, formerly unreserved keywords can become reserved. + +This module provides a shortcut for quoting identifiers in strings by way of overloading a hash +so that we can easily call C inside double-quoted strings. + +=cut + -- 2.47.3