среда, 28 ноября 2007 г.

Не все DateTime одинаково полезны

Маленькое предисловие

С базами данных я практически не работал. Ну так, знаю четыре базовых SQL-команды и умею пользоваться гуглом :) В принципе, этого достаточно, учитывая возможности студии. И вот столкнулся я вчера с очень оригинальной ошибкой...




Есть у меня одна программа, предназначенная для поиска дубликатов файлов. Для сравнения файлов используется алгоритм рассчета Tiger Tree Hash. Рассчеты ТТН ведутся только для первых 5 Мб с начала файла, что позволяет резко сократить время работы программы (Естественно, что при сравнении учитывается не только ТТН).
Основная идея программы в том, чтобы запоминать уже рассчитанные ТТН. И в дальнейшем сравнивать ТТН новых файлов с запомненными - причем старый файл уже может и не существовать на диске.
Поскольку программа писалась на коленке, для, так сказать, "внутреннего использования" - все данные сохранялись в XML (о том, как сериализовать сложные коллекции - типа Dictionary и ей подобных - я писал ранее). И всё было бы ничего, да вот только сейчас xml с данными весит уже 70 Мб и собирается расти дальше :) Ну, в принципе, что-то такое я и ожидал... Так что было принято волевое решение переписать программу так, чтобы она использовала базу данных как хранилище.

Сказано - сделано.

Как база данных был выбран Access 2007 - т.к. он у меня уже установлен, а со всеми остальными базами данных надо разбираться (вообщем, лень :) )
Открываю Access, рисую таблицу вида:

код
ТТНstring
размер файлаint
полный путь к файлуstring
дата созданияDateTime


Вообщем, ничего сложного. Используя мастера студии 2008 создаю DataSetTableAdapter, добавляю в него два запроса - Select и Insert.

Тестирую:

FileInfo1TableAdapter fi=new FileInfo1TableAdapter();
string TTH="aaa";
int Length=10;
string path="filename";
DateTime date=new DateTime(2007, 11, 27, 9, 20, 10);

fi.InsertQuery(TTH, Length, path, date);
Работает! Ура :)

Прикручиваю к новой программе хранилище данных из старой программы - с целью перенести эти самые данные в базу. Пишу алгоритм переноса и... получаю ошибку приведения типов при попытке поместить данные в базу!

Потратив полчаса времени, я все-таки выяснил, что причина ошибки кроется в параметре date.

А теперь внимание! Значение date - это дата и время создания файла. Время создания дается с точностью до миллисекунд. При тестировании я использовал значение времени с точностью до секунд (напоминаю: тестовый пример - работал). Так вот, оказывается, что если вызывать, например, вот такой конструктор DateTime(2007, 11, 27, 9 /*часы*/, 20 /*минуты*/, 10 /*секунды*/, 10 /*миллисекунды*/) - мы гарантированно получаем ошибку не соответствия типов при попытке поместить значение DateTime в базу!

P.S.: вывод - если нечто выглядит как DateTime, ведет себя как DateTime, то это не значит что данное нечто - DateTime :)

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

Отправить комментарий