содержит $cookies{session} такой шаблон случайных символов:
my @r = ( 0 .. 9, 'A' .. 'Z', 'a' .. 'z' );будет ли инъекци в таком запросе?
$cookies{session} =~ s/\W+//g;
$cookies{session} =~ s/[<>\|\-&\.\\\/\0]//g;
$session = $dbh->selectrow_hashref(qq{SELECT t1.u,
................
WHERE t1.session = ?
LIMIT 1
}, undef, $cookies{session});этот запрос нужно выполнять всегда, очень часто, я попробовал ускорить его поставив selectrow_hashref() вместо fetchrow_hashref()
(Storable не понравился, так как дополниельный геморой настойки прав доступа и etc для того кто будет устанавливать программу)
При использовании(даже неявном) бинда параметров инъекции в любом случае не будет. Логика работы регекса неясна, если есть используемый класс символов, то поставь его отрицание и всех делов. В данном случае s/[^\dA-Za-z]//g. Еще с tr(он же ~y//) можно попробовать, по идее он быстрее, но, учитывая последующий запрос в базу, роли это играть не будет. Ну и до кучи arrayref все-таки побыстрее hashref, так как не нужно отдельно запрашивать у сервера fieldlist.
>При использовании(даже неявном) бинда параметров инъекции в любом случае не будет. Логика
>работы регекса неясна, если есть используемый класс символов, то поставь его
>отрицание и всех делов. В данном случае s/[^\dA-Za-z]//g. Еще с tr(он
>же ~y//) можно попробовать, по идее он быстрее, но, учитывая последующий
>запрос в базу, роли это играть не будет. Ну и допонятно, спасибо
>кучи arrayref все-таки побыстрее hashref, так как не нужно отдельно запрашивать
>у сервера fieldlist.да, быстрее arrayref, но мне надо будет заносить в шаблон HTML::Template массив хэшей, в данном случае все равно надо будет делать хэши
то есть я незнаю будет ли быстрее если я с базы возьму срузу hashref или если я в цыкле с arrayref сделаю массив хэшей
push @{$rows}, $_ while $_ = $sth->fetchrow_hashref();
$template->param(ROWS => $rows);
Еще раз, при использовании fetchrow_hashref не только делается преобразование в хеш, но еще и посылается дополнительный запрос серверу на получение имен полей. По логике вашей программы имена и так известны, так зачем лишние обращения. Более того самостоятельное превращение в хеш вам дает независимость названий ключей хеша и полей в запросе.
Использовать fetchrow_hashref удобно если по логике программы мы на момент обработки не знаем имена полей, например при "select * from ..." или передачи хендлера запроса в функцию.
В конце концов, что вам вам мешает проверить скорость обоих вариантов, может обращение к базе вообще не является узким местом в вашем коде и нет смысла его оптимизировать.
я написал программу, сейчас оптимизирую, пересматриваю класс работы с DBIопять хочу спросить быстрее ли методв do чем prepare?
предыдущая прогармма у меня ест не много, точнее более менее прилично, ресурсы СУБД... особенно когда боты прийдут под вечер, Яша и др.
передаються много int значнеией числовых в программе... кто-то тестировал быстрее ли selectall_hashref и selectall_arreyref чем от prepare???
или зачем сделали эти методы selectall_hashref и selectall_arreyref в DBI?
если do быстрее, то как написать для HTML::Template массив хєшей?
my $loop_data;
push @{$loop_data}, $_ while $_ = $sth->fetchrow_hashref();
так не работает:
push @{$loop_data}, $_ while $_ = $dbh->selectrow_hashref ( $sql2 );
тут только arrayref подходит и названия столбцов через цыклы пропустить? но это не удобно... но можно...
> my $loop_data;
> push @{$loop_data}, $_ while $_ = $sth->fetchrow_hashref();клево конечно что перл позволяет такие матерные обороты ))
но чето я их затрудняюсь на русский )) толи уже поздна и пора спать ))
Да где же тут матерные обороты?. Цикл while в постфиксной форме и стандартная команда push для забрасывания в массив значения. @{$loop_data} - разыменование ссылки на массив, если выражаться сишными терминами, причем фигурные скобки можно в данном случае опустить.
Автору топика. Если тебе нужны _все_ данные из запроса, то используй fetchall, если нужна построчная обработка, то просто fetch. Аналогично отдельный prepare, если нужно многократно выполнить один и тот же запрос с разными параметрами, в противном случае функции типа все_в_одном. Даже странно, что такие очевидные вещи нужно объяснять. Также непонятно как DBI можно осваивать дольше чем пару дней, он же простой как дверь. Другое дело DBIx, при всей красоте и "интуитивности" он таит массу подводных камней.
angra, спасибо за комментарий, но я не про это спрашиваля хотел доделать свой класс, спрашивал быстрее ли do чем выборка через prepare?
или зачем сделали select*_hashref()?я так понял, что нету разницы, но перл когда экранирует от инъкций он выделяет память чтобы провести защиту от инъекций, было написано что это может быть очень медленно, в СУБД mysql версии больше 5.0, есть возможность экранировать на стороне сервера СУБД (у нее самой, в самом сервере) ...
провести тестирование я не могу, не знаю как правильно....
>angra, спасибо за комментарий, но я не про это спрашивал
>
>я хотел доделать свой класс, спрашивал быстрее ли do чем выборка через
>prepare?Зависит от запросов. Вы бы лучше разобрались для чего нужен каждый из них.
>или зачем сделали select*_hashref()?А зачем сделали все остальное? В ряде ситуаций весьма полезная штука. Perl вообще отличается принципом "есть более чем один способ сделать это"
>я так понял, что нету разницы, но перл когда экранирует от инъкций
>он выделяет память чтобы провести защиту от инъекций, было написано что
>это может быть очень медленно, в СУБД mysql версии больше
>5.0, есть возможность экранировать на стороне сервера СУБД (у нее самой,
>в самом сервере) ...DBI это уровень абстракции и зачастую позволяет сделать то, что нет в движке БД. Однако prepare был в мускульном API с четвертой версии как минимум. Другое дело, что языки типа пыха в то время не владели всем мускулевым API. Задачи prepare не столько защита от инъекций сколько скорость и удобство, защита скорее побочный эффект.
>провести тестирование я не могу, не знаю как правильно....
Поищите модули типа benchmark.
извените, я не много прогналв методе do, есть метод prepare и экранирование есть, тоже...
по этому нету смысла сравнивать эти два метода do и prepare...sub do {
my($dbh, $statement, $attr, @bind_values) = @_;
my $sth = $dbh->prepare($statement, $attr) or return undef;
$sth->execute(@bind_values) or return undef;
my $rows = $sth->rows;
($rows == 0) ? "0E0" : $rows; # always return true if no error
}
Не стоит полагаться, что do реализован обязательно таким образом. Хотя на данный момент в DBI.pm это так, но не обязательно будет так в будущем, а самое главное DBD:: модули вполне могут этот метод перекрывать. К сожалению для DBD::mysql на данный момент именно такая(prepare+execute) реализация, хотя мускулевое API позволяет более скоростной вариант.