среда, 27 октября 2010 г.

Сравнение кириллицы в SQLite без учета регистра

У SQLite есть одна особенность. Сравнение строк без учета регистра, функции изменения регистра работают только для ASCII-символов. Это особенность может принести немало хлопот, если нужно строить запросы с использованием, например, кириллицы.

Например, если в колонке str сохранены значения “VaLuE”, “value”, то запрос SELECT * FROM tab WHERE str LIKE “value” вернет две строки. LIKE по-умолчанию не чувствителен к регистру. Если в базе данных сохранены значения “ЗнАчЕнИе” и “значение”, то такой же запрос вернет только одну строку.

Для решения подобных задач SQLite предоставляет механизм переопределения встроенных функций и правил сравнения в пользовательском коде. Ниже пример кода на Python, который выполняет переопределение:

среда, 20 октября 2010 г.

Изменился формат вывода bytea в PostgreSQL 9.0

После перехода на PostgreSQL 9, в одном из приложений, в разработке которого я учавствую, начала возникать ошибка при получении и десериализации данных, которые хранятся в базе данных в поле типа byte. В приложении используется библиотека Npgsql.

Причиной возникновения ошибки стало изменение формата вывода данных типа bytea. До версии PostgreSQL 9 форматом вывода по умолчанию был escape. Начиная с версии PostgreSQL 9 форматом вывода по умолчанию стал hex. Библиотека Npgsql этих изменений еще не учитывает.

Я нашел два способа решения этой проблемы. Первый, это изменение параметра bytea_output в конфигурационном файле postgresql.conf. Нужно убрать комментарий и установить значение escape. Второй способ, это в клиентском коде преобразовать массив из hex-формата в обычный массив байт. Что из себя представляет hex-формат можно прочитать здесь. Вот быстро набросанный код, который получает исходный массив байт:


  1. using (var reader = command.ExecuteReader())
  2. {
  3.   reader.Read();
  4.   data2 = (byte[])reader[0];
  5.  
  6.   byte[] data3 = new byte[(data2.Length - 1) / 2];
  7.   for (int i = 0; i < data3.Length; ++i)
  8.   {
  9.     var hi = byte.Parse(((char)data2[(i + 1) * 2 - 1]).ToString(), NumberStyles.AllowHexSpecifier);
  10.     var lo = byte.Parse(((char)data2[(i + 1) * 2]).ToString(), NumberStyles.AllowHexSpecifier);
  11.     data3[i] = (byte)((hi << 4) | (lo & 0x0F));
  12.   }
  13. }

Скорее всего есть более цивилизованные способы, но я их пока не нашел. :)

понедельник, 4 октября 2010 г.

Ресурс с статьями и примерами исходных кодов

На stackoverflow.com нашел ссылку на интересный ресурс Programming tutorials and source code examples. Наверное, у каждого программиста есть набор собственных шаблонов, готовых решений. На java2s.com собрано большое количество примеров на разных языках программирования. Начиная c примеров работы с памятью в C и заканчивая шаблонами HTML+CSS.