Spec-Zone.ru › SQLite

Модуль SQLite Zipfile

Содержание
1. Обзор
2. Получение и компиляция Zipfile
3. Использование Zipfile
3.1. Функция со значениями таблицы (только чтение)
3.2. Интерфейс виртуальной таблицы (чтение/запись)
3.2.1. Добавление записей в архив ZIP
3.2.2. Удаление записей из архива ZIP
3.2.3. Обновление существующих записей в архиве ZIP
3.3. Функция агрегирования zipfile

1. Обзор

Модуль zipfile предоставляет чтение/запись в простые архивы ZIP. Текущая реализация имеет следующие ограничения:

  • Не поддерживает шифрование.
  • Не поддерживает архивы ZIP, распределённые по нескольким файлам.
  • Не поддерживает расширения zip64.
  • Поддерживается только алгоритм сжатия "deflate".

Некоторые или все эти ограничения могут быть сняты в будущем.

2. Получение и компиляция Zipfile

Код модуля zipfile находится в файле ext/misc/zipfile.c основного дерева исходного кода SQLite. Его можно скомпилировать в загружаемый расширение SQLite с помощью команды типа:

gcc -g -fPIC -shared zipfile.c -o zipfile.so

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

int sqlite3_zipfile_init(sqlite3 *db, void*, void*);

В качестве первого аргумента должен быть передан дескриптор базы данных, с которым нужно зарегистрировать расширение. Второй и третий аргументы должны быть равны 0.

Zipfile включен в большинство сборок оболочки командной строки.

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

Модуль zipfile предоставляет три похожих интерфейса для доступа, обновления и создания архивов zip-файлов:

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

Модуль zipfile предоставляет два аналогичных интерфейса для доступа к архивам zip. Функция со значениями таблицы, предоставляющая доступ только для чтения к существующим архивам, и интерфейс виртуальной таблицы, предоставляющий доступ для чтения и записи.

3.1. Функция со значениями таблицы (только чтение)

Для чтения существующих архивов zip модуль Zipfile предоставляет функцию со значениями таблицы, принимающую один аргумент. Если аргумент имеет текстовое значение, то это путь к архиву zip для чтения из файловой системы. Или, если аргумент — SQL-двоичное значение, то это данные самого архива zip.

Например, чтобы проверить содержимое архива zip "test.zip" из текущего каталога:

SELECT * FROM zipfile('test.zip');

Или, из инструмента оболочки SQLite (функция readfile() считывает содержимое файла из файловой системы и возвращает его в виде двоичных данных):

SELECT * FROM zipfile( readfile('test.zip') );

Функция со значениями таблицы возвращает одну строку для каждой записи (файл, каталог или символическая ссылка) в архиве zip. Каждая строка содержит следующие столбцы:

Имя столбца Содержание
name Имя/путь к файлу для записи zip-файла.
mode Режим UNIX, как возвращается stat(2) для записи zip-файла (целое число). Это определяет тип записи (файл, каталог или символическая ссылка) и соответствующие разрешения пользователя/группы/все.
mtime Маркер времени UTC, в секундах с начала эпохи UNIX (целое число).
sz Размер связанных данных в байтах после их разархивирования (целое число).
rawdata Необработанные (возможно, сжатые) данные, связанные с записью в zip-файле (двоичные данные).
data Если метод сжатия для записи равен либо 0, либо 8 (см. ниже), то необработанные данные, связанные с записью в zip-файле. Или, если метод сжатия не 0 и не 8, этот столбец содержит значение NULL.
method Метод сжатия, используемый для сжатия данных (целое число). Значение 0 указывает, что данные хранятся в архиве zip без сжатия. 8 означает алгоритм raw deflate.

3.2. Интерфейс виртуальной таблицы (чтение/запись)

Для создания или изменения существующего zip-файла необходимо создать виртуальную таблицу "zipfile" в схеме базы данных. Оператор CREATE VIRTUAL TABLE ожидает путь к zip-файлу в качестве единственного аргумента. Например, для записи в zip-файл "test.zip" в текущем каталоге виртуальная таблица zipfile может быть создана с помощью:

CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip');

Такая виртуальная таблица имеет те же столбцы, что и функция со значениями таблицы, описанная в предыдущем разделе. К ней можно обращаться с помощью оператора SELECT так же, как и к функции со значениями таблицы.

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

3.2.1. Добавление записей в архив ZIP

Записи могут быть добавлены в архив zip путем вставки новых строк. Наиболее простой способ — указать значения только для столбцов "name" и "data", и zipfile заполнит разумные значения для других полей. Чтобы вставить каталог в архив, установите значение столбца "data" в NULL. Например, чтобы добавить каталог "dir1" и файл "m.txt" содержащий текст "abcdefghi" в архив zip "test.zip":

INSERT INTO temp.zip(name, data) VALUES('dir1', NULL);           -- Add directory 
INSERT INTO temp.zip(name, data) VALUES('m.txt', 'abcdefghi');   -- Add regular file 

Когда вставляется каталог, если значение "name" не заканчивается символом '/', модуль zipfile добавляет его. Это необходимо для совместимости с другими программами (в первую очередь "info-zip"), которые работают с архивами zip.

Чтобы вставить символическую ссылку, пользователь также должен указать значение "mode". Например, чтобы добавить символическую ссылку от "link.txt" к "m.txt":

INSERT INTO temp.zip(name, mode, data) VALUES('link.txt', 'lrwxrw-rw-', 'm.txt');

Следующие правила и замечания применяются к значениям, указанным в качестве части каждого оператора INSERT:

