exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

commit d406945fa9c1e8f792dcbdc26260829b8af2a84c
parent 53687b03bb24e07f585b24b6734709349bfd1421
Author: Florian Dold <florian@dold.me>
Date:   Wed, 26 Mar 2025 14:43:43 +0100

Revert "adapt exchange_statistic_helpers.sql to exchange version of tables"

This reverts commit 257a54ddbc6755fb7ce9e11a0f7d3d588e4f3098.

Diffstat:
Msrc/exchangedb/exchange-xx10.sql | 2+-
Msrc/exchangedb/exchange_statistics_helpers.sql | 282+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
2 files changed, 177 insertions(+), 107 deletions(-)

diff --git a/src/exchangedb/exchange-xx10.sql b/src/exchangedb/exchange-xx10.sql @@ -151,7 +151,7 @@ BEGIN ,partition_suffix ); PERFORM comment_partitioned_table ( - 'various amount statistics being tracked', + 'various amount statistics (in various currencies) being tracked', ,'exchange_statistic_bucket_amount' ,partition_suffix ); diff --git a/src/exchangedb/exchange_statistics_helpers.sql b/src/exchangedb/exchange_statistics_helpers.sql @@ -14,7 +14,12 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- --- FIXME: add helper function to drop data based on new 'origin' field in _meta +-- FIXME: adapt procedures to changes in table structure for the exchange: +-- - remove multi-currency support, consistent use of exchange amount type +-- - replace instances by h_payto (or NULL!) +-- - new 'origin' field in _meta + + SET search_path TO exchange; DROP FUNCTION IF EXISTS interval_to_start; @@ -35,7 +40,7 @@ COMMENT ON FUNCTION interval_to_start DROP PROCEDURE IF EXISTS exchange_do_bump_number_bucket_stat; CREATE OR REPLACE PROCEDURE exchange_do_bump_number_bucket_stat( in_slug TEXT, - in_h_payto BYTEA, + in_exchange_serial BIGINT, in_timestamp TIMESTAMP, in_delta INT8 ) @@ -72,20 +77,20 @@ BEGIN UPDATE exchange_statistic_bucket_counter SET cumulative_number = cumulative_number + in_delta WHERE bmeta_serial_id=my_meta - AND h_payto=in_h_payto + AND exchange_serial=in_exchange_serial AND bucket_start=my_bucket_start AND bucket_range=my_range; IF NOT FOUND THEN INSERT INTO exchange_statistic_bucket_counter (bmeta_serial_id - ,h_payto + ,exchange_serial ,bucket_start ,bucket_range ,cumulative_number ) VALUES ( my_meta - ,in_h_payto + ,in_exchange_serial ,my_bucket_start ,my_range ,in_delta); @@ -98,9 +103,9 @@ END $$; DROP PROCEDURE IF EXISTS exchange_do_bump_amount_bucket_stat; CREATE OR REPLACE PROCEDURE exchange_do_bump_amount_bucket_stat( in_slug TEXT, - in_h_payto BYTEA, + in_exchange_serial BIGINT, in_timestamp TIMESTAMP, - in_delta taler_amount + in_delta taler_amount_currency ) LANGUAGE plpgsql AS $$ @@ -134,20 +139,20 @@ BEGIN UPDATE exchange_statistic_bucket_amount SET - cumulative_value.val = (cumulative_value).val + (in_delta).val + cumulative_value = cumulative_value + (in_delta).val + CASE - WHEN (in_delta).frac + (cumulative_value).frac >= 100000000 + WHEN (in_delta).frac + cumulative_frac >= 100000000 THEN 1 ELSE 0 END, - cumulative_value.frac = (cumulative_value).frac + (in_delta).frac + cumulative_frac = cumulative_frac + (in_delta).frac - CASE - WHEN (in_delta).frac + (cumulative_value).frac >= 100000000 + WHEN (in_delta).frac + cumulative_frac >= 100000000 THEN 100000000 ELSE 0 END WHERE bmeta_serial_id=my_meta - AND h_payto=in_h_payto + AND exchange_serial=in_exchange_serial AND curr=(in_delta).curr AND bucket_start=my_bucket_start AND bucket_range=my_range; @@ -155,16 +160,20 @@ BEGIN THEN INSERT INTO exchange_statistic_bucket_amount (bmeta_serial_id - ,h_payto + ,exchange_serial ,bucket_start ,bucket_range + ,curr ,cumulative_value + ,cumulative_frac ) VALUES ( my_meta - ,in_h_payto + ,in_exchange_serial ,my_bucket_start ,my_range - ,in_delta); + ,(in_delta).curr + ,(in_delta).val + ,(in_delta).frac); END IF; END LOOP; CLOSE my_curs; @@ -177,7 +186,7 @@ COMMENT ON PROCEDURE exchange_do_bump_amount_bucket_stat DROP PROCEDURE IF EXISTS exchange_do_bump_number_interval_stat; CREATE OR REPLACE PROCEDURE exchange_do_bump_number_interval_stat( in_slug TEXT, - in_h_payto BYTEA, + in_exchange_serial BIGINT, in_timestamp TIMESTAMP, in_delta INT8 ) @@ -231,15 +240,15 @@ BEGIN INSERT INTO exchange_statistic_counter_event AS msce (imeta_serial_id - ,h_payto + ,exchange_serial ,slot ,delta) VALUES (my_meta - ,in_h_payto + ,in_exchange_serial ,my_start ,in_delta) - ON CONFLICT (imeta_serial_id, h_payto, slot) + ON CONFLICT (imeta_serial_id, exchange_serial, slot) DO UPDATE SET delta = msce.delta + in_delta RETURNING nevent_serial_id @@ -248,19 +257,19 @@ BEGIN UPDATE exchange_statistic_interval_counter SET cumulative_number = cumulative_number + in_delta WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = in_exchange_serial AND range=my_rangex; IF NOT FOUND THEN INSERT INTO exchange_statistic_interval_counter (imeta_serial_id - ,h_payto + ,exchange_serial ,range ,event_delimiter ,cumulative_number ) VALUES ( my_meta - ,in_h_payto + ,in_exchange_serial ,my_rangex ,my_event ,in_delta); @@ -274,9 +283,9 @@ COMMENT ON PROCEDURE exchange_do_bump_number_interval_stat DROP PROCEDURE IF EXISTS exchange_do_bump_amount_interval_stat; CREATE OR REPLACE PROCEDURE exchange_do_bump_amount_interval_stat( in_slug TEXT, - in_h_payto BYTEA, + in_exchange_serial BIGINT, in_timestamp TIMESTAMP, - in_delta taler_amount + in_delta taler_amount_currency -- new amount in table that we should add to the tracker ) LANGUAGE plpgsql AS $$ @@ -328,20 +337,20 @@ BEGIN INSERT INTO exchange_statistic_amount_event AS msae (imeta_serial_id - ,h_payto + ,exchange_serial ,slot ,delta_curr ,delta_value ,delta_frac ) VALUES ( my_meta - ,in_h_payto + ,in_exchange_serial ,my_start ,(in_delta).curr ,(in_delta).val ,(in_delta).frac ) - ON CONFLICT (imeta_serial_id, h_payto, slot, delta_curr) + ON CONFLICT (imeta_serial_id, exchange_serial, slot, delta_curr) DO UPDATE SET delta_value = msae.delta_value + (in_delta).val + CASE @@ -360,35 +369,40 @@ BEGIN UPDATE exchange_statistic_interval_amount SET - cumulative_value.val = (cumulative_value).val + (in_delta).val + cumulative_value = cumulative_value + (in_delta).val + CASE - WHEN (in_delta).frac + (cumulative_value).frac >= 100000000 + WHEN (in_delta).frac + cumulative_frac >= 100000000 THEN 1 ELSE 0 END, - cumulative_value.frac = (cumulative_value).frac + (in_delta).frac + cumulative_frac = cumulative_frac + (in_delta).frac - CASE - WHEN (in_delta).frac + (cumulative_value).frac >= 100000000 + WHEN (in_delta).frac + cumulative_frac >= 100000000 THEN 100000000 ELSE 0 END WHERE imeta_serial_id=my_meta - AND h_payto=in_h_payto - AND range=my_rangex; + AND exchange_serial=in_exchange_serial + AND range=my_rangex + AND curr=(in_delta).curr; IF NOT FOUND THEN INSERT INTO exchange_statistic_interval_amount (imeta_serial_id - ,h_payto + ,exchange_serial ,range ,event_delimiter + ,curr ,cumulative_value + ,cumulative_frac ) VALUES ( my_meta - ,in_h_payto + ,in_exchange_serial ,my_rangex ,my_event - ,in_delta); + ,(in_delta).curr + ,(in_delta).val + ,(in_delta).frac); END IF; END $$; COMMENT ON PROCEDURE exchange_do_bump_amount_interval_stat @@ -398,15 +412,15 @@ COMMENT ON PROCEDURE exchange_do_bump_amount_interval_stat DROP PROCEDURE IF EXISTS exchange_do_bump_number_stat; CREATE OR REPLACE PROCEDURE exchange_do_bump_number_stat( in_slug TEXT, - in_h_payto BYTEA, + in_exchange_serial BIGINT, in_timestamp TIMESTAMP, in_delta INT8 ) LANGUAGE plpgsql AS $$ BEGIN - CALL exchange_do_bump_number_bucket_stat (in_slug, in_h_payto, in_timestamp, in_delta); - CALL exchange_do_bump_number_interval_stat (in_slug, in_h_payto, in_timestamp, in_delta); + CALL exchange_do_bump_number_bucket_stat (in_slug, in_exchange_serial, in_timestamp, in_delta); + CALL exchange_do_bump_number_interval_stat (in_slug, in_exchange_serial, in_timestamp, in_delta); END $$; COMMENT ON PROCEDURE exchange_do_bump_number_stat IS 'Updates a numeric statistic (bucket or interval)'; @@ -415,15 +429,15 @@ COMMENT ON PROCEDURE exchange_do_bump_number_stat DROP PROCEDURE IF EXISTS exchange_do_bump_amount_stat; CREATE OR REPLACE PROCEDURE exchange_do_bump_amount_stat( in_slug TEXT, - in_h_payto BYTEA, + in_exchange_serial BIGINT, in_timestamp TIMESTAMP, - in_delta taler_amount + in_delta taler_amount_currency ) LANGUAGE plpgsql AS $$ BEGIN - CALL exchange_do_bump_amount_bucket_stat (in_slug, in_h_payto, in_timestamp, in_delta); - CALL exchange_do_bump_amount_interval_stat (in_slug, in_h_payto, in_timestamp, in_delta); + CALL exchange_do_bump_amount_bucket_stat (in_slug, in_exchange_serial, in_timestamp, in_delta); + CALL exchange_do_bump_amount_interval_stat (in_slug, in_exchange_serial, in_timestamp, in_delta); END $$; COMMENT ON PROCEDURE exchange_do_bump_amount_stat IS 'Updates an amount statistic (bucket or interval)'; @@ -432,7 +446,7 @@ COMMENT ON PROCEDURE exchange_do_bump_amount_stat DROP FUNCTION IF EXISTS exchange_statistic_interval_number_get; CREATE OR REPLACE FUNCTION exchange_statistic_interval_number_get ( IN in_slug TEXT, - IN in_h_payto BYTA + IN in_instance_id TEXT ) RETURNS SETOF exchange_statistic_interval_number_get_return_value LANGUAGE plpgsql @@ -444,12 +458,22 @@ DECLARE my_delta INT8; my_meta INT8; my_next_max_serial INT8; + my_instance_id INT8; my_rec RECORD; my_irec RECORD; my_i INT; my_min_serial INT8 DEFAULT NULL; my_rval exchange_statistic_interval_number_get_return_value; BEGIN + SELECT exchange_serial + INTO my_instance_id + FROM exchange_instances + WHERE exchange_id=in_instance_id; + IF NOT FOUND + THEN + RETURN; + END IF; + SELECT imeta_serial_id ,ranges ,precisions @@ -473,7 +497,7 @@ BEGIN FROM exchange_statistic_interval_counter WHERE imeta_serial_id = my_meta AND range = my_range - AND h_payto = in_h_payto; + AND exchange_serial = my_instance_id; IF FOUND THEN my_min_serial = my_irec.event_delimiter; @@ -484,7 +508,7 @@ BEGIN INTO my_irec FROM exchange_statistic_counter_event WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND slot < my_time - my_range AND nevent_serial_id >= my_min_serial; @@ -498,7 +522,7 @@ BEGIN INTO my_next_max_serial FROM exchange_statistic_counter_event WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND slot >= my_time - my_range AND nevent_serial_id >= my_min_serial ORDER BY slot ASC @@ -512,13 +536,13 @@ BEGIN SET cumulative_number = cumulative_number - my_delta, event_delimiter = my_next_max_serial WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND range = my_range; ELSE -- actually, slot is now empty, remove it entirely DELETE FROM exchange_statistic_interval_counter WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND range = my_range; END IF; IF (my_i < array_length(my_ranges,1)) @@ -528,19 +552,19 @@ BEGIN cumulative_number = cumulative_number + my_delta, event_delimiter = LEAST(usic.event_delimiter,my_min_serial) WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND range=my_ranges[my_i+1]; IF NOT FOUND THEN INSERT INTO exchange_statistic_interval_counter (imeta_serial_id - ,h_payto + ,exchange_serial ,range ,event_delimiter ,cumulative_number ) VALUES ( my_meta - ,in_h_payto + ,my_instance_id ,my_ranges[my_i+1] ,my_min_serial ,my_delta); @@ -549,7 +573,7 @@ BEGIN -- events are obsolete, delete them DELETE FROM exchange_statistic_counter_event WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND slot < my_time - my_range; END IF; END IF; @@ -578,9 +602,10 @@ DECLARE my_range INT8; my_delta_value INT8; my_delta_frac INT8; - my_delta taler_amount; my_meta INT8; + my_instance_id INT8; my_next_max_serial INT8; + my_currency TEXT; my_rec RECORD; my_irec RECORD; my_jrec RECORD; @@ -588,6 +613,15 @@ DECLARE my_min_serial INT8 DEFAULT NULL; my_rval exchange_statistic_interval_amount_get_return_value; BEGIN + SELECT exchange_serial + INTO my_instance_id + FROM exchange_instances + WHERE exchange_id=in_instance_id; + IF NOT FOUND + THEN + RETURN; + END IF; + SELECT imeta_serial_id ,ranges ,precisions @@ -602,25 +636,34 @@ BEGIN my_meta = my_rec.imeta_serial_id; my_ranges = my_rec.ranges; + FOR my_currency IN + SELECT DISTINCT delta_curr + FROM exchange_statistic_amount_event + WHERE imeta_serial_id = my_meta + LOOP + my_rval.rvalue.val = 0; my_rval.rvalue.frac = 0; + my_rval.rvalue.curr = my_currency; FOR my_i IN 1..COALESCE(array_length(my_ranges,1),0) LOOP my_range = my_ranges[my_i]; SELECT event_delimiter ,cumulative_value + ,cumulative_frac INTO my_irec FROM exchange_statistic_interval_amount WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id + AND curr = my_currency AND range = my_range; IF FOUND THEN my_min_serial = my_irec.event_delimiter; - my_rval.rvalue.val = (my_rval.rvalue).val + (my_irec.cumulative_value).val + (my_irec.cumulative_value).frac / 100000000; - my_rval.rvalue.frac = (my_rval.rvalue).frac + (my_irec.cumulative_value).frac % 100000000; + my_rval.rvalue.val = (my_rval.rvalue).val + my_irec.cumulative_value + my_irec.cumulative_frac / 100000000; + my_rval.rvalue.frac = (my_rval.rvalue).frac + my_irec.cumulative_frac % 100000000; IF (my_rval.rvalue).frac > 100000000 THEN my_rval.rvalue.frac = (my_rval.rvalue).frac - 100000000; @@ -633,7 +676,8 @@ BEGIN INTO my_jrec FROM exchange_statistic_amount_event WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id + AND delta_curr = my_currency AND slot < my_time - my_range AND aevent_serial_id >= my_min_serial; @@ -656,7 +700,8 @@ BEGIN INTO my_next_max_serial FROM exchange_statistic_amount_event WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id + AND delta_curr = my_currency AND slot >= my_time - my_range AND aevent_serial_id >= my_min_serial ORDER BY slot ASC @@ -665,71 +710,75 @@ BEGIN THEN -- remove expired events from the sum of the current slot UPDATE exchange_statistic_interval_amount SET - cumulative_value.val = (cumulative_value).val - my_delta_value + cumulative_value = cumulative_value - my_delta_value - CASE - WHEN (cumulative_value).frac < my_delta_frac + WHEN cumulative_frac < my_delta_frac THEN 1 ELSE 0 END, - cumulative_value.frac = (cumulative_value).frac - my_delta_frac + cumulative_frac = cumulative_frac - my_delta_frac + CASE - WHEN (cumulative_value).frac < my_delta_frac + WHEN cumulative_frac < my_delta_frac THEN 100000000 ELSE 0 END, event_delimiter = my_next_max_serial WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id + AND curr = my_currency AND range = my_range; ELSE -- actually, slot is now empty, remove it entirely DELETE FROM exchange_statistic_interval_amount WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id + AND curr = my_currency AND range = my_range; END IF; IF (my_i < array_length(my_ranges,1)) THEN -- carry over all events into the next (larger) slot UPDATE exchange_statistic_interval_amount AS msia SET - cumulative_value.val = (cumulative_value).val + my_delta_value + cumulative_value = cumulative_value + my_delta_value + CASE - WHEN (cumulative_value).frac + my_delta_frac > 100000000 + WHEN cumulative_frac + my_delta_frac > 100000000 THEN 1 ELSE 0 END, - cumulative_value.frac = (cumulative_value).frac + my_delta_value + cumulative_frac = cumulative_frac + my_delta_value - CASE - WHEN (cumulative_value).frac + my_delta_frac > 100000000 + WHEN cumulative_frac + my_delta_frac > 100000000 THEN 100000000 ELSE 0 END, event_delimiter = LEAST (msia.event_delimiter,my_min_serial) WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND range=my_ranges[my_i+1]; IF NOT FOUND THEN - my_delta.val = my_delta_value; - my_delta.frac = my_delta_frac; INSERT INTO exchange_statistic_interval_amount (imeta_serial_id - ,h_payto + ,exchange_serial ,event_delimiter ,range + ,curr ,cumulative_value + ,cumulative_frac ) VALUES ( my_meta - ,in_h_payto + ,my_instance_id ,my_min_serial ,my_ranges[my_i+1] - ,my_delta); + ,my_currency + ,my_delta_value + ,my_delta_frac); END IF; ELSE -- events are obsolete, delete them DELETE FROM exchange_statistic_amount_event WHERE imeta_serial_id = my_meta - AND h_payto = in_h_payto + AND exchange_serial = my_instance_id AND slot < my_time - my_range; END IF; END IF; @@ -738,10 +787,11 @@ BEGIN RETURN NEXT my_rval; END IF; END LOOP; -- over my_ranges + END LOOP; -- over my_currency END $$; COMMENT ON FUNCTION exchange_statistic_interval_amount_get - IS 'Returns deposit statistic tracking deposited amounts over certain time intervals; we first trim the stored data to only track what is still in-range, and then return the remaining value; multiple values are returned, one per range'; + IS 'Returns deposit statistic tracking deposited amounts over certain time intervals; we first trim the stored data to only track what is still in-range, and then return the remaining value; multiple values are returned, one per currency and range'; @@ -753,7 +803,8 @@ LANGUAGE plpgsql AS $$ DECLARE my_time INT8 DEFAULT ROUND(EXTRACT(epoch FROM CURRENT_TIMESTAMP(0)::TIMESTAMP) * 1000000)::INT8 / 1000 / 1000; - my_h_payto BYTEA; + my_instance INT8; + my_instance_name TEXT; my_rec RECORD; my_sum RECORD; my_meta INT8; @@ -767,8 +818,8 @@ DECLARE my_total INT8; BEGIN -- GC for all instances - FOR my_h_payto IN - SELECT DISTINCT h_payto + FOR my_instance IN + SELECT DISTINCT exchange_serial FROM exchange_statistic_counter_event LOOP -- Do combination work for all numeric statistic events @@ -780,7 +831,11 @@ BEGIN FROM exchange_statistic_interval_meta LOOP -- First, we query the current interval statistic to update its counters - PERFORM FROM exchange_statistic_interval_number_get (my_rec.slug, my_h_payto); + SELECT exchange_id + INTO my_instance_name + FROM exchange_instances + WHERE exchange_serial = my_instance; + PERFORM FROM exchange_statistic_interval_number_get (my_rec.slug, my_instance_name); my_meta = my_rec.imeta_serial_id; my_ranges = my_rec.ranges; @@ -812,7 +867,7 @@ BEGIN MIN(nevent_serial_id) AS rep_serial_id INTO my_sum FROM exchange_statistic_counter_event - WHERE h_payto=my_instance + WHERE exchange_serial=my_instance AND imeta_serial_id=my_meta AND slot >= my_time - max_slot AND slot < my_time - min_slot; @@ -827,7 +882,7 @@ BEGIN -- combine entries DELETE FROM exchange_statistic_counter_event - WHERE h_payto=my_instance + WHERE exchange_serial=my_instance AND imeta_serial_id=my_meta AND slot >= my_time - max_slot AND slot < my_time - min_slot @@ -836,7 +891,7 @@ BEGIN UPDATE exchange_statistic_counter_event SET delta = my_total WHERE imeta_serial_id = my_meta - AND h_payto = my_instance + AND exchange_serial = my_instance AND nevent_serial_id = my_sum.rep_serial_id; END IF; min_slot = min_slot + my_precision; @@ -846,7 +901,7 @@ BEGIN RAISE NOTICE 'deleting entries of %/% before % - % = %', my_instance, my_meta, my_time, my_ranges[array_length(my_ranges,1)], my_time - my_ranges[array_length(my_ranges,1)]; DELETE FROM exchange_statistic_counter_event - WHERE h_payto=my_instance + WHERE exchange_serial=my_instance AND imeta_serial_id=my_meta AND slot < my_time - my_ranges[array_length(my_ranges,1)]; END LOOP; -- my_rec loop @@ -863,13 +918,15 @@ LANGUAGE plpgsql AS $$ DECLARE my_time INT8 DEFAULT ROUND(EXTRACT(epoch FROM CURRENT_TIMESTAMP(0)::TIMESTAMP) * 1000000)::INT8 / 1000 / 1000; - my_h_payto BYTEA; + my_instance INT8; + my_instance_name TEXT; my_rec RECORD; my_sum RECORD; my_meta INT8; my_ranges INT8[]; my_precisions INT8[]; my_precision INT4; + my_currency TEXT; my_i INT4; min_slot INT8; max_slot INT8; @@ -877,9 +934,9 @@ DECLARE my_total_val INT8; my_total_frac INT8; BEGIN - -- GC for all accounts - FOR my_h_payto IN - SELECT DISTINCT h_payto + -- GC for all instances + FOR my_instance IN + SELECT DISTINCT exchange_serial FROM exchange_statistic_counter_event LOOP -- Do combination work for all numeric statistic events @@ -891,12 +948,21 @@ BEGIN FROM exchange_statistic_interval_meta LOOP - -- First, we query the current interval statistic to update its counters - PERFORM FROM exchange_statistic_interval_amount_get (my_rec.slug, my_h_payto); + -- First, we query the current interval statistic to update its counters + SELECT exchange_id + INTO my_instance_name + FROM exchange_instances + WHERE exchange_serial = my_instance; + PERFORM FROM exchange_statistic_interval_amount_get (my_rec.slug, my_instance_name); - my_meta = my_rec.imeta_serial_id; - my_ranges = my_rec.ranges; - my_precisions = my_rec.precisions; + my_meta = my_rec.imeta_serial_id; + my_ranges = my_rec.ranges; + my_precisions = my_rec.precisions; + FOR my_currency IN + SELECT DISTINCT delta_curr + FROM exchange_statistic_amount_event + WHERE imeta_serial_id = my_meta + LOOP FOR my_i IN 1..COALESCE(array_length(my_ranges,1),0) LOOP @@ -926,7 +992,8 @@ BEGIN INTO my_sum FROM exchange_statistic_amount_event WHERE imeta_serial_id=my_meta - AND h_payto=my_h_payto + AND exchange_serial=my_instance + AND delta_curr = my_currency AND slot >= my_time - max_slot AND slot < my_time - max_slot; -- we only proceed if we had more then one match (optimization) @@ -939,7 +1006,8 @@ BEGIN -- combine entries DELETE FROM exchange_statistic_amount_event WHERE imeta_serial_id=my_meta - AND h_payto=my_h_payto + AND exchange_serial=my_instance + AND delta_curr = my_currency AND slot >= my_time - max_slot AND slot < my_time - max_slot AND aevent_serial_id > my_sum.rep_serial_id; @@ -948,21 +1016,23 @@ BEGIN delta_value = my_total_value ,delta_frac = my_total_frac WHERE imeta_serial_id = my_meta - AND h_payto = my_h_payto + AND exchange_serial = my_instance + AND delta_curr = my_currency AND aevent_serial_id = my_sum.rep_serial_id; END IF; min_slot = min_slot + my_precision; END LOOP; -- min_slot to end_slot by precision loop END LOOP; -- my_i loop - -- Finally, delete all events beyond the range we care about - - RAISE NOTICE 'deleting entries of %/% before % - % = %', my_h_payto, my_meta, my_time, my_ranges[array_length(my_ranges,1)], my_time - my_ranges[array_length(my_ranges,1)]; - DELETE FROM exchange_statistic_amount_event - WHERE h_payto=my_h_payto - AND imeta_serial_id=my_meta - AND slot < my_time - my_ranges[array_length(my_ranges,1)]; - END LOOP; -- my_rec loop - END LOOP; -- my_h_payto loop + END LOOP; -- my_currency loop + -- Finally, delete all events beyond the range we care about + + RAISE NOTICE 'deleting entries of %/% before % - % = %', my_instance, my_meta, my_time, my_ranges[array_length(my_ranges,1)], my_time - my_ranges[array_length(my_ranges,1)]; + DELETE FROM exchange_statistic_amount_event + WHERE exchange_serial=my_instance + AND imeta_serial_id=my_meta + AND slot < my_time - my_ranges[array_length(my_ranges,1)]; + END LOOP; -- my_rec loop + END LOOP; -- my_instance loop END $$; COMMENT ON PROCEDURE exchange_statistic_amount_gc IS 'Performs garbage collection and compaction of the exchange_statistic_amount_event table';