![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Эта страница определяет интерфейс языка C к SQLite
расширению session.
Это не обучающая программа. Эти страницы разработаны, чтобы быть точными.
Обучающая программа доступна здесь.
Эта страница содержит всю информацию об интерфейсе языка C в единственном
файле HTML. Та же самая информация также доступна
маленькими порциями
для более легкого просмотра Этот документ создается скриптом, который сканирует комментарии в файле
исходного кода sqlite3session.h. Следующие флаги могут быть переднаы через 4-й параметр
sqlite3changeset_start_v2 и
sqlite3changeset_start_v2_strm: changegroup это объект, используемый, чтобы объединить два или больше
changesets или
patchsets. Конструктор: sqlite3changegroup_new() Деструктор:
sqlite3changegroup_delete() Методы: sqlite3changegroup_add(),
sqlite3changegroup_output() Экземпляр этого объекта действует как курсор для повторения по элементам
changeset или
patchset. Конструкторы:
sqlite3changeset_start(),
sqlite3changeset_start_v2() Важно: Этот интерфейс
экспериментален и подлежит изменению без уведомления.
Предположим, что есть место, принимающее базу данных в состоянии S0.
Модификации сделаны, база данных перешла в состояние S1 и зарегистрирован
changeset ("local" changeset). Затем changeset на основе S0 получается от
другого места ("remote" changeset) и применяется
к базе данных. База данных находится тогда в состоянии (S1+"remote"),
где точное состояние зависит от любых решений разрешения конфликтов
(OMIT или REPLACE) сделанных, применяя "remote".
Перебазирование changeset должно обновить его, чтобы принять те решения
разрешения конфликтов во внимание, так, чтобы те же самые конфликты не были
решены в другом месте в сети. Например, если местные и отдаленные changesets содержат INSERT того же
самого ключа на "CREATE TABLE t1(a PRIMARY KEY, b)": local: INSERT INTO t1 VALUES(1, 'v1');
remote: INSERT INTO t1 VALUES(1, 'v2'); и разрешение конфликтов REPLACE, тогда изменение INSERT удалено из
местного changeset (это было отвергнуто). Или, если разрешением конфликтов
был "OMIT", то местный changeset изменяется, чтобы вместо этого содержать: UPDATE t1 SET b = 'v2' WHERE a=1; Изменения в местном changeset перебазируются следующим образом: Если конфликт с удаленным обновлением, и резолюция OMIT, значения
old.* перебазирующиеся, используя значения new.* в удаленном изменении.
Или, если резолюция REPLACE, то изменение копируется в перебазированный
changeset с обновлениями колонок, также обновленных противоречивым удаленным
UPDATE. Если это означает, что никакие колонки не были бы
обновлены, изменение пропущено. Местное изменение может быть перебазирующимся против многократных
отдаленных изменений одновременно. Если единственный ключ изменяется
многократным отдаленным changeset, они объединены следующим образом, прежде
чем местный changeset перебазируется: Обратите внимание на то, что разрешения конфликтов от многократного
отдаленного changeset объединены на основе поля, а не строки.
Это означает, что в случае многократных операций по удаленному обновлению,
некоторые области единственного местного изменения могут быть
перебазирующимися для REPLACE, в то время как другие
перебазирующиеся для OMIT. Чтобы повторно основывать местный changeset, отдаленный changeset должен
сначала быть применен к локальной базе данных, используя
sqlite3changeset_apply_v2() и буфер захваченной информации. Тогда: Экземпляр этого объекта это session,
который может использоваться, чтобы сделать запись изменений базы данных. Конструктор: sqlite3session_create() Деструктор: sqlite3session_delete() Добавьте все изменения в changeset (или patchset) в буфере pData
(размеом nData байт) к changegroup. Если буфер содержит patchset, то все предшествующие обращения
к этой функции на том же самом объекте changegroup, должно быть, также
определили patchsets. Или, если буфер содержит changeset, должны быть
более ранние обращения к этой функции. Иначе SQLITE_ERROR возвращен, и
никакие изменения не добавляются к changegroup. Строки в changeset и changegroup определяются значениями в их колонках
PRIMARY KEY. Изменение в changeset, как полагают, относится к той же самой
строке, как изменение, уже существующее в changegroup, если у этих двух
строк есть тот же самый первичный ключ. Изменения строк, которые уже не появляются в changegroup, просто
копируются в него. Или, если новый changeset и changegroup содержат
изменения, которые относятся к единственной строке, заключительное содержание
changegroup зависит от типа каждого изменения, следующим образом: Если новый changeset содержит изменения, которые уже присутствуют в
changegroup, то количество колонок и положение колонок первичного ключа для
таблицы должны быть последовательными. Если дело обстоит не так, эта функция
терпит неудачу с SQLITE_SCHEMA. Кроме того, если объект changegroup
формировался со схемой базы данных, используя
sqlite3changegroup_schema() API, возможно объединить changeset с различными
числами колонок для единственной таблицы
при условии, что они в других отношениях совместимы. Во всех случаях, если ошибка происходит, статус
заключительного содержания changegroup не определен.
Если никакая ошибка не происходит, SQLITE_OK возвращен. Если вход changeset, кажется, поврежден, SQLITE_CORRUPT возвращен. Или,
если переполнение памяти происходит во время обработки, эта функция
возвращает SQLITE_NOMEM. Объект sqlite3_changegroup используется, чтобы объединить два или больше
changeset (или patchset) в единственный changeset (или patchset).
Единственный объект changegroup может объединить changeset или patchset,
но не обоих. Вывод всегда находится в том же самом формате как вход. Если успешно, эта функция возвращает SQLITE_OK и наполняет (*pp)
с указателем на новый объект sqlite3_changegroup перед возвращением.
Вызывающий должен в конечном счете освободить возвращенный объект, используя
sqlite3changegroup_delete(). Если ошибка происходит, код ошибки SQLite (то
есть, SQLITE_NOMEM) возвращен и *pp = NULL. Обычный образец использования для объекта
sqlite3_changegroup следующий: Любое количество add() и output() может быть сделано между обращениями к
new() и delete() в любом порядке. А также регулярные функции sqlite3changegroup_add() и
sqlite3changegroup_output() являются текущими версиями
sqlite3changegroup_add_strm() и sqlite3changegroup_output_strm(). Получите буфер, содержащий changeset (или patchset), представляющий
текущее содержание changegroup. Если входы к changegroup были самостоятельно
changeset, вывод это changeset. Или, если входы были patchsets, выводом будет
также patchset. Как с выводом sqlite3session_changeset() и
sqlite3session_patchset(), все изменения, связанные с единственной таблицей,
группируются в выводе этой функции. Таблицы появляются в том же самом
порядке, как у самого первого changeset, добавленного к changegroup.
Если вторые или последующие changeset, добавленные к changegroup, содержат
изменения для таблиц, которые не появляются в первом changeset, они приложены
в конце вывода changeset, снова в порядке,
в котором с ними сначала сталкиваются. Если ошибка происходит, код ошибки SQLite возвращен, и выходные переменные
(*pnData) и (*ppData) установлены в 0. Иначе SQLITE_OK возвращен, и выходные
переменные установлены в размер и указатель на буфер вывода,
соответственно. В этом случае ответственность вызвавшего
освободить буфер, используя sqlite3_free(). Этот метод может использоваться, чтобы произвольно провести в жизнь
правило, что changeset, добавленный к дескриптору changegroup, должен
соответствовать схеме базы данных zDb
("main", "temp" или название приложенной базы данных). Если вызывают
sqlite3changegroup_add(), чтобы добавить changeset, который несовместим с
формируемой схемой, SQLITE_SCHEMA возвращен, и объект changegroup
оставляют в неопределенном состоянии. changeset схему считают совместимой со схемой базы данных таким же
образом, что касается sqlite3changeset_apply().
Определенно, для каждой таблицы в changeset
там существует таблица базы данных с: У вывода объекта changegroup всегда есть та же самая схема, как у базы
данных при использовании этой функции.
В случаях, где у changeset, переданных к sqlite3changegroup_add(), есть
меньше колонок, чем у соответствующей таблицы в схеме базы данных, они
заполнены с использованием значений столбцов по умолчанию из схемы базы
данных. Это позволяет объединение changeset, у которых есть различные числа
колонок для единственной таблицы в changegroup, при условии, что они в
других отношениях совместимы. Эта функция используется, чтобы связать два changeset A и B
в единственный changeset. Результат это changeset, эквивалентный применению
changeset A, сопровождаемого changeset B. Эта функция объединяет два входных changeset с использованием объекта
sqlite3_changegroup. Запрос его приводит к подобным результатам как к
следующему кодовому фрагменту: Обратитесь к документации на sqlite3_changegroup ниже для деталей. Эта функция должна использоваться только с объектами iterator, переданными
к отзыву обработчика конфликта
sqlite3changeset_apply() с
SQLITE_CHANGESET_DATA или
SQLITE_CHANGESET_CONFLICT.
Если эта функция вызвана на каком-либо другом iterator,
SQLITE_MISUSE
возвращена и *ppValue установлен в NULL. iVal должен быть больше или равным 0, но меньше, чем количество колонок в
таблице, затронутой текущим изменением. Иначе вернется
SQLITE_RANGE и *ppValue = NULL. Если успешно, эта функция устанавливает указатель *ppValue
на защищенный объект sqlite3_value, содержащий iVal-ое значение
от "противоречивой строки", связанной с текущим отзывом дескриптора
конфликта, и вернет SQLITE_OK. Если некоторая другая ошибка происходит (например, условие OOM), код
ошибки SQLite возвращен, и *ppValue установлен в NULL. Эта функция используется, чтобы завершить iterator, ассигнованный
sqlite3changeset_start(). К этой функции нужно обратиться только в итераторах,
созданных с использованием функции
sqlite3changeset_start().
Если применение вызывает эту функцию с iterator, переданным обработчику
конфликта sqlite3changeset_apply(),
SQLITE_MISUSE
немедленно возвращен, и вызов не имеет никакого эффекта. Если с ошибкой столкнулись в рамках обращения к sqlite3changeset_xxx()
(например, SQLITE_CORRUPT в
sqlite3changeset_next() или
SQLITE_NOMEM в
sqlite3changeset_new()),
код ошибки, соответствующий той ошибке, возвращен этой функцией.
Иначе SQLITE_OK возвращен. Это должно позволить
следующий образец (псевдокод): Эта функция может быть вызвана только с iterator, переданным к отзыву
обработчика конфликта SQLITE_CHANGESET_FOREIGN_KEY. В этом случае это
устанавливает выходную переменную в общее количество известных нарушений
внешнего ключа в целевой базе данных и возвращает SQLITE_OK. Во всех других случаях эта функция возвращает SQLITE_MISUSE. Эта функция используется, чтобы "инвертировать" объект
changeset. Применение перевернутого changeset к базе данных полностью
изменяет эффекты применения неперевернутого changeset. Определенно: Эта функция не изменяет порядок, в котором изменения появляются в
changeset. Это просто полностью изменяет смысл
каждого отдельного изменения. Если успешно, указатель на буфер, содержащий перевернутый changeset,
сохранен в *ppOut, размер того буфера сохранен в *pnOut, и SQLITE_OK
возвращен. Если ошибка происходит, *pnOut и *ppOut обнулены и возвращен
код ошибки SQLite. Обязанность вызвавшего в конечном счете вызвать sqlite3_free() для
указателя *ppOut, чтобы освободить распределение буферов после успешного
вызова этой функции. WARNING/TODO: Эта функция в настоящее время предполагает, что вход
это действительный changeset. Если это не так, результаты не определены. pIter аргументом, переданным к этой функции, может быть iterator,
переданный обработчику конфликта
sqlite3changeset_apply(), или итератор, созданный
sqlite3changeset_start().
В последнем случае новое обращение к
sqlite3changeset_next()
должно быть, возвратило SQLITE_ROW. Кроме того, это можно вызвать только
если тип изменения, на которое в настоящее время указывает iterator, является
SQLITE_UPDATE или
SQLITE_INSERT.
Иначе эта функция возвращает
SQLITE_MISUSE и *ppValue = NULL. Аргумент iVal должен быть больше или равным 0, но
меньше, чем количество колонок в таблице,
затронутой текущим изменением. Иначе
SQLITE_RANGE
возвращен, и *ppValue установлен в NULL. Если успешно, эта функция устанавливает указатель *ppValue
на защищенный объект sqlite3_value, содержащий значение iVal от вектора новых
значений строки, сохраненных как часть изменения UPDATE или INSERT и
вернет SQLITE_OK. Если изменение UPDATE и не включает новое значение
для требуемой колонки, *ppValue установлен в NULL и возвращен
SQLITE_OK. Название функции происходит от того, что это подобно
колонке "new.*", доступной, чтобы обновить или удалить триггеры. Если некоторая другая ошибка происходит (например, условие OOM), код
ошибки SQLite возвращен, и *ppValue установлен в NULL. Эта функция может использоваться только с итератором, созданным функцией
sqlite3changeset_start().
Если это вызывают на iterator, переданном к отзыву дескриптора
конфликта
sqlite3changeset_apply(), SQLITE_MISUSE
SQLITE_MISUSE возвращен, и вызов не имеет никакого эффекта. Немедленно после того, как iterator создается sqlite3changeset_start(),
это не указывает ни на какое изменение в changeset. Считая changeset не
пустым, первое обращение к этой функции продвигает iterator, чтобы указать на
первое изменение в changeset. Каждое последующее обращение продвигает
iterator, чтобы указать на следующее изменение в changeset (если таковые
имеются). Если никакая ошибка не происходит, и iterator указывает на
действительное изменение после того, как обращение к
sqlite3changeset_next() продвинуло его, SQLITE_ROW возвращен. Иначе, если все
изменения в changeset уже отработаны, SQLITE_DONE возвращен. Если ошибка происходит, код ошибки SQLite возвращен. Возможные коды ошибок
включают SQLITE_CORRUPT (если буфер changeset поврежден) или
SQLITE_NOMEM. Аргументом pIter, переданным к этой функции, может быть iterator,
переданный обработчику конфликта
sqlite3changeset_apply(), или iterator, созданный
sqlite3changeset_start().
В последнем случае новое обращение к
sqlite3changeset_next()
должно возвратить SQLITE_ROW. Кроме того, это можно вызвать только, если тип
изменения, на которое в настоящее время указывает iterator, является
SQLITE_DELETE или
SQLITE_UPDATE. Иначе эта функция
возвращает SQLITE_MISUSE и ставит
*ppValue = NULL. iVal должен быть больше или равным 0, но меньше, чем количество колонок в
таблице, затронутой текущим изменением. Иначе возвращен
SQLITE_RANGE и *ppValue = NULL. Если успешно, эта функция устанавливает указатель *ppValue
на защищенный объект sqlite3_value, содержащий значение iVal
от вектора первоначальных значений строки, сохраненных как часть изменения
UPDATE или DELETE и вернет SQLITE_OK.
Название функции происходит от того, что это подобно столбцам "old.*",
доступным, чтобы обновить или удалить триггеры Если некоторая другая ошибка происходит (например, условие OOM), код
ошибки SQLite возвращен, и *ppValue установлен в NULL. Аргументом pIter, переданным к этой функции, может быть iterator,
переданный обработчику конфликта
sqlite3changeset_apply(), или итератор, созданный
sqlite3changeset_start().
В последнем случае новое обращение к
sqlite3changeset_next()
должно вернуть SQLITE_ROW.
Если дело обстоит не так, эта функция возвращает
SQLITE_MISUSE. Аргументы pOp, pnCol и pzTab не могут быть NULL.
По возвращению три вывода установлены через эти указатели: *pOp установлен в один из
SQLITE_INSERT, SQLITE_DELETE или
SQLITE_UPDATE,
в зависимости от типа изменения, на которое в настоящее
время указывает iterator. *pnCol установлен в количество колонок в
таблице, затронутых изменением *pzTab указывает на nul-законченную utf-8 последовательность, содержащую
название таблицы, затронутой текущим изменением. Буфер остается
действительным до вызова sqlite3changeset_next()
на iterator или до возврата функции-обработчика конфликта. Если pbIndirect не NULL, *pbIndirect = true (1),
если изменение косвенное, или в false (0) иначе. См. документацию для
sqlite3session_indirect()
для описания прямых и косвенных изменений. Если никакая ошибка не происходит, SQLITE_OK возвращен.
Если ошибка происходит, код ошибки SQLite возвращен.
Значениям выходных переменных нельзя доверять в этом случае. Для каждой измененной таблицы changeset включает следующее: Эта функция используется, чтобы найти, какие колонки включают PRIMARY KEY
таблицы, измененной тем изменением, на которое в настоящее время указывает
iterator pIter. Если успешно, *pabPK укажет на множество записей nCol, где
nCol это количество колонок в таблице. Элементы *pabPK установлены в 0x01,
если соответствующая колонка это часть первичного ключа
таблицы, иначе в 0x00. Если pnCol не NULL, *pnCol установлен в количество колонок в таблице. Если эта функция вызвана, когда iterator не указывает на действительный
доступ, SQLITE_MISUSE возвращен, и выходные переменные обнулены.
Иначе SQLITE_OK возвращен, и выходные переменные наполнены,
как описано выше. Важно: Этот интерфейс
экспериментален и подлежит изменению без уведомления. Формируйте объект changeset rebaser,
чтобы повторно основывать changesets согласно разрешениям конфликтов,
описанным буферной предварительной основой (размером nRebase байт),
который был получен от предыдущего вызова
sqlite3changeset_apply_v2(). Важно: Этот интерфейс
экспериментален и подлежит изменению без уведомления. Ассигнуйте новый объект changeset rebaser. Если успешно, установит
(*ppNew), чтобы указать на новый объект и возвратит SQLITE_OK.
Иначе, если ошибка происходит, возвратит код ошибки SQLite (например,
SQLITE_NOMEM) и установит (*ppNew) в NULL. Важно: Этот интерфейс
экспериментален и подлежит изменению без уведомления. Удалите объект changeset rebaser и все связанные ресурсы. Должно быть одно
обращение к этой функции для каждого успешного вызова
sqlite3rebaser_create(). Важно: Этот интерфейс
экспериментален и подлежит изменению без уведомления. Аргумент pIn должен указать на буфер, содержащий байты changeset размером
nIn. Эта функция ассигнует и наполняет буфер копией changeset,
перебазирующегося согласно конфигурации объекта rebaser, переданного как
первый аргумент. Если успешно, (*ppOut) укажет на новый буфер, содержащий
переоснованный changeset, (*pnOut) на его размер в байтах и возвратит
SQLITE_OK. Ответственность вызывающего в конечном счете освободить новый
буфер, используя sqlite3_free().
Иначе, если ошибка происходит, (*ppOut) и (*pnOut) установлены в ноль и
возвращен код ошибки SQLite. Если zTab не NULL, это название таблицы, чтобы присоединить к
объекту сессии, переданному как первый аргумент. Будут зарегистрированы все
последующие изменения, внесенные в таблицу
в то время, как объект сессии позволен. См. документацию для
sqlite3session_changeset(). Если zTab = NULL, изменения зарегистрированы для всех таблиц
в базе данных. Если дополнительные таблицы добавляются к базе данных
(выполняя "CREATE) после того, как этот вызов
сделан, изменения для новых таблиц также зарегистрированы. Изменения могут быть зарегистрированы только для таблиц, которым
определили PRIMARY KEY явно как часть их CREATE TABLE.
Не имеет значения, является ли PRIMARY KEY это "INTEGER PRIMARY KEY"
(псевдоним rowid) или нет. PRIMARY KEY может состоять из отдельного столбца
или может быть составным ключом. Это не ошибка, если названная таблица
не существует в базе данных. И при этом это не ошибка, если у названной
таблицы нет PRIMARY KEY. Однако, никакие изменения не будут зарегистрированы
ни в одном из этих сценариев. Изменения не зарегистрированы для отдельных строк, которым сохранили NULL
в одну или больше их колонок PRIMARY KEY. SQLITE_OK возвращен, если обращение заканчивается без ошибки.
Если ошибка происходит, код ошибки SQLite (например,
SQLITE_NOMEM) возвращен. С SQLite version 3.22.0 таблица "sqlite_stat1" это исключение
из правил выше. В SQLite схема sqlite_stat1:
Даже при том, что у sqlite_stat1 нет PRIMARY KEY, изменения
зарегистрированы, как будто PRIMARY KEY это (tbl,idx).
Кроме того, изменения зарегистрированы для строк, для которых (idx IS NULL)
верно. Однако, для таких строк blob нулевой длины (SQL value X'')
сохранен в changeset или patchset вместо NULL.
Это позволяет такому changesets управляться устаревшими внедрениями
sqlite3changeset_invert(), concat() и подобными. Функция sqlite3changeset_apply() автоматически преобразовывает
blob нулевой длины назад в NULL, обновляя таблицу sqlite_stat1.
Однако, если применение вызывает sqlite3changeset_new(),
sqlite3changeset_old() или sqlite3changeset_conflict на итераторе changeset
непосредственно (включая передачу changeset iterator отзыву обработчика
конфликта), тогда возвращено значение X''.
Применение должно перевести X'' к NULL при необходимости. Старые (до 3.22.0) версии модуля сессий не могут захватить изменения,
внесенные в таблицу sqlite_stat1. Старые версии функции
sqlite3changeset_apply() тихо игнорируют любые модификации таблицы
sqlite_stat1, которые являются частью changeset или patchset. Получите changeset, содержащий изменения таблиц, приложенных к объекту
сессии, переданному как первый аргумент. Если успешно, установит
*ppChangeset, чтобы указать на буфер, содержащий changeset, а *pnChangeset
к размеру changeset в байтах прежде, чем возвратить SQLITE_OK.
Если ошибка происходит, установит *ppChangeset и *pnChangeset в 0
и возвращает код ошибки SQLite. changeset состоит из ноля или большего количества изменений INSERT,
UPDATE и/или DELETE, каждый представляющий изменение единственной строки
приложенной таблицы. Изменение INSERT содержит значения каждой области новой
строки базы данных. DELETE содержит исходные значения каждой области
удаленной строки базы данных. Изменение UPDATE содержит исходные значения
каждой области обновленной строки базы данных
с обновленными значениями для каждой обновленной колонки непервичного ключа.
Для изменения UPDATE невозможно представлять изменение, которое изменяет
значения колонок первичного ключа. Если такое изменение внесено, оно
представляется в changeset как DELETE, сопровождаемый INSERT. Изменения не зарегистрированы для строк, которым сохранили NULL
в одну или больше их колонок PRIMARY KEY. Если такая строка
вставлена или удалена, никакое соответствующее изменение не присутствует в
changeset, возвращенном этой функцией. Если существующая строка
с одним или более NULL, сохраненными в колонках PRIMARY KEY, обновляется так,
чтобы всеми колонками PRIMARY KEY был не-NULL, только INSERT, появляется в
changeset. Точно так же, если существующая строка со значениями не-NULL,
PRIMARY KEY, обновляется так, чтобы одна или больше колонок PRIMARY KEY были
установлены в NULL, получающийся changeset содержит
только изменение DELETE. Содержание changeset может быть пересечено, используя iterator, созданный
использованием sqlite3changeset_start()
API. changeset может быть применен к базе данных с совместимой схемой,
используя sqlite3changeset_apply()
API. В changeset, произведенном этой функцией, группируются все изменения,
связанные с единственной таблицей. Другими словами, повторяя через changeset
или применяя changeset к базе данных, все изменения, связанные с единственной
таблицей, обрабатываются перед прохождением дальше к следующей таблице.
Таблицы приведены в порядок в том же самом порядке, в котором они были
приложены к объекту. Порядок, в котором, сохранены изменения, связанные с
единственной таблицей, не определен. После успешного вызова этой функции, ответственность вызывающего
в конечном счете освобождить буфер, который указывает на *ppChangeset,
использованием sqlite3_free(). Как только таблица добавлена к объекту сессии, объект сессии пишет
значения первичного ключа всех новых строк, вставленных в таблицу.
Это также делает запись оригинального первичного ключа и других значений
столбцов любых удаленных или обновленных строк. Для каждого уникального
значения первичного ключа данные зарегистрированы только однажды,
в первый раз, когда строка с первичным ключом вставлена, обновлена или
удалена в жизни сессии. Есть одно исключение к предыдущему параграфу: когда строка
вставляется, обновляется или удаляется, если одна или больше его колонок
первичного ключа содержат NULL, никакой отчет изменения не сделан. Объект сессии поэтому накапливает два типа отчетов:
которые состоят только из значений первичного ключа (созданы, когда
пользователь вставляет новую запись) и те, которые состоят из
значений первичного ключа и исходных значений других столбцов таблицы
(созданы, когда пользователи удаляют или обновляют записи). Когда эта функция вызвана, требуемый changeset создается, используя
накопленные отчеты и текущее содержание файла базы данных. Определенно: Это означает среди других вещей, что, если строка
вставлена и затем позже удалена,
в то время как объект сессии активен, ни вставка, ни удаление не будут
присутствовать в changeset. Или если строка будет удален и затем позже
строка с теми же самыми значениями первичного ключа вставлена в то время,
как объект сессии активен, получающийся changeset будет содержать изменение
UPDATE вместо DELETE и INSERT. Когда объект сессии отключен (см.
sqlite3session_enable() API),
это не накапливает отчеты, когда строки
вставлены, обновлены или удалены. Это, может казаться, имеет некоторые
парадоксальные эффекты, если единственная строка
написана несколько раз во время сессии. Например, если она будет вставлена в
то время, как объект сессии позволен, затем позже удалена в то время, как тот
же самый объект сессии отключен, никакой отчет INSERT не появится в
changeset, даже при том, что удаление произошло в то время, как сессия была
отключена. Или если одна область строки будет обновлена в то время, как
сессия отключена, а другая область той же самой строки обновляется в то
время, как сессия позволена, получающийся changeset будет содержать изменение
UPDATE, которое обновляет обе области. По умолчанию эта функция всегда возвращает 0.
Чтобы возвратить полезный результат, объект sqlite3_session должен быть
настроен, чтобы позволить этот API, используя sqlite3session_object_config()
с SQLITE_SESSION_OBJCONFIG_SIZE. Когда позволено, эта функция возвращает верхний предел, в байтах, для
размера changeset, который мог бы быть произведен, если бы вызвали
sqlite3session_changeset(). Финальный размер changeset мог бы быть равным или
меньшим, чем размер в байтах, возвращенных этой функцией. sqlite3session_config() используется, чтобы сделать глобальные изменения
конфигурации модуля сессий, чтобы настроить его на
определенные потребности применения. sqlite3session_config() не ориентирован на многопотоковое исполнение.
Если это вызвано в то время, как любой другой поток работает
в любом другом методе сессий, результаты не определены.
Кроме того, если это вызвано после того, как любыми сессиями
объекты были созданы, результаты также не определены. Первым аргументом функции sqlite3session_config()
должна быть одна из констант SQLITE_SESSION_CONFIG_XXX, определенных ниже.
Интерпретация (void*), переданного как второй параметр, и эффект вызова этой
функции зависят от значения первого параметра. Эта функция возвращает SQLITE_OK в случае успеха или код
ошибки SQLite иначе. Создайте новый объект сессии, приложенный к дескриптору базы данных db.
Если успешно, указатель на новый объект написан в *ppSession, и
SQLITE_OK возвращен. Если ошибка происходит, *ppSession установлен в NULL, а
код ошибки SQLite (например, SQLITE_NOMEM) возвращен. Возможно создать многократные объекты сессии, приложенные к дескриптору
единой базы данных. Объекты сессии, созданные этой функцией, должны быть удалены, используя
sqlite3session_delete()
до закрытия обработчика базы данных, к которому они присоединены.
Если обработчик базы данных закрывается прежде, чем объект сессии удален, то
результаты вызова любой функции модуля сессии, включая
sqlite3session_delete()
на объекте сессии не определены. Поскольку модуль сессии использует
sqlite3_preupdate_hook() API,
невозможно для запроса зарегистрировать перехватчик предварительного
обновления базы данных, у которой есть один или несколько приложенных
объектов сессии. И при этом невозможно создать объект сессии, приложенный к
дескриптору базы данных, для которой уже определяется перехватчик
перед обновлением. Результаты попытки любой из этих вещей не определены. Объект сессии будет использоваться, чтобы создать changesets для таблиц в
базе данных zDb, где zDb "main", "temp", или название приложенной базы
данных. Это не ошибка, если база данных zDb не присоединена к базе данных,
когда объект сессии создается. Удалите объект сессии ранее ассигнованный использованием
sqlite3session_create().
Как только объект сессии был удален, результаты попытки использовать pSession
с любой другой функцией модуля сессии не определены. Объекты сессии должны быть удалены, прежде чем обработчик
базы данных, к которой они приложены, закрывается. Обратитесь к документации
для sqlite3session_create(). Если это еще не присоединено к объекту сессии, переданному как первый
аргумент, эта функция прилагает таблицу zTbl таким же образом, как функция
sqlite3session_attach().
Если zTbl не существует или если у нее нет первичного ключа, эта функция не
делает (но не возвращает ошибку). zFromDb должно быть название базы данных ("main", "temp", ...)
приложенной к тому же самому дескриптору базы данных как объект сессии,
который содержит таблицу, совместимую с таблицей, приложенной к сессии этой
функцией. Таблицу считают совместимой, если: Если таблицы не совместимы, SQLITE_SCHEMA возвращен.
Если таблицы совместимы, но не имеют никаких колонок PRIMARY KEY, это не
ошибка, но никакие изменения не добавляются к объекту сессии.
Как с другой сессией API, просто проигнорированы таблицы без PRIMARY KEY. Эта функция добавляет ряд изменений объекта сессии, который мог
использоваться, чтобы обновить таблицу
в базе данных zFrom (назовите это "from-table")
так, чтобы ее содержание совпало с таблицей, приложенной
к объекту сессии (назовите это "to-table"): Если эта функция вызвана и затем changeset построен с использованием
sqlite3session_changeset(),
то после применения этого changeset к базе данных zFrom содержание двух
совместимых таблиц будет идентичным. Это ошибка, если база данных zFrom не существует или не содержит
необходимую совместимую таблицу. Если операция успешна, SQLITE_OK возвращен. Иначе вернется код ошибки
SQLite. В этом случае, если аргументом pzErrMsg не является NULL, *pzErrMsg
может указать на буфер, содержащий английское языковое сообщение об ошибке.
Обязанность вызывающего освободить этот буфер, используя sqlite3_free(). Позвольте или отключите запись изменений объектом сессии.
Когда позволено, объект сессии пишет изменения,
внесенные в базу данных. Когда отключено, он это не делает.
Созданный объект сессии изначально позволен. Обратитесь к документации на
sqlite3session_changeset()
для получения дальнейшей информации относительно того, как
включение объекта сессии затрагивает возможный changeset. Передача 0 к этой функции отключает сессию.
Передача значения больше, чем ноль, включает.
Передача значения меньше, чем ноль не делает ничего, но может использоваться,
чтобы запросить текущее состояние сессии. Возвращаемое значение указывает на конечное состояние объекта сессии: 0,
если сессия отключена, или 1, если она позволена. Каждое изменение, зарегистрированное объектом сессии, отмечено как прямое
или косвенное. Изменение отмечено как косвенное, если: Если единственная строка затронута больше, чем одной операцией в сессии,
то изменение считают косвенным, если все операции соответствуют критериям для
косвенного изменения выше, или прямым иначе. Эта функция используется, чтобы установить, очистить или запросить
косвенный флаг объекта сессии. Если вторым аргументом, переданным к этой
функции, является ноль, то косвенный флаг очищен. Если это больше, чем ноль,
косвенный флаг установлен. Передача значение меньше, чем ноль, не изменяет
текущее значение косвенного флага и может использоваться, чтобы запросить
текущее состояние косвенного флага для указанного объекта сессии. Возвращаемое значение указывает на конечное состояние косвенного флага:
0, если сброшено, или 1, если установлено. Возвратит не 0, если никакие изменения приложенных таблиц не были
зарегистрированы объектом сессии, переданным как первый аргумент. Иначе, если
одно или более изменений были зарегистрированы, возвратит ноль. Даже если эта функция возвращает ноль, возможно, что запрос
sqlite3session_changeset()
на дескрипторе сессии может все еще возвратить changeset, который не
содержит изменений. Это может произойти, когда строка
в таблице изменяется, и затем позже исходные значения восстановлены.
Однако, если эта функция вернет не 0, то гарантируется, что обращение к
sqlite3session_changeset() возвратит changeset,
содержащий нулевые изменения. Этот API возвращает общую сумму памяти кучи в байтах, в настоящее время
используемых объектом сессии, переданным как единственный аргумент. Этот метод используется, чтобы формировать объект сессии после того, как
он был создан. В настоящее время единственные действительные значения
для второго параметра:
SQLITE_SESSION_OBJCONFIG_SIZE
и
SQLITE_SESSION_OBJCONFIG_ROWID. Различия между patchset и changeset в том, что: patchset blob может использоваться с актуальными версиями всех функций
sqlite3changeset_xxx API кроме sqlite3changeset_invert(), которая вернет
SQLITE_CORRUPT. Точно так же попытка использовать patchset blob
со старыми версиями sqlite3changeset_xxx API также вызывает
ошибку SQLITE_CORRUPT. Поскольку поля "old.*" непервичного ключа
опущены, никакие конфликты SQLITE_CHANGESET_DATA нельзя обнаружить или
сообщить, если patchset передается к sqlite3changeset_apply() API.
Другой конфликт работает таким же образом, как с changeset. Изменения в patchset упорядочены таким же образом, как в changeset,
произведенном sqlite3session_changeset() (то есть, все изменения для
единственной таблицы группируются, таблицы появляются в порядке, в котором
они были присоединены к объекту сессии). Вторым аргументом (xFilter) является "отзыв фильтра".
Для изменений строк в таблицах, которые не присоединены к объекту сессии,
фильтр вызывают, чтобы определить, должны ли изменения строк таблицы быть
прослежены или нет. Если xFilter возвращает 0, изменения не прослежены.
Обратите внимание на то, что, как только таблица добавлена,
xFilter больше не вызовут. Следующие флаги могут передаваться через 9-й параметр
sqlite3changeset_apply_v2 и
sqlite3changeset_apply_v2_strm: Отзыв обработчика конфликта должен возвратить одно из
следующих трех значений.
Если CHANGESET_REPLACE возвращен обработчиком конфликта
SQLITE_CHANGESET_DATA, противоречивая строка
обновлена или удалена, в зависимости от типа изменения. Если CHANGESET_REPLACE возвращен обработчиком конфликта
SQLITE_CHANGESET_CONFLICT, то противоречивая строка
удален из базы данных, и предпринята вторая попытка применить изменение.
Если эта вторая попытка терпит неудачу, оригинальная строка
вернется базе данных перед продолжением. Значения, которые могут быть переданы как второй
аргумент обработчику конфликта. Противоречивая строка в этом случае является строкой базы данных с
соответствующим первичным ключом. В этом случае нет никакой противоречивой строки. Результаты
sqlite3changeset_conflict() API не определены. Противоречивая строка в этом случае это строка базы данных с
соответствующим первичным ключом. Никакая информация о строке не обеспечивается. Единственная функция,
которая может обратиться к поставляемому дескриптору sqlite3_changeset_iter,
это sqlite3changeset_fk_conflicts(). В этом случае нет никакой конфликтной строки. Результаты
sqlite3changeset_conflict() API не определены. Следующие значения могут быть переданы как 2-й параметр
sqlite3session_object_config(). Ошибка (SQLITE_MISUSE) попытаться изменить это урегулирование после того,
как первая таблица была присоединена к объекту сессии. Обычно таблицы без явного PRIMARY KEY просто проигнорированы модулем
сессий. Однако, если этот флаг установлен, он ведет себя, как будто у таких
таблиц есть колонка "_rowid_ INTEGER PRIMARY KEY", вставленная как их
крайний левый столбец. Ошибка (SQLITE_MISUSE) попытаться изменить это урегулирование после того,
как первая таблица была присоединена к объекту сессии. Шесть потоковых функции API xxx_strm () служат подобным целям к
соответствующим функциям непотокового API: Непотоковые функции, которые принимают changeset (или patchset) как вход,
требуют, чтобы все changeset были сохранены в единственном буфере в памяти.
Точно так же те, которые возвращают changeset или patchset, делают так,
возвращая указатель на единственный большой буфер, ассигнованный, используя
sqlite3_malloc(). Обычно это удобно. Однако, если применение, работающее
в окружающей среде с маленькой памятью, должно
обращаться с очень большим changeset, большие смежные требуемые выделения
памяти могут стать проблемой. Чтобы избежать этой проблемы, вместо единственного большого буфера ввод
передается к функциям потокового API посредством функции обратного вызова,
которую модуль сессий вызывает, чтобы с приращением запросить входные данные,
когда это требуется. Во всех случаях пара параметров API-функции, такая как
заменена на: Каждый раз, когда отзыв xInput вызван модулем сессий,
первым переданным аргументом является копия поставляемого указателя контекста
pIn. Второй аргумент, pData, указывает на буфер (*pnData) байт
в размере. Считая, что никакой ошибки не происходит, метод xInput должен
скопировать (*pnData) байт данных в буфер и установить (*pnData) в
фактическое число байтов, скопированных прежде, чем возвратить SQLITE_OK.
Если вход полностью исчерпан, (*pnData) должен быть установлен в 0, чтобы
указать на это. Или, если ошибка происходит, код ошибки SQLite должен быть
возвращен. Во всех случаях, если отзыв xInput возвращает ошибку, оставлена
вся обработка, и функция потокового API возвращает копию кода ошибки. В случае sqlite3changeset_start_strm() отзыв xInput
может быть вызван модулем сессий в любом пункте в течение жизни iterator.
Если отзыв xInput возвращает ошибку, iterator входит в состояние ошибки,
посредством чего все последующие обращения к функциям iterator немедленно
терпят неудачу с тем же самым кодом ошибки, как возвращено xInput. Точно так же функции потокового API, которые возвращают changeset
(или patchset) возвращают их в кусках посредством функции обратного вызова
вместо указателя на единственный большой буфер. В этом случае пара
параметров, таких как: заменена на: Отзыв xOutput вызван ноль или больше раз, чтобы возвратить данные к
применению. Первый параметр, переданный к каждому вызову, является копией
указателя pOut, поставляемого применением. Второй параметр, pData, указывает
на буфер nData байт в размере, содержащий кусок возвращаемых выходных данных.
Если отзыв xOutput успешно обрабатывает поставляемые данные, он должен
возвратить SQLITE_OK, чтобы указать на успех. Иначе это должно возвратить
некоторый другой код ошибки SQLite. В этом случае немедленно оставлена
обработка, и функция потокового API возвращает применению копию
кода ошибки xOutput. Модуль сессий никогда не призывает отзыв xOutput с третьим параметром,
установленным в значения 0 или меньше. Кроме этого, никакие гарантии не
сделаны относительно размера кусков возвращенных данных. Примените changeset или patchset к базе данных. Эти функции пытаются
обновить БД "main", присоединенную к db, с изменениями, найденными в
changeset, переданном через второй и третий аргументы. Четвертый аргумент (xFilter), переданный этим функциям, это "отзыв
фильтра". Если это не NULL, то для каждой таблицы, затронутой
по крайней мере одним изменением в changeset, отзыв фильтра вызван с именем
таблицы как второй аргумент и копией указателя контекста, переданного как
шестой аргумент, как первый. Если "отзыв фильтра" возвращает ноль,
то никакая попытка не предпринята, чтобы применить любые изменения таблицы.
Иначе, если возвращаемое значение отличное от нуля, или аргументом xFilter
является NULL, все изменения, связанные с таблицей, предприняты. Для каждой таблицы, которая не исключена отзывом фильтра, эта функция
проверяет, что целевая база данных содержит совместимую таблицу.
Ее считают совместимой, если все следующее верно: Если нет никакого совместимой таблицы, это не ошибка, но ни одно из
изменений, связанных с таблицей, не применяется. Предупреждающее сообщение
выпущено через механизм sqlite3_log() с кодом ошибки SQLITE_SCHEMA.
Самое большее одно такое предупреждение выпущено для
каждой таблицы в changeset. Для каждого изменения, для которого есть совместимая таблица,
предпринята попытка изменить содержание таблицы согласно изменению UPDATE,
INSERT или DELETE. Если изменение не может быть применено чисто,
функция-обработчик конфликта, переданная как пятый аргумент
sqlite3changeset_apply(), может быть вызвана. Описание точно, когда
обработчик конфликта вызван для каждого типа изменения, ниже.
В отличие от аргумента xFilter, xConflict
не может быть передан NULL. Результаты прохождения чего-либо, кроме
действительного указателя функции, как аргумент xConflict не определены. Каждый раз, когда функция-обработчик конфликта вызвана, она должна
возвратить одно из SQLITE_CHANGESET_OMIT
, SQLITE_CHANGESET_ABORT или
SQLITE_CHANGESET_REPLACE.
SQLITE_CHANGESET_REPLACE может быть возвращен только если вторым аргументом,
переданным обработчику конфликта, является SQLITE_CHANGESET_DATA или
SQLITE_CHANGESET_CONFLICT. Если обработчик конфликта возвращает
неправильное значение, любые изменения, уже внесенные, отменены, и обращение
к sqlite3changeset_apply() вернет SQLITE_MISUSE. Различные меры приняты
sqlite3changeset_apply() в зависимости от значения, возвращенного каждым
вызовом функции-обработчика конфликта. Обратитесь к документации для трех
доступных возвращаемых значений
для деталей. Если строка с соответствием значениям первичного ключа найдена,
но одна или больше областей непервичного ключа содержит значение,
отличающееся от первоначального значения строки, сохраненной в changeset,
функция-обработчик конфликта вызвана с
SQLITE_CHANGESET_DATA
как второй аргумент. Если у таблицы базы данных есть больше колонок, чем
зарегистрировано в changeset, только значения тех областей непервичного ключа
сравнены с текущим содержанием базы данных,
любые другие колонки таблицы базы данных проигнорированы. Если никакой строки с соответствием значениям первичного ключа не найдено
в базе данных, функция-обработчик конфликта вызвана с
SQLITE_CHANGESET_NOTFOUND,
переданным как второй аргумент. Если операция DELETE предпринята, но SQLite возвращает SQLITE_CONSTRAINT
(который может произойти только если ограничение внешнего ключа нарушено),
функция-обработчик конфликта вызвана с
SQLITE_CHANGESET_CONSTRAINT, переданным как второй аргумент. Это включает
случай, где операция DELETE предпринята потому что более раннее обращение к
функции-обработчику конфликта вернуло
SQLITE_CHANGESET_REPLACE. Если попытка вставить строку
терпит неудачу, потому что база данных уже содержит строку
с теми же самыми значениями первичного ключа, функция-обработчик конфликта
вызвана со вторым аргументом
SQLITE_CHANGESET_CONFLICT. Если попытка вставить строку терпит неудачу из-за некоторого другого
ограничительного нарушения (например, NOT NULL или UNIQUE),
функция-обработчик конфликта вызвана со вторым аргументом
SQLITE_CHANGESET_CONSTRAINT.
Это включает случай, где операция INSERT повторно предпринята потому, что
более раннее обращение к функции-обработчику конфликта вернуло
SQLITE_CHANGESET_REPLACE. Если строка с соответствием значениям первичного ключа найдена,
но одна или больше измененных областей непервичного ключа содержит значение,
отличающееся от первоначального значения строки, сохраненной в changeset,
функция-обработчик конфликта вызвана с вторым параметром
SQLITE_CHANGESET_DATA.
Так как UPDATE содержит только значения для областей непервичного ключа,
которые должны быть изменены, только те области должны соответствовать
исходным значениям, чтобы избежать отзыва обработчика конфликта
SQLITE_CHANGESET_DATA. Если никакая строка с соответствием значениям первичного ключа не найдена
в базе данных, функция-обработчик конфликта вызвана с
SQLITE_CHANGESET_NOTFOUND,
переданным как второй аргумент. Если операция UPDATE предпринята, но SQLite возвращает SQLITE_CONSTRAINT,
функция-обработчик конфликта вызвана с
SQLITE_CHANGESET_CONSTRAINT,
переданным как второй аргумент. Это включает случай, где операция UPDATE
предпринята после более раннего обращения к функции-обработчику конфликта,
вернувшей SQLITE_CHANGESET_REPLACE
. Безопасно выполнить SQL-операторы, включая тех, которые пишут таблицу,
связанную с отзывом, из отзыва xConflict.
Это может использоваться, чтобы далее настроить стратегию
разрешения конфликтов применения. Все изменения, внесенные этими функциями, приложены в транзакции точки
сохранения. Если какая-либо другая ошибка (кроме ограничительной неудачи,
пытаясь написать целевой базе данных) происходит, то транзакция
точки сохранения отменена, вернув целевую базу данных к ее исходному
состоянию и возвратив код ошибки SQLite. Если параметры вывода (ppRebase) и (pnRebase) не NULL, а
вход changeset (не patchset), то sqlite3changeset_apply_v2()
может установить (*ppRebase), чтобы указывать на "rebase",
которая может использоваться с буфером sqlite3_rebaser API
перед возвращением. В этом случае (*pnRebase) установлен в
размер буфера в байтах. Ответственность вызывающего в конечном счете
освободить любой такой буфер, используя sqlite3_free().
Буфер ассигнован и наполнен только если с одним или более конфликтами
столкнулись, применяя patchset. См. комментарии sqlite3_rebaser API. Поведение sqlite3changeset_apply_v2() может быть изменено, передав
комбинацию поддержанных флагов
как 9-й параметр. Обратите внимание на то, что sqlite3changeset_apply_v2() API
все еще экспериментален и поэтому подлежит изменению. Создайте iterator, используемый, чтобы пройти
через содержание changeset. Если успешно, *pp указывает
на обработчик iterator, и SQLITE_OK возвращен. Иначе, если ошибка происходит,
*pp = 0 и код ошибки SQLite возвращен. Следующие функции могут использоваться, чтобы продвинуть и запросить
changeset iterator, созданный этой функцией: Обязанность вызывающего в конечном счете разрушить iterator, передавая его
sqlite3changeset_finalize().
Буфер, содержащий changeset (pChangeset),
должен остаться действительным, пока iterator не будет разрушен. Предположим, что changeset blob создан одной из функций
sqlite3session_changeset(),
sqlite3changeset_concat() или
sqlite3changeset_invert(), все
изменения в changeset, которые относятся к единственной таблице,
группируются. Это означает, что, когда применение повторяет через changeset
с использованием iterator, созданного этой функцией, все изменения, которые
касаются единственной таблицы, посещают последовательно.
Нет никакого шанса, что iterator посетит изменение для таблицы X, затем для
Y и снова для X. Поведение sqlite3changeset_start_v2() может быть изменено, передав
комбинацию
поддержанных флагов как 4-й параметр. Обратите внимание на то, что sqlite3changeset_start_v2() API
все еще экспериментален и поэтому подлежит изменению.
Choose any three.
Интерфейс C/C++ модуля сессии SQLite
Объекты:
Константы:
Функции:
Флаги для sqlite3changeset_start_v2
#define SQLITE_CHANGESETSTART_INVERT 0x0002
Значения для sqlite3session_config().
#define SQLITE_SESSION_CONFIG_STRMSIZE 1
Обработчик Changegroup
typedef struct sqlite3_changegroup sqlite3_changegroup;
Обработчик Changeset Iterator
typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
Перебазирование changesets
typedef struct sqlite3_rebaser sqlite3_rebaser;
Обработчик объекта Session
typedef struct sqlite3_session sqlite3_session;
Добавьте Changeset к Changegroup
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
Существующее изменение
Новое изменение
Изменение на выходе
INSERT INSERT
Новое изменение проигнорировано. Этот случай не происходит, если новый
changeset был немедленно зарегистрирован после changesets,
уже добавленного к changegroup.
INSERT UPDATE Изменение INSERT остается в changegroup.
Значения в изменении INSERT изменяются, как будто строка
была вставлена существующим изменением и затем обновлена
согласно новому изменению.
INSERT DELETE
Существующий INSERT удален из changegroup. DELETE не добавляется.
UPDATE INSERT
Новое изменение проигнорировано. Этот случай не происходит, если новый
changeset был немедленно зарегистрирован после changeset,
уже добавленного к changegroup.
UPDATE UPDATE
Существующий UPDATE остается в changegroup. Это исправлено так, чтобы
сопровождающие значения состояли в том, как будто строка
была обновлена однажды существующим изменением, а затем
еще и новым изменением.
UPDATE DELETE
Существующий UPDATE заменяется новым DELETE в changegroup.
DELETE INSERT
Если одно или больше значений столбцов в строке, вставленной
новым изменением, отличаются от таких же в строке,
удаленной существующим изменением, существующий DELETE заменяется UPDATE в
changegroup. Иначе, если вставленная строка это
точно то же самое как удаленная, от существующего DELETE просто отказываются.
DELETE UPDATE
Новое изменение проигнорировано. Этот случай не происходит, если новый
changeset был немедленно зарегистрирован после changeset,
уже добавленного к changegroup.
DELETE DELETE
Новое изменение проигнорировано. Этот случай не происходит, если новый
changeset был немедленно зарегистрирован после changeset,
добавленного к changegroup.
Удалите объект Changegroup
void sqlite3changegroup_delete(sqlite3_changegroup*);
Создайте объект Changegroup
int sqlite3changegroup_new(sqlite3_changegroup **pp);
Получите сложный Changeset из Changegroup
int sqlite3changegroup_output(
sqlite3_changegroup*,
int *pnData, /* OUT: Size of output buffer in bytes */
void **ppData /* OUT: Pointer to output buffer */
);
Добавьте схему к Changegroup
int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*,
const char *zDb);
Свяжите два объекта Changeset
int sqlite3changeset_concat(
int nA, /* Number of bytes in buffer pA */
void *pA, /* Pointer to buffer containing changeset A */
int nB, /* Number of bytes in buffer pB */
void *pB, /* Pointer to buffer containing changeset B */
int *pnOut, /* OUT: Number of bytes in output changeset */
void **ppOut /* OUT: Buffer containing output changeset */
);
sqlite3_changegroup *pGrp;
rc = sqlite3_changegroup_new(&pGrp);
if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
if( rc==SQLITE_OK )
{
rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
}
else
{
*ppOut = 0;
*pnOut = 0;
}
Получите значения строк конфликтов из Changeset Iterator
int sqlite3changeset_conflict
(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: Value from conflicting row */
);
Завершите Changeset Iterator
int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
sqlite3changeset_start();
while( SQLITE_ROW==sqlite3changeset_next() )
{
// Do something with change.
}
rc = sqlite3changeset_finalize();
if( rc!=SQLITE_OK )
{
// An error has occurred
}
Определите количество ограничительных нарушений внешнего ключа
int sqlite3changeset_fk_conflicts
(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int *pnOut /* OUT: Number of FK violations */
);
Инвертируйте Changeset
int sqlite3changeset_invert
(
int nIn, const void *pIn, /* Input changeset */
int *pnOut, void **ppOut /* OUT: Inverse of input */
);
Получите значения new.* из Changeset Iterator
int sqlite3changeset_new
(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */
);
Продвиньте Changeset Iterator
int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
Получите значения old.* из Changeset Iterator
int sqlite3changeset_old
(
sqlite3_changeset_iter *pIter, /* Changeset iterator */
int iVal, /* Column number */
sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */
);
Получите текущую операцию из Changeset Iterator
int sqlite3changeset_op
(
sqlite3_changeset_iter *pIter, /* Iterator object */
const char **pzTab, /* OUT: Pointer to table name */
int *pnCol, /* OUT: Number of columns in table */
int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */
int *pbIndirect /* OUT: True for an 'indirect' change */
);
Получите определение первичного ключа таблицы
int sqlite3changeset_pk
(
sqlite3_changeset_iter *pIter, /* Iterator object */
unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
int *pnCol /* OUT: Number of entries in output array */
);
Модернизируйте схему Changeset/Patchset
int sqlite3changeset_upgrade(sqlite3 *db, const char *zDb,
int nIn, const void *pIn, /* Input changeset */
int *pnOut, void **ppOut /* OUT: Inverse of input */
);
Формируйте changeset rebaser объект
int sqlite3rebaser_configure(sqlite3_rebaser*, int nRebase,
const void *pRebase);
Создайте объект changeset rebaser
int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
Удалите объект changeset rebaser
void sqlite3rebaser_delete(sqlite3_rebaser *p);
Перебазируйте changeset
int sqlite3rebaser_rebase(sqlite3_rebaser*, int nIn, const void *pIn,
int *pnOut, void **ppOut);
Присоединить таблицу к объекту сессии
int sqlite3session_attach
(
sqlite3_session *pSession, /* Session object */
const char *zTab /* Table name */
);
Специальная обработка sqlite_stat1
CREATE TABLE sqlite_stat1(tbl,idx,stat)
Произведите Changeset от объекта сессии
int sqlite3session_changeset
(
sqlite3_session *pSession, /* Session object */
int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
void **ppChangeset /* OUT: Buffer containing changeset */
);
Создание Changeset
Возвратите верхний предел для размера Changeset
sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession);
Формируйте глобальные параметры
int sqlite3session_config(int op, void *pArg);
Создайте новый объект сессии
int sqlite3session_create
(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of db (e.g. "main") */
sqlite3_session **ppSession /* OUT: New session object */
);
Удалите объект сессии
void sqlite3session_delete(sqlite3_session *pSession);
Загрузите различие между таблицами в сессию
int sqlite3session_diff(sqlite3_session *pSession, const char *zFromDb,
const char *zTbl, char **pzErrMsg);
Позвольте или отключите объект сессии
int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
Переключите косвенный флаг изменения
int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
Тест, сделал ли changeset запись каких-либо изменений
int sqlite3session_isempty(sqlite3_session *pSession);
Сколько памяти кучи используется объектом сессии
sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);
Формируйте объект сессии
int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
Произведите Patchset от объекта сессии
int sqlite3session_patchset
(
sqlite3_session *pSession, /* Session object */
int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */
void **ppPatchset /* OUT: Buffer containing patchset */
);
Установите фильтр таблицы на объекте сессии
void sqlite3session_table_filter
(
sqlite3_session *pSession, /* Session object */
int(*xFilter)
(
void *pCtx, /* Copy of third arg to _filter_table() */
const char *zTab /* Table name */
),
void *pCtx /* First argument passed to xFilter */
);
Флаги для sqlite3changeset_apply_v2
#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001
#define SQLITE_CHANGESETAPPLY_INVERT 0x0002
#define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004
#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008
Константы, возвращенные обработчиком конфликта
#define SQLITE_CHANGESET_OMIT 0
#define SQLITE_CHANGESET_REPLACE 1
#define SQLITE_CHANGESET_ABORT 2
Константы, переданные обработчику конфликта
#define SQLITE_CHANGESET_DATA 1
#define SQLITE_CHANGESET_NOTFOUND 2
#define SQLITE_CHANGESET_CONFLICT 3
#define SQLITE_CHANGESET_CONSTRAINT 4
#define SQLITE_CHANGESET_FOREIGN_KEY 5
Опции sqlite3session_object_config
#define SQLITE_SESSION_OBJCONFIG_SIZE 1
#define SQLITE_SESSION_OBJCONFIG_ROWID 2
Текущие версии API-функций
int sqlite3changeset_apply_strm
(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)
(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)
(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx /* First argument passed to xConflict */
);
int sqlite3changeset_apply_v2_strm
(
sqlite3 *db, /* Apply change to "main" db of this handle */
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
void *pIn, /* First arg for xInput */
int(*xFilter)
(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)
(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, int flags);
int sqlite3changeset_concat_strm(
int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA,
int (*xInputB)(void *pIn, void *pData, int *pnData), void *pInB,
int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut);
int sqlite3changeset_invert_strm(
int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut);
int sqlite3changeset_start_strm(sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn);
int sqlite3changeset_start_v2_strm(sqlite3_changeset_iter **pp,
int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int flags);
int sqlite3session_changeset_strm(sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut);
int sqlite3session_patchset_strm(sqlite3_session *pSession,
int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut);
int sqlite3changegroup_add_strm(sqlite3_changegroup*,
int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn);
int sqlite3changegroup_output_strm(sqlite3_changegroup*,
int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut);
int sqlite3rebaser_rebase_strm(sqlite3_rebaser *pRebaser,
int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn,
int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut);
Потоковая функция Непотоковая функция
sqlite3changeset_apply_strm
sqlite3changeset_apply
sqlite3changeset_apply_strm_v2
sqlite3changeset_apply_v2
sqlite3changeset_concat_strm
sqlite3changeset_concat
sqlite3changeset_invert_strm
sqlite3changeset_invert
sqlite3changeset_start_strm
sqlite3changeset_start
sqlite3session_changeset_strm
sqlite3session_changeset
sqlite3session_patchset_strm
sqlite3session_patchset
int nChangeset, void *pChangeset,
int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn,
int *pnChangeset, void **ppChangeset,
int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut
Примените Changeset к базе данных
int sqlite3changeset_apply
(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)
(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)
(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx /* First argument passed to xConflict */
);
int sqlite3changeset_apply_v2(
sqlite3 *db, /* Apply change to "main" db of this handle */
int nChangeset, /* Size of changeset in bytes */
void *pChangeset, /* Changeset blob */
int(*xFilter)(
void *pCtx, /* Copy of sixth arg to _apply() */
const char *zTab /* Table name */
),
int(*xConflict)(
void *pCtx, /* Copy of sixth arg to _apply() */
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
sqlite3_changeset_iter *p /* Handle describing change and conflict */
),
void *pCtx, /* First argument passed to xConflict */
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
int flags /* SESSION_CHANGESETAPPLY_* flags */
);
Создайте Iterator, чтобы пересечь Changeset
int sqlite3changeset_start(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset /* Pointer to blob containing changeset */
);
int sqlite3changeset_start_v2(
sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */
int nChangeset, /* Size of changeset blob in bytes */
void *pChangeset, /* Pointer to blob containing changeset */
int flags /* SESSION_CHANGESETSTART_* flags */
);