Столбцы Замечания
name Для столбца name должно быть указано ненулевое текстовое значение. Ошибка возникает, если указанное имя уже существует в архиве.
mode Если в столбец mode вставляется значение NULL, то режим новой записи архива автоматически устанавливается в 33188 (-rw-r--r--) или 16877 (drwxr-xr-x), в зависимости от того, указывают ли значения, указанные для столбцов "sz", "data" и "rawdata", что новая запись является каталогом.

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

Наконец, если указанное для этого столбца значение не является целым числом или NULL, то оно предполагается строкой разрешений UNIX, подобной тем, которые выводятся командой "ls -l" (например, "-rw-r--r--", "drwxr-xr-x" и т. д.). В этом случае, если строка не может быть обработана, это ошибка.
mtime Если в столбец mtime вставляется значение NULL, то метка времени новой записи устанавливается на текущее время. В противном случае указанное значение интерпретируется как целое число и используется как есть.
sz Этот столбец должен быть установлен в NULL. Если в этот столбец вставляется ненулевое значение, или если новое ненулевое значение предоставляется с помощью оператора UPDATE, это ошибка.
rawdata Этот столбец должен быть установлен в NULL. Если в этот столбец вставляется ненулевое значение, или если новое ненулевое значение предоставляется с помощью оператора UPDATE, это ошибка.
data Чтобы вставить каталог в архив, это поле должно быть установлено в NULL. В этом случае, если для столбца "mode" было явно указано значение, оно должно соответствовать каталогу (т.е. должно быть истинно, что (mode & 0040000)=0040000).

В противном случае, значение, вставляемое в это поле, представляет собой содержимое файла для обычного файла или целевой объект символической ссылки.
method Это поле должно быть установлено в одно из целочисленных значений 0 и 8, или в NULL.

Для записи каталога любое значение, вставленное в это поле, игнорируется. В противном случае, если оно установлено в 0, то данные файла или целевой объект символической ссылки сохраняются в архиве zip как есть, и метод сжатия устанавливается в 0. Если оно установлено в 8, то данные файла или целевой объект ссылки сжимаются с помощью сжатия deflate перед сохранением, а метод сжатия устанавливается в 8. Наконец, если в это поле вставляется значение NULL, модуль zipfile автоматически решает, следует ли сжимать данные перед их сохранением.

Указание явного значения для поля rowid в операторе INSERT не поддерживается. Любое предоставленное значение игнорируется.

3.2.2. Удаление записей из архива ZIP

Записи могут быть удалены из существующего архива zip путем удаления соответствующих строк. Например, чтобы удалить файл "m.txt" из архива zip "test.zip" с использованием созданной выше виртуальной таблицы:

DELETE FROM temp.zip WHERE name = 'm.txt';

Обратите внимание, что удаление записей из архива zip не освобождает место, используемое в архиве — это просто удаляет запись из "структуры центрального каталога" архива, делая запись недоступной. Один из способов обойти эту неэффективность — создать новый архив zip на основе содержимого измененного архива. Например, после редактирования архива, доступного через виртуальную таблицу temp.zzz:

-- Create a new, empty, archive: 
CREATE VIRTUAL TABLE temp.newzip USING zipfile('new.zip');

-- Copy the contents of the existing archive into the new archive
INSERT INTO temp.newzip(name, mode, mtime, data, method)
    SELECT name, mode, mtime, data, method FROM temp.zzz;

3.2.3. Обновление существующих записей в архиве ZIP

Существующие записи в архиве zip могут быть изменены с помощью операторов UPDATE.

Три столбца слева, "name", "mode" и "mtime", могут быть установлены на любое значение, которое может быть вставлено в тот же столбец (см. выше). Если "mode" или "mtime" установлены в NULL, конечное значение определяется, как описано для вставки значения NULL — текущее время для "mtime" и либо 33188, либо 16877 для "mode", в зависимости от того, указывают ли значения, указанные для следующих четырех столбцов таблицы zipfile, что запись является каталогом или файлом.

Попытка установить поля sz или rawdata на любое значение, кроме NULL, является ошибкой.

Столбцы data и method также могут быть установлены, как описано выше для вставки.

3.3. Функция агрегирования zipfile()

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

Функция агрегирования zipfile() может быть вызвана с 2, 4 или 5 аргументами. Если она вызвана с 5 аргументами, то запись, добавляемая в архив, эквивалентна вставке тех же значений в столбцы "name", "mode", "mtime", "data" и "method" виртуальной таблицы zipfile.

Если zipfile() вызывается с 2 аргументами, то добавляемая в архив запись эквивалентна записи, добавляемой при вставке тех же двух значений в столбцы "name" и "data" виртуальной таблицы zipfile, а все остальные значения устанавливаются в NULL. Если вызывается с 4 аргументами, она эквивалентна вставке 4 значений в столбцы "name", "mode", "mtime" и "data". Другими словами, следующие пары запросов эквивалентны:

SELECT zipfile(name, data) ...
SELECT zipfile(name, NULL, NULL, data, NULL) ...

SELECT zipfile(name, mode, mtime, data) ...
SELECT zipfile(name, mode, mtime, data, NULL) ...

Например, чтобы создать архив, содержащий два текстовых файла "a.txt" и "b.txt", содержащие текст "abc" и "123" соответственно:

WITH contents(name, data) AS (
  VALUES('a.txt', 'abc') UNION ALL
  VALUES('b.txt', '123')
)
SELECT zipfile(name, data) FROM contents;

Эта страница была в последний раз изменена 07.06.2023 13:17:51 UTC

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

Spec-Zone.ru

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