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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сериализация DBI, сохранить объект в сессии 
V
    Опции темы
KSURi
Дата 19.3.2008, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Возникла необходимость сохранить в сессии пользователя объект, в котором один из атрибутов является экземпляром DBI. Объект соотвественно надо сериализировать.

Пробую через Storable:
Код

C:\>perl -MDBI -MStorable -e"$a=DBI->connect('...', '...', '...');$b=Storable::dclone($a);$a->do('SELECT 1');$b->do('SELECT 1')"
Can't store CODE items at -e line 1.

dclone($a), это тоже самое, что и Storable::thaw(Storable::freeze($a)). Вобщем Storable честно предупредил, что не может сериализовать DBI.

Пробую через FreezeThaw:
Код

C:\>perl -MDBI -MFreezeThaw -e"$a=DBI->connect('...', '...', '...');($b)=FreezeThaw::thaw(FreezeThaw::freeze($a));$a->do('SELECT 1');$b->do('SELECT 1')"
SV = RV(0x19a71e8) at 0x224f74
  REFCNT = 1
  FLAGS = (ROK)
  RV = 0x19f3eb4
dbih_getcom handle DBI::db=HASH(0x19f3eb4) is not a DBI handle (has no magic) at -e line 1.
SV = RV(0x18341b8) at 0x140fd4c
  REFCNT = 1
  FLAGS = (ROK,READONLY)
  RV = 0x19f3eb4

Как видно, десериализованная переменная уже не является экземпляром DBI =(

Итак, вопрос: существует ли возможность каким-то образом сереалиазовать экземпляр DBI, естествено не потеряв при этом его работоспособность?


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 19.3.2008, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Как верно подметили в рекламе: "Нет, сынок, это фантастика!"
Честно говоря, даже в голову не приходила такая идея.  KSURi, можете указать мотивы, которые Вами движут в направлении сериализации объекта DBI?
Я бы передавал идентификатор типа соединения, если их может быть несколько.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 19.3.2008, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Мне надо не просто DBI упрятать в сессию, а другой объект, один из атрибутов которого - DBI. Редизайнить класс, чтобы не хранить в его экземплярах DBI - самый крайний вариант, почти даже не вариант)


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 19.3.2008, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Я бы перед сериализацией заменил объект DBI внутри другого объекта на идентификатор типа соединения (если требуется), а при восстановлении объекта сделал обратную операцию.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 19.3.2008, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Что-то я в документации к DBI ничего не нашел про это ухищрение(
Плохо смотрел или не туда?)


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 19.3.2008, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



К модулю DBI мое сообщение отношения не имеет.

я предлагаю при создании соединения с БД указывать дополнительный параметр private_dbh_type (это наш собственный параметр для указания типа соединения, в случае, если в программе возможны разные типы соединений).
Перед сериализацией выполняем

Код

$object->set_dbh($object->get_dbh()->{private_dbh_type});


после десериализации объекта выполняем

Код

$object->set_dbh(get_dbh_by_type($object->get_dbh()));


где get_dbh_by_type() - функция установки соединения указанного типа


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 20.3.2008, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Чтож, ginnie, вы направили меня на путь истинный) На самом деле все оказалось гораздо проще: перед сохранением объекта в сессию я делаю $obj->set_dbh(undef), а при ее восстановлении $obj->set_dbh($obj->db_connect). Пожалуй это конечно более ресурсоемкий вариант, но у меня нет высокой нагрузки.

ЗЫ: не понимаю, почему мне сразу это в голову не пришло =\


--------------------
Died at Life.pl line 21
PM Jabber   Вверх
ginnie
Дата 20.3.2008, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



KSURi, показалась странной строка
Код

$obj->set_dbh($obj->db_connect)


должно быть либо

Код

$obj->set_dbh($db_obj->db_connect)


либо

Код

$obj->db_connect()





--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
KSURi
Дата 20.3.2008, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Ну это я абстрактно написал. На самом деле все вот так:
Код

    my $Client = $session->param('CLIENT');
    unless(defined $Client && ref $Client eq 'Client') {
        $RootObj->write_log($VERSION . ': invalid CLIENT param in session for ip=' . $ENV{REMOTE_ADDR});
        return
    }
    $Client->get_root_obj->db_connect; # initialize new db connection

get_root_obj возвращает экземпляр класса в котором прописаны методы для работы с базой.


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


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

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


 




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


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

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