![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Относительно недействительного UTF SQLite следует за политикой
Garbage-In, Garbage-Out (GIGO). Если вы вставляете недействительный UTF в
базу данных SQLite, то при попытке запросить те данные, что вы возвращаете,
не могут быть точно теми, что вы вставляете. Если вы вставляете мусор, то вы
не можете жаловаться, что возвращаете мусор. В целях этого обсуждения, "недействительный UTF" может означать
любое из следующих обстоятельств: Недействительные суррогатные пары в UTF-16. Недействительные мультибайтные последовательности в UTF-8. Использование большего количества байтов UTF-8, чем необходимо, чтобы
представлять единственную кодовую точку. Пример: кодируя как двухбайтовая
последовательность 0xc1, 0x01 вместо
просто единственного байта 0x41. Символы NUL (U+0000) включены в последовательности. Недействительные последовательности комбинированных символов. Последовательности байтов UTF-8 или UTF-16, которые кодируют числа,
которые не являются определенными знаками Unicode. Если вы вставляете недействительный UTF в базу данных SQLite, то SQLite не
делает гарантий о том, какой текст вы могли бы возвратить.
Но это обещает, что недействительный UTF никогда не будет вызывать ошибки
памяти (выход за пределы множества, чтение или запись неинициализированной
памяти и т.д.), по крайней мере для встроенной обработки SQLite.
Другими словами, недействительный UTF не заставит SQLite терпеть крах. Это обещание относится только к основным компонентам SQLite, не
обеспеченным применением расширения, конечно. Если приложение добавляет новые
определенные приложением функции SQL, виртуальные таблицы,
последовательности сопоставления или другие расширения, а
база данных содержит недействительный UTF, то недействительный UTF мог бы
быть передан в те расширения.
Если недействительный UTF заставляет одно из тех расширений терпеть крах,
то это проблема с расширением, а не с SQLite. SQLite не пытается провести в жизнь форматирующие правила UTF.
Можно вставить недействительный UTF в поле TEXT, и SQLite
не будет жаловаться на это. Это хранит недействительный TEXT как может.
SQLite видит свою роль в мире как система хранения, а не
проверки текстового формата. SQLite не обещает всегда сохранить недействительный UTF, но
действительно прилагает усилие.
Вообще говоря, если вы вставите недействительный UTF в SQLite, вы вернете ту
же самую последовательность байтов, пока вы не просите, чтобы SQLite
как-то преобразовал текст. Например, если вы вставляете некоторый UTF-16LE с недействительными
суррогатами в столбец TEXT базы данных, у которой есть
PRAGMA encoding=UTF16LE,
тогда более поздний запрос колонки, используя
sqlite3_column_text16(),
вероятно, возвратит тот же самый точный недействительный UTF-16.
Но если вы вставляете то же самое недействительное содержание UTF-16LE в
БД с PRAGMA encoding=UTF8,
содержание должно быть преобразовано в UTF8, когда это сохранено, что может
вызвать необратимые изменения содержания. Или если вы вставляете то же самое
недействительное содержание UTF-16LE в базу данных с
PRAGMA encoding=UTF16LE,
но читаете его используя
sqlite3_column_text(), конвертация UTF16 в UTF8
должна произойти во время считывания, и это преобразование могло бы
ввести необратимые изменения. Или, предположите, что вы делаете все, используя UTF-8 (наиболее
распространенный случай). Недействительный UTF-8 будет обычно проходить через
базу данных без любого изменения в его последовательности байт.
Однако, при попытке преобразовать недействительный UTF-8 функцией SQL вроде
substr() или
replace()
или при попытке сделать проверку соответствия последовательности через
оператор LIKE,
вы могли бы получить неожиданные результаты. Так, другими словами SQLite активно не пытается ниспровергать ваш
недействительный текст. Но когда вы просите, чтобы SQLite сделал
преобразования недействительного UTF, нет никаких гарантий, что те
преобразования будут обратимы или даже разумны. Если схема базы данных будет содержать имена (имена таблиц, столбцов,
индексов и т.д), которые являются недействительным UTF, SQLite продолжит
работать как обычно. С точки зрения SQLite, те имена это
просто последовательности байт.
SQLite не заботится, являются ли они действительным UTF или нет. Производя сообщения об ошибках (используя, например,
sqlite3_errmsg()),
иногда SQLite будет включать части схемы базы данных в сообщение об ошибке.
Если те вложенные элементы схемы недействительный UTF, то получающееся
сообщение об ошибке могло бы также быть недействительным UTF. Точно так же
вывод
PRAGMA integrity_check и подобных запросов
будет иногда включать названия элементов схемы. Если те имена элементов
схемы будут недействительным UTF, то вывод
команды также будет недействительным UTF.
Choose any three.
1. Мусор
1.1.
Недействительный UTF никогда не будет вызывать ошибки памяти
2.
Никакого осуществления правил формата текста
3.
Максимальные усилия сохранить текст
4.
Недействительный UTF в схеме базы данных