Spec-Zone.ru › SQLite

Виртуальная таблица SQLITE_DBPAGE

1. Обзор

Расширение SQLITE_DBPAGE реализует одноимённую виртуальную таблицу, которая предоставляет прямой доступ к файлу базы данных, взаимодействуя с пейджером. SQLITE_DBPAGE может как читать, так и записывать любую страницу базы данных. Поскольку взаимодействие происходит через слой пейджера, все изменения являются транзакционными.

Предупреждение: запись в виртуальную таблицу SQLITE_DBPAGE может очень легко привести к необратимой порче базы данных. Не позволяйте недоверенным компонентам обращаться к таблице SQLITE_DBPAGE. Будьте внимательны при работе с таблицей SQLITE_DBPAGE. Сделайте резервную копию важных данных перед экспериментированием с таблицей SQLITE_DBPAGE. Записи в виртуальную таблицу SQLITE_DBPAGE отключены, когда установлен флаг SQLITE_DBCONFIG_DEFENSIVE.

Расширение SQLITE_DBPAGE включено в ассоциацию, хотя по умолчанию оно отключено. Используйте опцию компиляции SQLITE_ENABLE_DBPAGE_VTAB, чтобы включить расширение SQLITE_DBPAGE. Расширение SQLITE_DBPAGE использует не опубликованные внутренние интерфейсы и не загружается во время выполнения. Единственный способ добавить SQLITE_DBPAGE в приложение — скомпилировать его с помощью опции компиляции SQLITE_ENABLE_DBPAGE_VTAB.

Расширение SQLITE_DBPAGE включено в стандартных сборках консольной оболочки, но по умолчанию является только для чтения. Используйте командную строку --unsafe-testing в CLI, чтобы включить запись в виртуальную таблицу sqlite_dbpage.

2. Использование

Виртуальная таблица SQLITE_DBPAGE — это таблица чтения/записи, предоставляющая прямой доступ к файлу на диске на основе страниц. Виртуальная таблица имеет схему примерно такого вида:

CREATE TABLE sqlite_dbpage(
  pgno INTEGER PRIMARY KEY,
  data BLOB
);

Файл базы данных SQLite разделён на страницы. Первая страница — 1, вторая — 2 и так далее. Нет страницы 0. Все страницы имеют одинаковый размер. Размер каждой страницы является степенью двойки от 512 до 65536. Подробности см. в документации по формату файла.

Таблица SQLITE_DBPAGE позволяет приложению просматривать или заменять сырое бинарное содержимое каждой страницы файла базы данных. Никакой попытки интерпретировать содержимое страницы не предпринимается. Содержимое возвращается байт за байтом, так как оно отображается на диске.

Таблица SQLITE_DBPAGE имеет по одной строке для каждой страницы в файле базы данных. SQLITE_DBPAGE позволяет читать страницы с помощью оператора SELECT или перезаписывать их с помощью операторов UPDATE или INSERT. При использовании INSERT в sqlite_dbpage, он работает как REPLACE. Другими словами, INSERT в уже существующую страницу перезаписывает её. Для увеличения размера базы данных, INSERT в страницу за пределами конца базы данных.

2.1. Использование SQLITE_DBPAGE в прикреплённых базах данных

Приведённая выше схема таблицы SQLITE_DBPAGE неполна. Есть третий скрытый столбец под названием "schema", который определяет, какую прикреплённую базу данных следует читать или записывать. Поскольку столбец "schema" скрыт, он может использоваться в качестве параметра, когда SQLITE_DBPAGE вызывается как функция таблицы.

Например, предположим, что дополнительная база данных присоединена к подключению к базе данных с помощью оператора такого типа:

ATTACH 'auxdata1.db' AS aux1;

Тогда для чтения первой страницы этого файла базы данных достаточно выполнить:

SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=1;

Если "schema" опущен, он по умолчанию устанавливается в основную базу данных (обычно называется 'main', если не переименовано с помощью SQLITE_DBCONFIG_MAINDBNAME). Следовательно, следующие два запроса обычно эквивалентны:

SELECT data FROM sqlite_dbpage('main') WHERE pgno=1;
SELECT data FROM sqlite_dbpage WHERE pgno=1;

Таблица SQLITE_DBPAGE может участвовать в объединении, как и любая другая таблица. Следовательно, для просмотра содержимого первой страницы всех подключённых файлов баз данных можно выполнить оператор такого типа:

SELECT dbpage.data, dblist.name
  FROM pragma_database_list AS dblist
  JOIN sqlite_dbpage(dblist.name) AS dbpage
 WHERE dbpage.pgno=1;

2.2. Обрезка базы данных

Обычно данные для UPDATE и INSERT должны быть блобом, имеющим точно такой же размер, как и страница базы данных. Однако в качестве специального случая, выполнение INSERT нулевого значения в страницу 2 или выше в качестве последней операции перед COMMIT приводит к удалению вставляемой страницы и всех последующих страниц, обрезая базу данных. Например, команда "INSERT INTO sqlite_dbpage(pgno,data) VALUES(52,NULL)" приводит к обрезке базы данных до 51 страницы. Номера страниц начинаются с 1, поэтому общее количество оставшихся страниц такое же, как последний номер страницы, или 51 в данном случае.

Вызов INSERT в sqlite_dbpage с нулевым содержимым страницы — это "null-INSERT". Поведение null-INSERT — это специальный случай, и оно не обязательно следует обычным правилам. Ниже приведены некоторые специфические ограничения null-INSERT:

  1. Таблица sqlite_dbpage не позволяет выполнить null-INSERT на страницу 1. Поэтому невозможно обрезать базу данных до нулевых байтов или нулевых страниц с помощью sqlite_dbpage, поскольку это приведет к пропусканию заголовка базы данных, и файл перестанет быть базой данных SQLite.

  2. Null-INSERT обрезает базу данных только в том случае, если это последняя операция записи, которая произошла перед подтверждением транзакции. Если null-INSERT находится внутри многострочной транзакции и за ним следуют одна или несколько операций UPDATE или INSERT в рамках той же транзакции, то null-INSERT становится бесполезной операцией, и база данных не обрезается.

  3. Только один файл базы данных может быть обрезан за одну транзакцию. Виртуальная таблица sqlite_dbpage способна записывать в несколько прикреплённых баз данных в рамках одной транзакции, но так как null-INSERT должен быть последним оператором записи, который произошёл перед COMMIT, sqlite_dbpage может обрезать только одну из прикреплённых баз данных. Если требуется обрезать несколько прикреплённых баз данных, каждая из них должна быть обрезанной в отдельной транзакции.

  4. Любой ROLLBACK TO отменит null-INSERT, даже ROLLBACK TO, который не включает сам null-INSERT. Специальное поведение null-INSERT гарантируется только в том случае, если оно происходит как отдельная транзакция или непосредственно перед COMMIT.

3. Совместимость

Возможность выполнить INSERT в sqlite_dbpage и увеличить или уменьшить размер базы данных с помощью INSERT была добавлена в SQLite версии 3.47.0 (2024-10-21). Более старые версии не позволяют выполнить INSERT в sqlite_dbpage.

Эта страница была изменена в последний раз 2024-10-22 19:45:21 UTC

SQLite is in the Public Domain.
https://sqlite.org/dbpage.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API