Files
2025-12-17 13:02:12 +01:00

266 lines
7.9 KiB
Markdown

# XLIB_COMPONENT
## Package Specification
```sql
PACKAGE "XLIB_COMPONENT"
AS
/*=========================================================================
$Id: xlib_component.pks 57 2013-05-13 07:09:51Z dietmar.aust $
Purpose :
License : Copyright (c) 2010 Dietmar Aust (opal-consulting.de)
Licensed under a BSD style license (license.txt)
http://www.opal-consulting.de/pls/apex/f?p=20090928:14
$LastChangedDate: 2013-05-13 09:09:51 +0200 (Mon, 13 May 2013) $
$LastChangedBy: dietmar.aust $
Date Author Comment
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
06.01.2010 D. Aust Initial creation
=========================================================================*/
-- how many digits does the version key have?
-- 3 => e.g. 1.0.0
-- 4 => e.g. 1.0.0.0
c_num_version_components CONSTANT NUMBER := 6;
PROCEDURE create_component (
p_name xlib_components.comp_name%TYPE,
p_version xlib_components.comp_version%TYPE,
p_version_label xlib_components.comp_version_label%TYPE DEFAULT NULL,
p_depends_on xlib_components.comp_depends_on%TYPE DEFAULT NULL
);
PROCEDURE set_component (
p_name xlib_components.comp_name%TYPE,
p_version xlib_components.comp_version%TYPE,
p_version_label xlib_components.comp_version_label%TYPE DEFAULT NULL,
p_depends_on xlib_components.comp_depends_on%TYPE DEFAULT NULL
);
PROCEDURE delete_component (p_name IN xlib_components.comp_name%TYPE);
/*****
utility functions
****/
FUNCTION get_version (p_name IN xlib_components.comp_name%TYPE)
RETURN xlib_components.comp_version%TYPE;
FUNCTION make_version_string (p_version IN VARCHAR2)
RETURN VARCHAR2;
PROCEDURE verify_required_component (
p_comp_name IN VARCHAR2,
p_comp_version_min IN VARCHAR2
);
END xlib_component;```
## Package Body
```sql
PACKAGE BODY "XLIB_COMPONENT"
AS
/*=========================================================================
FILE : $Id: xlib_component.pkb 57 2013-05-13 07:09:51Z dietmar.aust $
=========================================================================*/
TYPE vc2_arr_t IS TABLE OF VARCHAR2 (32767 CHAR)
INDEX BY BINARY_INTEGER;
PROCEDURE create_component (
p_name xlib_components.comp_name%TYPE,
p_version xlib_components.comp_version%TYPE,
p_version_label xlib_components.comp_version_label%TYPE DEFAULT NULL,
p_depends_on xlib_components.comp_depends_on%TYPE DEFAULT NULL
)
IS
BEGIN
INSERT INTO xlib_components
(comp_id, comp_name, comp_version, comp_version_label, comp_depends_on
)
VALUES (xlib_seq.NEXTVAL, p_name, p_version, p_version_label, p_depends_on
);
END;
PROCEDURE set_component (
p_name xlib_components.comp_name%TYPE,
p_version xlib_components.comp_version%TYPE,
p_version_label xlib_components.comp_version_label%TYPE DEFAULT NULL,
p_depends_on xlib_components.comp_depends_on%TYPE DEFAULT NULL
)
IS
BEGIN
INSERT INTO xlib_components
(comp_id, comp_name, comp_version, comp_version_label, comp_depends_on
)
VALUES (xlib_seq.NEXTVAL, p_name, p_version, p_version_label, p_depends_on
);
EXCEPTION
WHEN DUP_VAL_ON_INDEX
THEN
UPDATE xlib_components
SET comp_version = p_version,
comp_version_label = p_version_label,
comp_depends_on = p_depends_on
WHERE comp_name = p_name;
IF SQL%ROWCOUNT = 0
THEN
raise_application_error (-20006,
'component ' || p_name || ' not found'
);
END IF;
END;
PROCEDURE delete_component (p_name IN xlib_components.comp_name%TYPE)
IS
BEGIN
-- delete component
DELETE FROM xlib_components
WHERE comp_name = p_name;
IF SQL%ROWCOUNT = 0
THEN
raise_application_error (-20001,
'Component ' || p_name || ' not found'
);
END IF;
END;
FUNCTION split_string (p_str IN VARCHAR2, p_sep IN VARCHAR2 DEFAULT ',')
RETURN vc2_arr_t
AS
l_string VARCHAR2 (32767) := p_str || p_sep;
l_sep_index PLS_INTEGER;
l_index PLS_INTEGER := 1;
l_tab vc2_arr_t;
BEGIN
-- assertions
IF LENGTH (p_sep) != 1
THEN
raise_application_error
(-20004,
'wrong separator format, must be only one character'
);
END IF;
LOOP
l_sep_index := INSTR (l_string, p_sep, l_index);
EXIT WHEN l_sep_index = 0;
l_tab (l_tab.COUNT) :=
SUBSTR (l_string, l_index, l_sep_index - l_index);
l_index := l_sep_index + 1;
END LOOP;
RETURN l_tab;
END;
FUNCTION get_version (p_name IN xlib_components.comp_name%TYPE)
RETURN xlib_components.comp_version%TYPE
IS
l_version xlib_components.comp_version%TYPE;
BEGIN
SELECT comp_version
INTO l_version
FROM xlib_components
WHERE comp_name = p_name;
RETURN l_version;
END;
PROCEDURE assert_version_format (p_version IN VARCHAR2)
IS
l_tab vc2_arr_t;
l_num NUMBER;
BEGIN
-- '.' at the beginning or end of the version?
IF SUBSTR (p_version, 1, 1) = '.'
OR SUBSTR (p_version, LENGTH (p_version), 1) = '.'
OR INSTR (p_version, ' ') > 0
THEN
raise_application_error (-20002, 'wrong version format');
END IF;
l_tab := split_string (p_version, '.');
FOR i IN 0 .. l_tab.COUNT - 1
LOOP
l_num := TO_NUMBER (l_tab (i));
END LOOP;
EXCEPTION
WHEN OTHERS
THEN
IF SQLCODE = -6502 /* numeric or value error */
THEN
raise_application_error (-20005,
'wrong version format, no numbers.'
);
ELSE
RAISE;
END IF;
END;
FUNCTION make_version_string (p_version IN VARCHAR2)
RETURN VARCHAR2
IS
l_num_dots NUMBER;
l_tab vc2_arr_t;
l_str VARCHAR2 (32767 CHAR);
l_comp VARCHAR2 (50 CHAR);
BEGIN
-- assertions
assert_version_format (p_version => p_version);
l_tab := split_string (p_version, '.');
FOR i IN 1 .. c_num_version_components
LOOP
IF l_tab.EXISTS (i - 1)
THEN
l_comp :=
TO_CHAR (TO_NUMBER (NVL (l_tab (i - 1), '0')), 'FM0000');
ELSE
l_comp := '0000';
END IF;
IF l_str IS NULL
THEN
l_str := l_comp;
ELSE
l_str := l_str || '.' || l_comp;
END IF;
END LOOP;
RETURN l_str;
END;
PROCEDURE verify_required_component (
p_comp_name IN VARCHAR2,
p_comp_version_min IN VARCHAR2
)
IS
l_current_version VARCHAR2 (50);
BEGIN
l_current_version := xlib_component.get_version (p_name => p_comp_name);
IF make_version_string (l_current_version)
>= make_version_string (p_comp_version_min)
THEN
NULL; -- ok
ELSE
raise_application_error
(-20020,
'this upgrade requires '||p_comp_name||' in version '
|| p_comp_version_min
|| ' or higher, not version '
|| l_current_version
);
END IF;
END;
END xlib_component;```