Android: SQLite один-ко-многим дизайн

envsubst - отличное решение (см. ответ LenW), если содержимое, которое вы заменяете, имеет «разумную» длину.

В моем случае мне нужно было заменить содержимое файла, чтобы заменить имя переменной. envsubst требует, чтобы содержимое экспортировалось как переменные среды, а bash - при экспорте переменных окружения размером более мегабайта.

awk solution

Использование cuonglm's solution из другого вопроса:

needle="doc1_base64" # The "variable name" in the file. (A $ is not needed.)
needle_file="doc1_base64.txt" # Will be substituted for the needle 
haystack=$requestfile1 # File containing the needle
out=$requestfile2
awk "BEGIN{getline l < \"${needle_file}\"}/${needle}/{gsub(\"${needle}\",l)}1" $haystack > $out

Это решение работает даже для больших файлов.

11
задан Bostone 5 February 2010 в 06:01
поделиться

2 ответа

Я думаю, вы смотрите не на ту сторону отношений «один ко многим».

Взгляните, например, на поставщика контента ContactsContract . У контактов может быть много адресов электронной почты, много номеров телефонов и т. Д. Это достигается путем вставки / обновления / удаления на стороне "многие" . Чтобы добавить новый номер телефона, вы вставляете новый номер телефона, предоставляя идентификатор контакта, которому этот номер телефона принадлежит.

Вы бы поступили так же, если бы у вас была простая база данных SQLite без поставщика контента. Отношения «один ко многим» в реляционных базах данных достигаются посредством вставок / обновлений / удалений в таблице для стороны «многие», каждая из которых имеет внешний ключ обратно на сторону «один».

С точки зрения объектно-ориентированного подхода это не идеально. Вы можете создавать объекты-оболочки в стиле ORM (подумайте о Hibernate), которые позволяют управлять коллекцией дочерних элементов с «одной» стороны. Достаточно интеллектуальный класс коллекции может затем развернуться и синхронизировать таблицу "многие" для соответствия. Однако их не обязательно реализовать должным образом.

6
ответ дан 3 December 2019 в 08:04
поделиться

Итак, я собираюсь ответить на свой собственный вопрос. Я был на правильном пути с двумя столами и двумя модельными объектами. Чего мне не хватало и что меня сбивало с толку, так это того, что я хотел напрямую вставить сложные данные через ContentProvider#insert в один вызов. Это неправильно. ContentProvider должен создавать и поддерживать эти две таблицы, но решение о том, какую таблицу использовать, должно быть продиктовано параметром Uri ContentProvider#insert. Очень удобно использовать ContentResolver и добавлять методы типа "addFoo" в объект модели. Такой метод возьмет параметр ContentResolver и в конце приведем последовательность вставки сложной записи:

  1. Вставить родительскую запись через ContentProvider#insert и получить идентификатор записи
  2. На каждого дочернего элемента предоставить идентификатор родителя (foregn key) и использовать ContentProvider#insert с разными Uri для вставки дочерних записей

Так что единственный оставшийся вопрос - как обернуть вышеприведенный код в транзакцию?

.
4
ответ дан 3 December 2019 в 08:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: