From 3827e56736586ba29e5cb02796127587877ba7fd Mon Sep 17 00:00:00 2001 From: Georgi Hristov Date: Mon, 27 Jul 2020 00:43:20 +0200 Subject: [PATCH] [update] combine union test in single class --- tests/Model/Client.php | 2 +- tests/Model/Payment.php | 1 - tests/Model/Transaction.php | 6 +- tests/Model/Transaction2.php | 30 ---- tests/ModelAggregateTest.php | 6 +- tests/ModelUnionExprTest.php | 276 ----------------------------------- tests/ModelUnionTest.php | 160 ++++++++++++++++++-- 7 files changed, 158 insertions(+), 323 deletions(-) delete mode 100644 tests/Model/Transaction2.php delete mode 100644 tests/ModelUnionExprTest.php diff --git a/tests/Model/Client.php b/tests/Model/Client.php index c7917706eb..f04200b51d 100644 --- a/tests/Model/Client.php +++ b/tests/Model/Client.php @@ -7,7 +7,7 @@ class Client extends User { public $table = 'client'; - + public function init(): void { parent::init(); diff --git a/tests/Model/Payment.php b/tests/Model/Payment.php index 1333cf23c2..6bf8e0ef94 100644 --- a/tests/Model/Payment.php +++ b/tests/Model/Payment.php @@ -5,7 +5,6 @@ namespace atk4\data\tests\Model; use atk4\data\Model; -use atk4\data\tests\Model\Client; class Payment extends Model { diff --git a/tests/Model/Transaction.php b/tests/Model/Transaction.php index 7c4f17bf6d..ab364c1277 100644 --- a/tests/Model/Transaction.php +++ b/tests/Model/Transaction.php @@ -10,13 +10,15 @@ class Transaction extends Union { public $nestedInvoice; public $nestedPayment; - + + public $subtractInvoice; + public function init(): void { parent::init(); // first lets define nested models - $this->nestedInvoice = $this->addNestedModel(new Invoice()); + $this->nestedInvoice = $this->addNestedModel(new Invoice(), $this->subtractInvoice ? ['amount' => '-[]'] : []); $this->nestedPayment = $this->addNestedModel(new Payment()); // next, define common fields diff --git a/tests/Model/Transaction2.php b/tests/Model/Transaction2.php deleted file mode 100644 index e31cf85252..0000000000 --- a/tests/Model/Transaction2.php +++ /dev/null @@ -1,30 +0,0 @@ -nestedInvoice = $this->addNestedModel(new Invoice(), ['amount' => '-[]']); - $this->nestedPayment = $this->addNestedModel(new Payment()); - - //$this->nestedInvoice->hasOne('client_id', [new Client()]); - //$this->nestedPayment->hasOne('client_id', [new Client()]); - - // next, define common fields - $this->addField('name'); - $this->addField('amount', ['type' => 'money']); - //$this->hasOne('client_id', [new Client()]); - } -} diff --git a/tests/ModelAggregateTest.php b/tests/ModelAggregateTest.php index e5fb97d926..2ede199ac6 100644 --- a/tests/ModelAggregateTest.php +++ b/tests/ModelAggregateTest.php @@ -34,10 +34,10 @@ protected function setUp(): void parent::setUp(); $this->setDB($this->init_db); - $m_invoice = new Model\Invoice($this->db); - $m_invoice->getRef('client_id')->addTitle(); + $invoice = new Model\Invoice($this->db); + $invoice->getRef('client_id')->addTitle(); - $this->aggregate = new Aggregate($m_invoice); + $this->aggregate = new Aggregate($invoice); $this->aggregate->addField('client'); } diff --git a/tests/ModelUnionExprTest.php b/tests/ModelUnionExprTest.php deleted file mode 100644 index 00de312296..0000000000 --- a/tests/ModelUnionExprTest.php +++ /dev/null @@ -1,276 +0,0 @@ - [ - ['name' => 'Vinny'], - ['name' => 'Zoe'], - ], - 'invoice' => [ - ['client_id' => 1, 'name' => 'chair purchase', 'amount' => 4.0], - ['client_id' => 1, 'name' => 'table purchase', 'amount' => 15.0], - ['client_id' => 2, 'name' => 'chair purchase', 'amount' => 4.0], - ], - 'payment' => [ - ['client_id' => 1, 'name' => 'prepay', 'amount' => 10.0], - ['client_id' => 2, 'name' => 'full pay', 'amount' => 4.0], - ], - ]; - - protected function setUp(): void - { - parent::setUp(); - $this->setDB($this->init_db); - - $this->transaction = new Model\Transaction2($this->db); - $this->client = new Model\Client($this->db, 'client'); - - $this->client->hasMany('Payment', [Model\Payment::class]); - $this->client->hasMany('Invoice', [Model\Invoice::class]); - } - - public function testFieldExpr() - { - $transaction = $this->transaction; - - $e = $this->getEscapeChar(); - $this->assertSame(str_replace('"', $e, '"amount"'), $transaction->expr('[]', [$transaction->getFieldExpr($transaction->nestedInvoice, 'amount')])->render()); - $this->assertSame(str_replace('"', $e, '-"amount"'), $transaction->expr('[]', [$transaction->getFieldExpr($transaction->nestedInvoice, 'amount', '-[]')])->render()); - $this->assertSame(str_replace('"', $e, '-NULL'), $transaction->expr('[]', [$transaction->getFieldExpr($transaction->nestedInvoice, 'blah', '-[]')])->render()); - } - - public function testNestedQuery1() - { - $transaction = $this->transaction; - - $e = $this->getEscapeChar(); - $this->assertSame( - str_replace('"', $e, '(select "name" "name" from "invoice" UNION ALL select "name" "name" from "payment") "derivedTable"'), - $transaction->getSubQuery(['name'])->render() - ); - - $this->assertSame( - str_replace('"', $e, '(select "name" "name",-"amount" "amount" from "invoice" UNION ALL select "name" "name","amount" "amount" from "payment") "derivedTable"'), - $transaction->getSubQuery(['name', 'amount'])->render() - ); - - $this->assertSame( - str_replace('"', $e, '(select "name" "name" from "invoice" UNION ALL select "name" "name" from "payment") "derivedTable"'), - $transaction->getSubQuery(['name'])->render() - ); - } - - /** - * If field is not set for one of the nested model, instead of generating exception, NULL will be filled in. - */ - public function testMissingField() - { - $transaction = $this->transaction; - $transaction->nestedInvoice->addExpression('type', '\'invoice\''); - $transaction->addField('type'); - - $e = $this->getEscapeChar(); - $this->assertSame( - str_replace('`', $e, '(select (\'invoice\') `type`,-`amount` `amount` from `invoice` UNION ALL select NULL `type`,`amount` `amount` from `payment`) `derivedTable`'), - $transaction->getSubQuery(['type', 'amount'])->render() - ); - } - - public function testActions() - { - $transaction = $this->transaction; - - $e = $this->getEscapeChar(); - $this->assertSame( - str_replace('"', $e, 'select "name","amount" from (select "name" "name",-"amount" "amount" from "invoice" UNION ALL select "name" "name","amount" "amount" from "payment") "derivedTable"'), - $transaction->action('select')->render() - ); - - $this->assertSame( - str_replace('"', $e, 'select "name" from (select "name" "name" from "invoice" UNION ALL select "name" "name" from "payment") "derivedTable"'), - $transaction->action('field', ['name'])->render() - ); - - $this->assertSame( - str_replace('"', $e, 'select sum("cnt") from (select count(*) "cnt" from "invoice" UNION ALL select count(*) "cnt" from "payment") "derivedTable"'), - $transaction->action('count')->render() - ); - - $this->assertSame( - str_replace('"', $e, 'select sum("val") from (select sum(-"amount") "val" from "invoice" UNION ALL select sum("amount") "val" from "payment") "derivedTable"'), - $transaction->action('fx', ['sum', 'amount'])->render() - ); - } - - public function testActions2() - { - $transaction = $this->transaction; - $this->assertSame(5, (int) $transaction->action('count')->getOne()); - $this->assertSame(-9.0, (float) $transaction->action('fx', ['sum', 'amount'])->getOne()); - } - - public function testSubAction1() - { - $transaction = $this->transaction; - $e = $this->getEscapeChar(); - $this->assertSame( - str_replace('"', $e, '(select sum(-"amount") from "invoice" UNION ALL select sum("amount") from "payment") "derivedTable"'), - $transaction->getSubAction('fx', ['sum', 'amount'])->render() - ); - } - - public function testBasics() - { - $this->setDB($this->init_db); - - $client = $this->client; - - // There are total of 2 clients - $this->assertSame(2, (int) $client->action('count')->getOne()); - - // Client with ID=1 has invoices for 19 - $client->load(1); - $this->assertSame(19.0, (float) $client->ref('Invoice')->action('fx', ['sum', 'amount'])->getOne()); - - $transaction = new Model\Transaction2($this->db); - $this->assertSame([ - ['name' => 'chair purchase', 'amount' => -4.0], - ['name' => 'table purchase', 'amount' => -15.0], - ['name' => 'chair purchase', 'amount' => -4.0], - ['name' => 'prepay', 'amount' => 10.0], - ['name' => 'full pay', 'amount' => 4.0], - ], $transaction->export()); - - // Transaction is Union Model - $client->hasMany('Transaction', new Model\Transaction2()); - - $this->assertSame([ - ['name' => 'chair purchase', 'amount' => -4.0], - ['name' => 'table purchase', 'amount' => -15.0], - ['name' => 'prepay', 'amount' => 10.0], - ], $client->ref('Transaction')->export()); - } - - public function testGrouping1() - { - $transaction = $this->transaction; - - $transaction->groupBy('name', ['amount' => ['sum([])', 'type' => 'money']]); - - $e = $this->getEscapeChar(); - $this->assertSame( - str_replace('"', $e, '(select "name" "name",sum(-"amount") "amount" from "invoice" group by "name" UNION ALL select "name" "name",sum("amount") "amount" from "payment" group by "name") "derivedTable"'), - $transaction->getSubQuery(['name', 'amount'])->render() - ); - } - - public function testGrouping2() - { - $transaction = $this->transaction; - - $transaction->groupBy('name', ['amount' => ['sum([])', 'type' => 'money']]); - - $e = $this->getEscapeChar(); - $this->assertSame( - str_replace('"', $e, 'select "name",sum("amount") "amount" from (select "name" "name",sum(-"amount") "amount" from "invoice" group by "name" UNION ALL select "name" "name",sum("amount") "amount" from "payment" group by "name") "derivedTable" group by "name"'), - $transaction->action('select', [['name', 'amount']])->render() - ); - } - - /** - * If all nested models have a physical field to which a grouped column can be mapped into, then we should group all our - * sub-queries. - */ - public function testGrouping3() - { - $transaction = $this->transaction; - $transaction->groupBy('name', ['amount' => ['sum([])', 'type' => 'money']]); - $transaction->setOrder('name'); - - $this->assertSame([ - ['name' => 'chair purchase', 'amount' => -8.0], - ['name' => 'full pay', 'amount' => 4.0], - ['name' => 'prepay', 'amount' => 10.0], - ['name' => 'table purchase', 'amount' => -15.0], - ], $transaction->export()); - } - - /** - * If a nested model has a field defined through expression, it should be still used in grouping. We should test this - * with both expressions based off the fields and static expressions (such as "blah"). - */ - public function testSubGroupingByExpressions() - { - $transaction = $this->transaction; - $transaction->nestedInvoice->addExpression('type', '\'invoice\''); - $transaction->nestedPayment->addExpression('type', '\'payment\''); - $transaction->addField('type'); - - $transaction->groupBy('type', ['amount' => ['sum([])', 'type' => 'money']]); - - $this->assertSame([ - ['type' => 'invoice', 'amount' => -23.0], - ['type' => 'payment', 'amount' => 14.0], - ], $transaction->export(['type', 'amount'])); - } - - public function testReference() - { - $client = $this->client; - $client->hasMany('tr', new Model\Transaction2()); - - $this->assertSame(19.0, (float) $client->load(1)->ref('Invoice')->action('fx', ['sum', 'amount'])->getOne()); - $this->assertSame(10.0, (float) $client->load(1)->ref('Payment')->action('fx', ['sum', 'amount'])->getOne()); - $this->assertSame(-9.0, (float) $client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->getOne()); - - $e = $this->getEscapeChar(); - $this->assertSame( - str_replace('"', $e, 'select sum("val") from (select sum(-"amount") "val" from "invoice" where "client_id" = :a ' . - 'UNION ALL select sum("amount") "val" from "payment" where "client_id" = :b) "derivedTable"'), - $client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->render() - ); - } - - /** - * Aggregation is supposed to work in theory, but MySQL uses "semi-joins" for this type of query which does not support UNION, - * and therefore it complains about `client`.`id` field. - * - * See also: http://stackoverflow.com/questions/8326815/mysql-field-from-union-subselect#comment10267696_8326815 - */ - public function testFieldAggregate() - { - $this->client->hasMany('tr', new Model\Transaction2()) - ->addField('balance', ['field' => 'amount', 'aggregate' => 'sum']); - - $this->assertTrue(true); // fake assert - //select "client"."id","client"."name",(select sum("val") from (select sum("amount") "val" from "invoice" where "client_id" = "client"."id" UNION ALL select sum("amount") "val" from "payment" where "client_id" = "client"."id") "derivedTable") "balance" from "client" where "client"."id" = 1 limit 0, 1 - //$c->load(1); - } - - /** - * Model's conditions can still be placed on the original field values. - */ - public function testConditionOnMappedField() - { - $transaction = new Model\Transaction2($this->db); - $transaction->nestedInvoice->addCondition('amount', 4); - - $this->assertSame([ - ['name' => 'chair purchase', 'amount' => -4.0], - ['name' => 'chair purchase', 'amount' => -4.0], - ['name' => 'prepay', 'amount' => 10.0], - ['name' => 'full pay', 'amount' => 4.0], - ], $transaction->export()); - } -} diff --git a/tests/ModelUnionTest.php b/tests/ModelUnionTest.php index 96deef3fd6..5871049d81 100644 --- a/tests/ModelUnionTest.php +++ b/tests/ModelUnionTest.php @@ -8,8 +8,9 @@ class ModelUnionTest extends \atk4\schema\PhpunitTestCase { /** @var Model\Transaction */ protected $transaction; + protected $subtractInvoiceTransaction; protected $client; - + /** @var array */ private $init_db = [ @@ -33,13 +34,34 @@ protected function setUp(): void parent::setUp(); $this->setDB($this->init_db); - $this->transaction = new Model\Transaction($this->db); - + $this->transaction = $this->getTransaction($this->db); + $this->subtractInvoiceTransaction = $this->getSubtractInvoiceTransaction($this->db); + $this->client = new Model\Client($this->db); - + $this->client->hasMany('Payment', [Model\Payment::class]); $this->client->hasMany('Invoice', [Model\Invoice::class]); } + + protected function getTransaction($persistence = null) + { + return new Model\Transaction($persistence); + } + + protected function getSubtractInvoiceTransaction($persistence = null) + { + return new Model\Transaction($persistence, ['subtractInvoice' => true]); + } + + public function testFieldExpr() + { + $transaction = $this->subtractInvoiceTransaction; + + $e = $this->getEscapeChar(); + $this->assertSame(str_replace('"', $e, '"amount"'), $transaction->expr('[]', [$transaction->getFieldExpr($transaction->nestedInvoice, 'amount')])->render()); + $this->assertSame(str_replace('"', $e, '-"amount"'), $transaction->expr('[]', [$transaction->getFieldExpr($transaction->nestedInvoice, 'amount', '-[]')])->render()); + $this->assertSame(str_replace('"', $e, '-NULL'), $transaction->expr('[]', [$transaction->getFieldExpr($transaction->nestedInvoice, 'blah', '-[]')])->render()); + } public function testNestedQuery1() { @@ -102,6 +124,13 @@ public function testActions() str_replace('"', $e, 'select sum("val") from (select sum("amount") "val" from "invoice" UNION ALL select sum("amount") "val" from "payment") "derivedTable"'), $transaction->action('fx', ['sum', 'amount'])->render() ); + + $transaction = $this->subtractInvoiceTransaction; + + $this->assertSame( + str_replace('"', $e, 'select sum("val") from (select sum(-"amount") "val" from "invoice" UNION ALL select sum("amount") "val" from "payment") "derivedTable"'), + $transaction->action('fx', ['sum', 'amount'])->render() + ); } public function testActions2() @@ -109,20 +138,35 @@ public function testActions2() $transaction = $this->transaction; $this->assertSame(5, (int) $transaction->action('count')->getOne()); $this->assertSame(37.0, (float) $transaction->action('fx', ['sum', 'amount'])->getOne()); + + $transaction = $this->subtractInvoiceTransaction; + $this->assertSame(-9.0, (float) $transaction->action('fx', ['sum', 'amount'])->getOne()); + } + + public function testSubAction1() + { + $transaction = $this->subtractInvoiceTransaction; + $e = $this->getEscapeChar(); + $this->assertSame( + str_replace('"', $e, '(select sum(-"amount") from "invoice" UNION ALL select sum("amount") from "payment") "derivedTable"'), + $transaction->getSubAction('fx', ['sum', 'amount'])->render() + ); } public function testBasics() { - $client = $this->client; + $client = clone $this->client; // There are total of 2 clients $this->assertSame(2, (int) $client->action('count')->getOne()); // Client with ID=1 has invoices for 19 $client->load(1); + $this->assertSame(19.0, (float) $client->ref('Invoice')->action('fx', ['sum', 'amount'])->getOne()); - $transaction = new Model\Transaction($this->db); + $transaction = $this->transaction; + $this->assertSame([ ['name' => 'chair purchase', 'amount' => 4.0], ['name' => 'table purchase', 'amount' => 15.0], @@ -132,13 +176,36 @@ public function testBasics() ], $transaction->export()); // Transaction is Union Model - $client->hasMany('Transaction', new Model\Transaction()); + $client->hasMany('Transaction', $transaction); $this->assertSame([ ['name' => 'chair purchase', 'amount' => 4.0], ['name' => 'table purchase', 'amount' => 15.0], ['name' => 'prepay', 'amount' => 10.0], ], $client->ref('Transaction')->export()); + + $client = clone $this->client; + + $client->load(1); + + $transaction = $this->subtractInvoiceTransaction; + + $this->assertSame([ + ['name' => 'chair purchase', 'amount' => -4.0], + ['name' => 'table purchase', 'amount' => -15.0], + ['name' => 'chair purchase', 'amount' => -4.0], + ['name' => 'prepay', 'amount' => 10.0], + ['name' => 'full pay', 'amount' => 4.0], + ], $transaction->export()); + + // Transaction is Union Model + $client->hasMany('Transaction', $transaction); + + $this->assertSame([ + ['name' => 'chair purchase', 'amount' => -4.0], + ['name' => 'table purchase', 'amount' => -15.0], + ['name' => 'prepay', 'amount' => 10.0], + ], $client->ref('Transaction')->export()); } public function testGrouping1() @@ -152,6 +219,16 @@ public function testGrouping1() str_replace('"', $e, '(select "name" "name",sum("amount") "amount" from "invoice" group by "name" UNION ALL select "name" "name",sum("amount") "amount" from "payment" group by "name") "derivedTable"'), $transaction->getSubQuery(['name', 'amount'])->render() ); + + $transaction = $this->subtractInvoiceTransaction; + + $transaction->groupBy('name', ['amount' => ['sum([])', 'type' => 'money']]); + + $e = $this->getEscapeChar(); + $this->assertSame( + str_replace('"', $e, '(select "name" "name",sum(-"amount") "amount" from "invoice" group by "name" UNION ALL select "name" "name",sum("amount") "amount" from "payment" group by "name") "derivedTable"'), + $transaction->getSubQuery(['name', 'amount'])->render() + ); } public function testGrouping2() @@ -165,6 +242,16 @@ public function testGrouping2() str_replace('"', $e, 'select "name",sum("amount") "amount" from (select "name" "name",sum("amount") "amount" from "invoice" group by "name" UNION ALL select "name" "name",sum("amount") "amount" from "payment" group by "name") "derivedTable" group by "name"'), $transaction->action('select', [['name', 'amount']])->render() ); + + $transaction = $this->subtractInvoiceTransaction; + + $transaction->groupBy('name', ['amount' => ['sum([])', 'type' => 'money']]); + + $e = $this->getEscapeChar(); + $this->assertSame( + str_replace('"', $e, 'select "name",sum("amount") "amount" from (select "name" "name",sum(-"amount") "amount" from "invoice" group by "name" UNION ALL select "name" "name",sum("amount") "amount" from "payment" group by "name") "derivedTable" group by "name"'), + $transaction->action('select', [['name', 'amount']])->render() + ); } /** @@ -183,6 +270,17 @@ public function testGrouping3() ['name' => 'prepay', 'amount' => 10.0], ['name' => 'table purchase', 'amount' => 15.0], ], $transaction->export()); + + $transaction = $this->subtractInvoiceTransaction; + $transaction->groupBy('name', ['amount' => ['sum([])', 'type' => 'money']]); + $transaction->setOrder('name'); + + $this->assertSame([ + ['name' => 'chair purchase', 'amount' => -8.0], + ['name' => 'full pay', 'amount' => 4.0], + ['name' => 'prepay', 'amount' => 10.0], + ['name' => 'table purchase', 'amount' => -15.0], + ], $transaction->export()); } /** @@ -202,12 +300,24 @@ public function testSubGroupingByExpressions() ['type' => 'invoice', 'amount' => 23.0], ['type' => 'payment', 'amount' => 14.0], ], $transaction->export(['type', 'amount'])); + + $transaction = $this->subtractInvoiceTransaction; + $transaction->nestedInvoice->addExpression('type', '\'invoice\''); + $transaction->nestedPayment->addExpression('type', '\'payment\''); + $transaction->addField('type'); + + $transaction->groupBy('type', ['amount' => ['sum([])', 'type' => 'money']]); + + $this->assertSame([ + ['type' => 'invoice', 'amount' => -23.0], + ['type' => 'payment', 'amount' => 14.0], + ], $transaction->export(['type', 'amount'])); } public function testReference() { - $client = $this->client; - $client->hasMany('tr', new Model\Transaction()); + $client = clone $this->client; + $client->hasMany('tr', $this->getTransaction()); $this->assertSame(19.0, (float) $client->load(1)->ref('Invoice')->action('fx', ['sum', 'amount'])->getOne()); $this->assertSame(10.0, (float) $client->load(1)->ref('Payment')->action('fx', ['sum', 'amount'])->getOne()); @@ -219,6 +329,20 @@ public function testReference() 'UNION ALL select sum("amount") "val" from "payment" where "client_id" = :b) "derivedTable"'), $client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->render() ); + + $client = clone $this->client; + $client->hasMany('tr', $this->getSubtractInvoiceTransaction()); + + $this->assertSame(19.0, (float) $client->load(1)->ref('Invoice')->action('fx', ['sum', 'amount'])->getOne()); + $this->assertSame(10.0, (float) $client->load(1)->ref('Payment')->action('fx', ['sum', 'amount'])->getOne()); + $this->assertSame(-9.0, (float) $client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->getOne()); + + $e = $this->getEscapeChar(); + $this->assertSame( + str_replace('"', $e, 'select sum("val") from (select sum(-"amount") "val" from "invoice" where "client_id" = :a ' . + 'UNION ALL select sum("amount") "val" from "payment" where "client_id" = :b) "derivedTable"'), + $client->load(1)->ref('tr')->action('fx', ['sum', 'amount'])->render() + ); } /** @@ -230,11 +354,27 @@ public function testReference() public function testFieldAggregate() { $client = $this->client; - $client->hasMany('tr', new Model\Transaction2()) + $client->hasMany('tr', $this->getTransaction()) ->addField('balance', ['field' => 'amount', 'aggregate' => 'sum']); $this->assertTrue(true); // fake assert //select "client"."id","client"."name",(select sum("val") from (select sum("amount") "val" from "invoice" where "client_id" = "client"."id" UNION ALL select sum("amount") "val" from "payment" where "client_id" = "client"."id") "derivedTable") "balance" from "client" where "client"."id" = 1 limit 0, 1 //$c->load(1); } + + /** + * Model's conditions can still be placed on the original field values. + */ + public function testConditionOnMappedField() + { + $transaction = $this->subtractInvoiceTransaction; + $transaction->nestedInvoice->addCondition('amount', 4); + + $this->assertSame([ + ['name' => 'chair purchase', 'amount' => -4.0], + ['name' => 'chair purchase', 'amount' => -4.0], + ['name' => 'prepay', 'amount' => 10.0], + ['name' => 'full pay', 'amount' => 4.0], + ], $transaction->export()); + } }