Problem/Motivation

Core should not use direct db calls to entity tables because they are managed by the table mapper entity API.

Proposed resolution

All db_query() and similar should be replaced with \Drupal::entityQuery() or with injected entity storage, and updates/deletes should be done via the Entity API.

Remaining tasks

replace all usage

User interface changes

no

API changes

no

Data model changes

no

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mondrake created an issue. See original summary.

mondrake’s picture

Status: Active » Needs review
FileSize
7.88 KB

Patch.

mondrake’s picture

Forgot some.

goodboy’s picture

  1.     $fids = \Drupal::entityQuery('file')->sort('fid', 'DESC')->range(0, 1)->execute();
    -    return empty($fids) ? 0 : array_values($fids)[0];
    +    return (int) reset($fids);

    We enshure that returns an integer value because it may be used on compare operations.

  2.      $fids_query = \Drupal::entityQuery('file')->sort('fid', 'DESC')->range(0, 1);
    -    $max_fid_after = array_values($fids_query->execute())[0];
    +    $max_fid_after = (int) reset($fids_query->execute());
         $this->assertTrue($max_fid_after > $this->maxFidBefore, 'A new file was created.');

    For empty $fids_query results $max_fid_after is NULL (or FALSE) and can't be used on compare operation.

Or use current() instead reset() to prevent errors with reset's argument array &$array.

voleger’s picture

Status: Needs review » Needs work
mondrake’s picture

Thanks for review @goodboy!

For empty $fids_query results $max_fid_after is NULL (or FALSE) and can't be used on compare operation.

You are right in principle... I left that consciouly though because at that point in the test we expect at least one entity is returned.

Can you make #4 into a patch?

goodboy’s picture

Assigned: Unassigned » goodboy
goodboy’s picture

@mondrake , I'll do a patch.

I understand that specific tests will be correct, but I would like to make uniform functions.

goodboy’s picture

Assigned: goodboy » Unassigned
Status: Needs work » Needs review
FileSize
6.37 KB
10.2 KB

Patch #4

voleger’s picture

Status: Needs review » Reviewed & tested by the community

#9 addressed all from #4
Tests pass
+1 for rtbc

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/file/src/Tests/FileFieldTestBase.php
@@ -59,7 +59,8 @@ public function getTestFile($type_name, $size = NULL) {
-    return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField();
+    $fids = \Drupal::entityQuery('file')->sort('fid', 'DESC')->range(0, 1)->execute();
+    return (int) current($fids);

+++ b/core/modules/file/tests/src/Functional/FileFieldTestBase.php
@@ -60,7 +60,8 @@ public function getTestFile($type_name, $size = NULL) {
-    return (int) db_query('SELECT MAX(fid) FROM {file_managed}')->fetchField();
+    $fids = \Drupal::entityQuery('file')->sort('fid', 'DESC')->range(0, 1)->execute();
+    return (int) current($fids);

+++ b/core/modules/file/tests/src/Functional/SaveUploadFormTest.php
@@ -66,7 +66,8 @@ protected function setUp() {
-    $this->maxFidBefore = db_query('SELECT MAX(fid) AS fid FROM {file_managed}')->fetchField();
+    $fids = \Drupal::entityQuery('file')->sort('fid', 'DESC')->range(0, 1)->execute();
+    $this->maxFidBefore = (int) current($fids);

@@ -89,7 +90,8 @@ protected function setUp() {
-    $max_fid_after = db_query('SELECT MAX(fid) AS fid FROM {file_managed}')->fetchField();
+    $fids_query = \Drupal::entityQuery('file')->sort('fid', 'DESC')->range(0, 1);
+    $max_fid_after = (int) current($fids_query->execute());

@@ -107,7 +109,7 @@ public function testNormal() {
-    $max_fid_after = db_query('SELECT MAX(fid) AS fid FROM {file_managed}')->fetchField();
+    $max_fid_after = (int) current($fids_query->execute());

This can use an aggregate query. Ie.
return (int) \Drupal::entityQueryAggregate('file')->aggregate('fid', 'max')->execute()[0]['fid_max']
... and all the other places... it seems the only query this replaces is the max ones so we should be using \Drupal::entityQueryAggregate('file')->aggregate('fid', 'max') so people learn the right way to do that.

goodboy’s picture

Status: Needs work » Needs review
FileSize
7.37 KB
10.12 KB

Apply #11

Status: Needs review » Needs work

The last submitted patch, 12: 3014950-12.patch, failed testing. View results

alexpott’s picture

+++ b/core/modules/file/tests/src/Functional/SaveUploadFormTest.php
@@ -89,7 +89,8 @@ protected function setUp() {
+    $fids_query = \Drupal::entityQueryAggregate('file')->aggregate('fid', 'max');
+    $max_fid_after = (int) $fids_query->execute()[0]['fid_max'];

+++ b/core/modules/file/tests/src/Functional/SaveUploadTest.php
@@ -82,7 +82,9 @@ protected function setUp() {
+    $fids_query = \Drupal::entityQueryAggregate('file')->aggregate('fid', 'max');
+    $max_fid_after = (int) $fids_query->execute()[0]['fid_max'];

Unfortunately re-executing an aggregate query appears not to work. Let's do (int) \Drupal::entityQueryAggregate('file')->aggregate('fid', 'max')->execute()[0]['fid_max']; each time and open a bug report about this as you would expect it to work (if there is no existing bug report).

goodboy’s picture

Status: Needs work » Needs review
FileSize
2.74 KB
10.15 KB

Status: Needs review » Needs work

The last submitted patch, 15: 3014950-15.patch, failed testing. View results

goodboy’s picture

Status: Needs work » Needs review
FileSize
839 bytes
10.15 KB
mondrake’s picture

Status: Needs review » Reviewed & tested by the community
alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed c503bb6 and pushed to 8.7.x. Thanks!

  • alexpott committed c503bb6 on 8.7.x
    Issue #3014950 by goodboy, mondrake, alexpott: Replace all db calls to...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.