Usage¶
omni_manifest allows to install and upgrade extensions as a set. Instead of doing this with create extension
and alter extension
manually, especially when it comes to dependencies, this extension will take manifests (similar to
lock files in other systems) and provision them.
This extension is implemented in PL/pgSQL to simplify its provisioning (for example in environments where only trusted languages are allowed.)
Types¶
Requirement¶
Requirement is a composite type (omni_manifest.requirement
) that describes a name
& version
pair, both of
type text
.
It can be converted to and from the text format of name=version
through casting and the functions used in cast. Also,
an array (requirement[]
)
can be converted to and from the text format of `name1=version1,name2=version2'.
Both the type and the array can be similarly converted to and from the JSON representation of
"name": "version"
.
Examples¶
From¶
select ('myext=1.0'::text::omni_manifest.requirement).*
-- or
select ('{"myext": "1.0"}'::json::omni_manifest.requirement).*
select *
from
unnest('myext=1.0,myotherext=2.0'::text::omni_manifest.requirement[])
-- or
select *
from
unnest('{"myext": "1.0", "myotherext": "2.0"}'::json::omni_manifest.requirement[])
To¶
select row ('myext','1.0')::omni_manifest.requirement::text
-- alternatively,
select row ('myext','1.0')::omni_manifest.requirement::json
row
-----------
myext=1.0
(1 row)
# -- alternatively,
row
-------------------
{"myext" : "1.0"}
(1 row)
select array [row ('myext','1.0'),row ('myotherext','2.0')]::omni_manifest.requirement[]::text
-- alternatively,
select array [row ('myext','1.0'),row ('myotherext','2.0')]::omni_manifest.requirement[]::json
array
--------------------------
myext=1.0,myotherext=2.0
(1 row)
# -- alternatively,
omni_manifest=# select array[row('myext','1.0'),row('myotherext','2.0')]::omni_manifest.requirement[]::json;
array
-------------------------------------------
{ "myext" : "1.0", "myotherext" : "2.0" }
(1 row)
Artifact¶
Artifact is a composite type (omni_manifest.artifact
) that consists of a requirement (self
,
typed omni_manifest.requirement
) followed by its versioned requirements (requirements
of omni_manifest.requirement[]
).
It can be constructed with the omni_manifest.artifact
function:
self | requirements
-----------+------------------------------------
(ext,3.0) | {"(myext,1.0)","(myotherext,2.0)"}
(1 row)
Besides that, artifacts can be constructed from and deconstructed to both text and JSON forms.
The text form of a single artifact is the text representation of a requirement optionally followed by #
(the hash
sign) with a text representation of a list of requirements:
The text form of multiple artifacts is a semicolon-separated list:
Tip
For convenience, newline is also allowed instead of the semicolon:
JSON representation is a JSON list of objects with a target
property containing the target requirement,
and requirements
property containing all the requirements:
[
{
"target": {
"omni_manifest": "1.0"
},
"requirements": {}
},
{
"target": {
"omni_httpd": "1.0"
},
"requirements": {
"omni_http": "1.0"
}
}
]
Examples¶
From¶
select *
from
unnest('omni_manifest=1.0;omni_httpd=1.0#omni_http=1.0'::text::omni_manifest.artifact[]);
-- alternatively,
select *
from
unnest('[{"target" : {"omni_manifest" : "1.0"}, "requirements" : {}}, {"target" : {"omni_httpd" : "1.0"}, "requirements" : { "omni_http" : "1.0" }}]'::json::omni_manifest.artifact[]);
self | requirements
---------------------+---------------------
(omni_manifest,1.0) |
(omni_httpd,1.0) | {"(omni_http,1.0)"}
(2 rows)
To¶
select
'[{"target" : {"omni_manifest" : "1.0"}, "requirements" : {}}, {"target" : {"omni_httpd" : "1.0"}, "requirements" : { "omni_http" : "1.0" }}]'::json::omni_manifest.artifact[]::text;
Install Plan¶
From an array of artifacts, omni_manifest.install_plan
can be used to show the order in which all extensions will be
installed to satisfy the requirements.
select *
from
unnest(omni_manifest.install_plan(
array [omni_manifest.artifact('ext=3.0'::text,
'myext=1.0,myotherext=2.0'::text),
omni_manifest.artifact('ext2=3.0'::text, 'myext=1.0'::text) ])) with ordinality t(name, version, position)
name | version | position
------------+---------+----------
myext | 1.0 | 1
myotherext | 2.0 | 2
ext | 3.0 | 3
ext2 | 3.0 | 4
(4 rows)
Tip
This step is not necessary for installation. It is primarily used to preview the steps that the install step will take.
Install¶
Similar to install_plan
, omni_manifest.install
takes an array of artifacts and attempts to install them. It returns
a set of omni_manifest.install_report
composite type values. Each row contains a requirement (requirement
) and
status (status
, typed requirement_status
, an enum of installed
, missing
, updated
or kept
.
For each effective requirement in the install plan, it'll attempt to install a given version. If one is not available,
it'll report it as missing
, otherwise, if a different version is installed it'll try to update and report it updated
if successful. Otherwise, it'll try to install it and return a value of installed
, unless such version is already
installed, at which point it'll return kept
.
Install transactionally
It is highly recommended to perform installations transactionally to be able to check reports for missing dependencies.