F.46. pgpro_bfile — составной тип для доступа к внешнему файлу #
Расширение pgpro_bfile
добавляет составной тип bfile
, который реализует метод Oracle для доступа к внешнему файлу.
F.46.1. Структуры данных #
Тип bfile
содержит два поля:
dir_id
— идентификатор каталога в таблицеbfile_directories
file_name
— имя внешнего файла
Информация о каталогах хранится в таблице bfile_directories
, которая состоит из следующих столбцов:
dir_id
— уникальный идентификатор каталога типаint32
.dir_alias
— уникальный псевдоним каталога.dir_path
— путь к каталогу.
Хотя наличие двух уникальных идентификаторов dir_id
и dir_alias
является избыточным, работа с dir_alias
удобнее для пользователя, мигрирующего с Oracle, особенно для понимания семантики команд, а для хранения dir_id
лучше использовать тип bfile
, поскольку для него требуется меньше места в хранилище и он обеспечивает более быстрый поиск.
Информация о правах доступа к каталогам хранится в таблице bfile_directory_roles
, которая состоит из следующих столбцов:
dr_dir_id
— идентификатор каталога типаint32
, то есть внешняя ссылка на столбецdir_id
в таблицеbfile_directories
.dr_role_id
— идентификатор пользователя или роли, имеющей права доступа к каталогу.dr_rights
— битовый массив прав доступа к каталогу (1 означает доступ для чтения, 2 — доступ для записи). Выбор битового массива предусматривает возможность предоставления новых прав доступа, например необходимость в отдельном праве на удаление.
F.46.2. Функции #
Функции для работы с каталогами и управления правами доступа к каталогам реализованы на языке PL/PgSQL, а функции для работы со значениями bfile
реализованы на языке C для повышения эффективности.
Таблица F.36. Функции для работы с каталогами
Функция Описание |
---|
Создаёт каталог для заданных псевдонима и пути и возвращает идентификатор созданного каталога. Для вызова этой функции требуются права суперпользователя. |
Удаляет каталог с заданным псевдонимом. Для вызова этой функции требуются права суперпользователя. |
Изменяет псевдоним каталога. Для вызова этой функции требуются права суперпользователя. |
Изменяет путь к каталогу с заданным псевдонимом. Для вызова этой функции требуются права суперпользователя. |
Возвращает путь к каталогу с заданным псевдонимом. |
Возвращает путь к каталогу с заданным идентификатором. |
Возвращает псевдоним каталога с заданным идентификатором. |
Возвращает идентификатор каталога с заданным псевдонимом. |
Таблица F.37. Функции предоставления и отзыва прав доступа к каталогам
Функция Описание |
---|
Предоставляет права доступа к каталогу |
Отзывает права доступа к каталогу |
Удаляет из таблицы |
Таблица F.38. Функции для работы со значениями bfile
Функция Описание |
---|
Возвращает структуру |
Возвращает структуру |
Открывает файл для заданного |
Закрывает файл для заданного дескриптора, возвращаемого функцией |
Закрывает все файлы, которые были открыты ранее функцией |
Возвращает длину открытого файла с заданным дескриптором. |
Считывает |
Записывает буфер, заданный в |
Возвращает |
Возвращает длину файла для заданного значения |
Для заданного значения |
Для заданного значения |
Удаляет файл для заданного значения |
Когда аргументы |
F.46.3. Пример #
В следующем примере показано использование типа bfile
.
Скрипт будет запускаться в файловой системе сервера. Но сначала создайте каталог для хранения данных bfile
:
mkdir "/tmp/bfiles"
Теперь для запуска следующего скрипта будет использоваться psql:
-- Создание расширения pgpro_bfile: CREATE EXTENSION pgpro_bfile; -- Создание каталога в базе данных для хранения bfile: SELECT bfile_directory_create('BFILE_DATA', '/tmp/bfiles'); -- Создание файла bfile.data в файловой системе и добавление в него значения '0123456789': SELECT bfile_write_direct(bfile_make('BFILE_DATA', 'bfile.data'), '0123456789'); -- Создание таблицы bfile и добавление в неё одной записи, ссылающейся на этот файл: CREATE TABLE bfile_table(id int, bf bfile); INSERT INTO bfile_table VALUES (1, bfile_make('BFILE_DATA', 'bfile.data')); -- Создание пользователя для запуска скрипта: CREATE USER bf_test_user; -- Предоставление пользователю bf_test_user права чтения и записи в файл BFILE_DATA: SELECT bfile_grant_directory('BFILE_DATA', 'bf_test_user', 3); -- Предоставление пользователю bf_test_user прав на таблицу bfile_table: GRANT ALL ON bfile_table TO bf_test_user; -- Авторизация bf_test_user: SET SESSION AUTHORIZATION bf_test_user; DO $$ DECLARE v_bfile bfile; v_buffer bytea; v_length bigint; v_handler int; BEGIN -- Открытие файла для чтения и записи: SELECT bfile_open(bf, 3) INTO v_handler FROM bfile_table WHERE id = 1; -- Эта строка символов будет записана в конец файла: PERFORM bfile_write(v_handler, '_suffix'); -- Эта строка символов будет записана с позиции 0 и заменит '0123456': PERFORM bfile_write(v_handler, 'prefix_', 0); -- Считывание строки символов из файла в буфер и вывод её длины и содержимого: v_buffer = bfile_read(v_handler); RAISE NOTICE 'Buffer length: %', length(v_buffer); RAISE NOTICE 'Buffer content: %', encode(v_buffer, 'escape'); -- Получение и вывод длины файла: v_length = bfile_length(v_handler); RAISE NOTICE 'BFILE length: %', v_length; -- Закрытие bfile: PERFORM bfile_close(v_handler); END $$; -- Проверка содержимого таблицы: SELECT encode(b, 'escape'), length(b) from (SELECT bfile_read_direct(bf) b FROM bfile_table) x; -- Удаление таблицы, пользователя и расширения pgpro_bfile: RESET SESSION AUTHORIZATION; DROP TABLE bfile_table; DROP USER bf_test_user; DROP EXTENSION pgpro_bfile;
Скрипт выдаёт следующий результат:
CREATE EXTENSION bfile_directory_create ------------------------ 1 (1 row) bfile_write_direct -------------------- (1 row) CREATE TABLE INSERT 0 1 CREATE ROLE bfile_grant_directory ----------------------- (1 row) GRANT SET NOTICE: Buffer length: 17 NOTICE: Buffer content: prefix_789_suffix NOTICE: BFILE length: 17 DO encode | length -------------------+-------- prefix_789_suffix | 17 (1 row) RESET DROP TABLE DROP ROLE DROP EXTENSION