taler-api-procedures.sql (3778B)
1 -- 2 -- This file is part of TALER 3 -- Copyright (C) 2025 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 SET search_path TO taler_api; 17 18 -- Remove all existing functions 19 DO 20 $do$ 21 DECLARE 22 _sql text; 23 BEGIN 24 SELECT INTO _sql 25 string_agg(format('DROP %s %s CASCADE;' 26 , CASE prokind 27 WHEN 'f' THEN 'FUNCTION' 28 WHEN 'p' THEN 'PROCEDURE' 29 END 30 , oid::regprocedure) 31 , E'\n') 32 FROM pg_proc 33 WHERE pronamespace = 'taler_api'::regnamespace; 34 35 IF _sql IS NOT NULL THEN 36 EXECUTE _sql; 37 END IF; 38 END 39 $do$; 40 41 CREATE FUNCTION taler_transfer( 42 IN in_amount taler_amount, 43 IN in_exchange_base_url TEXT, 44 IN in_subject TEXT, 45 IN in_credit_payto TEXT, 46 IN in_request_uid BYTEA, 47 IN in_wtid BYTEA, 48 IN in_now INT8, 49 -- Error status 50 OUT out_request_uid_reuse BOOLEAN, 51 OUT out_wtid_reuse BOOLEAN, 52 -- Success return 53 OUT out_transfer_row_id INT8, 54 OUT out_created_at INT8 55 ) 56 LANGUAGE plpgsql AS $$ 57 BEGIN 58 -- Check for idempotence and conflict 59 SELECT (amount != in_amount 60 OR credit_payto != in_credit_payto 61 OR exchange_base_url != in_exchange_base_url 62 OR wtid != in_wtid) 63 ,transfer_id, created_at 64 INTO out_request_uid_reuse, out_transfer_row_id, out_created_at 65 FROM transfer 66 WHERE request_uid = in_request_uid; 67 IF FOUND THEN 68 RETURN; 69 END IF; 70 -- Check for wtid reuse 71 out_wtid_reuse = EXISTS(SELECT FROM transfer WHERE wtid=in_wtid); 72 IF out_wtid_reuse THEN 73 RETURN; 74 END IF; 75 out_created_at=in_now; 76 -- Register exchange 77 INSERT INTO transfer ( 78 amount, 79 exchange_base_url, 80 subject, 81 credit_payto, 82 request_uid, 83 wtid, 84 status, 85 status_msg, 86 created_at 87 ) VALUES ( 88 in_amount, 89 in_exchange_base_url, 90 in_subject, 91 in_credit_payto, 92 in_request_uid, 93 in_wtid, 94 'success', 95 NULL, 96 in_now 97 ) RETURNING transfer_id INTO out_transfer_row_id; 98 -- Notify new transaction 99 PERFORM pg_notify('outgoing_tx', out_transfer_row_id || ''); 100 END $$; 101 COMMENT ON FUNCTION taler_transfer IS 'Create an outgoing taler transaction and register it'; 102 103 CREATE FUNCTION add_incoming( 104 IN in_amount taler_amount, 105 IN in_subject TEXT, 106 IN in_debit_payto TEXT, 107 IN in_type incoming_type, 108 IN in_metadata BYTEA, 109 IN in_now INT8, 110 -- Error status 111 OUT out_reserve_pub_reuse BOOLEAN, 112 -- Success return 113 OUT out_tx_row_id INT8, 114 OUT out_created_at INT8 115 ) 116 LANGUAGE plpgsql AS $$ 117 BEGIN 118 -- Check conflict 119 SELECT in_type = 'reserve'::incoming_type AND EXISTS(SELECT FROM tx_in WHERE metadata = in_metadata AND type = 'reserve') 120 INTO out_reserve_pub_reuse; 121 IF out_reserve_pub_reuse THEN 122 RETURN; 123 END IF; 124 -- Register incoming transaction 125 out_created_at=in_now; 126 INSERT INTO tx_in ( 127 amount, 128 debit_payto, 129 created_at, 130 subject, 131 type, 132 metadata, 133 origin_exchange_url 134 ) VALUES ( 135 in_amount, 136 in_debit_payto, 137 in_now, 138 in_subject, 139 in_type, 140 in_metadata, 141 NULL 142 ) RETURNING tx_in_id INTO out_tx_row_id; 143 -- Notify new incoming transaction 144 PERFORM pg_notify('incoming_tx', out_tx_row_id || ''); 145 END $$; 146 COMMENT ON FUNCTION add_incoming IS 'Create an incoming taler transaction and register it';