NSData усекается при хранении в базе данных sqlite - PullRequest
3 голосов
/ 16 марта 2010

Я пытаюсь сохранить NSMutableDictionaries в виде больших двоичных объектов в sqlite, сначала преобразовав их в NSData через NSPropertyListSerialization или NSKeyedArchiver.

Когда я сохраняю блоб, длина объекта NSData указывается в тысячах (диапазон КБ). Когда я получаю его обратно, оно усекается до 10 байтов. Когда я проверяю БД через браузер SQLite, большая часть данных исчезает (я могу распознать ключи в записи, если я сохраню словарь как NSPropertyListSerialization, но значения словаря пропали). Это происходит независимо от того, использую ли я NSPropertyListSerialization или NSKeyedArchiver для сериализации моих данных.

NSMutableDictionary* item = [items objectAtIndex:i];
NSData *dictionary  = [NSKeyedArchiver archivedDataWithRootObject:item];
sqlite3_bind_blob(  compiledStatement, 5, [dictionary bytes], [dictionary length], SQLITE_TRANSIENT);

Это на самом деле фрагмент моего кода, полный раздел которого я разместил в другом связанном вопросе.

Массовые вставки в sqlite db на iphone

Проверка значения [длина словаря] с помощью gdb или NSLog дает тот же результат: длина данных находится в диапазоне КБ.

Когда я проверяю, получить данные позже:

NSData* raw = [[NSData alloc] initWithBytes:sqlite3_column_blob(compiledStatement, 1) length:sqlite3_column_bytes(compiledStatement, 1)];
[raw release];

Проверка [raw length] дает мне всего 10 байтов. Это верно для каждого экземпляра данных, которые я пытался сохранить в этом столбце, независимо от их начального размера, в итоге они заканчиваются 10 байтами. С моим поисковым запросом все в порядке. Я запустил его в командной строке и в браузере SQL и получаю правильные записи и столбцы, но данные, которые были сохранены в записи для этого конкретного столбца, неверны.

Что случилось с остальными моими данными? Что-то не так с тем, как я использую sqlite3_bind_blob? Я проверил документацию sqlite на наличие завершающих символов или ограничений максимального размера. Мои данные находятся в пределах максимального размера записи большого двоичного объекта, и я не могу найти информацию о терминалах, которые могли бы сократить мои данные до размера.

Ответы [ 2 ]

2 голосов
/ 16 марта 2010

Вы проверили тип возврата этой привязки? Возможно, он вернет код ошибки (оператор все еще будет выполняться, возможно, в этом случае, просто неправильно).

В качестве обходного пути пытались ли вы создать ZEROBLOB и затем выполнить запись в него с помощью процедур ввода-вывода BLOB, описанных в документации SQLite ? Это будет следующее, что я попробую, посмотрев на коды ошибок.

0 голосов
/ 16 марта 2010

Я нашел преступника в этой дикой доброй погоне ... Я взял значение столбца 1 вместо столбца 0, который был фактическим столбцом, который содержал мои данные. Я предположил, что, поскольку привязка значений к вашему запросу начинается со столбца 1, извлечение столбцов из результатов запроса также начнется с 1. Моя ошибка.

10 байтов в строке на самом деле были НЕ моими словарными данными, а отметкой времени, которую я использовал для сортировки результатов.

...