RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.

SQLite C Interface

Online Backup API

sqlite3_backup *sqlite3_backup_init(
  sqlite3 *pDest,                        /* Destination database handle */
  const char *zDestName,                 /* Destination database name */
  sqlite3 *pSource,                      /* Source database handle */
  const char *zSourceName                /* Source database name */
);
int sqlite3_backup_step(sqlite3_backup *p, int nPage);
int sqlite3_backup_finish(sqlite3_backup *p);
int sqlite3_backup_remaining(sqlite3_backup *p);
int sqlite3_backup_pagecount(sqlite3_backup *p);

Резервный API копирует содержание одной базы данных в другую. Это полезно для создания резервных копий баз данных или для копирования баз данных в памяти к или от постоянных файлов.

SQLite считает транзакцию записи открытой на файле целевой базы данных на время операции резервного копирования. Исходная база данных блокируется только на чтение в то время, как она читается, это не блокируется непрерывно для всей операции резервного копирования. Таким образом резервная копия может быть выполнена на живой исходной базе данных, не препятствуя тому, чтобы другие соединения с базой данных читали или писали исходную базу данных, в то время как резервная копия идет полным ходом.

Выполнить операцию резервного копирования:

  1. sqlite3_backup_init() вызывают однажды, чтобы инициализировать резервную копию,
  2. sqlite3_backup_step() вызывают один или несколько раз, чтобы передать данные между этими двумя базами данных и наконец
  3. sqlite3_backup_finish() вызывают, чтобы высвободить все ресурсы, связанные с операцией резервного копирования.
Должен быть точно один запрос sqlite3_backup_finish() для каждого успешного вызова sqlite3_backup_init().

sqlite3_backup_init()

Параметры D и N для sqlite3_backup_init(D,N,S,M) это соединения с базой данных, связанные с целевой базой данных и именем базы данных, соответственно. Имя базы данных "main" для главной базы данных, "temp" для временной базы данных или имени, определенного после ключевого слова AS в ATTACH для добавленной базы данных. Аргументы S и M, переданные sqlite3_backup_init(D,N,S,M), определяют соединение с базой данных и имя базы данных исходной базы данных, соответственно. Источник и целевая база данных (параметры S и D) должны отличаться, иначе sqlite3_backup_init(D,N,S,M) потерпит неудачу с ошибкой.

Вызов sqlite3_backup_init() потерпит неудачу, возвращая NULL, если уже будет транзакция чтения или чтения-записи, открытая на целевой базе данных.

Если ошибка происходит в sqlite3_backup_init(D,N,S,M), NULL вернется, код ошибки и сообщение об ошибке сохранены в связи целевой базы данных D. Код ошибки и сообщение для неудавшегося вызова sqlite3_backup_init() можно получить через sqlite3_errcode(), sqlite3_errmsg() и/или sqlite3_errmsg16(). Успешный вызов sqlite3_backup_init() возвращает указатель на объект sqlite3_backup. Объект sqlite3_backup может использоваться с sqlite3_backup_step() и sqlite3_backup_finish(), чтобы выполнить указанную операцию резервного копирования.

sqlite3_backup_step()

Функция sqlite3_backup_step(B,N) скопирует до N страниц между источником и целевой базой данных, определенных объектом sqlite3_backup B. Если N отрицателен, все остающиеся исходные страницы копируются. Если sqlite3_backup_step(B,N) успешно копирует N страниц и есть еще больше страниц, которые будут скопированы, то функция возвращает SQLITE_OK. Если sqlite3_backup_step(B,N) успешно заканчивает копировать все страницы от источника до места назначения, то это возвращает SQLITE_DONE. Если ошибка происходит, выполняя sqlite3_backup_step(B,N), код ошибки возвращен. А также SQLITE_OK и SQLITE_DONE, вызывая sqlite3_backup_step(), могут вернуть расширенный код ошибки SQLITE_READONLY, SQLITE_NOMEM, SQLITE_BUSY, SQLITE_LOCKED или SQLITE_IOERR_XXX.

sqlite3_backup_step() может вернуть SQLITE_READONLY если:

  1. целевая база данных была открыта только для чтения,
  2. целевая база данных использует журнал с упреждающей записью и размеры страниц в исходной и результирующей БД отличаются,
  3. целевая база данных это база данных в памяти и размеры страниц в исходной и результирующей БД отличаются.

Если sqlite3_backup_step() не может получить необходимую блокировку файловой системы, то занятая функция-обработчик вызвана (если вы ее определяете). Если занятый обработчик возвращает отличное от 0 значение, прежде чем блокировка будет доступна, то вызывающий получит SQLITE_BUSY. В этом случае запрос sqlite3_backup_step() может быть повторен позже. Если исходное соединение с базой данных используется, чтобы писать исходную базу данных, когда sqlite3_backup_step() вызван, SQLITE_LOCKED немедленно возвращен. Снова, в этом случае запрос sqlite3_backup_step() может быть повторен позже. Если возвращено SQLITE_IOERR_XXX, SQLITE_NOMEM, SQLITE_READONLY, то нет никакого смысла в повторении sqlite3_backup_step(). Эти ошибки считают фатальными. Применение должно признать, что операция резервного копирования не удалась и передает обработчик операции резервного копирования sqlite3_backup_finish(), чтобы высвободить связанные ресурсы.

