exchange_do_amount_specific.sql (2592B)
1 -- 2 -- This file is part of TALER 3 -- Copyright (C) 2014--2022 Taler Systems SA 4 -- 5 -- TALER is free software; you can redistribute it and/or modify it under the 6 -- terms of the GNU General Public License as published by the Free Software 7 -- Foundation; either version 3, or (at your option) any later version. 8 -- 9 -- TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 -- A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 -- 13 -- You should have received a copy of the GNU General Public License along with 14 -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 -- 16 17 -------------------------------------------------------------- 18 -- Taler amounts and helper functions 19 ------------------------------------------------------------- 20 21 CREATE OR REPLACE FUNCTION amount_normalize( 22 IN amount taler_amount 23 ,OUT normalized taler_amount 24 ) 25 LANGUAGE plpgsql 26 AS $$ 27 BEGIN 28 normalized.val = amount.val + amount.frac / 100000000; 29 normalized.frac = amount.frac % 100000000; 30 END $$; 31 32 COMMENT ON FUNCTION amount_normalize 33 IS 'Returns the normalized amount by adding to the .val the value of (.frac / 100000000) and removing the modulus 100000000 from .frac.'; 34 35 CREATE OR REPLACE FUNCTION amount_add( 36 IN a taler_amount 37 ,IN b taler_amount 38 ,OUT sum taler_amount 39 ) 40 LANGUAGE plpgsql 41 AS $$ 42 BEGIN 43 sum = (a.val + b.val, a.frac + b.frac); 44 SELECT * 45 INTO sum 46 FROM amount_normalize(sum); 47 48 IF (sum.val > (1<<52)) 49 THEN 50 RAISE EXCEPTION 'addition overflow'; 51 END IF; 52 END $$; 53 54 COMMENT ON FUNCTION amount_add 55 IS 'Returns the normalized sum of two amounts. It raises an exception when the resulting .val is larger than 2^52'; 56 57 CREATE OR REPLACE FUNCTION amount_left_minus_right( 58 IN l taler_amount 59 ,IN r taler_amount 60 ,OUT diff taler_amount 61 ,OUT ok BOOLEAN 62 ) 63 LANGUAGE plpgsql 64 AS $$ 65 BEGIN 66 67 IF (l.val > r.val) 68 THEN 69 ok = TRUE; 70 IF (l.frac >= r.frac) 71 THEN 72 diff.val = l.val - r.val; 73 diff.frac = l.frac - r.frac; 74 ELSE 75 diff.val = l.val - r.val - 1; 76 diff.frac = l.frac + 100000000 - r.frac; 77 END IF; 78 ELSE 79 IF (l.val = r.val) AND (l.frac >= r.frac) 80 THEN 81 diff.val = 0; 82 diff.frac = l.frac - r.frac; 83 ok = TRUE; 84 ELSE 85 diff = (-1, -1); 86 ok = FALSE; 87 END IF; 88 END IF; 89 90 RETURN; 91 END $$; 92 93 COMMENT ON FUNCTION amount_left_minus_right 94 IS 'Subtracts the right amount from the left and returns the difference and TRUE, if the left amount is larger than the right, or an invalid amount and FALSE otherwise.';