Verified Commit 478fb374 authored by godotislate's avatar godotislate
Browse files

fix: #3569316 Client connection () must be of type object, null given when deleting a node

By: titouille
By: mondrake
By: sdjili
By: adraco
By: duaelfr
By: daffie
By: godotislate
(cherry picked from commit 7634c658)
parent 12e1396d
Loading
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -170,6 +170,11 @@ public function commitAll(): void {
    foreach (array_reverse($this->stack()) as $id => $item) {
      $this->unpile($item->name, $id);
    }

    // Run post-transaction callbacks now (while Connection is still valid).
    // Prevents destructor-order bug: Connection::__destruct can run before
    // Transaction::__destruct, leaving PDO null when callbacks run.
    $this->processPostTransactionCallbacks();
  }

  /**
+28 −0
Original line number Diff line number Diff line
@@ -1249,6 +1249,34 @@ public function testRootTransactionEndCallbackFailureUponDdlAndRollbackForNonTra
    $this->assertRowPresent('row');
  }

  /**
   * Tests post-transaction callback executes on "garbage collection".
   *
   * Simulate the end of a request by closing the connection and destroying
   * the transaction manually. The order matters for this test as the garbage
   * collection is unpredictable and could operate this way.
   */
  public function testPostTransactionsAlwaysExecutedBeforeConnectionIsDestroyed(): void {
    $transaction = $this->createRootTransaction('', FALSE);
    $this->connection->transactionManager()->addPostTransactionCallback([$this, 'rootTransactionCallback']);
    $this->insertRow('row');
    $this->assertNull($this->postTransactionCallbackAction);
    $this->assertRowAbsent('rtcCommit');

    Database::closeConnection();
    unset($this->connection);
    unset($transaction);

    // Reopen the database connection so we can continue running assertions.
    $this->connection = Database::getConnection();

    // The post-transaction callback should now have inserted a 'rtcCommit'
    // row.
    $this->assertSame('rtcCommit', $this->postTransactionCallbackAction);
    $this->assertRowPresent('row');
    $this->assertRowPresent('rtcCommit');
  }

  /**
   * A post-transaction callback for testing purposes.
   */