Как получить доступ к конкретному возвращаемому значению из функции CDBI::Search?
Я использую DB::CDBI
класс для доступа к базе данных в нашем приложении. Наш проект находится в объектно-ориентированном Perl.
package LT::LanguageImport;
use strict;
use warnings;
use base 'Misk5::CDBI';
__PACKAGE__->table( 'english_text_translation' );
__PACKAGE__->columns( Primary => qw/english language translation/ );
__PACKAGE__->columns( Essential => qw/english language translation/ );
__PACKAGE__->has_a( english => 'LT::EnglishLanguage' );
В одном из таких сценариев я должен проверить, существует ли строка в таблице. Я использую встроенный API поиска в вызове CDBI.
sub find_translation {
my $translation_exists_r_not = $class->search(
english => $english,
language => $language,
translation => $translation
);
return;
}
$translation_exists_r_not
получает ожидаемые значения в зависимости от входных данных, приведенных в поиске. Если строка существует, то _data
обновляется с подробностями строки.
$translation_exists_r_not = bless({
'_data' => [
{
'language' => 'polish',
'translation' => 'Admin',
'english' => 'admin'
}
],
'_place' => 0,
'_mapper' => [],
'_class' => 'LT::LanguageImport'
},
'Class::DBI::Iterator'
);
Если строка не существует, то я получаю возвращаемое значение, как это.
$translation_exists_r_not = bless({
'_data' => [],
'_place' => 0,
'_mapper' => [],
'_class' => 'LT::LanguageImport'
},
'Class::DBI::Iterator'
);
Я хочу вернуть значение translation
из этого саба find_translation
в зависимости от результата поиска. Я не могу получить лучшее условие для этого.
Я пытался скопировать _data
в массив, но я не уверен, что делать дальше. Как _data
будет пустой arrayref и другим условием будет иметь хеш-ссылку внутри arrayref.
my @Arr = $translation_exists_r_not->{'_data'};
2 ответа
CDBI-х search
Метод вернет итератор, поскольку может быть возвращено несколько строк в зависимости от ваших критериев.
Если вы знаете, что может быть только одна строка, соответствующая вашим критериям, вы хотите использовать retrieve
метод, то есть:
if (my $translation_exists_r_not = $class->retrieve(
english => $english,
language => $language,
translation => $translation
)){
return [$translation_exists_r_not->translation,
'Misk5::TranslationAlreadyExists']
}
else {
return [ '', undef ]
}
И если из вашего поиска могут быть возвращены несколько строк, и вас интересует только правдивость, то опять же, не копайтесь в CDBI::Iterator, а используйте его методы:
my $translation_exists_r_not = $class->search(
english => $english,
language => $language,
translation => $translation
); # returns an iterator
if ($translation_exists_r_not){
my $first = $translation_exists_r_not->first;
return [ $first->translation, 'Misk5::TranslationAlreadyExists' ]
}
Посмотри на perldoc Class::DBI
а также perldoc Class::DBI::Iterator
, CDBI имеет отличную документацию.
Я думаю, что я получил решение. Спасибо тому, кто пытался это решить.
my @req_array = %$translation_exists_r_not->{_data};
my $length_of_data = '9';
foreach my $elem (@req_array) {
$length_of_data = @{$elem};
}
Теперь проверьте длину массива.
if ($length_of_data == 0) {
$error = '';
$result = [undef, $error];
}
Теперь проверьте, если это так.
if ($length_of_data == 1) {
my @result_array = @{%$translation_exists_r_not->{_data}};
my $translation = $result_array[0]{'translation'};
$error = 'Misk5::TranslationAlreadyExists';
$result = [$translation, $error];
}
return @$result;