Первый вызов sqlite3_backup_step() получает монопольную блокировку на файле назначения. Монопольная блокировка не снята до любого вызова sqlite3_backup_finish() или завершения операции резервного копирования (sqlite3_backup_step() вернул SQLITE_DONE). Каждый запрос sqlite3_backup_step() получает коллективную блокировку на исходной базе данных, которая продолжается в период запроса sqlite3_backup_step(). Поскольку исходная база данных не блокирована между вызовами sqlite3_backup_step(), она может быть изменена на полпути процесса резервного копирования. Если исходная база данных будет изменена внешним процессом или через соединение с базой данных кроме того, используемого операцией резервного копирования, то резервная копия будет автоматически перезапущена следующим запросом sqlite3_backup_step(). Если исходная база данных изменяется с использованием того же самого соединения с базой данных, которое используется операцией резервного копирования, то резервная база данных автоматически обновляется в то же время.

sqlite3_backup_finish()

Когда sqlite3_backup_step() вернет SQLITE_DONE приложение хочет остановить операцию резервного копирования, приложение должно разрушить sqlite3_backup передав его sqlite3_backup_finish(). Интерфейс sqlite3_backup_finish() высвобождает все ресурсы, связанные с объектом sqlite3_backup. Если sqlite3_backup_step() еще не возвратил SQLITE_DONE, любая активная транзакция записи на целевой базе данных отменена. Объект sqlite3_backup некорректен и не может использоваться после sqlite3_backup_finish().

Значение, возвращенное sqlite3_backup_finish, это SQLITE_OK если ошибки произошли, независимо от того, закончил ли sqlite3_backup_step(). Если сбой памяти или ошибка IO произошли во время какого-либо предшествующего sqlite3_backup_step(), обращаясь к тому же самому объекту sqlite3_backup, то sqlite3_backup_finish() возвращает соответствующий код ошибки.

Возврат SQLITE_BUSY или SQLITE_LOCKED из sqlite3_backup_step() не является систематической ошибкой и не затрагивает возвращаемое значение sqlite3_backup_finish().

sqlite3_backup_remaining() и sqlite3_backup_pagecount()

sqlite3_backup_remaining() возвращает число страниц, которые надо скопировать в конце нового sqlite3_backup_step(). sqlite3_backup_pagecount() возвращает общее количество страниц в исходной базе данных в конце нового sqlite3_backup_step(). Значения, возвращенные этими функциями, обновляются только sqlite3_backup_step(). Если исходная база данных изменяется способом, который изменяет размер исходной базы данных или число остающихся страниц, те изменения не отражены в выводе sqlite3_backup_pagecount() и sqlite3_backup_remaining() до окончания следующего sqlite3_backup_step().

Параллельное использование обработчиков базы данных

Исходное соединение с базой данных может использоваться на другие цели, в то время как операция резервного копирования идет полным ходом. Если SQLite собирается и формируется, чтобы поддержать ориентированные на многопоточное исполнение соединения с базой данных, то исходное соединение с базой данных может использоваться одновременно из других потоков.

Однако, приложение должно гарантировать, что связь целевой базы данных не передается ни к какому другому API (любым потоком) после того, как вызван sqlite3_backup_init() и перед соответствующим запросом sqlite3_backup_finish(). SQLite в настоящее время не проверяет, получает ли приложение неправильно доступ к к связи целевой базы данных и таким образом, ни о каком коде ошибки не сообщают, но операции могут работать со сбоями, тем не менее. Использование связи целевой базы данных, в то время как резервная копия происходит, могло бы также вызвать мертвую блокировку mutex.

Работая в общем режиме кэширования, надо гарантировать, что к общему кэшу, используемому целевой базой данных, не получают доступ, в то время как резервная копия работает. На практике это означает, что приложение должно гарантировать, что к резервируемому дисковому файлу не получает доступ никакая связь в рамках процесса, не только определенная связь, которая была передана sqlite3_backup_init().

Объект sqlite3_backup частично ориентирован на многопоточное исполнение. Многократные потока могут безопасно сделать многократные параллельные вызовы sqlite3_backup_step(). Однако, sqlite3_backup_remaining() и sqlite3_backup_pagecount() API не строго ориентированы на многопоточное исполнение. Если они вызваны в то же время, что и другой поток вызвал sqlite3_backup_step(), возможно, что они возвращают недействительные значения.