266 lines
7.9 KiB
Markdown
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;```
|