Могу ли я распечатать вывод DBIC_TRACE в DBIx :: Class? - PullRequest
20 голосов
/ 17 февраля 2009

Установка для переменной среды DBIC_TRACE значения true:

BEGIN { $ENV{DBIC_TRACE} = 1 }

генерирует очень полезный вывод, особенно показывающий выполняемый SQL-запрос, но SQL-запрос находится в одной строке.

Есть ли способ протолкнуть его через какую-то подпрограмму "sql tidy", чтобы лучше отформатировать ее, возможно, разбив ее на несколько строк? Если это не удастся, может кто-нибудь подсказать мне, где в коде мне нужно взломать, чтобы добавить такой хук? И какой лучший инструмент - принять плохо отформатированный SQL-запрос и выдать красиво отформатированный?

«хорошее форматирование» в этом контексте просто означает лучше, чем «все в одной строке». Меня не особо волнуют конкретные стили форматирования запросов

Спасибо!

Ответы [ 3 ]

21 голосов
/ 20 декабря 2010

По состоянию на DBIx :: Класс 0.08124 он встроен.

Просто установите $ENV{DBIC_TRACE_PROFILE} на console или console_monochrome.

10 голосов
/ 17 февраля 2009

Из документации DBIx :: Class :: Storage

Если установлен DBIC_TRACE, то генерируется информация трассировки (например, когда установлен метод отладки).

...

debug
Вызывает вывод информации трассировки в debugobj. объект. (или STDERR, если debugobj специально не был установлен).

debugobj
Устанавливает или получает объект, используемый для сбора метрик. По умолчанию используется экземпляр DBIx :: Class :: Storage :: Statistics, который совместим с оригинальным методом использования coderef в качестве обратного вызова. См. Вышеупомянутый класс Статистика для получения дополнительной информации.

Другими словами, вы должны установить debugobj в этом классе для объекта, который подклассов DBIx :: Class :: Storage :: Statistics . В своем подклассе вы можете переформатировать запрос так, как вы хотите.

3 голосов
/ 18 февраля 2009

Во-первых, спасибо за указатели! Частичный ответ следует ....

То, что у меня так далеко ... сначала несколько лесов:

# Connect to our db through DBIx::Class
my $schema = My::Schema->connect('dbi:SQLite:/home/me/accounts.db');

# See also BEGIN { $ENV{DBIC_TRACE} = 1 }
$schema->storage->debug(1);

# Create an instance of our subclassed (see below)
# DBIx::Class::Storage::Statistics class
my $stats = My::DBIx::Class::Storage::Statistics->new();

# Set the debugobj object on our schema's storage
$schema->storage->debugobj($stats);

И определение My :: DBIx :: Class :: Storage :: Statistics:

package My::DBIx::Class::Storage::Statistics;

use base qw<DBIx::Class::Storage::Statistics>;
use Data::Dumper qw<Dumper>;
use SQL::Statement;
use SQL::Parser;

sub query_start {
    my ($self, $sql_query, @params) = @_;

    print "The original sql query is\n$sql_query\n\n";

    my $parser = SQL::Parser->new();
    my $stmt   = SQL::Statement->new($sql_query, $parser);
    #printf "%s\n", $stmt->command;

    print "The parameters for this query are:";
    print Dumper \@params;
}

Что решает проблему о том, как подключиться, чтобы получить для меня SQL-запрос "pretty-ify".

Затем я запускаю запрос:

my $rs = $schema->resultset('SomeTable')->search(
    {   
        'email' => $email,
        'others.some_col' => 1,
    },
    { join => 'others' }
);
$rs->count;

Однако SQL :: Parser barfs для SQL, сгенерированного DBIx :: Class:

The original sql query is
SELECT COUNT( * ) FROM some_table me LEFT JOIN others other_table ON ( others.some_col_id = me.id ) WHERE ( others.some_col_id = ? AND email = ? )

SQL ERROR: Bad table or column name '(others' has chars not alphanumeric or underscore!

SQL ERROR: No equijoin condition in WHERE or ON clause

Итак ... есть ли синтаксический анализатор лучше, чем SQL :: Parser для этой работы?

...