envsubst
- отличное решение (см. ответ LenW), если содержимое, которое вы заменяете, имеет «разумную» длину.
В моем случае мне нужно было заменить содержимое файла, чтобы заменить имя переменной. envsubst
требует, чтобы содержимое экспортировалось как переменные среды, а bash - при экспорте переменных окружения размером более мегабайта.
Использование 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
Это решение работает даже для больших файлов.
Я думаю, вы смотрите не на ту сторону отношений «один ко многим».
Взгляните, например, на поставщика контента ContactsContract
. У контактов может быть много адресов электронной почты, много номеров телефонов и т. Д. Это достигается путем вставки / обновления / удаления на стороне "многие" . Чтобы добавить новый номер телефона, вы вставляете новый номер телефона, предоставляя идентификатор контакта, которому этот номер телефона принадлежит.
Вы бы поступили так же, если бы у вас была простая база данных SQLite без поставщика контента. Отношения «один ко многим» в реляционных базах данных достигаются посредством вставок / обновлений / удалений в таблице для стороны «многие», каждая из которых имеет внешний ключ обратно на сторону «один».
С точки зрения объектно-ориентированного подхода это не идеально. Вы можете создавать объекты-оболочки в стиле ORM (подумайте о Hibernate), которые позволяют управлять коллекцией дочерних элементов с «одной» стороны. Достаточно интеллектуальный класс коллекции может затем развернуться и синхронизировать таблицу "многие" для соответствия. Однако их не обязательно реализовать должным образом.
Итак, я собираюсь ответить на свой собственный вопрос. Я был на правильном пути с двумя столами и двумя модельными объектами. Чего мне не хватало и что меня сбивало с толку, так это того, что я хотел напрямую вставить сложные данные через ContentProvider#insert
в один вызов. Это неправильно. ContentProvider
должен создавать и поддерживать эти две таблицы, но решение о том, какую таблицу использовать, должно быть продиктовано параметром Uri ContentProvider#insert
. Очень удобно использовать ContentResolver и добавлять методы типа "addFoo" в объект модели. Такой метод возьмет параметр ContentResolver и в конце приведем последовательность вставки сложной записи:
ContentProvider#insert
и получить идентификатор записиContentProvider#insert
с разными Uri для вставки дочерних записейТак что единственный оставшийся вопрос - как обернуть вышеприведенный код в транзакцию?
.