diff options
-rw-r--r-- | src/exchangedb/exchange_do_reserves_in_insert.sql | 888 | ||||
-rw-r--r-- | src/exchangedb/pg_reserves_in_insert.c | 566 |
2 files changed, 0 insertions, 1454 deletions
diff --git a/src/exchangedb/exchange_do_reserves_in_insert.sql b/src/exchangedb/exchange_do_reserves_in_insert.sql index f8c7f1971..d2347bde8 100644 --- a/src/exchangedb/exchange_do_reserves_in_insert.sql +++ b/src/exchangedb/exchange_do_reserves_in_insert.sql @@ -14,894 +14,6 @@ -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> -- -CREATE OR REPLACE FUNCTION exchange_do_batch_reserves_in_insert( - IN in_gc_date INT8, - IN in_reserve_expiration INT8, - IN in_reserve_pub BYTEA, - IN in_wire_ref INT8, - IN in_credit taler_amount, - IN in_exchange_account_name TEXT, - IN in_execution_date INT8, - IN in_wire_source_h_payto BYTEA, - IN in_payto_uri TEXT, - IN in_notify TEXT, - OUT transaction_duplicate0 BOOLEAN, - OUT ruuid0 INT8) -LANGUAGE plpgsql -AS $$ -BEGIN - - INSERT INTO wire_targets - (wire_target_h_payto - ,payto_uri) - VALUES - (in_wire_source_h_payto - ,in_payto_uri) - ON CONFLICT DO NOTHING; - - INSERT INTO reserves - (reserve_pub - ,current_balance - ,expiration_date - ,gc_date) - VALUES - (in_reserve_pub - ,in_credit - ,in_reserve_expiration - ,in_gc_date) - ON CONFLICT DO NOTHING - RETURNING reserve_uuid - INTO ruuid0; - - INSERT INTO reserves_in - (reserve_pub - ,wire_reference - ,credit - ,exchange_account_section - ,wire_source_h_payto - ,execution_date) - VALUES - (in_reserve_pub - ,in_wire_ref - ,in_credit - ,in_exchange_account_name - ,in_wire_source_h_payto - ,in_execution_date) - ON CONFLICT DO NOTHING; - - transaction_duplicate0 = NOT FOUND; - IF FOUND - THEN - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in_notify); - END IF; - RETURN; -END $$; - - -CREATE OR REPLACE FUNCTION exchange_do_batch2_reserves_insert( - IN in_gc_date INT8, - IN in_reserve_expiration INT8, - IN in0_reserve_pub BYTEA, - IN in0_wire_ref INT8, - IN in0_credit taler_amount, - IN in0_exchange_account_name TEXT, - IN in0_execution_date INT8, - IN in0_wire_source_h_payto BYTEA, - IN in0_payto_uri TEXT, - IN in0_notify TEXT, - IN in1_reserve_pub BYTEA, - IN in1_wire_ref INT8, - IN in1_credit taler_amount, - IN in1_exchange_account_name TEXT, - IN in1_execution_date INT8, - IN in1_wire_source_h_payto BYTEA, - IN in1_payto_uri TEXT, - IN in1_notify TEXT, - OUT transaction_duplicate0 BOOLEAN, - OUT transaction_duplicate1 BOOLEAN, - OUT ruuid0 INT8, - OUT ruuid1 INT8) -LANGUAGE plpgsql -AS $$ -DECLARE - curs_reserve_exist REFCURSOR; - k INT8; - curs_transaction_exist REFCURSOR; - i RECORD; -BEGIN - transaction_duplicate0 = TRUE; - transaction_duplicate1 = TRUE; - - INSERT INTO wire_targets - (wire_target_h_payto - ,payto_uri) - VALUES - (in0_wire_source_h_payto - ,in0_payto_uri), - (in1_wire_source_h_payto - ,in1_payto_uri) - ON CONFLICT DO NOTHING; - - OPEN curs_reserve_exist FOR - WITH reserve_changes AS ( - INSERT INTO reserves - (reserve_pub - ,current_balance - ,expiration_date - ,gc_date) - VALUES - (in0_reserve_pub - ,in0_credit - ,in_reserve_expiration - ,in_gc_date), - (in1_reserve_pub - ,in1_credit - ,in_reserve_expiration - ,in_gc_date) - ON CONFLICT DO NOTHING - RETURNING reserve_uuid, reserve_pub) - SELECT reserve_uuid, reserve_pub FROM reserve_changes; - - k=0; - <<loop_reserve>> LOOP - FETCH FROM curs_reserve_exist INTO i; - IF NOT FOUND - THEN - EXIT loop_reserve; - END IF; - - <<loop_k>> LOOP - CASE k - WHEN 0 THEN - k = k + 1; - IF in0_reserve_pub = i.reserve_pub - THEN - ruuid0 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 1 THEN - IF in1_reserve_pub = i.reserve_pub - THEN - ruuid1 = i.reserve_uuid; - END IF; - EXIT loop_reserve; - END CASE; - END LOOP loop_k; - END LOOP loop_reserve; - - CLOSE curs_reserve_exist; - - OPEN curs_transaction_exist FOR - WITH reserve_transaction AS ( - INSERT INTO reserves_in - (reserve_pub - ,wire_reference - ,credit - ,exchange_account_section - ,wire_source_h_payto - ,execution_date) - VALUES - (in0_reserve_pub - ,in0_wire_ref - ,in0_credit - ,in0_exchange_account_name - ,in0_wire_source_h_payto - ,in0_execution_date), - (in1_reserve_pub - ,in1_wire_ref - ,in1_credit - ,in1_exchange_account_name - ,in1_wire_source_h_payto - ,in1_execution_date) - ON CONFLICT DO NOTHING - RETURNING reserve_pub) - SELECT reserve_pub FROM reserve_transaction; - - k=0; - <<loop_transaction>> LOOP - FETCH FROM curs_transaction_exist INTO i; - IF NOT FOUND - THEN - EXIT loop_transaction; - END IF; - - <<loop2_k>> LOOP - CASE k - WHEN 0 THEN - k = k + 1; - IF in0_reserve_pub = i.reserve_pub - THEN - transaction_duplicate0 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in0_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 1 THEN - IF in1_reserve_pub = i.reserve_pub - THEN - transaction_duplicate1 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in1_notify); - END IF; - EXIT loop_transaction; - END CASE; - END LOOP loop2_k; - END LOOP loop_transaction; - - CLOSE curs_transaction_exist; - - RETURN; -END $$; - - -CREATE OR REPLACE FUNCTION exchange_do_batch4_reserves_insert( - IN in_gc_date INT8, - IN in_reserve_expiration INT8, - IN in0_reserve_pub BYTEA, - IN in0_wire_ref INT8, - IN in0_credit taler_amount, - IN in0_exchange_account_name TEXT, - IN in0_execution_date INT8, - IN in0_wire_source_h_payto BYTEA, - IN in0_payto_uri TEXT, - IN in0_notify TEXT, - IN in1_reserve_pub BYTEA, - IN in1_wire_ref INT8, - IN in1_credit taler_amount, - IN in1_exchange_account_name TEXT, - IN in1_execution_date INT8, - IN in1_wire_source_h_payto BYTEA, - IN in1_payto_uri TEXT, - IN in1_notify TEXT, - IN in2_reserve_pub BYTEA, - IN in2_wire_ref INT8, - IN in2_credit taler_amount, - IN in2_exchange_account_name TEXT, - IN in2_execution_date INT8, - IN in2_wire_source_h_payto BYTEA, - IN in2_payto_uri TEXT, - IN in2_notify TEXT, - IN in3_reserve_pub BYTEA, - IN in3_wire_ref INT8, - IN in3_credit taler_amount, - IN in3_exchange_account_name TEXT, - IN in3_execution_date INT8, - IN in3_wire_source_h_payto BYTEA, - IN in3_payto_uri TEXT, - IN in3_notify TEXT, - OUT transaction_duplicate0 BOOLEAN, - OUT transaction_duplicate1 BOOLEAN, - OUT transaction_duplicate2 BOOLEAN, - OUT transaction_duplicate3 BOOLEAN, - OUT ruuid0 INT8, - OUT ruuid1 INT8, - OUT ruuid2 INT8, - OUT ruuid3 INT8) -LANGUAGE plpgsql -AS $$ -DECLARE - curs_reserve_exist REFCURSOR; - k INT8; - curs_transaction_exist REFCURSOR; - i RECORD; -BEGIN - transaction_duplicate0=TRUE; - transaction_duplicate1=TRUE; - transaction_duplicate2=TRUE; - transaction_duplicate3=TRUE; - - INSERT INTO wire_targets - (wire_target_h_payto - ,payto_uri) - VALUES - (in0_wire_source_h_payto - ,in0_payto_uri), - (in1_wire_source_h_payto - ,in1_payto_uri), - (in2_wire_source_h_payto - ,in2_payto_uri), - (in3_wire_source_h_payto - ,in3_payto_uri) - ON CONFLICT DO NOTHING; - - OPEN curs_reserve_exist FOR - WITH reserve_changes AS ( - INSERT INTO reserves - (reserve_pub - ,current_balance - ,expiration_date - ,gc_date) - VALUES - (in0_reserve_pub - ,in0_credit - ,in_reserve_expiration - ,in_gc_date), - (in1_reserve_pub - ,in1_credit - ,in_reserve_expiration - ,in_gc_date), - (in2_reserve_pub - ,in2_credit - ,in_reserve_expiration - ,in_gc_date), - (in3_reserve_pub - ,in3_credit - ,in_reserve_expiration - ,in_gc_date) - ON CONFLICT DO NOTHING - RETURNING reserve_uuid,reserve_pub) - SELECT reserve_uuid, reserve_pub FROM reserve_changes; - - k=0; - <<loop_reserve>> LOOP - FETCH FROM curs_reserve_exist INTO i; - IF NOT FOUND - THEN - EXIT loop_reserve; - END IF; - - <<loop_k>> LOOP - CASE k - WHEN 0 THEN - k = k + 1; - IF in0_reserve_pub = i.reserve_pub - THEN - ruuid0 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 1 THEN - k = k + 1; - IF in1_reserve_pub = i.reserve_pub - THEN - ruuid1 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 2 THEN - k = k + 1; - IF in2_reserve_pub = i.reserve_pub - THEN - ruuid2 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 3 THEN - IF in3_reserve_pub = i.reserve_pub - THEN - ruuid3 = i.reserve_uuid; - END IF; - EXIT loop_reserve; - END CASE; - END LOOP loop_k; - END LOOP loop_reserve; - - CLOSE curs_reserve_exist; - - OPEN curs_transaction_exist FOR - WITH reserve_transaction AS ( - INSERT INTO reserves_in - (reserve_pub - ,wire_reference - ,credit - ,exchange_account_section - ,wire_source_h_payto - ,execution_date) - VALUES - (in0_reserve_pub - ,in0_wire_ref - ,in0_credit - ,in0_exchange_account_name - ,in0_wire_source_h_payto - ,in0_execution_date), - (in1_reserve_pub - ,in1_wire_ref - ,in1_credit - ,in1_exchange_account_name - ,in1_wire_source_h_payto - ,in1_execution_date), - (in2_reserve_pub - ,in2_wire_ref - ,in2_credit - ,in2_exchange_account_name - ,in2_wire_source_h_payto - ,in2_execution_date), - (in3_reserve_pub - ,in3_wire_ref - ,in3_credit - ,in3_exchange_account_name - ,in3_wire_source_h_payto - ,in3_execution_date) - ON CONFLICT DO NOTHING - RETURNING reserve_pub) - SELECT reserve_pub FROM reserve_transaction; - - k=0; - <<loop_transaction>> LOOP - FETCH FROM curs_transaction_exist INTO i; - IF NOT FOUND - THEN - EXIT loop_transaction; - END IF; - - <<loop2_k>> LOOP - CASE k - WHEN 0 THEN - k = k + 1; - IF in0_reserve_pub = i.reserve_pub - THEN - transaction_duplicate0 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in0_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 1 THEN - k = k + 1; - IF in1_reserve_pub = i.reserve_pub - THEN - transaction_duplicate1 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in1_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 2 THEN - k = k + 1; - IF in2_reserve_pub = i.reserve_pub - THEN - transaction_duplicate2 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in2_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 3 THEN - IF in3_reserve_pub = i.reserve_pub - THEN - transaction_duplicate3 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in3_notify); - END IF; - EXIT loop_transaction; - END CASE; - END LOOP loop2_k; - END LOOP loop_transaction; - - CLOSE curs_transaction_exist; - - RETURN; -END $$; - - -CREATE OR REPLACE FUNCTION exchange_do_batch8_reserves_insert( - IN in_gc_date INT8, - IN in_reserve_expiration INT8, - IN in0_reserve_pub BYTEA, - IN in0_wire_ref INT8, - IN in0_credit taler_amount, - IN in0_exchange_account_name TEXT, - IN in0_execution_date INT8, - IN in0_wire_source_h_payto BYTEA, - IN in0_payto_uri TEXT, - IN in0_notify TEXT, - IN in1_reserve_pub BYTEA, - IN in1_wire_ref INT8, - IN in1_credit taler_amount, - IN in1_exchange_account_name TEXT, - IN in1_execution_date INT8, - IN in1_wire_source_h_payto BYTEA, - IN in1_payto_uri TEXT, - IN in1_notify TEXT, - IN in2_reserve_pub BYTEA, - IN in2_wire_ref INT8, - IN in2_credit taler_amount, - IN in2_exchange_account_name TEXT, - IN in2_execution_date INT8, - IN in2_wire_source_h_payto BYTEA, - IN in2_payto_uri TEXT, - IN in2_notify TEXT, - IN in3_reserve_pub BYTEA, - IN in3_wire_ref INT8, - IN in3_credit taler_amount, - IN in3_exchange_account_name TEXT, - IN in3_execution_date INT8, - IN in3_wire_source_h_payto BYTEA, - IN in3_payto_uri TEXT, - IN in3_notify TEXT, - IN in4_reserve_pub BYTEA, - IN in4_wire_ref INT8, - IN in4_credit taler_amount, - IN in4_exchange_account_name TEXT, - IN in4_execution_date INT8, - IN in4_wire_source_h_payto BYTEA, - IN in4_payto_uri TEXT, - IN in4_notify TEXT, - IN in5_reserve_pub BYTEA, - IN in5_wire_ref INT8, - IN in5_credit taler_amount, - IN in5_exchange_account_name TEXT, - IN in5_execution_date INT8, - IN in5_wire_source_h_payto BYTEA, - IN in5_payto_uri TEXT, - IN in5_notify TEXT, - IN in6_reserve_pub BYTEA, - IN in6_wire_ref INT8, - IN in6_credit taler_amount, - IN in6_exchange_account_name TEXT, - IN in6_execution_date INT8, - IN in6_wire_source_h_payto BYTEA, - IN in6_payto_uri TEXT, - IN in6_notify TEXT, - IN in7_reserve_pub BYTEA, - IN in7_wire_ref INT8, - IN in7_credit taler_amount, - IN in7_exchange_account_name TEXT, - IN in7_execution_date INT8, - IN in7_wire_source_h_payto BYTEA, - IN in7_payto_uri TEXT, - IN in7_notify TEXT, - OUT transaction_duplicate0 BOOLEAN, - OUT transaction_duplicate1 BOOLEAN, - OUT transaction_duplicate2 BOOLEAN, - OUT transaction_duplicate3 BOOLEAN, - OUT transaction_duplicate4 BOOLEAN, - OUT transaction_duplicate5 BOOLEAN, - OUT transaction_duplicate6 BOOLEAN, - OUT transaction_duplicate7 BOOLEAN, - OUT ruuid0 INT8, - OUT ruuid1 INT8, - OUT ruuid2 INT8, - OUT ruuid3 INT8, - OUT ruuid4 INT8, - OUT ruuid5 INT8, - OUT ruuid6 INT8, - OUT ruuid7 INT8) -LANGUAGE plpgsql -AS $$ -DECLARE - curs_reserve_exist REFCURSOR; - k INT8; - curs_transaction_exist REFCURSOR; - i RECORD; - r RECORD; - -BEGIN - transaction_duplicate0=TRUE; - transaction_duplicate1=TRUE; - transaction_duplicate2=TRUE; - transaction_duplicate3=TRUE; - transaction_duplicate4=TRUE; - transaction_duplicate5=TRUE; - transaction_duplicate6=TRUE; - transaction_duplicate7=TRUE; - - INSERT INTO wire_targets - (wire_target_h_payto - ,payto_uri) - VALUES - (in0_wire_source_h_payto - ,in0_payto_uri), - (in1_wire_source_h_payto - ,in1_payto_uri), - (in2_wire_source_h_payto - ,in2_payto_uri), - (in3_wire_source_h_payto - ,in3_payto_uri), - (in4_wire_source_h_payto - ,in4_payto_uri), - (in5_wire_source_h_payto - ,in5_payto_uri), - (in6_wire_source_h_payto - ,in6_payto_uri), - (in7_wire_source_h_payto - ,in7_payto_uri) - ON CONFLICT DO NOTHING; - - OPEN curs_reserve_exist FOR - WITH reserve_changes AS ( - INSERT INTO reserves - (reserve_pub - ,current_balance - ,expiration_date - ,gc_date) - VALUES - (in0_reserve_pub - ,in0_credit - ,in_reserve_expiration - ,in_gc_date), - (in1_reserve_pub - ,in1_credit - ,in_reserve_expiration - ,in_gc_date), - (in2_reserve_pub - ,in2_credit - ,in_reserve_expiration - ,in_gc_date), - (in3_reserve_pub - ,in3_credit - ,in_reserve_expiration - ,in_gc_date), - (in4_reserve_pub - ,in4_credit - ,in_reserve_expiration - ,in_gc_date), - (in5_reserve_pub - ,in5_credit - ,in_reserve_expiration - ,in_gc_date), - (in6_reserve_pub - ,in6_credit - ,in_reserve_expiration - ,in_gc_date), - (in7_reserve_pub - ,in7_credit - ,in_reserve_expiration - ,in_gc_date) - ON CONFLICT DO NOTHING - RETURNING - reserve_uuid - ,reserve_pub) - SELECT - reserve_uuid - ,reserve_pub - FROM reserve_changes; - - k=0; - <<loop_reserve>> LOOP - FETCH FROM curs_reserve_exist INTO i; - IF NOT FOUND - THEN - EXIT loop_reserve; - END IF; - - <<loop_k>> LOOP - CASE k - WHEN 0 THEN - k = k + 1; - IF in0_reserve_pub = i.reserve_pub - THEN - ruuid0 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 1 THEN - k = k + 1; - IF in1_reserve_pub = i.reserve_pub - THEN - ruuid1 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 2 THEN - k = k + 1; - IF in2_reserve_pub = i.reserve_pub - THEN - ruuid2 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 3 THEN - k = k + 1; - IF in3_reserve_pub = i.reserve_pub - THEN - ruuid3 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 4 THEN - k = k + 1; - IF in4_reserve_pub = i.reserve_pub - THEN - ruuid4 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 5 THEN - k = k + 1; - IF in5_reserve_pub = i.reserve_pub - THEN - ruuid5 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 6 THEN - k = k + 1; - IF in6_reserve_pub = i.reserve_pub - THEN - ruuid6 = i.reserve_uuid; - CONTINUE loop_reserve; - END IF; - CONTINUE loop_k; - WHEN 7 THEN - IF in7_reserve_pub = i.reserve_pub - THEN - ruuid7 = i.reserve_uuid; - END IF; - EXIT loop_reserve; - END CASE; - END LOOP loop_k; - END LOOP loop_reserve; - - CLOSE curs_reserve_exist; - - OPEN curs_transaction_exist FOR - WITH reserve_transaction AS ( - INSERT INTO reserves_in - (reserve_pub - ,wire_reference - ,credit - ,exchange_account_section - ,wire_source_h_payto - ,execution_date) - VALUES - (in0_reserve_pub - ,in0_wire_ref - ,in0_credit - ,in0_exchange_account_name - ,in0_wire_source_h_payto - ,in0_execution_date), - (in1_reserve_pub - ,in1_wire_ref - ,in1_credit - ,in1_exchange_account_name - ,in1_wire_source_h_payto - ,in1_execution_date), - (in2_reserve_pub - ,in2_wire_ref - ,in2_credit - ,in2_exchange_account_name - ,in2_wire_source_h_payto - ,in2_execution_date), - (in3_reserve_pub - ,in3_wire_ref - ,in3_credit - ,in3_exchange_account_name - ,in3_wire_source_h_payto - ,in3_execution_date), - (in4_reserve_pub - ,in4_wire_ref - ,in4_credit - ,in4_exchange_account_name - ,in4_wire_source_h_payto - ,in4_execution_date), - (in5_reserve_pub - ,in5_wire_ref - ,in5_credit - ,in5_exchange_account_name - ,in5_wire_source_h_payto - ,in5_execution_date), - (in6_reserve_pub - ,in6_wire_ref - ,in6_credit - ,in6_exchange_account_name - ,in6_wire_source_h_payto - ,in6_execution_date), - (in7_reserve_pub - ,in7_wire_ref - ,in7_credit - ,in7_exchange_account_name - ,in7_wire_source_h_payto - ,in7_execution_date) - ON CONFLICT DO NOTHING - RETURNING reserve_pub) - SELECT reserve_pub FROM reserve_transaction; - - k=0; - <<loop_transaction>> LOOP - FETCH FROM curs_transaction_exist INTO i; - IF NOT FOUND - THEN - EXIT loop_transaction; - END IF; - - <<loop2_k>> LOOP - CASE k - WHEN 0 THEN - k = k + 1; - IF in0_reserve_pub = i.reserve_pub - THEN - transaction_duplicate0 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in0_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 1 THEN - k = k + 1; - IF in1_reserve_pub = i.reserve_pub - THEN - transaction_duplicate1 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in1_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 2 THEN - k = k + 1; - IF in2_reserve_pub = i.reserve_pub - THEN - transaction_duplicate2 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in2_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 3 THEN - k = k + 1; - IF in3_reserve_pub = i.reserve_pub - THEN - transaction_duplicate3 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in3_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 4 THEN - k = k + 1; - IF in4_reserve_pub = i.reserve_pub - THEN - transaction_duplicate4 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in4_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 5 THEN - k = k + 1; - IF in5_reserve_pub = i.reserve_pub - THEN - transaction_duplicate5 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in5_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 6 THEN - k = k + 1; - IF in6_reserve_pub = i.reserve_pub - THEN - transaction_duplicate6 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in6_notify); - CONTINUE loop_transaction; - END IF; - CONTINUE loop2_k; - WHEN 7 THEN - IF in7_reserve_pub = i.reserve_pub - THEN - transaction_duplicate7 = FALSE; - EXECUTE FORMAT ( - 'NOTIFY %s' - ,in7_notify); - END IF; - EXIT loop_transaction; - END CASE; - END LOOP loop2_k; - END LOOP loop_transaction; - - CLOSE curs_transaction_exist; - RETURN; -END $$; - - CREATE OR REPLACE FUNCTION exchange_do_array_reserves_insert( IN in_gc_date INT8, diff --git a/src/exchangedb/pg_reserves_in_insert.c b/src/exchangedb/pg_reserves_in_insert.c index 77a68c90d..d5cb8820d 100644 --- a/src/exchangedb/pg_reserves_in_insert.c +++ b/src/exchangedb/pg_reserves_in_insert.c @@ -56,572 +56,6 @@ compute_notify_on_reserve (const struct TALER_ReservePublicKeyP *reserve_pub) /** - * Record we keep per reserve to process. - */ -struct ReserveRecord -{ - /** - * Details about reserve to insert (input). - */ - const struct TALER_EXCHANGEDB_ReserveInInfo *reserve; - - /** - * Hash of the payto URI in @e reserve. - */ - struct TALER_PaytoHashP h_payto; - - /** - * Notification to trigger on the reserve (input). - */ - char *notify_s; - - /** - * Set to UUID of the reserve (output); - */ - uint64_t reserve_uuid; - - /** - * Set to true if the transaction was an exact duplicate (output). - */ - bool transaction_duplicate; - - /** - * Set to true if the transaction conflicted with an existing reserve (output) - * and needs to be re-done with an UPDATE. - */ - bool conflicts; -}; - - -/** - * Generate the SQL parameters to insert the record @a rr at - * index @a index - */ -#define RR_QUERY_PARAM(rr,index) \ - GNUNET_PQ_query_param_auto_from_type (rr[index].reserve->reserve_pub), \ - GNUNET_PQ_query_param_uint64 (&rr[index].reserve->wire_reference), \ - TALER_PQ_query_param_amount (pg->conn, rr[index].reserve->balance), \ - GNUNET_PQ_query_param_string (rr[index].reserve->exchange_account_name), \ - GNUNET_PQ_query_param_timestamp (&rr[index].reserve->execution_time), \ - GNUNET_PQ_query_param_auto_from_type (&rr[index].h_payto), \ - GNUNET_PQ_query_param_string (rr[index].reserve->sender_account_details), \ - GNUNET_PQ_query_param_string (rr[index].notify_s) - - -/** - * Generate the SQL parameters to obtain results for record @a rr at - * index @a index - */ -#define RR_RESULT_PARAM(rr,index) \ - GNUNET_PQ_result_spec_bool ("transaction_duplicate" TALER_S (index), \ - &rr[index].transaction_duplicate), \ - GNUNET_PQ_result_spec_allow_null ( \ - GNUNET_PQ_result_spec_uint64 ("reserve_uuid" TALER_S (index), \ - &rr[index].reserve_uuid), \ - &rr[index].conflicts) - - -/** - * Insert 1 reserve record @a rr into the database. - * - * @param pg database context - * @param gc gc timestamp to use - * @param reserve_expiration expiration time to use - * @param[in,out] rr array of reserve details to use and update - * @return database transaction status - */ -static enum GNUNET_DB_QueryStatus -insert1 (struct PostgresClosure *pg, - struct GNUNET_TIME_Timestamp gc, - struct GNUNET_TIME_Timestamp reserve_expiration, - struct ReserveRecord *rr) -{ - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_timestamp (&gc), - GNUNET_PQ_query_param_timestamp (&reserve_expiration), - RR_QUERY_PARAM (rr, 0), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - RR_RESULT_PARAM (rr, 0), - GNUNET_PQ_result_spec_end - }; - - PREPARE (pg, - "batch1_reserve_create", - "SELECT " - " transaction_duplicate0 AS transaction_duplicate0" - ",ruuid0 AS reserve_uuid0" - " FROM exchange_do_batch_reserves_in_insert" - " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10);"); - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "batch1_reserve_create", - params, - rs); - if (qs < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to create reserves 1(%d)\n", - qs); - return qs; - } - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs); - if ((! rr[0].conflicts) && rr[0].transaction_duplicate) - { - GNUNET_break (0); - TEH_PG_rollback (pg); - return GNUNET_DB_STATUS_HARD_ERROR; - } - return qs; -} - - -/** - * Insert 2 reserve records @a rr into the database. - * - * @param pg database context - * @param gc gc timestamp to use - * @param reserve_expiration expiration time to use - * @param[in,out] rr array of reserve details to use and update - * @return database transaction status - */ -static enum GNUNET_DB_QueryStatus -insert2 (struct PostgresClosure *pg, - struct GNUNET_TIME_Timestamp gc, - struct GNUNET_TIME_Timestamp reserve_expiration, - struct ReserveRecord *rr) -{ - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_timestamp (&gc), - GNUNET_PQ_query_param_timestamp (&reserve_expiration), - RR_QUERY_PARAM (rr, 0), - RR_QUERY_PARAM (rr, 1), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - RR_RESULT_PARAM (rr, 0), - RR_RESULT_PARAM (rr, 1), - GNUNET_PQ_result_spec_end - }; - - PREPARE (pg, - "batch2_reserve_create", - "SELECT" - " transaction_duplicate0" - ",transaction_duplicate1" - ",ruuid0 AS reserve_uuid0" - ",ruuid1 AS reserve_uuid1" - " FROM exchange_do_batch2_reserves_insert" - " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18);"); - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "batch2_reserve_create", - params, - rs); - if (qs < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to create reserves 2(%d)\n", - qs); - return qs; - } - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs); - for (unsigned int i = 0; i<2; i++) - { - if ((! rr[i].conflicts) && (rr[i].transaction_duplicate)) - { - GNUNET_break (0); - TEH_PG_rollback (pg); - return GNUNET_DB_STATUS_HARD_ERROR; - } - } - return qs; -} - - -/** - * Insert 4 reserve records @a rr into the database. - * - * @param pg database context - * @param gc gc timestamp to use - * @param reserve_expiration expiration time to use - * @param[in,out] rr array of reserve details to use and update - * @return database transaction status - */ -static enum GNUNET_DB_QueryStatus -insert4 (struct PostgresClosure *pg, - struct GNUNET_TIME_Timestamp gc, - struct GNUNET_TIME_Timestamp reserve_expiration, - struct ReserveRecord *rr) -{ - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_timestamp (&gc), - GNUNET_PQ_query_param_timestamp (&reserve_expiration), - RR_QUERY_PARAM (rr, 0), - RR_QUERY_PARAM (rr, 1), - RR_QUERY_PARAM (rr, 2), - RR_QUERY_PARAM (rr, 3), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - RR_RESULT_PARAM (rr, 0), - RR_RESULT_PARAM (rr, 1), - RR_RESULT_PARAM (rr, 2), - RR_RESULT_PARAM (rr, 3), - GNUNET_PQ_result_spec_end - }; - - PREPARE (pg, - "batch4_reserve_create", - "SELECT" - " transaction_duplicate0" - ",transaction_duplicate1" - ",transaction_duplicate2" - ",transaction_duplicate3" - ",ruuid0 AS reserve_uuid0" - ",ruuid1 AS reserve_uuid1" - ",ruuid2 AS reserve_uuid2" - ",ruuid3 AS reserve_uuid3" - " FROM exchange_do_batch4_reserves_insert" - " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34);"); - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "batch4_reserve_create", - params, - rs); - if (qs < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to create reserves4 (%d)\n", - qs); - return qs; - } - - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs); - for (unsigned int i = 0; i<4; i++) - { - if ((! rr[i].conflicts) && (rr[i].transaction_duplicate)) - { - GNUNET_break (0); - TEH_PG_rollback (pg); - return GNUNET_DB_STATUS_HARD_ERROR; - } - } - return qs; -} - - -/** - * Insert 8 reserve records @a rr into the database. - * - * @param pg database context - * @param gc gc timestamp to use - * @param reserve_expiration expiration time to use - * @param[in,out] rr array of reserve details to use and update - * @return database transaction status - */ -static enum GNUNET_DB_QueryStatus -insert8 (struct PostgresClosure *pg, - struct GNUNET_TIME_Timestamp gc, - struct GNUNET_TIME_Timestamp reserve_expiration, - struct ReserveRecord *rr) -{ - enum GNUNET_DB_QueryStatus qs; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_timestamp (&gc), - GNUNET_PQ_query_param_timestamp (&reserve_expiration), - RR_QUERY_PARAM (rr, 0), - RR_QUERY_PARAM (rr, 1), - RR_QUERY_PARAM (rr, 2), - RR_QUERY_PARAM (rr, 3), - RR_QUERY_PARAM (rr, 4), - RR_QUERY_PARAM (rr, 5), - RR_QUERY_PARAM (rr, 6), - RR_QUERY_PARAM (rr, 7), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - RR_RESULT_PARAM (rr, 0), - RR_RESULT_PARAM (rr, 1), - RR_RESULT_PARAM (rr, 2), - RR_RESULT_PARAM (rr, 3), - RR_RESULT_PARAM (rr, 4), - RR_RESULT_PARAM (rr, 5), - RR_RESULT_PARAM (rr, 6), - RR_RESULT_PARAM (rr, 7), - GNUNET_PQ_result_spec_end - }; - - PREPARE (pg, - "batch8_reserve_create", - "SELECT" - " transaction_duplicate0" - ",transaction_duplicate1" - ",transaction_duplicate2" - ",transaction_duplicate3" - ",transaction_duplicate4" - ",transaction_duplicate5" - ",transaction_duplicate6" - ",transaction_duplicate7" - ",ruuid0 AS reserve_uuid0" - ",ruuid1 AS reserve_uuid1" - ",ruuid2 AS reserve_uuid2" - ",ruuid3 AS reserve_uuid3" - ",ruuid4 AS reserve_uuid4" - ",ruuid5 AS reserve_uuid5" - ",ruuid6 AS reserve_uuid6" - ",ruuid7 AS reserve_uuid7" - " FROM exchange_do_batch8_reserves_insert" - " ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$30,$31,$32,$33,$34,$35,$36,$37,$38,$39, $40, $41,$42,$43,$44,$45,$46,$47,$48,$49,$50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$60,$61,$62,$63,$64,$65,$66);"); - - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "batch8_reserve_create", - params, - rs); - if (qs < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to create reserves8 (%d)\n", - qs); - return qs; - } - - GNUNET_assert (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS != qs); - for (unsigned int i = 0; i<8; i++) - { - if ((! rr[i].conflicts) && (rr[i].transaction_duplicate)) - { - GNUNET_break (0); - TEH_PG_rollback (pg); - return GNUNET_DB_STATUS_HARD_ERROR; - } - } - return qs; -} - - -static enum GNUNET_DB_QueryStatus -transact ( - struct PostgresClosure *pg, - struct ReserveRecord *rr, - unsigned int reserves_length, - unsigned int batch_size, - enum GNUNET_DB_QueryStatus *results) -{ - struct GNUNET_TIME_Timestamp reserve_expiration - = GNUNET_TIME_relative_to_timestamp (pg->idle_reserve_expiration_time); - struct GNUNET_TIME_Timestamp gc - = GNUNET_TIME_relative_to_timestamp (pg->legal_reserve_expiration_time); - bool need_update = false; - - if (GNUNET_OK != - TEH_PG_preflight (pg)) - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - if (GNUNET_OK != - TEH_PG_start_read_committed (pg, - "READ_COMMITED")) - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - { - unsigned int i = 0; - - while (i < reserves_length) - { - enum GNUNET_DB_QueryStatus qs; - enum GNUNET_DB_QueryStatus - (*fun)(struct PostgresClosure *pg, - struct GNUNET_TIME_Timestamp gc, - struct GNUNET_TIME_Timestamp reserve_expiration, - struct ReserveRecord *rr); - unsigned int lim; - unsigned int bs; - - bs = GNUNET_MIN (batch_size, - reserves_length - i); - switch (bs) - { - case 7: - case 6: - case 5: - case 4: - fun = &insert4; - lim = 4; - break; - case 3: - case 2: - fun = &insert2; - lim = 2; - break; - case 1: - fun = &insert1; - lim = 1; - break; - case 0: - GNUNET_assert (0); - break; - default: - fun = insert8; - lim = 8; - break; - } - - qs = fun (pg, - gc, - reserve_expiration, - &rr[i]); - if (qs < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to create reserve batch_%u (%d)\n", - lim, - qs); - results[i] = qs; - return qs; - } - for (unsigned int j = 0; j<lim; j++) - { - need_update |= rr[i + j].conflicts; - results[i + j] = rr[i + j].transaction_duplicate - ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS - : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - } - i += lim; - continue; - } /* end while */ - } /* end scope i */ - - { - enum GNUNET_DB_QueryStatus cs; - - cs = TEH_PG_commit (pg); - if (cs < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to commit\n"); - return cs; - } - } - - if (! need_update) - return reserves_length; - - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "updated needed!\n"); - if (GNUNET_OK != - TEH_PG_start (pg, - "reserve-insert-continued")) - { - GNUNET_break (0); - return GNUNET_DB_STATUS_HARD_ERROR; - } - - PREPARE (pg, - "reserves_update", - "SELECT" - " out_duplicate AS duplicate " - "FROM exchange_do_batch_reserves_update" - " ($1,$2,$3,$4,$5,$6,$7);"); - for (unsigned int i = 0; i<reserves_length; i++) - { - if (! rr[i].conflicts) - continue; - { - bool duplicate; - struct GNUNET_PQ_QueryParam params[] = { - GNUNET_PQ_query_param_auto_from_type (rr[i].reserve->reserve_pub), - GNUNET_PQ_query_param_timestamp (&reserve_expiration), - GNUNET_PQ_query_param_uint64 (&rr[i].reserve->wire_reference), - TALER_PQ_query_param_amount (pg->conn, - rr[i].reserve->balance), - GNUNET_PQ_query_param_string (rr[i].reserve->exchange_account_name), - GNUNET_PQ_query_param_auto_from_type (&rr[i].h_payto), - GNUNET_PQ_query_param_string (rr[i].notify_s), - GNUNET_PQ_query_param_end - }; - struct GNUNET_PQ_ResultSpec rs[] = { - GNUNET_PQ_result_spec_bool ("duplicate", - &duplicate), - GNUNET_PQ_result_spec_end - }; - enum GNUNET_DB_QueryStatus qs; - - qs = GNUNET_PQ_eval_prepared_singleton_select (pg->conn, - "reserves_update", - params, - rs); - if (qs < 0) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to update reserves (%d)\n", - qs); - results[i] = qs; - return qs; - } - results[i] = duplicate - ? GNUNET_DB_STATUS_SUCCESS_NO_RESULTS - : GNUNET_DB_STATUS_SUCCESS_ONE_RESULT; - } - } - - { - enum GNUNET_DB_QueryStatus cs = TEH_PG_commit (pg); - - if (0 > cs) - return cs; - } - return reserves_length; -} - - -enum GNUNET_DB_QueryStatus -TEH_PG_reserves_in_insertL ( - void *cls, - const struct TALER_EXCHANGEDB_ReserveInInfo *reserves, - unsigned int reserves_length, - unsigned int batch_size, - enum GNUNET_DB_QueryStatus *results) -{ - struct PostgresClosure *pg = cls; - struct ReserveRecord rrs[reserves_length]; - enum GNUNET_DB_QueryStatus qs; - - for (unsigned int i = 0; i<reserves_length; i++) - { - const struct TALER_EXCHANGEDB_ReserveInInfo *reserve = &reserves[i]; - struct ReserveRecord *rr = &rrs[i]; - - rr->reserve = reserve; - TALER_payto_hash (reserves->sender_account_details, - &rr->h_payto); - rr->notify_s = compute_notify_on_reserve (reserve->reserve_pub); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating reserve %s with expiration in %s\n", - TALER_B2S (&reserve->reserve_pub), - GNUNET_STRINGS_relative_time_to_string ( - pg->idle_reserve_expiration_time, - false)); - } - qs = transact (pg, - rrs, - reserves_length, - batch_size, - results); - GNUNET_PQ_event_do_poll (pg->conn); - for (unsigned int i = 0; i<reserves_length; i++) - GNUNET_free (rrs[i].notify_s); - return qs; -} - - -/** * Closure for our helper_cb() */ struct Context |