merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

merchant-0047.sql (2685B)


      1 --
      2 -- This file is part of TALER
      3 -- Copyright (C) 2026 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 -- @file merchant-0047.sql
     18 -- @brief Advance order sequences past retained contracts after migration 0036
     19 --
     20 -- Run database upgrades with merchant writers stopped. This prevents further
     21 -- serial reuse; it does not renumber orders already assigned low serials or
     22 -- repair existing collisions. Historical listing order therefore stays as is.
     23 
     24 BEGIN;
     25 
     26 SELECT _v.register_patch('merchant-0047', NULL, NULL);
     27 
     28 SET search_path TO merchant;
     29 
     30 CREATE PROCEDURE merchant.merchant_0047_init(s TEXT)
     31   LANGUAGE plpgsql
     32   AS $OUTER$
     33 DECLARE
     34   order_sequence REGCLASS;
     35   current_next NUMERIC;
     36   required_next NUMERIC;
     37   max_serial INT8;
     38 BEGIN
     39   EXECUTE format('SET LOCAL search_path TO %I', s);
     40   LOCK TABLE merchant_orders, merchant_contract_terms IN ACCESS EXCLUSIVE MODE;
     41 
     42   order_sequence := pg_get_serial_sequence(
     43     format('%I.merchant_orders', s), 'order_serial')::REGCLASS;
     44   EXECUTE format(
     45     'SELECT last_value::NUMERIC + CASE WHEN is_called THEN 1 ELSE 0 END FROM %s',
     46     order_sequence)
     47     INTO current_next;
     48   SELECT GREATEST(
     49            COALESCE((SELECT MAX(order_serial)::NUMERIC FROM merchant_orders), 0),
     50            COALESCE((SELECT MAX(order_serial)::NUMERIC FROM merchant_contract_terms), 0)) + 1
     51     INTO required_next;
     52   SELECT seqmax INTO max_serial FROM pg_sequence WHERE seqrelid = order_sequence;
     53   IF GREATEST(current_next, required_next) > max_serial THEN
     54     RAISE EXCEPTION 'Order serial sequence exhausted for instance %', s;
     55   END IF;
     56 
     57   -- Unlike setval(), RESTART is rolled back if a later instance fixup fails.
     58   -- Leave already-safe sequences alone, including their is_called state.
     59   IF current_next < required_next THEN
     60     EXECUTE format('ALTER SEQUENCE %s RESTART WITH %s',
     61                    order_sequence, required_next);
     62   END IF;
     63 
     64   SET LOCAL search_path TO merchant;
     65 END
     66 $OUTER$;
     67 
     68 INSERT INTO merchant.instance_fixups
     69   (migration_name, version)
     70   VALUES ('merchant_0047_init', 47);
     71 CALL merchant.fixup_instance_schema (47::INT8);
     72 
     73 COMMIT;