Устанавливаем файлы расширения:
student$ sudo make install -C /home/student/uom PG_CONFIG=/usr/local/pgsql/bin/pg_config
make: Entering directory '/home/student/uom' /bin/mkdir -p '/usr/local/pgsql/share/extension' /bin/mkdir -p '/usr/local/pgsql/share/extension' /usr/bin/install -c -m 644 .//uom.control '/usr/local/pgsql/share/extension/' /usr/bin/install -c -m 644 .//uom--1.0.sql .//uom--1.2.sql .//uom--1.0--1.1.sql .//uom--1.1--1.2.sql '/usr/local/pgsql/share/extension/' make: Leaving directory '/home/student/uom'
Проверим, что расширение доступно для загрузки в базу данных:
=> SELECT * FROM pg_available_extensions WHERE name = 'uom';
name | default_version | installed_version | comment ------+-----------------+-------------------+---------------------- uom | 1.2 | | Units of Measurement (1 row)
Создаем расширение uom в новой базе:
=> CREATE DATABASE admin_extensions;
CREATE DATABASE
=> \c admin_extensions
You are now connected to database "admin_extensions" as user "postgres".
=> CREATE EXTENSION uom;
CREATE EXTENSION
Версия расширения соответствует значению параметра default_version:
=> \dx uom
List of installed extensions Name | Version | Schema | Description ------+---------+--------+--------------------------------- uom | 1.2 | public | Единицы измерения. uom--1.2.sql (1 row)
Поскольку для версии 1.2 есть файл uom--1.2.sql, то он и используется для создания расширения. А для тех, кто хочет перейти с 1.1 или с 1.0, имеются соответствующие пути обновления.
Добавляем футы и дюймы. Столбец predefined заполняется значением по умолчанию (false):
=> INSERT INTO uom_ref VALUES ('фут', 0.3048);
INSERT 0 1
=> INSERT INTO uom_ref VALUES ('дюйм', 0.0254);
INSERT 0 1
Сколько же дюймов в футе?
=> SELECT uom2uom(1, 'фут', 'дюйм');
uom2uom --------------------- 12.0000000000000000 (1 row)
Создаем отдельную роль для доступа к таблице uom_ref:
=> CREATE ROLE util;
CREATE ROLE
Читать из таблицы может только новая роль:
=> GRANT SELECT ON uom_ref TO util;
GRANT
=> REVOKE SELECT ON uom_ref FROM public;
REVOKE
Информация о том, содержимое каких таблиц будет выгружать pg_dump, сохраняется в pg_extension:
=> SELECT extname, extconfig::regclass[], extcondition FROM pg_extension WHERE extname = 'uom';
extname | extconfig | extcondition ---------+-----------+-------------------------- uom | {uom_ref} | {"WHERE NOT predefined"} (1 row)
Запускаем pg_dump:
student$ pg_dump -d admin_extensions
-- -- PostgreSQL database dump -- -- Dumped from database version 10.6 -- Dumped by pg_dump version 10.6 SET statement_timeout = 0; SET lock_timeout = 0; SET idle_in_transaction_session_timeout = 0; SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; SET client_min_messages = warning; SET row_security = off; -- -- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -- CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; -- -- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -- COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; -- -- Name: uom; Type: EXTENSION; Schema: -; Owner: -- CREATE EXTENSION IF NOT EXISTS uom WITH SCHEMA public; -- -- Name: EXTENSION uom; Type: COMMENT; Schema: -; Owner: -- COMMENT ON EXTENSION uom IS 'Единицы измерения. uom--1.2.sql'; -- -- Data for Name: uom_ref; Type: TABLE DATA; Schema: public; Owner: postgres -- COPY public.uom_ref (name, k, predefined) FROM stdin; фут 0.3048 f дюйм 0.0254 f \. -- -- Name: TABLE uom_ref; Type: ACL; Schema: public; Owner: postgres -- REVOKE SELECT ON TABLE public.uom_ref FROM PUBLIC; GRANT SELECT ON TABLE public.uom_ref TO util; -- -- PostgreSQL database dump complete --
Проверим, как pg_dump выгружает объекты расширения:
Для того, чтобы правильно выгрузить права доступа, в системном каталоге сохраняется информация о правах на объекты, выданные скриптами создания расширений:
=> SELECT objoid::regclass, initprivs FROM pg_init_privs WHERE privtype = 'e';
objoid | initprivs ---------+----------------------------------------- uom_ref | {postgres=arwdDxt/postgres,=r/postgres} (1 row)
Без этого было бы невозможно сформировать команду REVOKE.