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

Small. Fast. Reliable.
Choose any three.

1. Обзор

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

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

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

2. Получение и компилирование Zipfile

Код модуля zipfile найден в файле ext/misc/zipfile.c главного исходного дерева 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. Табличная функция (доступ только для чтения)

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

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

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

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

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

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

ИмяСодержание
name Имя файла/путь для записи в файле zip.
mode UNIX mode, как возвращено stat(2) для файла zip (integer). Это определяет тип записи (file, directory или symbolic link) и связанные разрешения user/group/all.
mtime UTC timestamp в секундах с эпохи UNIX (integer).
sz Размер связанных данных в байтах после того, как это было разсжато (integer).
rawdata Сырые (возможно, сжатые) данные, связанные с входом zip-файла (blob).
data Если метод сжатия для записи 0 или 8 (см. ниже), то несжатые данные, связанные с входом zip-файла. Если метод сжатия не 0 или 8, эта колонка содержит NULL.
methodМетод сжатия данных (integer). 0 указывает, что данные хранятся в архиве zip без сжатия. 8 означает, что использован алгоритм.

3.2. Виртуальный интерфейс таблицы (доступ для чтения-записи)

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

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

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

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

3.2.1. Добавление записей в архив 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 Текстовое значение не-NULL должно быть определено для колонки имени. Ошибка, если указанное имя уже существует в архиве.
mode Если NULL вставляется в колонку mode, то mode новой записи архива автоматически установлен в 33188 (-rw-r--r--) или 16877 (drwxr-xr-x), в зависимости от того, указывают ли значения, определенные для колонок "sz", "data" и "rawdata", что новый вход это каталог. Если указанное значение integer (или текст, который похож на целое число), это вставляется дословно. Если значение не действительный UNIX mode, некоторые программы могут неожиданно вести себя, извлекая файлы из архива. Наконец, если значение, определенное для этой колонки, не является целым числом или NULL, то это, как предполагается, строка прав UNIX, подобная произведенной "ls -l" (например, "-rw-r--r--", "drwxr-xr-x", ...). В этом случае, если последовательность не может быть разобрана, это ошибка.
mtime Если NULL вставляется в колонку mtime, то метка времени нового входа установлена в текущее время. Иначе указанное значение интерпретируется как целое число и используется как есть.
sz Эта колонка должна быть установлена в NULL. Если ненулевое значение вставляется в эту колонку или если новое ненулевое значение обеспечивается, используя UPDATE, это ошибка.
rawdata Эта колонка должна быть установлена в NULL. Если ненулевое значение вставляется в эту колонку или если новое ненулевое значение обеспечивается, используя UPDATE это ошибка.
data Чтобы вставить каталог в архив, эта область должна быть установлена в NULL. В этом случае, если бы значение было явно определено для колонки "mode", то это должно согласовываться с каталогом (то есть должно быть верно, что (mode & 0040000)=0040000). Иначе значение, вставленное в эту область, является содержанием файла для обычного файла или целью символьной ссылки.
method Эта область должна быть установлена в одно из целочисленных значений 0 или 8, иначе в NULL. Для записи каталога проигнорировано любое значение, вставленное в эту область. Иначе, если это установлено в 0, тогда цель канала передачи данных или символьной ссылки файла сохранена, как находится в архиве и метод сжатия установлен в 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';

Обратите внимание на то, что удаление записей из архива не освобождает место, использованное в архиве, это просто удаляет вход из "Central Directory Structure" архива, делая вход недоступным. Один способ работать вокруг этой неэффективности состоит в том, чтобы создать новый архив на основе содержания отредактированного архива. Например, после редактирования архива через виртуальную таблицу 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. Обновление существующих записей архива

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

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

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

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

3.3. Агрегатная функция zipfile()

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

Агрегатную функцию 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;