📄 c_functions.sql
字号:
-- Helper functions---- VoIP Billing Platform for GnuGk-- Copyright (c) 2004, Michal Zygmuntowicz---- This work is published under the GNU Public License (GPL)-- see file COPYING for details-- This function translates '=XX' ASCII escape sequences-- back to ASCI characters-- This is required because FreeRADIUS escapes strings before-- passing them to the SQL backendCREATE OR REPLACE FUNCTION radius_xlat(TEXT) RETURNS TEXT AS'DECLARE input_str TEXT; xlated_str TEXT; hex_str TEXT; eq_pos INT; hexcode INT;BEGIN input_str := $1; xlated_str := ''''; LOOP -- find =XX escape hex_str := substring(input_str from ''=[0-9A-Fa-f][0-9A-Fa-f]''); EXIT WHEN hex_str IS NULL OR input_str = ''''; IF length(hex_str) < 1 THEN eq_pos := 0; ELSE eq_pos := position(hex_str in input_str); END IF; EXIT WHEN eq_pos = 0; -- append to the result substring preceeding =XX xlated_str := xlated_str || substring(input_str from 1 for (eq_pos-1)); -- remove the processed substring from the input string input_str := substring(input_str from eq_pos + 3); -- convert hex to integer hex_str := lower(hex_str); eq_pos := ascii(substring(hex_str from 2 for 1)); IF eq_pos > ascii(''9'') THEN eq_pos := eq_pos - ascii(''a'') + 10; ELSE eq_pos := eq_pos - ascii(''0''); END IF; hexcode := eq_pos * 16; eq_pos := ascii(substring(hex_str from 3 for 1)); IF eq_pos > ascii(''9'') THEN eq_pos := eq_pos - ascii(''a'') + 10; ELSE eq_pos := eq_pos - ascii(''0''); END IF; hexcode := hexcode + eq_pos; -- append ASCII char to the result xlated_str := xlated_str || chr(hexcode); END LOOP; -- append any remaining characters to the result xlated_str := xlated_str || input_str; RETURN xlated_str;END;' LANGUAGE 'plpgsql' IMMUTABLE RETURNS NULL ON NULL INPUT SECURITY INVOKER;-- This function tries to find a tariff with the longest prefix match-- $1 - E.164 number to match-- $2 - account that the tariff should apply to-- $3 - currency for the tariffCREATE OR REPLACE FUNCTION match_tariff(TEXT, INT, TEXT) RETURNS voiptariff AS'DECLARE trf voiptariff%ROWTYPE; dst voiptariffdst%ROWTYPE; e164 ALIAS FOR $1; accid ALIAS FOR $2; curr ALIAS FOR $3;BEGIN SELECT INTO trf.id NULL; SELECT INTO dst.id NULL; IF e164 IS NULL THEN RETURN trf; END IF; -- first try to find an exact match SELECT INTO dst * FROM voiptariffdst WHERE exactmatch AND prefix = e164 LIMIT 1; IF dst.id IS NOT NULL THEN -- check whether the destination is blocked or not IF NOT dst.active THEN RETURN trf; END IF; SELECT INTO trf T.id, T.dstid, T.grpid, T.price, T.currencysym, T.initialincrement, T.regularincrement, T.graceperiod, T.description, T.active FROM voiptariff T JOIN voiptariffgrp G ON T.grpid = G.id JOIN voiptariffsel S ON G.id = S.grpid WHERE NOT T.terminating AND T.dstid = dst.id AND T.currencysym = curr AND S.accountid = accid ORDER BY G.priority DESC LIMIT 1; IF FOUND AND trf.id IS NOT NULL THEN IF NOT trf.active THEN SELECT INTO trf.id NULL; END IF; RETURN trf; END IF; SELECT INTO trf * FROM voiptariff WHERE NOT terminating AND dstid = dst.id AND currencysym = curr AND grpid IS NULL AND active; RETURN trf; END IF; IF length(e164) > 0 THEN IF ascii(e164) >= 48 AND ascii(e164) <= 57 THEN SELECT INTO dst.id, dst.active, trf.id D.id, D.active, T.id FROM voiptariffdst D LEFT JOIN voiptariff T ON T.dstid = D.id LEFT JOIN voiptariffgrp G ON T.grpid = G.id LEFT JOIN voiptariffsel S ON S.grpid = G.id WHERE NOT D.exactmatch AND (e164 LIKE (D.prefix || ''%'')) AND NOT T.terminating AND T.currencysym = curr AND (T.grpid IS NULL OR S.accountid = accid) ORDER BY length(D.prefix) DESC, G.priority DESC LIMIT 1; ELSE SELECT INTO dst.id, dst.active, trf.id D.id, D.active, T.id FROM voiptariffdst D JOIN voiptariff T ON T.dstid = D.id JOIN voiptariffgrp G ON T.grpid = G.id JOIN voiptariffsel S ON S.grpid = G.id WHERE D.prefix = ''PC'' AND T.currencysym = curr AND S.accountid = accid ORDER BY G.priority DESC LIMIT 1; IF trf.id IS NULL THEN SELECT INTO dst.id, dst.active, trf.id D.id, D.active, T.id FROM voiptariffdst D LEFT JOIN voiptariff T ON T.dstid = D.id WHERE D.prefix = ''PC'' AND T.currencysym = curr AND T.grpid IS NULL LIMIT 1; END IF; END IF; IF trf.id IS NOT NULL THEN SELECT INTO trf * FROM voiptariff WHERE id = trf.id; END IF; END IF; -- no active destination found IF dst.id IS NULL OR trf.id IS NULL THEN SELECT INTO trf.id NULL; RETURN trf; END IF; IF NOT dst.active OR NOT trf.active THEN SELECT INTO trf.id NULL; END IF; RETURN trf;END;' LANGUAGE 'plpgsql' STABLE CALLED ON NULL INPUT SECURITY INVOKER;-- This function tries to find a tariff with the longest prefix match-- $1 - voiptariffdst identifier-- $2 - account that the tariff should apply to-- $3 - currency for the tariffCREATE OR REPLACE FUNCTION match_terminating_tariff(INT, INT, TEXT) RETURNS voiptariff AS'DECLARE trf voiptariff%ROWTYPE; dst_id ALIAS FOR $1; acc_id ALIAS FOR $2; curr ALIAS FOR $3;BEGIN SELECT INTO trf.id NULL; IF curr IS NULL OR dst_id IS NULL THEN RETURN trf; END IF; SELECT INTO trf T.id, T.dstid, T.grpid, T.price, T.currencysym, T.initialincrement, T.regularincrement, T.graceperiod, T.description, T.active FROM voiptariff T JOIN voiptariffgrp G ON T.grpid = G.id JOIN voiptariffsel S ON G.id = S.grpid WHERE T.terminating AND T.dstid = dst_id AND T.currencysym = curr AND S.accountid = acc_id ORDER BY G.priority DESC LIMIT 1; IF FOUND AND trf.id IS NOT NULL THEN IF NOT trf.active THEN SELECT INTO trf.id NULL; END IF; RETURN trf; END IF; SELECT INTO trf * FROM voiptariff WHERE terminating AND dstid = dst_id AND currencysym = curr AND grpid IS NULL AND active; RETURN trf;END;' LANGUAGE 'plpgsql' STABLE CALLED ON NULL INPUT SECURITY INVOKER;-- This function tries to find an user account based on the specified-- network address and/or H.323 identifier-- $1 - H.323 user's identifier to match-- $2 - user's IP address CREATE OR REPLACE FUNCTION match_user(TEXT, INET) RETURNS INT AS'DECLARE userh323id ALIAS FOR $1; userip ALIAS FOR $2; userid INT := NULL;BEGIN SELECT INTO userid id FROM voipuser WHERE NOT checkh323id AND framedip >>= userip AND NOT disabled; IF NOT FOUND OR userid IS NULL THEN SELECT INTO userid id FROM voipuser WHERE checkh323id AND h323id = userh323id AND NOT disabled; END IF; RETURN userid;END;' LANGUAGE 'plpgsql' STABLE CALLED ON NULL INPUT SECURITY INVOKER;-- This function tries to find a terminating user account based on the specified-- network address and/or H.323 identifier-- $1 - H.323 user's identifier or an E.164 number called-- $2 - whether the $1 is an H.323 Id or an E.164 number-- $3 - user's IP address CREATE OR REPLACE FUNCTION match_terminating_user(TEXT, BOOLEAN, INET) RETURNS voipuser AS'DECLARE userh323id ALIAS FOR $1; h323idmatch ALIAS FOR $2; userip ALIAS FOR $3; user voipuser%ROWTYPE;BEGIN user.id := NULL; IF h323idmatch THEN SELECT INTO user * FROM voipuser WHERE terminating AND h323id = userh323id AND NOT disabled; END IF; IF NOT FOUND OR user.id IS NULL THEN SELECT INTO user * FROM voipuser WHERE terminating AND framedip >>= userip AND NOT disabled; END IF; RETURN user;END;' LANGUAGE 'plpgsql' STABLE CALLED ON NULL INPUT SECURITY INVOKER;-- Converts 'T'/'F' string into a boolean valueCREATE OR REPLACE FUNCTION get_bool(TEXT) RETURNS BOOLEAN AS' SELECT CASE $1 WHEN ''T'' THEN TRUE ELSE FALSE END;' LANGUAGE SQL IMMUTABLE CALLED ON NULL INPUT SECURITY INVOKER;-- Parse nested attribute-value pairs and, optionally, extract-- a specific variable from the parsed attribute value-- $1 - av-pair to parse (example: 'h323-ivr-in=terminal-alias:123,456')-- $2 - attribute name to match (example: 'h323-ivr-in')-- $3 - NULL or a specific variable to extract from the value (example: 'terminal-alias')CREATE OR REPLACE FUNCTION parse_avpair(TEXT, TEXT, TEXT) RETURNS TEXT AS'DECLARE avpair ALIAS FOR $1; attrname ALIAS FOR $2; varname ALIAS FOR $3; parsedval TEXT; idx INT;BEGIN IF avpair IS NULL OR attrname IS NULL THEN RETURN NULL; END IF; parsedval := radius_xlat(avpair); idx := strpos(parsedval, attrname || ''=''); IF idx = 0 THEN RETURN NULL; END IF; parsedval := substring(parsedval, idx + length(attrname) + 1); IF varname IS NULL THEN RETURN parsedval; END IF; parsedval := substring(parsedval from varname || '':[^;]*''); idx := strpos(parsedval, '':''); IF idx > 0 THEN parsedval := substring(parsedval, idx + 1); END IF; RETURN parsedval;END;' LANGUAGE 'plpgsql' IMMUTABLE CALLED ON NULL INPUT SECURITY INVOKER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -