58 lines
1.5 KiB
PL/PgSQL
58 lines
1.5 KiB
PL/PgSQL
-- Deploy camper:parse_price to pg
|
|
-- requires: roles
|
|
-- requires: schema_camper
|
|
|
|
begin;
|
|
|
|
set search_path to camper, public;
|
|
|
|
create or replace function parse_price(price text, decimal_digits integer default 2) returns integer as
|
|
$$
|
|
declare
|
|
parts text[];
|
|
result int;
|
|
frac_part text;
|
|
sign int := 1;
|
|
begin
|
|
if price like '-%' Then
|
|
sign := -1;
|
|
price := substring(price from 2);
|
|
end if;
|
|
|
|
parts := string_to_array(price, '.');
|
|
if array_length(parts, 1) > 2 then
|
|
raise invalid_parameter_value using message = price || ' is not a valid price representation.';
|
|
end if;
|
|
|
|
result := parts[1]::integer;
|
|
if result is null then
|
|
raise invalid_parameter_value using message = price || ' is not a valid price representation.';
|
|
end if;
|
|
for d in 1..decimal_digits loop
|
|
result := result * 10;
|
|
end loop;
|
|
|
|
if array_length(parts, 1) = 2 then
|
|
frac_part := rtrim(parts[2], '0');
|
|
if length(frac_part) > decimal_digits then
|
|
raise invalid_parameter_value using message = price || ' has too many digits in the fraction part.';
|
|
end if;
|
|
frac_part := rpad(frac_part, decimal_digits, '0');
|
|
result := result + frac_part::integer;
|
|
end if;
|
|
|
|
return sign * result;
|
|
end;
|
|
$$
|
|
language plpgsql
|
|
immutable;
|
|
|
|
comment on function parse_price(text, integer) is
|
|
'Converts the string representation of a price in decimal form to cents, according to the number of decimal digits passed.';
|
|
|
|
revoke execute on function parse_price(text, integer) from public;
|
|
grant execute on function parse_price(text, integer) to employee;
|
|
grant execute on function parse_price(text, integer) to admin;
|
|
|
|
commit;
|