merchant-0036-copy.sql.fragment (25916B)
1 -- ================================================================= 2 -- Copy per-instance row data from merchant.* into the new schema. 3 -- Tables are listed in FK-dependency order so plain INSERT works 4 -- (no DEFERRABLE games, no WITH ORDINALITY). $1 is bound to 5 -- rec.merchant_serial via USING. The merchant_serial column is 6 -- dropped from every column list — the schema name is the 7 -- discriminator. All target tables use GENERATED BY DEFAULT AS 8 -- IDENTITY (so we can keep the source serial values), except 9 -- merchant_login_tokens whose `serial` is GENERATED ALWAYS — that 10 -- one needs OVERRIDING SYSTEM VALUE. 11 -- 12 -- Two stat-meta tables (merchant_statistic_bucket_meta, 13 -- merchant_statistic_interval_meta) have no merchant_serial in the 14 -- source schema — they are global slug catalogs and are copied 15 -- verbatim into every per-instance schema. 16 -- ================================================================= 17 18 -- ---------------- direct merchant_serial (no JOIN) -------------- 19 20 EXECUTE FORMAT('INSERT INTO %I.merchant_accounts' 21 || ' (account_serial, h_wire, salt, credit_facade_url,' 22 || ' credit_facade_credentials, last_bank_serial, payto_uri,' 23 || ' active, extra_wire_subject_metadata)' 24 || ' SELECT account_serial, h_wire, salt, credit_facade_url,' 25 || ' credit_facade_credentials, last_bank_serial, payto_uri,' 26 || ' active, extra_wire_subject_metadata' 27 || ' FROM merchant.merchant_accounts' 28 || ' WHERE merchant_serial = $1', s) 29 USING rec.merchant_serial; 30 31 EXECUTE FORMAT('INSERT INTO %I.merchant_categories' 32 || ' (category_serial, category_name, category_name_i18n)' 33 || ' SELECT category_serial, category_name, category_name_i18n' 34 || ' FROM merchant.merchant_categories' 35 || ' WHERE merchant_serial = $1', s) 36 USING rec.merchant_serial; 37 38 EXECUTE FORMAT('INSERT INTO %I.merchant_contract_terms' 39 || ' (order_serial, order_id, contract_terms, wallet_data,' 40 || ' h_contract_terms, creation_time, pay_deadline, refund_deadline,' 41 || ' paid, wired, fulfillment_url, session_id, pos_key, pos_algorithm,' 42 || ' claim_token, choice_index)' 43 || ' SELECT order_serial, order_id, contract_terms, wallet_data,' 44 || ' h_contract_terms, creation_time, pay_deadline, refund_deadline,' 45 || ' paid, wired, fulfillment_url, session_id, pos_key, pos_algorithm,' 46 || ' claim_token, choice_index' 47 || ' FROM merchant.merchant_contract_terms' 48 || ' WHERE merchant_serial = $1', s) 49 USING rec.merchant_serial; 50 51 EXECUTE FORMAT('INSERT INTO %I.merchant_custom_units' 52 || ' (unit_serial, unit, unit_name_long, unit_name_short,' 53 || ' unit_name_long_i18n, unit_name_short_i18n,' 54 || ' unit_allow_fraction, unit_precision_level, unit_active)' 55 || ' SELECT unit_serial, unit, unit_name_long, unit_name_short,' 56 || ' unit_name_long_i18n, unit_name_short_i18n,' 57 || ' unit_allow_fraction, unit_precision_level, unit_active' 58 || ' FROM merchant.merchant_custom_units' 59 || ' WHERE merchant_serial = $1', s) 60 USING rec.merchant_serial; 61 62 -- merchant_donau_instances: source filter column is named 63 -- merchant_instance_serial (not merchant_serial). 64 EXECUTE FORMAT('INSERT INTO %I.merchant_donau_instances' 65 || ' (donau_instances_serial, donau_url, charity_name, charity_id,' 66 || ' charity_max_per_year, charity_receipts_to_date, current_year)' 67 || ' SELECT donau_instances_serial, donau_url, charity_name, charity_id,' 68 || ' charity_max_per_year, charity_receipts_to_date, current_year' 69 || ' FROM merchant.merchant_donau_instances' 70 || ' WHERE merchant_instance_serial = $1', s) 71 USING rec.merchant_serial; 72 73 -- merchant_login_tokens: target `serial` column is GENERATED ALWAYS 74 -- → must use OVERRIDING SYSTEM VALUE to preserve serial values. 75 EXECUTE FORMAT('INSERT INTO %I.merchant_login_tokens' 76 || ' (token, creation_time, expiration_time, validity_scope,' 77 || ' description, serial)' 78 || ' OVERRIDING SYSTEM VALUE' 79 || ' SELECT token, creation_time, expiration_time, validity_scope,' 80 || ' description, serial' 81 || ' FROM merchant.merchant_login_tokens' 82 || ' WHERE merchant_serial = $1', s) 83 USING rec.merchant_serial; 84 85 EXECUTE FORMAT('INSERT INTO %I.merchant_money_pots' 86 || ' (money_pot_serial, money_pot_name, money_pot_description, pot_totals)' 87 || ' SELECT money_pot_serial, money_pot_name, money_pot_description, pot_totals' 88 || ' FROM merchant.merchant_money_pots' 89 || ' WHERE merchant_serial = $1', s) 90 USING rec.merchant_serial; 91 92 EXECUTE FORMAT('INSERT INTO %I.merchant_otp_devices' 93 || ' (otp_serial, otp_id, otp_description, otp_key, otp_algorithm, otp_ctr)' 94 || ' SELECT otp_serial, otp_id, otp_description, otp_key, otp_algorithm, otp_ctr' 95 || ' FROM merchant.merchant_otp_devices' 96 || ' WHERE merchant_serial = $1', s) 97 USING rec.merchant_serial; 98 99 EXECUTE FORMAT('INSERT INTO %I.merchant_orders' 100 || ' (order_serial, order_id, claim_token, h_post_data, pay_deadline,' 101 || ' creation_time, contract_terms, pos_key, pos_algorithm,' 102 || ' fulfillment_url, session_id)' 103 || ' SELECT order_serial, order_id, claim_token, h_post_data, pay_deadline,' 104 || ' creation_time, contract_terms, pos_key, pos_algorithm,' 105 || ' fulfillment_url, session_id' 106 || ' FROM merchant.merchant_orders' 107 || ' WHERE merchant_serial = $1', s) 108 USING rec.merchant_serial; 109 110 EXECUTE FORMAT('INSERT INTO %I.merchant_product_groups' 111 || ' (product_group_serial, product_group_name, product_group_description)' 112 || ' SELECT product_group_serial, product_group_name, product_group_description' 113 || ' FROM merchant.merchant_product_groups' 114 || ' WHERE merchant_serial = $1', s) 115 USING rec.merchant_serial; 116 117 -- merchant_inventory references merchant_product_groups and merchant_money_pots 118 -- (already copied above). 119 EXECUTE FORMAT('INSERT INTO %I.merchant_inventory' 120 || ' (product_serial, product_id, description, description_i18n,' 121 || ' unit, image, taxes, total_stock, total_sold, total_lost,' 122 || ' address, next_restock, minimum_age, product_name, image_hash,' 123 || ' price_array, total_stock_frac, total_sold_frac, total_lost_frac,' 124 || ' allow_fractional_quantity, fractional_precision_level,' 125 || ' product_group_serial, money_pot_serial, price_is_net)' 126 || ' SELECT product_serial, product_id, description, description_i18n,' 127 || ' unit, image, taxes, total_stock, total_sold, total_lost,' 128 || ' address, next_restock, minimum_age, product_name, image_hash,' 129 || ' price_array, total_stock_frac, total_sold_frac, total_lost_frac,' 130 || ' allow_fractional_quantity, fractional_precision_level,' 131 || ' product_group_serial, money_pot_serial, price_is_net' 132 || ' FROM merchant.merchant_inventory' 133 || ' WHERE merchant_serial = $1', s) 134 USING rec.merchant_serial; 135 136 EXECUTE FORMAT('INSERT INTO %I.merchant_reports' 137 || ' (report_serial, report_program_section, report_description,' 138 || ' mime_type, report_token, data_source, target_address,' 139 || ' frequency, frequency_shift, next_transmission,' 140 || ' last_error_code, last_error_detail, one_shot_hidden)' 141 || ' SELECT report_serial, report_program_section, report_description,' 142 || ' mime_type, report_token, data_source, target_address,' 143 || ' frequency, frequency_shift, next_transmission,' 144 || ' last_error_code, last_error_detail, one_shot_hidden' 145 || ' FROM merchant.merchant_reports' 146 || ' WHERE merchant_serial = $1', s) 147 USING rec.merchant_serial; 148 149 -- merchant_template references merchant_otp_devices (already copied). 150 EXECUTE FORMAT('INSERT INTO %I.merchant_template' 151 || ' (template_serial, template_id, template_description,' 152 || ' otp_device_id, template_contract, editable_defaults)' 153 || ' SELECT template_serial, template_id, template_description,' 154 || ' otp_device_id, template_contract, editable_defaults' 155 || ' FROM merchant.merchant_template' 156 || ' WHERE merchant_serial = $1', s) 157 USING rec.merchant_serial; 158 159 EXECUTE FORMAT('INSERT INTO %I.merchant_token_families' 160 || ' (token_family_serial, slug, name, description, description_i18n,' 161 || ' valid_after, valid_before, duration, kind, issued, used,' 162 || ' validity_granularity, start_offset, cipher_choice, extra_data)' 163 || ' SELECT token_family_serial, slug, name, description, description_i18n,' 164 || ' valid_after, valid_before, duration, kind, issued, used,' 165 || ' validity_granularity, start_offset, cipher_choice, extra_data' 166 || ' FROM merchant.merchant_token_families' 167 || ' WHERE merchant_serial = $1', s) 168 USING rec.merchant_serial; 169 170 EXECUTE FORMAT('INSERT INTO %I.merchant_webhook' 171 || ' (webhook_serial, webhook_id, event_type, url, http_method,' 172 || ' header_template, body_template)' 173 || ' SELECT webhook_serial, webhook_id, event_type, url, http_method,' 174 || ' header_template, body_template' 175 || ' FROM merchant.merchant_webhook' 176 || ' WHERE merchant_serial = $1', s) 177 USING rec.merchant_serial; 178 179 180 EXECUTE FORMAT('INSERT INTO %I.merchant_builtin_unit_overrides' 181 || ' (builtin_unit_serial, override_allow_fraction,' 182 || ' override_precision_level, override_active)' 183 || ' SELECT builtin_unit_serial, override_allow_fraction,' 184 || ' override_precision_level, override_active' 185 || ' FROM merchant.merchant_builtin_unit_overrides' 186 || ' WHERE merchant_serial = $1', s) 187 USING rec.merchant_serial; 188 189 -- ---------------- statistics: meta tables are GLOBAL ------------ 190 -- Copied unfiltered (every instance gets a full stats catalog). 191 192 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_bucket_meta' 193 || ' (bmeta_serial_id, slug, description, stype, ranges, ages)' 194 || ' SELECT bmeta_serial_id, slug, description, stype, ranges, ages' 195 || ' FROM merchant.merchant_statistic_bucket_meta', s); 196 197 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_interval_meta' 198 || ' (imeta_serial_id, slug, description, stype, ranges, precisions)' 199 || ' SELECT imeta_serial_id, slug, description, stype, ranges, precisions' 200 || ' FROM merchant.merchant_statistic_interval_meta', s); 201 202 -- ---------------- statistics: per-instance event/bucket tables -- 203 204 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_amount_event' 205 || ' (aevent_serial_id, imeta_serial_id, slot,' 206 || ' delta_curr, delta_value, delta_frac)' 207 || ' SELECT aevent_serial_id, imeta_serial_id, slot,' 208 || ' delta_curr, delta_value, delta_frac' 209 || ' FROM merchant.merchant_statistic_amount_event' 210 || ' WHERE merchant_serial = $1', s) 211 USING rec.merchant_serial; 212 213 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_counter_event' 214 || ' (nevent_serial_id, imeta_serial_id, slot, delta)' 215 || ' SELECT nevent_serial_id, imeta_serial_id, slot, delta' 216 || ' FROM merchant.merchant_statistic_counter_event' 217 || ' WHERE merchant_serial = $1', s) 218 USING rec.merchant_serial; 219 220 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_bucket_amount' 221 || ' (bmeta_serial_id, bucket_start, bucket_range, curr,' 222 || ' cumulative_value, cumulative_frac)' 223 || ' SELECT bmeta_serial_id, bucket_start, bucket_range, curr,' 224 || ' cumulative_value, cumulative_frac' 225 || ' FROM merchant.merchant_statistic_bucket_amount' 226 || ' WHERE merchant_serial = $1', s) 227 USING rec.merchant_serial; 228 229 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_bucket_counter' 230 || ' (bmeta_serial_id, bucket_start, bucket_range, cumulative_number)' 231 || ' SELECT bmeta_serial_id, bucket_start, bucket_range, cumulative_number' 232 || ' FROM merchant.merchant_statistic_bucket_counter' 233 || ' WHERE merchant_serial = $1', s) 234 USING rec.merchant_serial; 235 236 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_interval_amount' 237 || ' (imeta_serial_id, event_delimiter, range, curr,' 238 || ' cumulative_value, cumulative_frac)' 239 || ' SELECT imeta_serial_id, event_delimiter, range, curr,' 240 || ' cumulative_value, cumulative_frac' 241 || ' FROM merchant.merchant_statistic_interval_amount' 242 || ' WHERE merchant_serial = $1', s) 243 USING rec.merchant_serial; 244 245 EXECUTE FORMAT('INSERT INTO %I.merchant_statistic_interval_counter' 246 || ' (imeta_serial_id, range, event_delimiter, cumulative_number)' 247 || ' SELECT imeta_serial_id, range, event_delimiter, cumulative_number' 248 || ' FROM merchant.merchant_statistic_interval_counter' 249 || ' WHERE merchant_serial = $1', s) 250 USING rec.merchant_serial; 251 252 -- ---------------- account-linked (JOIN via account_serial) ------ 253 254 EXECUTE FORMAT('INSERT INTO %I.merchant_kyc' 255 || ' (kyc_serial_id, kyc_timestamp, kyc_ok, account_serial,' 256 || ' exchange_url, access_token, exchange_http_status,' 257 || ' exchange_ec_code, aml_review, jaccount_limits,' 258 || ' last_rule_gen, next_kyc_poll, kyc_backoff)' 259 || ' SELECT k.kyc_serial_id, k.kyc_timestamp, k.kyc_ok, k.account_serial,' 260 || ' k.exchange_url, k.access_token, k.exchange_http_status,' 261 || ' k.exchange_ec_code, k.aml_review, k.jaccount_limits,' 262 || ' k.last_rule_gen, k.next_kyc_poll, k.kyc_backoff' 263 || ' FROM merchant.merchant_kyc k' 264 || ' JOIN merchant.merchant_accounts a' 265 || ' ON k.account_serial = a.account_serial' 266 || ' WHERE a.merchant_serial = $1', s) 267 USING rec.merchant_serial; 268 269 EXECUTE FORMAT('INSERT INTO %I.merchant_deposit_confirmations' 270 || ' (deposit_confirmation_serial, order_serial, deposit_timestamp,' 271 || ' exchange_url, total_without_fee, wire_fee, signkey_serial,' 272 || ' exchange_sig, account_serial, wire_transfer_deadline,' 273 || ' wire_pending, exchange_failure, retry_backoff)' 274 || ' SELECT dc.deposit_confirmation_serial, dc.order_serial, dc.deposit_timestamp,' 275 || ' dc.exchange_url, dc.total_without_fee, dc.wire_fee, dc.signkey_serial,' 276 || ' dc.exchange_sig, dc.account_serial, dc.wire_transfer_deadline,' 277 || ' dc.wire_pending, dc.exchange_failure, dc.retry_backoff' 278 || ' FROM merchant.merchant_deposit_confirmations dc' 279 || ' JOIN merchant.merchant_accounts a' 280 || ' ON dc.account_serial = a.account_serial' 281 || ' WHERE a.merchant_serial = $1', s) 282 USING rec.merchant_serial; 283 284 EXECUTE FORMAT('INSERT INTO %I.merchant_expected_transfers' 285 || ' (expected_credit_serial, exchange_url, wtid, expected_credit_amount,' 286 || ' wire_fee, account_serial, expected_time, retry_time, last_http_status,' 287 || ' last_ec, last_detail, retry_needed, signkey_serial, exchange_sig,' 288 || ' h_details, confirmed)' 289 || ' SELECT et.expected_credit_serial, et.exchange_url, et.wtid, et.expected_credit_amount,' 290 || ' et.wire_fee, et.account_serial, et.expected_time, et.retry_time, et.last_http_status,' 291 || ' et.last_ec, et.last_detail, et.retry_needed, et.signkey_serial, et.exchange_sig,' 292 || ' et.h_details, et.confirmed' 293 || ' FROM merchant.merchant_expected_transfers et' 294 || ' JOIN merchant.merchant_accounts a' 295 || ' ON et.account_serial = a.account_serial' 296 || ' WHERE a.merchant_serial = $1', s) 297 USING rec.merchant_serial; 298 299 EXECUTE FORMAT('INSERT INTO %I.merchant_transfers' 300 || ' (credit_serial, exchange_url, wtid, credit_amount, account_serial,' 301 || ' bank_serial_id, expected, execution_time)' 302 || ' SELECT t.credit_serial, t.exchange_url, t.wtid, t.credit_amount, t.account_serial,' 303 || ' t.bank_serial_id, t.expected, t.execution_time' 304 || ' FROM merchant.merchant_transfers t' 305 || ' JOIN merchant.merchant_accounts a' 306 || ' ON t.account_serial = a.account_serial' 307 || ' WHERE a.merchant_serial = $1', s) 308 USING rec.merchant_serial; 309 310 -- ---------------- deposits: deeper join (dc → accounts) --------- 311 312 EXECUTE FORMAT('INSERT INTO %I.merchant_deposits' 313 || ' (deposit_serial, coin_offset, deposit_confirmation_serial,' 314 || ' coin_pub, coin_sig, amount_with_fee, deposit_fee, refund_fee,' 315 || ' settlement_retry_needed, settlement_retry_time,' 316 || ' settlement_last_http_status, settlement_last_ec,' 317 || ' settlement_last_detail, settlement_wtid,' 318 || ' settlement_coin_contribution, settlement_expected_credit_serial,' 319 || ' signkey_serial, settlement_exchange_sig)' 320 || ' SELECT d.deposit_serial, d.coin_offset, d.deposit_confirmation_serial,' 321 || ' d.coin_pub, d.coin_sig, d.amount_with_fee, d.deposit_fee, d.refund_fee,' 322 || ' d.settlement_retry_needed, d.settlement_retry_time,' 323 || ' d.settlement_last_http_status, d.settlement_last_ec,' 324 || ' d.settlement_last_detail, d.settlement_wtid,' 325 || ' d.settlement_coin_contribution, d.settlement_expected_credit_serial,' 326 || ' d.signkey_serial, d.settlement_exchange_sig' 327 || ' FROM merchant.merchant_deposits d' 328 || ' JOIN merchant.merchant_deposit_confirmations dc' 329 || ' ON d.deposit_confirmation_serial = dc.deposit_confirmation_serial' 330 || ' JOIN merchant.merchant_accounts a' 331 || ' ON dc.account_serial = a.account_serial' 332 || ' WHERE a.merchant_serial = $1', s) 333 USING rec.merchant_serial; 334 335 -- expected_transfer_to_coin: deposit_serial → deposits → dc → accounts. 336 EXECUTE FORMAT('INSERT INTO %I.merchant_expected_transfer_to_coin' 337 || ' (deposit_serial, expected_credit_serial, offset_in_exchange_list,' 338 || ' exchange_deposit_value, exchange_deposit_fee)' 339 || ' SELECT ettc.deposit_serial, ettc.expected_credit_serial, ettc.offset_in_exchange_list,' 340 || ' ettc.exchange_deposit_value, ettc.exchange_deposit_fee' 341 || ' FROM merchant.merchant_expected_transfer_to_coin ettc' 342 || ' JOIN merchant.merchant_deposits d' 343 || ' ON ettc.deposit_serial = d.deposit_serial' 344 || ' JOIN merchant.merchant_deposit_confirmations dc' 345 || ' ON d.deposit_confirmation_serial = dc.deposit_confirmation_serial' 346 || ' JOIN merchant.merchant_accounts a' 347 || ' ON dc.account_serial = a.account_serial' 348 || ' WHERE a.merchant_serial = $1', s) 349 USING rec.merchant_serial; 350 351 -- transfer_signatures: expected_credit_serial → expected_transfers → accounts. 352 EXECUTE FORMAT('INSERT INTO %I.merchant_transfer_signatures' 353 || ' (expected_credit_serial, signkey_serial, wire_fee, credit_amount,' 354 || ' execution_time, exchange_sig)' 355 || ' SELECT ts.expected_credit_serial, ts.signkey_serial, ts.wire_fee, ts.credit_amount,' 356 || ' ts.execution_time, ts.exchange_sig' 357 || ' FROM merchant.merchant_transfer_signatures ts' 358 || ' JOIN merchant.merchant_expected_transfers et' 359 || ' ON ts.expected_credit_serial = et.expected_credit_serial' 360 || ' JOIN merchant.merchant_accounts a' 361 || ' ON et.account_serial = a.account_serial' 362 || ' WHERE a.merchant_serial = $1', s) 363 USING rec.merchant_serial; 364 365 -- ---------------- order/contract-linked (JOIN via order_serial) --- 366 367 EXECUTE FORMAT('INSERT INTO %I.merchant_refunds' 368 || ' (refund_serial, order_serial, rtransaction_id, refund_timestamp,' 369 || ' coin_pub, reason, refund_amount)' 370 || ' SELECT r.refund_serial, r.order_serial, r.rtransaction_id, r.refund_timestamp,' 371 || ' r.coin_pub, r.reason, r.refund_amount' 372 || ' FROM merchant.merchant_refunds r' 373 || ' JOIN merchant.merchant_contract_terms ct' 374 || ' ON r.order_serial = ct.order_serial' 375 || ' WHERE ct.merchant_serial = $1', s) 376 USING rec.merchant_serial; 377 378 EXECUTE FORMAT('INSERT INTO %I.merchant_refund_proofs' 379 || ' (refund_serial, exchange_sig, signkey_serial)' 380 || ' SELECT rp.refund_serial, rp.exchange_sig, rp.signkey_serial' 381 || ' FROM merchant.merchant_refund_proofs rp' 382 || ' JOIN merchant.merchant_refunds r' 383 || ' ON rp.refund_serial = r.refund_serial' 384 || ' JOIN merchant.merchant_contract_terms ct' 385 || ' ON r.order_serial = ct.order_serial' 386 || ' WHERE ct.merchant_serial = $1', s) 387 USING rec.merchant_serial; 388 389 EXECUTE FORMAT('INSERT INTO %I.merchant_order_token_blinded_sigs' 390 || ' (order_token_bs_serial, order_serial, token_index,' 391 || ' token_blinded_signature, token_hash)' 392 || ' SELECT otbs.order_token_bs_serial, otbs.order_serial, otbs.token_index,' 393 || ' otbs.token_blinded_signature, otbs.token_hash' 394 || ' FROM merchant.merchant_order_token_blinded_sigs otbs' 395 || ' JOIN merchant.merchant_contract_terms ct' 396 || ' ON otbs.order_serial = ct.order_serial' 397 || ' WHERE ct.merchant_serial = $1', s) 398 USING rec.merchant_serial; 399 400 -- unclaim_signatures: linked via h_contract_terms. 401 EXECUTE FORMAT('INSERT INTO %I.merchant_unclaim_signatures' 402 || ' (unclaim_serial, h_contract_terms, unclaim_sig, expiration_time)' 403 || ' SELECT us.unclaim_serial, us.h_contract_terms, us.unclaim_sig, us.expiration_time' 404 || ' FROM merchant.merchant_unclaim_signatures us' 405 || ' JOIN merchant.merchant_contract_terms ct' 406 || ' ON us.h_contract_terms = ct.h_contract_terms' 407 || ' WHERE ct.merchant_serial = $1', s) 408 USING rec.merchant_serial; 409 410 -- order_locks: order_serial → contract_terms. 411 EXECUTE FORMAT('INSERT INTO %I.merchant_order_locks' 412 || ' (product_serial, total_locked, order_serial, total_locked_frac)' 413 || ' SELECT ol.product_serial, ol.total_locked, ol.order_serial, ol.total_locked_frac' 414 || ' FROM merchant.merchant_order_locks ol' 415 || ' JOIN merchant.merchant_contract_terms ct' 416 || ' ON ol.order_serial = ct.order_serial' 417 || ' WHERE ct.merchant_serial = $1', s) 418 USING rec.merchant_serial; 419 420 -- inventory_locks: product_serial → inventory. 421 EXECUTE FORMAT('INSERT INTO %I.merchant_inventory_locks' 422 || ' (product_serial, lock_uuid, total_locked, expiration, total_locked_frac)' 423 || ' SELECT il.product_serial, il.lock_uuid, il.total_locked, il.expiration, il.total_locked_frac' 424 || ' FROM merchant.merchant_inventory_locks il' 425 || ' JOIN merchant.merchant_inventory i' 426 || ' ON il.product_serial = i.product_serial' 427 || ' WHERE i.merchant_serial = $1', s) 428 USING rec.merchant_serial; 429 430 -- product_categories: junction; pivot on product_serial → inventory. 431 EXECUTE FORMAT('INSERT INTO %I.merchant_product_categories' 432 || ' (category_serial, product_serial)' 433 || ' SELECT pc.category_serial, pc.product_serial' 434 || ' FROM merchant.merchant_product_categories pc' 435 || ' JOIN merchant.merchant_inventory i' 436 || ' ON pc.product_serial = i.product_serial' 437 || ' WHERE i.merchant_serial = $1', s) 438 USING rec.merchant_serial; 439 440 -- ---------------- token chain (token_families → keys → tokens) -- 441 442 EXECUTE FORMAT('INSERT INTO %I.merchant_token_family_keys' 443 || ' (token_family_key_serial, token_family_serial, pub, h_pub,' 444 || ' priv, cipher, signature_validity_start, signature_validity_end,' 445 || ' private_key_deleted_at, private_key_created_at)' 446 || ' SELECT tfk.token_family_key_serial, tfk.token_family_serial, tfk.pub, tfk.h_pub,' 447 || ' tfk.priv, tfk.cipher, tfk.signature_validity_start, tfk.signature_validity_end,' 448 || ' tfk.private_key_deleted_at, tfk.private_key_created_at' 449 || ' FROM merchant.merchant_token_family_keys tfk' 450 || ' JOIN merchant.merchant_token_families tf' 451 || ' ON tfk.token_family_serial = tf.token_family_serial' 452 || ' WHERE tf.merchant_serial = $1', s) 453 USING rec.merchant_serial; 454 455 EXECUTE FORMAT('INSERT INTO %I.merchant_issued_tokens' 456 || ' (issued_token_serial, h_contract_terms, token_family_key_serial, blind_sig)' 457 || ' SELECT it.issued_token_serial, it.h_contract_terms, it.token_family_key_serial, it.blind_sig' 458 || ' FROM merchant.merchant_issued_tokens it' 459 || ' JOIN merchant.merchant_token_family_keys tfk' 460 || ' ON it.token_family_key_serial = tfk.token_family_key_serial' 461 || ' JOIN merchant.merchant_token_families tf' 462 || ' ON tfk.token_family_serial = tf.token_family_serial' 463 || ' WHERE tf.merchant_serial = $1', s) 464 USING rec.merchant_serial; 465 466 EXECUTE FORMAT('INSERT INTO %I.merchant_used_tokens' 467 || ' (spent_token_serial, h_contract_terms, token_family_key_serial,' 468 || ' token_pub, token_sig, blind_sig)' 469 || ' SELECT ut.spent_token_serial, ut.h_contract_terms, ut.token_family_key_serial,' 470 || ' ut.token_pub, ut.token_sig, ut.blind_sig' 471 || ' FROM merchant.merchant_used_tokens ut' 472 || ' JOIN merchant.merchant_token_family_keys tfk' 473 || ' ON ut.token_family_key_serial = tfk.token_family_key_serial' 474 || ' JOIN merchant.merchant_token_families tf' 475 || ' ON tfk.token_family_serial = tf.token_family_serial' 476 || ' WHERE tf.merchant_serial = $1', s) 477 USING rec.merchant_serial;