Android SQLite вставляет JSON в столбец TEXT с экранированием двойных кавычек
Я использую SQLite в приложении для Android, в котором, помимо прочего, хранится таблица, в которой записывается настроение пользователя. Схема таблицы показана ниже
CREATE TABLE moods
(
dow INTEGER,
tsn INTEGER,
lato INTEGER,
agitation TEXT DEFAULT '{}',
preoccupancy TEXT DEFAULT '{}',
tensity TEXT DEFAULT '{}',
taps TEXT DEFAULT '{}'
);
В отличие, скажем, от Postgres, SQLite не имеет выделенного jsonb
тип хранения. Цитировать
Ограничения обратной совместимости означают, что SQLite может хранить только значения со значениями NULL, целыми числами, числами с плавающей точкой, текстом и BLOB-объектами. Невозможно добавить шестой тип "JSON".
Документация по расширению SQLite JSON1
На процессоре командной строки SQLite я могу заполнить эту таблицу с помощью простого оператора INSERT, такого как этот
INSERT INTO moods (dow,tsn,lato,agitation,preoccupancy,tensity,taps)
VALUES(1,0,20,'{"A2":1}','{"P4":2}','{"T4":3}','{"M10":4}');
так как он принимает одинарные и двойные кавычки для строк.
Чтобы сделать то же самое в моем приложении Hybrid Android, я делаю следующее
String ag = JOString("A" + DBManage.agitation,1);
String po = JOString("P" + (DBManage.preoccupancy + 15),1);
String te = JOString("T" + DBManage.tensity,1);
который возвращает строки, такие как {"P4":2}
и т. д. Мой следующий шаг заключается в следующем
ContentValues cv = new ContentValues();
cv.put("dow",0);
cv.put("tsn",1);
cv.put("lato",2);
cv.put("agitation",ag);
cv.put("preoccupancy",po);
cv.put("tensity",te);
long rowid = db.insert("moods",null,cv);
который работает. Однако, изучив сохраненные значения, я обнаружил, что на самом деле
{"dow":0,"tsn":5,"lato":191,"tensity":"{\"T0\":1}","agitation":"
{\"A1\":1}","preoccupancy":"{\"P15\":1}","taps":"{}"}]
Если я не понимаю что-то здесь ContentValues.put
или SQLiteDatabase.insert
реализация взяла на себя обязательство избегать цитируемых строк. Возможно, этого следовало ожидать, учитывая, что польза от снижения SQLiteDatabase.insert
маршрут с ContentValues
защита от атак SQL-инъекций Однако в данном случае это помеха, а не помощь.
За исключением выполнения необработанного SQL через execSQL
Есть ли другой способ получить JSON в таблицу базы данных SQLite здесь?
Я должен добавить, что простая замена двойных кавычек одинарными кавычками
String ag = JOString("A" + DBManage.agitation,1);
ag = ag.replaceAll("\"","'");
не будет работать после следующей попытки извлечь JSON из таблицы
SELECT ifnull((select json_extract(preoccupancy,'$.P4') from moods where dow = '1' AND tsn = '0'),0);
приведет к ошибке искаженного JSON, испускаемого расширением SQLite JSON1.