RPM
DDL scriptPackage source
Legend: string keyword reserved word operator
1: PACKAGE rpm AS
2: FUNCTION vercmp(
3: e1 VARCHAR2, v1 VARCHAR2, r1 VARCHAR2,
4: e2 VARCHAR2, v2 VARCHAR2, r2 VARCHAR2)
5: RETURN NUMBER
6: DETERMINISTIC
7: PARALLEL_ENABLE;
8: PRAGMA RESTRICT_REFERENCES(vercmp, WNDS, RNDS);
9: FUNCTION vercmpCounter
10: return NUMBER
11: DETERMINISTIC
12: PARALLEL_ENABLE;
13: PRAGMA RESTRICT_REFERENCES(vercmpCounter, WNDS, RNDS);
14: FUNCTION vercmpResetCounter
15: return NUMBER
16: DETERMINISTIC
17: PARALLEL_ENABLE;
18: PRAGMA RESTRICT_REFERENCES(vercmpResetCounter, WNDS, RNDS);
19: END rpm;
Package body source
Legend: string keyword reserved word operator
1: PACKAGE BODY rpm AS
2: vercmp_counter NUMBER := 0;
3: FUNCTION isdigit(ch CHAR)
4: RETURN BOOLEAN
5: IS
6: BEGIN
7: if ascii(ch) between ascii('0') and ascii('9')
8: then
9: return TRUE;
10: end if;
11: return FALSE;
12: END isdigit;
13: FUNCTION isalpha(ch CHAR)
14: RETURN BOOLEAN
15: IS
16: BEGIN
17: if ascii(ch) between ascii('a') and ascii('z') or
18: ascii(ch) between ascii('A') and ascii('Z')
19: then
20: return TRUE;
21: end if;
22: return FALSE;
23: END isalpha;
24: FUNCTION isalphanum(ch CHAR)
25: RETURN BOOLEAN
26: IS
27: BEGIN
28: if ascii(ch) between ascii('a') and ascii('z') or
29: ascii(ch) between ascii('A') and ascii('Z') or
30: ascii(ch) between ascii('0') and ascii('9')
31: then
32: return TRUE;
33: end if;
34: return FALSE;
35: END isalphanum;
36: FUNCTION rpmstrcmp (string1 IN VARCHAR2, string2 IN VARCHAR2)
37: RETURN NUMBER
38: IS
39: digits CHAR(10) := '0123456789';
40: lc_alpha CHAR(27) := 'abcdefghijklmnopqrstuvwxyz';
41: uc_alpha CHAR(27) := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
42: alpha CHAR(54) := lc_alpha || uc_alpha;
43: str1 VARCHAR2(32767) := string1;
44: str2 VARCHAR2(32767) := string2;
45: one VARCHAR2(32767);
46: two VARCHAR2(32767);
47: isnum BOOLEAN;
48: BEGIN
49: if str1 is NULL or str2 is NULL
50: then
51: raise VALUE_ERROR;
52: end if;
53: if str1 = str2
54: then
55: return 0;
56: end if;
57: one := str1;
58: two := str2;
59: <<segment_loop>>
60: while one is not null and two is not null
61: loop
62: declare
63: segm1 VARCHAR2(32767);
64: segm2 VARCHAR2(32767);
65: begin
66: while one is not null and not isalphanum(one)
67: loop
68: one := substr(one, 2);
69: end loop;
70: while two is not null and not isalphanum(two)
71: loop
72: two := substr(two, 2);
73: end loop;
74: str1 := one;
75: str2 := two;
76:
77:
78:
79: if str1 is not null and isdigit(str1)
80: then
81: str1 := ltrim(str1, digits);
82: str2 := ltrim(str2, digits);
83: isnum := true;
84: else
85: str1 := ltrim(str1, alpha);
86: str2 := ltrim(str2, alpha);
87: isnum := false;
88: end if;
89: if str1 is not null
90: then segm1 := substr(one, 1, length(one) - length(str1));
91: else segm1 := one;
92: end if;
93: if str2 is not null
94: then segm2 := substr(two, 1, length(two) - length(str2));
95: else segm2 := two;
96: end if;
97:
98:
99: if segm1 is null then return -1; end if;
100: if segm2 is null then
101: if isnum then
102: return 1;
103: else
104: return -1;
105: end if;
106: end if;
107: if isnum
108: then
109:
110:
111:
112:
113: segm1 := ltrim(segm1, '0');
114: segm2 := ltrim(segm2, '0');
115:
116: if segm1 is null and segm2 is not null
117: then
118: return -1;
119: end if;
120: if segm1 is not null and segm2 is null
121: then
122: return 1;
123: end if;
124: if length(segm1) > length(segm2) then return 1; end if;
125: if length(segm2) > length(segm1) then return -1; end if;
126: end if;
127:
128:
129:
130:
131: if segm1 < segm2 then return -1; end if;
132: if segm1 > segm2 then return 1; end if;
133: one := str1;
134: two := str2;
135: end;
136: end loop segment_loop;
137:
138:
139:
140: if one is null and two is null then return 0; end if;
141:
142: if one is null then return -1; end if;
143: return 1;
144: END rpmstrcmp;
145: FUNCTION vercmp(
146: e1 VARCHAR2, v1 VARCHAR2, r1 VARCHAR2,
147: e2 VARCHAR2, v2 VARCHAR2, r2 VARCHAR2)
148: RETURN NUMBER
149: IS
150: rc NUMBER;
151: BEGIN
152: DECLARE
153: ep1 NUMBER;
154: ep2 NUMBER;
155: BEGIN
156: vercmp_counter := vercmp_counter + 1;
157: if e1 is null then
158: ep1 := 0;
159: else
160: ep1 := TO_NUMBER(e1);
161: end if;
162: if e2 is null then
163: ep2 := 0;
164: else
165: ep2 := TO_NUMBER(e2);
166: end if;
167: if ep1 < ep2 then return -1; end if;
168: if ep1 > ep2 then return 1; end if;
169: rc := rpmstrcmp(v1, v2);
170: if rc != 0 then return rc; end if;
171: return rpmstrcmp(r1, r2);
172: END;
173: END vercmp;
174: FUNCTION vercmpCounter
175: RETURN NUMBER
176: IS
177: BEGIN
178: return vercmp_counter;
179: END vercmpCounter;
180: FUNCTION vercmpResetCounter
181: RETURN NUMBER
182: IS
183: result NUMBER;
184: BEGIN
185: result := vercmp_counter;
186: vercmp_counter := 0;
187: return result;
188: END vercmpResetCounter;
189: END rpm;