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