Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Постраничный вывод в cgi 
:(
    Опции темы
Guran
Дата 12.11.2011, 04:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 4.10.2011

Репутация: нет
Всего: нет



Здравствуйте. Возникла такая проблема: есть cgi скрипт, исполняющий роль фильтра. Он подключается к выбранной бд и выводит на экран все соответствующее параметрам. Проблема в том что под запрос могут попадать несколько тысяч строк. Догадался в запросах использовать лимиты, но не знаю как вставить кнопки для динамического изменения переменной, за этот лимит отвечающую.

Код

#!/usr/bin/perl

use DBI;
use CGI qw(:standard);
use strict;

my $n;
my $interval;
my @facility;
my @severity;
my @host;
my @syslogtag;
my @words;
my @base=(*Названия баз*);
my $sourse=param("sourse");
my $date=param("date");
my $fac=param("facility");
my $sev=param("severity");
my $hos=param("Host");
my $sys=param("syslogtag");
my $mes=param("message");

my $head = new CGI;
print $head->header(-charset => "UTF-8");
my $dbh = DBI->connect(***) || die $DBI::errstr;

#в следующих пяти запросах собираются данные для выпадающих списков фильтра
my $query = "SELECT facility FROM syslog GROUP BY facility ORDER BY facility;";
my $output = $dbh->prepare($query);
$output->execute;
my $facility;
$output->bind_columns(undef, \($facility));
@facility=('all');
while ($output->fetch) {
    push @facility, $facility;
}

my $query = "SELECT priority FROM `syslog` GROUP BY priority ORDER BY priority;";
my $output = $dbh->prepare($query);
$output->execute;
my $priority;
$output->bind_columns(undef, \($priority));
@severity=('all');
while ($output->fetch) {
    push @severity, $priority;
}

my $query = "SELECT host FROM `syslog` GROUP BY host ORDER BY host;";
my $output = $dbh->prepare($query);
$output->execute;
my $host;
$output->bind_columns(undef, \($host));
@host=('all');
while ($output->fetch) {
    push @host, $host;
}

my $query = "SELECT tag FROM `syslog` GROUP BY tag ORDER BY tag;";
my $output = $dbh->prepare($query);
$output->execute;
my $tag;
$output->bind_columns(undef, \($tag));
@syslogtag=('all');
while ($output->fetch) {
    push @syslogtag, $tag;
}

my $query = "SELECT fr FROM ind_word;";
my $output = $dbh->prepare($query);
$output->execute;
my $fr;
$output->bind_columns(undef, \($fr));
@words=('all');
while ($output->fetch) {
    push @words, $fr;
}

print start_html("Syslog filter"), h3("Syslog filter");
print p(hr);
print start_form;
print p("Sourse :", popup_menu ("sourse",[@base]), 
    "Date :", popup_menu ("date",['all time', 'last hour', 'last 12 hours', 'last 24 hours', 'last week', 'last month']),
    "Fasility :", popup_menu ("facility",[@facility]),
    "Severity :", popup_menu ("severity",[@severity]),
    "Host :", popup_menu ("Host",[@host]),
    "Syslogtag :", popup_menu ("syslogtag",[@syslogtag]),
    "Message :", popup_menu ("message",[@words]));
print p(submit("Ok"));
print end_form; hr;

    print qq{<table border="1" cellpadding="5" cellspacing="0" width="95%">
        <tr>
            <td width="10%" align="left">Date: </td>
            <td width="8%" align="left">Facility: </td>
            <td width="8%" align="left">Severity: </td>
            <td width="8%" align="left">Host: </td>
            <td width="8%" align="left">Syslogtag: </td>
            <td width="8%" align="left">ProcessID: </td>
            <td width="50%" align="left">Message: </td>
        </tr>};

if ($date eq 'all time') {$interval=100000;} 
elsif ($date eq 'last hour'){$interval=(1/24);}
elsif ($date eq 'last 12 hours'){$interval=0.5;}
elsif ($date eq 'last 24 hours'){$interval=1;}
elsif ($date eq 'last week'){$interval=7;}
elsif ($date eq 'last month'){$interval=30;};

#Условия для вывода таблицы с данными на экран
my $query = "SELECT datetime, facility, priority, host, tag, program, msg FROM `syslog` WHERE (TO_DAYS(NOW()) - TO_DAYS(datetime) <= ".$interval.")";
if ($fac ne 'all'){
    $query = $query." AND (facility=".$fac.")"
}
if ($sev ne 'all'){
    $query = $query." AND (priority=".$sev.")"
}
if ($hos ne 'all'){
    $query = $query." AND (host='".$hos."')"
}
if ($sys ne 'all'){
    $query = $query." AND (tag='".$sys."')"
}
if ($mes ne 'all'){
    $query = $query." AND (msg like '%".$mes."%')"
}
$query=$query." LIMIT ".$n;
my $output = $dbh->prepare($query);
$output->execute;
my ($datetime, $facility, $priority, $host, $tag, $program, $msg);
$output->bind_columns(undef, \($datetime, $facility, $priority, $host, $tag, $program, $msg));
while ($output->fetch) {
        print qq{<tr>
            <td width="10%" align="left">$datetime </td>
            <td width="8%" align="left">$facility </td>
            <td width="8%" align="left">$priority </td>
            <td width="8%" align="left">$host </td>
            <td width="8%" align="left">$tag </td>
            <td width="8%" align="left">$program </td>
            <td width="50%" align="left">$msg </td>
        </tr>};
}
    print qq{</table>};
print end_html();
$dbh->close();


Это сообщение отредактировал(а) Guran - 12.11.2011, 04:45
PM MAIL   Вверх
tishaishii
Дата 13.11.2011, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


Профиль
Группа: Завсегдатай
Сообщений: 1262
Регистрация: 14.2.2006
Где: Москва

Репутация: нет
Всего: 8



Код
package Controller;
BEGIN {
      %SUBS=(
            __no_routine__=>sub($$;@) {
                        die join "\n", @_, caller
            }
            sa_firm=>sub($$;@) {
               my($self, $routine)=(shift, shift);
               +$self->routine2xml($routine=>$self->param(@_))
            }
      );
}

sub new($;@) {
     my($class, $self)=(shift, {@_});
     +bless $self, $class
}
sub param($;@) {
    my$self=shift;
    +map $self->{cgi}->param($_), @_;
}
sub routine2xml($$;@) {
    my($self, $routine)=(shift, shift);
    if(my$sth=$self->{dbh}->prepare(<<".")) {
call dbname.`$routine`(${\join ', ', ('?') x @_})
.
        if($sth->execute(@_)>0) {
            while(my$row=$sth->fetchrow_hashref) {
#........................ вывод XML
            }
        }
        $sth->finish;
}
sub execute($) {
        my$self=shift;
        my$routine=$self->{cgi}->param('routine');
        $routine='__no_routine__' unless exists $SUBS{$routine};
        +$SUBS{$routine}($self, $routine=>@_)
}

package main;
use CGI;
use IO::Handle;

Controller->new(
      cgi=>CGI->new,
      request=>\*STDOUT
)->execute

PM MAIL ICQ Skype   Вверх
infarch
Дата 14.11.2011, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Ух ты, красиво у вас получилось... А можете пояснить, для чего нужен "плюс" в начале некоторых строк? Типа вот этого: "+map $self->{cgi}->param($_), @_;"
PM MAIL   Вверх
Ramirez
Дата 15.11.2011, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 305
Регистрация: 18.1.2005
Где: Moscow, ExUSSR

Репутация: 1
Всего: 5



tishaishii, ээээ, я видимо торможу, но где тут постраичный вывод?
PM ICQ   Вверх
Azudim
Дата 3.12.2011, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 3.12.2011

Репутация: нет
Всего: нет



В общем случае задачу "пейджинга" я бы решил так:

 1. Установить лимит строк в выдаче на одну страницу "по умолчанию" (к примеру 25 строк, зависит от дизайна интерфейса)
 2. Узнать общее количество строк в выдаче, как если бы мы не вводили лимиты (SELECT COUNT)
 3. Рассчитываем количество возможных страниц при нашем лимите ( ВСЕ ВОЗМОЖНЫЕ / НАШ ЛИМИТ )
 4. Проектируем область вывода меню управления страницами на "страничке". 
     Если к примеру у нас блок 250px под управление страницами,  а вывести с нашим запросом можно 900 страниц, то удобнее перемещаться не по 1 странице далее, а по 10 или 50. 
     т.е. выглядит такое меню примерно так  [<<][<][1] [2] [3] [_4_][5][6][10][20][50][100][>][>>]
     в скобках что вам нужно - или ссылки с передачей номера страницы через url, типа /article?page=5 или запуск JS скрипта. 
     Вариант с JS скриптом предпочтительнее по следующим соображениям: 
          а) параметров может передаваться очень много: номер страницы, количество строк в выводе, фильтры поиска и т.п. и в URL просто не поместятся все.
          б) размер HTML документа с длинными ссылками увеличится
          в) параметры в url доедут до следующей страницы, будет некрасиво смотреться адресная строка
     Как может работать JS скрипт - элементарно! Создаем в HTML теле страницы форму, складываем для нужное количество инпутов вида <input type="hidden" value="">
     и скриптом сабмитим форму, предворительно проставив нужные параметры. 
     Важно - эти параметры на следующей странице передать из CGI в value="" в инпутах.
  5. Генерируем в скрипте последовательность кнопок управления страницами

  Получаем: 
    первый проход - лимиты установлены по умолчанию, сгенерировано меню страниц, по клику на элемент меню передаются параметры на следующий проход page=X
    второй проход, если указан page и rows (кол. строк на страницу) передаем эти параметры в SQL запрос           

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: CGI программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к CGI программированию
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", качать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: разработка для Web | Следующая тема »


 




[ Время генерации скрипта: 0.0831 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.