поиск по дате в DBIx::Class

#perl #dbix-class

#perl #dbix-class

Вопрос:

У меня есть таблица в базе данных SQLite, где в столбце хранится время файла в эпохальных секундах.

Теперь я хотел бы выполнить поиск в этой таблице файлов, которые были изменены в определенном месяце?

В необработанном SQL я бы сделал:

  select * from my_table where strftime('%Y-%m', mtime, "unixepoch") = "2009-08"
  

Есть ли способ сделать это эффективно с помощью DBIx:: Class? Возможно ли сделать

  $m->search({ 'strftime('%Y-%m', mtime, "unixepoch")' => "2009-08" })
  

Я попытался понять, есть ли способ с DBIx:: Class ::InflateColumn::DateTime, но я его не нашел.

Спасибо

Simone

Комментарии:

1. В качестве обходного пути вы могли бы выбрать временные метки >= Y-m-1 0:00 и < Y-(m 1)-1 00:00 . Time::Local может использоваться для перевода дат в секунды.

Ответ №1:

Синтаксис, который вы ищете, является:

 $m->search(
  [ q{strftime('%Y-%m', mtime, "unixepoch") = ?}, "2009-08" ]
);
  

Да, это ссылкана массив-ref. Первый элемент — это буквальный SQL, которому разрешено использовать ? заполнители, а остальные элементы — это значения для привязки к этим заполнителям, и DBIC обязательно изменит порядок всего внутри, чтобы эти значения были помещены в нужное место в списке привязки при выполнении запроса.

Если вам нужно объединить один из этих критериев с другими, поскольку arrayrefref не является допустимым хэш-ключом, вам нужно использовать -and синтаксис:

 $m->search({ 
  -and => [
    foo => 'bar',
    [ q{ SQL }, $bind ],
  ],
});
  

Вот раздел SQL::Abstract docs для этой конструкции.

Ответ №2:

Я бы посоветовал вам использовать search_literal вместо:

 # assuming $m isa DBIx::Class::ResultSet
$m->search_literal('strftime("%Y%m", mtime, "unixepoch") = ?', '200908');
  

РЕДАКТИРОВАТЬ: я поддерживаю исправление. Пожалуйста, обратитесь к комментарию и ответу @hobbs.

Комментарии:

1. Пожалуйста, не делайте этого, это неработающий интерфейс, как говорится в документе, на который вы ссылались, и есть другой способ сделать это, который действительно работает должным образом.