Problem/Motivation

Convert the schema.inc functions to a service so it can be injected, unit tested and swapped. Affected functions:

  • drupal_get_schema_versions()
  • drupal_get_installed_schema_version()
  • drupal_set_installed_schema_version()

This functions are like a registry for last executed update function per module which is statically cached (clean-up of drupal_static() is second win here

The remaining functions should fall into the scope of extension services and processed in #2908886: Split off schema management out of schema.inc

  • drupal_get_module_schema()
  • drupal_install_schema()
  • drupal_uninstall_schema()
  • _drupal_schema_initialize()

Already removed in https://www.drupal.org/node/2467521

  • drupal_get_schema()
  • drupal_get_complete_schema()
  • drupal_get_schema_unprocessed()

drupal_schema_get_field_value() Fixed in #3051981: Deprecate drupal_schema_get_field_value()

Proposed resolution

Create new schema service with methods that replace the mentioned functions in schema.inc. See the API-changes.

The following functions will be deprecated:

  • drupal_get_schema_versions()
  • drupal_get_installed_schema_version()
  • drupal_set_installed_schema_version()

Remaining tasks

None

User interface changes

None

API changes

A new service called "update.update_hook_registry" is created with the following methods:

  • getAvailableUpdates($module)
  • getInstalledVersion($module)
  • setInstalledVersion($module, $version)
  • deleteInstalledVersion($module)
  • getAllInstalledVersions()

The service has a factory service for its creation ("update.update_hook_registry_factory").

CommentFileSizeAuthor
#293 2124069-292.patch52.77 KBandypost
#293 interdiff.txt1.03 KBandypost
#291 2124069-291.patch53 KBandypost
#291 interdiff.txt801 bytesandypost
#290 2124069-290.patch52.87 KBandypost
#290 interdiff.txt10.65 KBandypost
#288 2124069-288.patch53.07 KBandypost
#288 interdiff.txt657 bytesandypost
#286 2124069-286.patch52.43 KBandypost
#286 interdiff.txt6.29 KBandypost
#283 2124069-283.patch52.33 KBandypost
#283 interdiff.txt1.04 KBandypost
#282 2124069-282.patch52.13 KBandypost
#282 interdiff.txt8.17 KBandypost
#281 2124069-281.patch52.16 KBandypost
#281 interdiff.txt1.41 KBandypost
#279 2124069-279.patch52.94 KBandypost
#279 interdiff.txt6.31 KBandypost
#278 2124069-278.patch53.11 KBandypost
#278 interdiff.txt3.07 KBandypost
#276 2124069-interdiff-274-276.txt828 bytescburschka
#276 2124069-276.patch53.98 KBcburschka
#274 2124069-274.patch53.17 KBandypost
#274 interdiff.txt832 bytesandypost
#273 2124069-272.patch53.2 KBcburschka
#272 2124069-interdiff-268-272.txt6.37 KBcburschka
#272 2124069-interdiff-268-272.txt6.37 KBcburschka
#268 2124069-interdiff-265-268.txt596 bytescburschka
#268 2124069-268.patch53.68 KBcburschka
#265 2124069-interdiff-260-265.txt649 bytescburschka
#265 2124069-265.patch53.68 KBcburschka
#260 2124069-interdiff-257-260.txt600 bytescburschka
#260 2124069-260.patch53.69 KBcburschka
#259 2124069-259.patch53.69 KBandypost
#259 interdiff.txt1.27 KBandypost
#258 2124069-258.patch53.65 KBandypost
#258 interdiff.txt1.75 KBandypost
#257 2124069-interdiff-253-257.txt1.07 KBcburschka
#257 2124069-257.patch53.65 KBcburschka
#253 2124069-253.patch53.65 KBandypost
#253 interdiff.txt1.48 KBandypost
#252 2124069-interdiff-251-252.txt31.32 KBcburschka
#252 2124069-252.patch53.56 KBcburschka
#251 2124069-interdiff-249-251.txt9.83 KBcburschka
#251 2124069-251.patch26.54 KBcburschka
#249 2124069-interdiff-247-249.txt2.92 KBcburschka
#249 2124069-249.patch20.76 KBcburschka
#248 2124069-interdiff-246-247.txt6.21 KBcburschka
#248 2124069-247.patch22.48 KBcburschka
#246 2124069-interdiff-242-246.txt707 bytescburschka
#246 2124069-246.patch28.21 KBcburschka
#242 2124069-interdiff-241-242.txt5.45 KBcburschka
#242 2124069-242.patch27.68 KBcburschka
#241 2124069-241.patch27.67 KBcburschka
#235 interdiff-2124069-233-235.txt5.51 KBvoleger
#235 2124069-235.patch37.25 KBvoleger
#235 2124069-235-just-reroll.patch37.17 KBvoleger
#233 2124069-233.patch37.14 KBandypost
#233 interdiff.txt2.52 KBandypost
#230 2124069-230-interdiff.txt2.85 KBkim.pepper
#230 2124069-230.patch37.07 KBkim.pepper
#228 2124069-228-interdiff.txt14.52 KBkim.pepper
#228 2124069-228.patch36.94 KBkim.pepper
#225 2124069-225.patch23.69 KBvacho
#221 2124069-221-interdiff.txt4.04 KBkim.pepper
#221 2124069-221.patch29.53 KBkim.pepper
#219 2124069-219-interdiff.txt739 byteskim.pepper
#219 2124069-219.patch30.39 KBkim.pepper
#217 2124069-217-interdiff.txt22.23 KBkim.pepper
#217 2124069-217.patch30.38 KBkim.pepper
#212 2124069-212.patch29.23 KBkostyashupenko
#209 2124069-209.patch29.24 KBkim.pepper
#209 2124069-209-interdiff.txt470 byteskim.pepper
#207 2124069-207.patch29.23 KBkim.pepper
#207 2124069-207-interdiff.txt6.12 KBkim.pepper
#201 interdiff-2124069-200-201.txt7.71 KBvoleger
#201 2124069-201.patch26.98 KBvoleger
#200 2124069-200.patch26.25 KBvoleger
#196 interdiff-2124069-189-196.txt5.08 KBmartin107
#196 2124069-196.patch26.23 KBmartin107
#189 2124069-189.patch26.25 KBandypost
#189 interdiff.txt8.79 KBandypost
#187 2124069-187.patch33.93 KBandypost
#187 interdiff.txt1.91 KBandypost
#186 2124069-186.patch32.01 KBandypost
#186 interdiff.txt14.53 KBandypost
#184 interdiff-2124069-182-184.txt5.26 KBmartin107
#184 2124069-184.patch23.61 KBmartin107
#182 interdiff-2124069-179-182.patch1.27 KBmartin107
#182 2124069-182.patch23.05 KBmartin107
#179 interdiff-2124069-177-179.txt893 bytesmartin107
#179 2124069-179.patch23.04 KBmartin107
#177 interdiff-2124069-175-177.txt10.77 KBmartin107
#177 2124069-177.patch23.11 KBmartin107
#175 interdiff-2124069-172-175.txt3.39 KBmartin107
#175 2124069-175.patch22.57 KBmartin107
#172 2124069-172.patch22.4 KBvoleger
#171 2124069-171.patch22.42 KBandypost
#171 interdiff.txt9.01 KBandypost
#167 2124069-167.patch21.99 KBandypost
#167 interdiff.txt26 KBandypost
#166 2124069-166.patch39.74 KBmartin107
#166 interdiff-2124069-163-166.txt8.54 KBmartin107
#163 2124069-163.patch35.8 KBmartin107
#160 2124069-160.patch35.38 KBmartin107
#160 interdiff-2124069-157-160.txt291 bytesmartin107
#157 interdiff-2124069-154-157.txt300 bytesmartin107
#157 2124069-157.patch35.4 KBmartin107
#154 2124069-154.patch35.36 KBmartin107
#154 interdiff-153-154.txt13.74 KBmartin107
#153 interdiff-2124069-152-153.txt4.94 KBmartin107
#153 2124069-153.patch37.22 KBmartin107
#151 interdiff-2124069-148-150.txt3.07 KBmartin107
#151 2124069-150.patch32.27 KBmartin107
#148 interdiff-2124069-146-148.txt2.63 KBmartin107
#148 2124069-148.patch30.15 KBmartin107
#146 interdiff-2124069-142-146.txt5.6 KBmartin107
#146 2124069-146.patch30.07 KBmartin107
#142 interdiff-2124069-139-141.txt7.58 KBmartin107
#142 2124069-141.patch28.07 KBmartin107
#139 interdiff-2124069-136-139.txt3.87 KBmartin107
#139 2124069-139.patch21.75 KBmartin107
#136 2124069-136.patch22.07 KBmartin107
#136 interdiff-2124069-133-136.txt26.96 KBmartin107
#133 2124069-133.patch47.7 KBmartin107
#131 interdiff-126-131.txt5.36 KBMerryHamster
#131 2124069-131.patch47.72 KBMerryHamster
#126 interdiff-2124069-125-126.txt5.78 KBmartin107
#126 2124069-126.patch47.85 KBmartin107
#125 2124069-125.patch52.31 KBmartin107
#117 interdiff-2124069-115-117.txt3.8 KBdaffie
#117 2124069-117.patch49.63 KBdaffie
#115 2124069-115.patch49.74 KBdaffie
#115 interdiff-2124069-133-115.txt2.54 KBdaffie
#113 interdiff-111-113.txt816 bytesdaffie
#113 2124069-113.patch49.74 KBdaffie
#111 interdiff-109-111.txt2.92 KBdaffie
#111 2124069-111.patch50.54 KBdaffie
#109 interdiff-106-109.txt1.79 KBdaffie
#109 2124069-109.patch52.62 KBdaffie
#106 2124069-106.patch52.23 KBdaffie
#99 interdiff.txt2.59 KBdawehner
#99 2124069-99.patch33.86 KBdawehner
#97 interdiff.txt7.48 KBdawehner
#97 2124069-97.patch35.96 KBdawehner
#86 interdiff.txt508 bytesdawehner
#86 2124069-86.patch39.19 KBdawehner
#84 interdiff.txt18.2 KBdawehner
#84 2124069-84.patch39.2 KBdawehner
#80 interdiff.txt1.16 KBdawehner
#80 2124069-80.patch40.2 KBdawehner
#78 interdiff.txt8.12 KBdawehner
#78 2124069-78.patch40.18 KBdawehner
#76 interdiff.txt15.37 KBdawehner
#76 2124069-76.patch39.99 KBdawehner
#63 2124069-63.patch39.15 KBpcambra
#62 2124069-62.patch39.38 KBpcambra
#62 interdiff.txt5.36 KBpcambra
#56 2124069-56.patch39.53 KBpcambra
#56 interdiff.txt544 bytespcambra
#54 interdiff-2124069-54.txt580 bytesdamiankloip
#54 2124069-54.patch39.54 KBdamiankloip
#52 interdiff-2124069-52.txt3.22 KBdamiankloip
#52 2124069-52.patch39.11 KBdamiankloip
#51 212406-51.patch38.3 KBcilefen
#48 interdiff-2124069-48.txt1.37 KBdamiankloip
#48 2124069-48.patch38.19 KBdamiankloip
#46 interdiff-2124069-45.txt9.08 KBdamiankloip
#46 2124069-45.patch38.26 KBdamiankloip
#43 interdiff-2124069-43.txt4.78 KBdamiankloip
#43 2124069-43.patch37.51 KBdamiankloip
#40 interdiff-2124069-40.txt6.57 KBdamiankloip
#40 2124069-40.patch37.49 KBdamiankloip
#38 interdiff-2124069-38.txt2.79 KBdamiankloip
#38 2124069-38.patch44.07 KBdamiankloip
#35 interdiff-2124069-35.txt4.15 KBdamiankloip
#35 2124069-35.patch44.11 KBdamiankloip
#34 interdiff-2124069-34.txt39.84 KBdamiankloip
#34 2124069-34.patch47.22 KBdamiankloip
#31 2124069-31.patch45.67 KBParisLiakos
#28 interdiff-2124069-28.txt261 bytesParisLiakos
#28 2124069-28.patch45.67 KBParisLiakos
#26 interdiff-2124069-26.txt841 bytesdamiankloip
#26 2124069-26.patch45.67 KBdamiankloip
#24 2124069-24.patch45.67 KBdamiankloip
#21 schema-reroll-21.patch52.07 KBdawehner
#19 2124069-19.patch48.56 KBdawehner
#15 schema-2124069-15.patch48.66 KBdawehner
#11 drupal_2124069_11.patch49.04 KBxano
#11 interdiff.txt22.12 KBxano
#9 drupal_2124069_9.patch33.47 KBxano
#7 2124069-7.patch31.33 KBdamiankloip
#3 2124069-2.patch30.29 KBdamiankloip
#3 interdiff-2124069-2.txt3.39 KBdamiankloip
#1 2124069.patch29.51 KBdamiankloip

Issue fork drupal-2124069

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

damiankloip’s picture

StatusFileSize
new29.51 KB

Made a start, drupal nearly installs, get a nesting level too deep error when it tries to load an entity.

dawehner’s picture

+++ b/core/lib/Drupal/Core/Schema/Schema.php
@@ -0,0 +1,397 @@
+      db_create_table($name, $table);
...
+      if (db_table_exists($table['name'])) {
+        db_drop_table($table['name']);

Can we have the db connection injected?

damiankloip’s picture

Status: Active » Needs review
StatusFileSize
new3.39 KB
new30.29 KB

Let's try this. See what breaks.

EDIT: Sorry Daniel, cross posted that patch with your comment. I will see how this patch gets on then I can definitely inject the db, it's on my list of things to do. I just want to see how this initial bear minimum version gets on...

Status: Needs review » Needs work

The last submitted patch, 2124069-2.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review

3: 2124069-2.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 3: 2124069-2.patch, failed testing.

damiankloip’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new31.33 KB

Rerolled.

Status: Needs review » Needs work

The last submitted patch, 7: 2124069-7.patch, failed testing.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new33.47 KB

I didn't have time to do much, but I added a bare unit test and renamed one of the methods on the service (along the lines of "fooGet" to "getFoo").

Status: Needs review » Needs work

The last submitted patch, 9: drupal_2124069_9.patch, failed testing.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new22.12 KB
new49.04 KB

Status: Needs review » Needs work

The last submitted patch, 11: drupal_2124069_11.patch, failed testing.

damiankloip’s picture

I was hoping drupal_write_record would not live in schema.

xano’s picture

I'm fine with moving it to another service. Do you have anything in mind? database?

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new48.66 KB

I was just hoping ... we will get rid of drupal_write_record at the end anyway.
This was just a reroll for now.

Status: Needs review » Needs work

The last submitted patch, 15: schema-2124069-15.patch, failed testing.

andypost’s picture

is this possible to make schema revisionable with that?

andypost’s picture

Thinking a more about schema at all I see no usable example in core for schema.
Fields and entities is going to be schema-less so schema definitions could be deployed as yml files (with own schema)
so it makes sense to implement a schema plugin manager with plugins of definitions

hook_update_hook_N() should gone as migration latter in the cycle

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new48.56 KB

Just a reroll but still failing, but less than before.

Status: Needs review » Needs work

The last submitted patch, 19: 2124069-19.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new52.07 KB

Rerolled.

Status: Needs review » Needs work

The last submitted patch, 21: schema-reroll-21.patch, failed testing.

ParisLiakos’s picture

Issue tags: +Kill includes

drupal_write_record is gone, maybe makes this easier

damiankloip’s picture

Status: Needs work » Needs review
StatusFileSize
new45.67 KB

Another reroll

Status: Needs review » Needs work

The last submitted patch, 24: 2124069-24.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
StatusFileSize
new45.67 KB
new841 bytes

Let's try this

Status: Needs review » Needs work

The last submitted patch, 26: 2124069-26.patch, failed testing.

ParisLiakos’s picture

StatusFileSize
new45.67 KB
new261 bytes

nice! seems it worked, it just complains about the misplaced test.
had some time, and just moved it;) lets see; this should have tests up and running

ParisLiakos’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 28: 2124069-28.patch, failed testing.

ParisLiakos’s picture

Status: Needs work » Needs review
StatusFileSize
new45.67 KB

grr

ParisLiakos’s picture

  1. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,624 @@
    +class Schema {
    

    Lets add an interface

  2. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,624 @@
    +   */
    +  const UNINSTALLED = -1;
    ...
    +   */
    +  const INSTALLED = 0;
    

    and move those to the interface?

  3. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,624 @@
    +  function writeRecord($table, &$record, $primary_keys = array()) {
    

    we can get rid of this :D

  4. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,624 @@
    +  function getSchemaFieldsSql($table, $prefix = NULL) {
    

    public? protected?

Status: Needs review » Needs work

The last submitted patch, 31: 2124069-31.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
StatusFileSize
new47.22 KB
new39.84 KB

Yes, we were talking about the need to add an interface anyway. So let's go for it. Also, renamed the methods to remove schema from them.

Now needs the test coverage. I will be able to have a look later/tomorrow unless someone does it first. Might take a little while though.

damiankloip’s picture

StatusFileSize
new44.11 KB
new4.15 KB

Maybe a unit test is not really needed. This has more integration tests etc.. than you could need.

The last submitted patch, 34: 2124069-34.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 35: 2124069-35.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
StatusFileSize
new44.07 KB
new2.79 KB

ehm.

Status: Needs review » Needs work

The last submitted patch, 38: 2124069-38.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
StatusFileSize
new37.49 KB
new6.57 KB

Over zealous method renaming. I think this should work better...

ParisLiakos’s picture

In case this is rerolled:

+++ b/core/lib/Drupal/Core/Schema/Schema.php
@@ -0,0 +1,351 @@
+  function getFieldsSql($table, $prefix = NULL) {

+++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
@@ -0,0 +1,172 @@
+  function getFieldsSql($table, $prefix = NULL);

nitpick alert: visibility missing

Besides that, i think all we need now is just a change record draft?

almaudoh’s picture

+++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php
@@ -59,12 +60,15 @@ class SiteConfigureForm extends FormBase {
+   * @param \Drupal\Core\Schema\Schema $schema
...
+  public function __construct(UserStorageInterface $user_storage, StateInterface $state, ModuleHandlerInterface $module_handler, CountryManagerInterface $country_manager, Schema $schema) {

+++ b/core/modules/system/src/Controller/DbUpdateController.php
@@ -69,6 +70,13 @@ class DbUpdateController extends ControllerBase {
+   * @var \Drupal\Core\Schema\Schema

@@ -83,14 +91,17 @@ class DbUpdateController extends ControllerBase {
+   * @param \Drupal\Core\Schema\Schema $schema
...
+  public function __construct(KeyValueExpirableFactoryInterface $key_value_expirable_factory, CacheBackendInterface $cache, StateInterface $state, ModuleHandlerInterface $module_handler, AccountInterface $account, EntityDefinitionUpdateManagerInterface $entity_definition_update_manager, Schema $schema) {

Should we typehint SchemaInterface instead?

damiankloip’s picture

StatusFileSize
new37.51 KB
new4.78 KB

Yes! These are good points. I added the interface then missed some clean up off the back of that.

dawehner’s picture

  1. +++ b/core/includes/schema.inc
    @@ -197,14 +112,11 @@ function drupal_set_installed_schema_version($module, $version) {
    + *
    + * @deprecated Use \Drupal::service('schema')->install().
    
    @@ -222,16 +134,11 @@ function drupal_install_schema($module) {
    + *
    + * @deprecated Use \Drupal::service('schema')->uninstall().
    

    Let's add a description whether this is deprecated as of 8.0.x or 9.0.x

  2. +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
    @@ -946,6 +948,8 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
    +    /** @var \Drupal\Core\Schema\Schema $schemaInterface */
    +    $schema = \Drupal::service('schema');
    

    oh wow, now we get crazy. An interface with a variable as name :p

  3. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +  /**
    +   * A static cache of schema versions per module.
    +   *
    +   * @var array
    +   */
    +  protected $updates;
    ...
    +  /**
    +   * A static cache of current module schema versions.
    +   *
    +   * @var array
    +   */
    +  protected $versions;
    +
    

    The variable names are a bit odd, but I guess this came up from the existing code in HEAD.

  4. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +   * The module handler.
    +   *
    +   * @var \Drupal\Core\Extension\ModuleHandlerInterface
    +   */
    +  protected $moduleHandler;
    +
    +  /**
    +   * The cache backend.
    +   *
    +   * @var \Drupal\Core\Cache\CacheBackendInterface
    +   */
    +  protected $cacheBackend;
    +
    +  /**
    +   * The key value factory.
    +   *
    +   * @var \Drupal\Core\KeyValueStore\KeyValueFactory
    +   */
    +  protected $keyValue;
    +
    +  /**
    +   * The database connection.
    +   *
    +   * @var \Drupal\Core\Database\Connection
    +   */
    +  protected $connection;
    

    It is sad how this is not decoupled.

  5. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +
    +        $this->moduleHandler->alter('schema', $this->completeSchema);
    +
    

    We were thinking whether we really still need a schema alter hook. The amount of usecases really seems to not existing any longer.

  6. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +        // If the schema is empty, avoid saving it: some database engines require
    +        // the schema to perform queries, and this could lead to infinite loops.
    +        if (!empty($this->completeSchema) && ($this->drupalGetBootstrapPhase() == DRUPAL_BOOTSTRAP_FULL)) {
    +          $this->cacheBackend->set('schema', $this->completeSchema, Cache::PERMANENT, array('schema' => TRUE));
    +        }
    

    It feels like a potentially fundamental issue that storing schema cache in DB is a bad idea.

  7. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +   */
    +  public function getVersions($module) {
    +    if (!isset($this->updates[$module])) {
    +      $this->updates = array();
    +      foreach ($this->moduleHandler->getModuleList() as $loaded_module => $filename) {
    +        $this->updates[$loaded_module] = array();
    

    To be honest on an abstract level it is odd to have a) hook_schema() which primarily cares about table schema and hook_update_N() which cares about schema but also about arbitrary updates like potentially entity update, config changes and really what not.

  8. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +    if (!$this->versions) {
    +      if (!$this->versions = $this->keyValue->get('system.schema')->getAll()) {
    +        $this->versions = array();
    +      }
    +    }
    

    You could use one line of if here. Not sure whether this is really better to understand.

  9. +++ b/core/modules/system/src/Controller/DbUpdateController.php
    @@ -69,6 +70,13 @@ class DbUpdateController extends ControllerBase {
    +   * @var \Drupal\Core\Schema\Schema
    

    Can I haz interface?

catch’s picture

#6 I'm pretty sure that comment has been inaccurate for a long time.

damiankloip’s picture

StatusFileSize
new38.26 KB
new9.08 KB

Here are some comment cleanups, and renames etc...

I think some of the other questions are much bigger questions, and probably stuff that will not change for this release tbh.

damiankloip’s picture

Oh, missed that comment in #45, will look at that.

damiankloip’s picture

StatusFileSize
new38.19 KB
new1.37 KB
dawehner’s picture

Status: Needs review » Reviewed & tested by the community

I think this is good to go now. We have to cleanup the module handler coordinated anyway.

catch’s picture

Priority: Normal » Major
Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs issue summary update, +beta target

Sorry I'm not sure about this one.

For example https://api.drupal.org/api/drupal/core%21includes%21schema.inc/function/... only has only a couple of calls in core outside of tests. Two of the calls are only clearing caches which I think leaves this one place:

https://api.drupal.org/api/drupal/core%21modules%21views%21src%21Entity%...

We need that dependency information, but I'm not sure drupal_get_schema() is the right place to get it - could we instead figure out which module defines the table in hook_views_data() and get the dependency information from that. If for example module A provides the table, but another, optional, module B provides the hook_views_data(), we're really dependent on the module B (which in turn depends on module A via the module dependency system).

If we think we can fix the views issue, then it's probably dead code. If it's not dead code for contrib then still doesn't feel like the current patch would be quite right.

Didn't check the other methods. Bumping to major since if we do deprecate the functionality as well as just the procedural functions it'd be important to communicate that to contrib.

cilefen’s picture

Status: Needs work » Needs review
StatusFileSize
new38.3 KB

reroll

damiankloip’s picture

StatusFileSize
new39.11 KB
new3.22 KB

Reroll and adaptation for ModuleInstaller separation.

Status: Needs review » Needs work

The last submitted patch, 52: 2124069-52.patch, failed testing.

damiankloip’s picture

Status: Needs work » Needs review
StatusFileSize
new39.54 KB
new580 bytes

Status: Needs review » Needs work

The last submitted patch, 54: 2124069-54.patch, failed testing.

pcambra’s picture

Status: Needs work » Needs review
StatusFileSize
new544 bytes
new39.53 KB

Here's a re roll with a minor fix that the testbot should like better

andypost’s picture

for example module A provides the table, but another, optional, module B provides the hook_views_data(), we're really dependent on the module B (which in turn depends on module A via the module dependency system).

Maybe better to s/$module/$provider in SchemaInterface? this will allow to have Core provider

+++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
@@ -0,0 +1,172 @@
+   * @param string $module
+   *   A module name.
...
+  public function getVersions($module);

otoh this could became extension

damiankloip’s picture

Ha, yes that fix totally makes sense :)

amateescu’s picture

  1. +++ b/core/includes/schema.inc
    @@ -55,48 +46,16 @@ function drupal_get_schema($table = NULL, $rebuild = FALSE) {
    + * Returns an array of available schema currentVersions for a module.
    

    What's currentVersions? :D

  2. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +   *   (optional) Whether to additionally remove 'description' keys of all tables
    

    Over 80 chars.

  3. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,351 @@
    +   * Determines if the drupal bootstrap phase is full.
    +   *
    +   * @return bool
    +   */
    +  protected function isFullDrupalBootstrapPhase() {
    +    return drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL;
    +  }
    

    Does this method really need to exist? Its description is kinda.. funny :/

  4. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,172 @@
    + */
    +
    +
    +namespace Drupal\Core\Schema;
    

    Extra newline.

  5. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,172 @@
    + * Provides an interface for database schema handling.
    

    If this description is accurate, I wonder why this is in a new Drupal\Core\Schema namespace instead of Drupal\Core\Database.

  6. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,172 @@
    +   *   If TRUE, the schema will be rebuilt instead of retrieved from the cache.
    

    Missing (optional) and "Defaults to FALSE."

  7. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,172 @@
    +   *   If TRUE, the schema will be rebuilt instead of retrieved from the cache.
    

    Same as above.

amateescu’s picture

Also, this issue is tagged with "Kill includes" but schema.inc is not actually removed :(

dawehner’s picture

Also, this issue is tagged with "Kill includes" but schema.inc is not actually removed :(

Well yeah I doubt we can get rid of the actual include files, given of the BC layer at that point.

+++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
@@ -0,0 +1,172 @@
+interface SchemaInterface {

Do we maybe choose a better name? Can't think of one, just throwing out this idea.

pcambra’s picture

StatusFileSize
new5.36 KB
new39.38 KB

New patch taking into account comments in #59 but not moving SchemaInterface to the Drupal\Core\Database namespace.

pcambra’s picture

Berdir queued 63: 2124069-63.patch for re-testing.

dawehner’s picture

This still needs an issue summary as well as a change record.

pcambra’s picture

Issue summary: View changes
Issue tags: -Needs issue summary update
pcambra’s picture

Issue summary: View changes
pcambra’s picture

Issue tags: +Needs change record
pcambra’s picture

dawehner’s picture

Status: Needs review » Reviewed & tested by the community

Thank you!

dawehner’s picture

I'm wondering a bit whether the schema service should be named database.schema or something like that, but yeah I just throw out the idea for now.

amateescu’s picture

Assigned: damiankloip » Crell

I would like to hear what @Crell thinks about this patch.

dawehner’s picture

I'm pretty sure he'd like it.

Crell’s picture

Status: Reviewed & tested by the community » Needs work

A patch that moves a bunch of procedural functions into a nicely injected service? Why would I like that? :-)

Overall +1, but there are still some issues outstanding:

  1. +++ b/core/core.services.yml
    @@ -255,6 +255,9 @@ services:
    +  schema:
    +    class: Drupal\Core\Schema\Schema
    +    arguments: ['@module_handler', '@cache.default', '@keyvalue', '@database']
    

    I fear this will get confused with the Schema object in the Database namespace. OTOH, I don't want to call it a *Manager either so maybe we just have to live with it?

  2. +++ b/core/includes/schema.inc
    @@ -15,8 +15,10 @@
     /**
      * Indicates that a module has not been installed yet.
    + *
    + * @deprecated Use \Drupal\Core\Schema\SchemaInterface::UNINSTALLED.
      */
    -const SCHEMA_UNINSTALLED = -1;
    +const SCHEMA_UNINSTALLED = \Drupal\Core\Schema\SchemaInterface::UNINSTALLED;
    

    Minor pedantic point: Shouldn't this leverage a "use" statement instead, per coding standards?

  3. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,342 @@
    +        if ($rebuild) {
    +          Cache::invalidateTags(array('schema'));
    +        }
    

    Wait, this is static? Really, cache system? Is there nothing we can inject instead?

  4. +++ b/core/lib/Drupal/Core/Schema/Schema.php
    @@ -0,0 +1,342 @@
    +      // Ensure that updates are applied in numerical order.
    +      foreach ($this->allVersions as &$module_updates) {
    +        sort($module_updates, SORT_NUMERIC);
    +      }
    

    I think this is pre-existing, but eek at using &-format in a foreach(). That's a land mind. If there's no alternative (a basic for loop is fine), then at least explicitly unset $module_updates afterward. There's no bug here yet, since that variable is not reused, but it's a good habit to get into if you must use foreach-&. (Or just don't use foreach-&.)

  5. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,175 @@
    +  /**
    +   * Gets the schema definition of a table, or the whole database schema.
    +   *
    +   * The returned schema will include any modifications made by any
    +   * module that implements hook_schema_alter().
    +   *
    +   * @param string $table
    +   *   (optional) The name of the table. Defaults to NULL, which means that the
    +   *   schema of all tables is returned.
    +   * @param bool $rebuild
    +   *   (optional) If TRUE, the schema will be rebuilt instead of retrieved from
    +   *   the cache. Defaults to FALSE.
    +   */
    +  public function get($table = NULL, $rebuild = FALSE);
    

    With getComplete() there's no need for this method to do double-duty. Just make $table required. If someone wants the whole schema they can call getComplete().

    (The legacy procedural function can handle the if-branch for older code.)

  6. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,175 @@
    +   * @return array|bool
    +   *   If the module has updates, an array of available updates sorted by
    +   *   version. Otherwise, FALSE.
    +   */
    +  public function getVersions($module);
    

    Probably pre-existing, but array|bool is a stupid return type. If there's no versions available, return an empty array.

    See: http://www.garfieldtech.com/blog/empty-return-values

  7. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,175 @@
    +   * Note: This function does not pass the module's schema through
    +   * hook_schema_alter(). The module's tables will be created exactly as the
    +   * module defines them.
    

    Created? Don't you mean deleted?

  8. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,175 @@
    +   * @return array
    +   *   An array of arrays with the following key/value pairs:
    +   *    - success: a boolean indicating whether the query succeeded.
    +   *    - query: the SQL query(s) executed, passed through
    +   *      \Drupal\Component\Utility\String::checkPlain().
    

    It's not clear what the key is. This doesn't tell me enough about the return structure that I could write code against it.

  9. +++ b/core/lib/Drupal/Core/Schema/SchemaInterface.php
    @@ -0,0 +1,175 @@
    +   * It is also used by drupal_install_schema() and
    +   * drupal_uninstall_schema() to ensure that a module's tables are
    +   * created exactly as specified without any changes introduced by a
    +   * module that implements hook_schema_alter().
    

    Comment should be updated to reference the methods, no?

amateescu’s picture

#74.1 is exactly why I wanted your opinion on this, nice to see that it's also the first thing you spotted. That probably means we have to try and find a better name for this service/class :/

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new39.99 KB
new15.37 KB

#74.1 is exactly why I wanted your opinion on this, nice to see that it's also the first thing you spotted. That probably means we have to try and find a better name for this service/class :/

Yeah we kinda all agree here.

Wait, this is static? Really, cache system? Is there nothing we can inject instead?

Let's fix that

Probably pre-existing, but array|bool is a stupid return type. If there's no versions available, return an empty array.

Yeah, good idea to fix it. Its one small DX improvement.

It's not clear what the key is. This doesn't tell me enough about the return structure that I could write code against it.

Neither the old code nor the new code (which is basically the same) actually returned something, so lets drop that piece of documentation.

Status: Needs review » Needs work

The last submitted patch, 76: 2124069-76.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new40.18 KB
new8.12 KB

This time a little bit more sane.

Status: Needs review » Needs work

The last submitted patch, 78: 2124069-78.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new40.2 KB
new1.16 KB

There we go.

pcambra’s picture

dawehner’s picture

Adapted.

Crell’s picture

+++ b/core/lib/Drupal/Core/Schema/SchemaManager.php
@@ -0,0 +1,351 @@
+  public function getFieldsSql($table, $prefix = NULL) {

Does this need to be public? Seems like it should be an internal implementation detail of the class. Where is it called externally?

Also, dawehner and I are bikeshedding the SchemaManager name in IRC if anyone wants to join. :-P

dawehner’s picture

Assigned: Crell » Unassigned
StatusFileSize
new39.2 KB
new18.2 KB

@crell
... indeed, this method just used for drupal_write_record() and got removed in the meantime.

We talked about stuff and ended up with SchemaData which is at least relative similar to the way how views handles its schema like data.

Status: Needs review » Needs work

The last submitted patch, 84: 2124069-84.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new39.19 KB
new508 bytes

Ha, I've seen it, but ignored it.

Crell’s picture

Status: Needs review » Reviewed & tested by the community

Now I think we're good. Thanks, dawehner and others!

almaudoh’s picture

-use Drupal\Core\Database\Database;
+use Drupal\Core\Schema\SchemaDatanterface;
 .
.
  */
-const SCHEMA_UNINSTALLED = -1;
+const SCHEMA_UNINSTALLED = SchemaDatanterface::UNINSTALLED;
.
. 
+  /** @var \Drupal\Core\Schema\SchemaDatanterface $schema */
+  $schema = \Drupal::service('schema.data');
.
.
+use Drupal\Core\Schema\SchemaDatanterface;
. 
.
+   * @var \Drupal\Core\Schema\SchemaDatanterface
+   */
+  protected $schema;
.
.
+namespace Drupal\Core\Schema;
+
+/**
+ * Provides an interface for database schema handling.
+ */
+interface SchemaDatanterface {
+
+  /**
+   * Indicates that a module schema has not been installed yet.
+   */
+  const UNINSTALLED = -1;
+
.
...etc

s/SchemaDatanterface/SchemaDataInterface. Tests pass because of IDE autocomplete :P

almaudoh’s picture

Status: Reviewed & tested by the community » Needs work

CNW for #88

catch’s picture

No-one's replied to #50 yet when I last marked this CNW from RTBC.

drupal_get_schema() is used only in tests for itself (was not quite true 5 months ago but is now), and to clear its own cache in case other code uses it (which it never does). So in my opinion that's dead code and we should either leave it where it is with a strong message, or nuke it, but not convert it to a new service.

I didn't check the other methods then and I still haven't now, but I'd be very surprised if this wasn't true for other things too. IMO the service should only include things that we actually use in core or really think should be in there. We could add a new method later as an API addition in a minor release, but we can't take any public methods out of that interface if this patch lands.

Also note that for example field, entity, cache and several other things no-longer even appear in the array returned from drupal_get_schema() any more, so the information you get from that is pretty much useless anyway.

I also wonder a bit how much the install/uninstall schema methods belong here and how much they might live directly in the module installer or a separate service. But that question is better answered when we figure out what here is dead code or not.

Crell’s picture

catch: So you're suggesting removing this functionality entirely, or nearly so?

catch’s picture

I think we should either:

1. Remove it entirely - but see #2447573: [meta] Make sure 8.x - 8.x hook_update_N() testing is possible which wants to use it again

OR

2. Leave it where it is with a strongly worded comment that it's not very useful and/or explicitly deprecate it.

What I don't think we should do is add a new API with that functionality which we'd then have to change again later if we remove it.

Crell’s picture

hm. If I read that issue correctly, part of the challenge is that we have so many dynamically created tables now that hook_schema (what this code fronts for) is not a reliable source of authority for what tables actually exist, thus we need to either:

1) Remove/Deprecate this code as no longer meaningful.

2) Revamp this code to actually reflect what's in the database, not what's in hook_schema. At which point it's completely different code anyway, and I think that code even exists already in the DB layer. Or if it doesn't, such code should be.

In which case, yes, just remove this code entirely and if there is introspection logic we still need that the Database layer itself doesn't offer, add it. (The linked issue seems like a good test bed to find such introspection needs.)

catch: Sound reasonable to you?

catch’s picture

2) Revamp this code to actually reflect what's in the database, not what's in hook_schema. At which point it's completely different code anyway, and I think that code even exists already in the DB layer.

Don't think we do or ever had that unless I'm missing something. If we did have it, we could possibly use it for the field storage update comparison - right now the 'current schema' is stored in state.

You can check if a table, field or index exists, but you can't generate a schema definition automatically given a table.

Also I noticed the schemaapi defgroup in core/lib/Drupal/Core/Database/Schema.php is very outdated.

In Drupal 7 we handled field schema by a dynamic hook_schema() declaration: https://api.drupal.org/api/drupal/modules!field!modules!field_sql_storag... this was explicitly dropped as part of the entity/field schema changes. I don't think we should re-introduce that and it's not really possible with cache where they're responsible for creating their own tables and don't declare a schema to anywhere else.

Crell’s picture

Hm, you're right, our introspection is minimal right now. Some drivers use(d) schema API for some dynamic queries, which I never liked. I've wanted to add better introspection to the DB layer for a while, but never had the time or impetus. If Entity API and upgradeability provides the impetus, I can see about locating someone with time. (Should be non-BC-breaking as it's just additions; maybe an addition to the interfaces but that affects all of 4 people in the world.)

That seems like a better plan than trying to shore up dynamic hook_schema().

catch’s picture

I think the only place that has lived in https://www.drupal.org/project/schema, I considered porting that to core for #1119094: Add a test to verify the schema matches after a database update but it looked like a lot of work, then migrate made that issue less relevant.

Posted more on #2447573: [meta] Make sure 8.x - 8.x hook_update_N() testing is possible - that issue might need splitting into sub-issues one of might then require introspection.

For this issue, I think we should just leave the function where it is, maybe with @deprecated.

We can open a new issue to stop calling it in core and or remove it as 'dead code' but that's technically an API change whereas this issue isn't.

Also still note this likely is not the only function that's dead code that's being converted here, it's just the first/only one I checked.

dawehner’s picture

Status: Needs work » Needs review
Related issues: +#2451395: drupal_get_schema()/drupal_get_complete_schema() no longer work as expected; remove them
StatusFileSize
new35.96 KB
new7.48 KB

All the drupal_*_schema_version* functions are still used by update.php. The unprocessed schema getter is used by ModuleInstaller and simpletest
but @catch is totally right, we don't support drupal_get_schema() anymore.

Let's so skip drupal_get_schema() from this patch, kill it with fire in #2451395: drupal_get_schema()/drupal_get_complete_schema() no longer work as expected; remove them and keep the schema service as proposed in earlier versions of the patch.

Status: Needs review » Needs work

The last submitted patch, 97: 2124069-97.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new33.86 KB
new2.59 KB

More fire!!!!

Status: Needs review » Needs work

The last submitted patch, 99: 2124069-99.patch, failed testing.

dawehner’s picture

Status: Needs work » Postponed

... sometimes its better to go to bed ... we call to a previously private function in drupal_get_compete_schema(),
so let's first get rid of it, see #2451395: drupal_get_schema()/drupal_get_complete_schema() no longer work as expected; remove them

xjm’s picture

Issue tags: +Needs beta evaluation

So I agree with the major priority for #2451395: drupal_get_schema()/drupal_get_complete_schema() no longer work as expected; remove them for the reasons described in #50 -- we essentially have an API now that doesn't do what it implies it should. We should evaluate what's left here after that goes in though.

mgifford’s picture

Status: Postponed » Active

Ok, looks like we can proceed with this now.

mile23’s picture

Version: 8.0.x-dev » 8.1.x-dev
Status: Active » Needs work
Issue tags: -beta target, -Needs beta evaluation

A bit of a complicated reroll, so here's an easy review to get the ball rolling again if desired:

--- /dev/null
+++ b/core/lib/Drupal/Core/Schema/SchemaDatanterface.php

Missing an 'I.'

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.0-beta1 was released on March 2, 2016, which means new developments and disruptive changes should now be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

daffie’s picture

Status: Needs work » Needs review
StatusFileSize
new52.23 KB

Rerolled.

daffie’s picture

Status: Needs review » Needs work

The last submitted patch, 106: 2124069-106.patch, failed testing.

daffie’s picture

Status: Needs work » Needs review
StatusFileSize
new52.62 KB
new1.79 KB

Added the routebuilder to the ModuleInstaller class.

Status: Needs review » Needs work

The last submitted patch, 109: 2124069-109.patch, failed testing.

daffie’s picture

Status: Needs work » Needs review
StatusFileSize
new50.54 KB
new2.92 KB

Next try.

Status: Needs review » Needs work

The last submitted patch, 111: 2124069-111.patch, failed testing.

daffie’s picture

Status: Needs work » Needs review
StatusFileSize
new49.74 KB
new816 bytes

Reverted the changes to core/modules/system/system.install.

fabianx’s picture

+++ b/core/includes/schema.inc
@@ -72,26 +56,12 @@ function drupal_get_schema_versions($module) {
+ * @deprecated in Drupal 8.0.x, will be removed before Drupal 9.

8.2.x - IIRC

daffie’s picture

StatusFileSize
new2.54 KB
new49.74 KB

Changed deprecated 8.0.x to 8.2.x

mile23’s picture

Status: Needs review » Needs work
+++ b/core/includes/schema.inc
@@ -12,8 +14,10 @@
+ * @deprecated Use \Drupal\Core\Schema\SchemaDataInterface::UNINSTALLED.

Needs version info.

Also, phpcs says this:

FILE: ...ul/pj2/drupal/core/lib/Drupal/Core/Extension/ModuleInstaller.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 75 | ERROR | [x] Parameter comment indentation must be 3 spaces, found 2
    |       |     spaces
    |       |     (Drupal.Commenting.FunctionComment.ParamCommentIndentation)
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


FILE: ...Users/paul/pj2/drupal/core/lib/Drupal/Core/Schema/SchemaData.php
----------------------------------------------------------------------
FOUND 1 ERROR AND 1 WARNING AFFECTING 2 LINES
----------------------------------------------------------------------
  3 | ERROR   | [x] Namespaced classes, interfaces and traits should not
    |         |     begin with a file doc comment
    |         |     (Drupal.Commenting.FileComment.NamespaceNoFileDoc)
 10 | WARNING | [x] Unused use statement
    |         |     (Drupal.Classes.UnusedUseStatement.UnusedUse)
----------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


FILE: ...l/pj2/drupal/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 3 | ERROR | [x] Namespaced classes, interfaces and traits should not
   |       |     begin with a file doc comment
   |       |     (Drupal.Commenting.FileComment.NamespaceNoFileDoc)
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


FILE: ...drupal/core/modules/system/src/Controller/DbUpdateController.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 108 | ERROR | [x] Parameter comment indentation must be 3 spaces, found
     |       |     2 spaces
     |       |     (Drupal.Commenting.FunctionComment.ParamCommentIndentation)
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------


FILE: ...pj2/drupal/core/modules/system/src/Form/ModulesUninstallForm.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 68 | ERROR | [x] Parameter comment indentation must be 3 spaces, found 2
    |       |     spaces
    |       |     (Drupal.Commenting.FunctionComment.ParamCommentIndentation)
----------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------
daffie’s picture

Status: Needs work » Needs review
StatusFileSize
new49.63 KB
new3.8 KB

Thanks Mile23: fixed your points.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

catch’s picture

Status: Needs review » Needs work

Just saw a new usage of drupal_schema_get_field_value() on an issue which reminded me of this one.

  1. +++ b/core/includes/schema.inc
    @@ -72,26 +57,12 @@ function drupal_get_schema_versions($module) {
     function drupal_get_installed_schema_version($module, $reset = FALSE, $array = FALSE) {
    

    This should be in the extension system somewhere, it's got nothing to do with the schema API as such.

  2. +++ b/core/includes/schema.inc
    @@ -101,11 +72,12 @@ function drupal_get_installed_schema_version($module, $reset = FALSE, $array = F
     function drupal_set_installed_schema_version($module, $version) {
    

    Same here.

  3. +++ b/core/includes/schema.inc
    @@ -113,14 +85,12 @@ function drupal_set_installed_schema_version($module, $version) {
     function drupal_install_schema($module) {
    

    Same here.

  4. +++ b/core/includes/schema.inc
    @@ -128,16 +98,12 @@ function drupal_install_schema($module) {
     function drupal_uninstall_schema($module) {
    

    Same here.

  5. +++ b/core/includes/schema.inc
    @@ -215,21 +150,12 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
      */
     function drupal_schema_get_field_value(array $info, $value) {
    -  // Preserve legal NULL values.
    -  if (isset($value) || !empty($info['not null'])) {
    -    if ($info['type'] == 'int' || $info['type'] == 'serial') {
    -      $value = (int) $value;
    -    }
    -    elseif ($info['type'] == 'float') {
    -      $value = (float) $value;
    -    }
    -    elseif (!is_array($value)) {
    -      $value = (string) $value;
    -    }
    -  }
    -  return $value;
    +  return \Drupal::service('schema.data')->getFieldValue($info, $value);
     }
     
    

    This isn't related to install/uninstall, it could be a static method on a utility class maybe? Either way it shouldn't be on the install/uninstall-related methods.

mile23’s picture

Issue summary: View changes

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

larowlan’s picture

Does anyone watching this issue know if we have one to convert the actual guts/return of hook_schema to something that is easier to remember, i.e like the builder pattern we have for field definitions?

$table = SchemaTable::create('description goes here');
$table->addField('some_field', IntegerSchemaField::create()->setDefault(0)->setNotNull());

Add ArrayAccess to give it a BC layer.

If not I'll add one - cause I can never remember the magic array keys.

larowlan’s picture

martin107’s picture

Assigned: Unassigned » martin107
Status: Needs work » Needs review
Related issues: +#2908886: Split off schema management out of schema.inc
StatusFileSize
new52.31 KB

Here is a reroll....

all of the changes come from the fact that core has removed all instances of array for [].

While I did it I made notes on what changes to include next...

1) When we say deprecated in 8.2.x .. the issue is so old we now mean 8.5.x

2) as stated in #120 and the issue summary ... yes we seem to have gone too far ... things that belong in extension belong in a separate issue.

I will spend a little time fixing this up next ...

martin107’s picture

Assigned: martin107 » Unassigned
StatusFileSize
new47.85 KB
new5.78 KB

1) Correcting a screw-up of mine from the reroll my phpcs.local.yml file got mixed in... removed.

2) As I mention in #125 we now deprecating in 8.5.x

3) Removed changes to functions which are out of scope. ( which should resolve all the point raised in #120 )

So tasks remaining answer #123 ... my focus is shifting to #2908886: Split off schema management out of schema.inc before I forget.

martin107’s picture

Just making notes, as I update the issue summary

The following functions have been refactored away

drupal_get_complete_schema() --- and yet it is still talked about in the comments.
drupal_get_schema() -- mentioned in the comments and called but not defined ( see dump-database-d6/7.sh )
drupal_get_schema_unprocessed() -- refactored away no followup.

larowlan’s picture

Status: Needs review » Needs work
  1. +++ b/core/includes/schema.inc
    @@ -12,8 +14,11 @@
    + * @deprecated in Drupal 8.2.x, will be removed before Drupal 9.
    

    Still refs 8.2.x :)

  2. +++ b/core/includes/schema.inc
    @@ -24,38 +29,18 @@
    + * @deprecated in Drupal 8.5.x, will be removed before Drupal 9.
    

    We need to add a change record, and then add an @see to that (applies to all of the @deprecated tags)

  1. +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    @@ -997,7 +997,7 @@ protected function mapToStorageRecord(ContentEntityInterface $entity, $table_nam
    -        $value = drupal_schema_get_field_value($definition->getSchema()['columns'][$column_name], $value);
    +        $value = \Drupal::service('schema.data')->getFieldValue($definition->getSchema()['columns'][$column_name], $value);
    

    We can inject this, but it would most likely be a BC break on the constructor, so probably would require setter injection. Would require a setter and then in the createInstance factory method, call the setter (entity handlers use a createInstance factory method, not create).

  2. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -39,6 +41,18 @@ class ModuleInstaller implements ModuleInstallerInterface {
    +   * @var \Drupal\Core\Routing\RouteBuilderInterface
    +   */
    +  protected $routeBuilder;
    
    @@ -54,14 +68,21 @@ class ModuleInstaller implements ModuleInstallerInterface {
    +   * @param \Drupal\Core\Routing\RouteBuilderInterface $route_builder
    +   *   (optional) The route builder service to rebuild the routes if a theme is
    +   *   installed.
    ...
    +    $this->routeBuilder = $route_builder;
    

    These changes look unrelated - bad re-roll?

  3. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,267 @@
    +      $this->allVersions[$module] = [];
    +
    +      foreach ($this->moduleHandler->getModuleList() as $loaded_module => $filename) {
    +        $this->allVersions[$loaded_module] = [];
    +      }
    

    we could use array_map here instead of looping and avoid the initialisation call too?

    $this->allVersions = array_map(function () {
      return [];
    }, $this->moduleHandler->getModuleList());
    

    micro-optimisation though - but I don't think this is preexisting code, so figure in scope

  4. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,267 @@
    +    else {
    +      return isset($this->currentVersions[$module]) ? $this->currentVersions[$module] : static::UNINSTALLED;
    +    }
    

    no need for the else, the if returned already, although could be pre-existing code - if so - follow up

  5. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,267 @@
    +    // Reset the static cache of module schema currentVersions.
    +    $this->getInstalledVersion(NULL, TRUE);
    

    nice

  6. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,267 @@
    +    elseif (!empty($schema)) {
    

    same, this can be an if, not an elseif, the previous if returned in both code paths - but if existing code, again out of scope (follow ups for both)

  7. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,267 @@
    +      if ($info['type'] == 'int' || $info['type'] == 'serial') {
    ...
    +      elseif ($info['type'] == 'float') {
    

    nit: should use === here, we expect strings. Again...might be existing code though - if so, follow up

  8. +++ b/core/lib/Drupal/Core/Updater/Module.php
    @@ -88,7 +88,7 @@ public function getSchemaUpdates() {
    -    if (!$updates = drupal_get_schema_versions($this->name)) {
    +    if (!$updates = \Drupal::service('schema.data')->getVersions($this->name)) {
    

    oh wow, never seen these classes before. These are like a mix of OO and info hooks that aren't plugins. We should create a follow up to explore moving them to plugins.

  9. +++ b/core/modules/system/tests/src/Functional/Module/InstallTest.php
    @@ -44,9 +44,9 @@ public function testEnableUserTwice() {
    +    $version = \Drupal::service('schema.data')->getInstalledVersion('system', TRUE);
    ...
    +    $version = \Drupal::service('schema.data')->getInstalledVersion('user', TRUE);
    

    we could put this in a local variable here

  10. +++ b/core/modules/system/tests/src/Functional/System/StatusTest.php
    @@ -76,12 +76,12 @@ public function testStatusPage() {
    +    \Drupal::service('schema.data')->setInstalledVersion('update_test_postupdate', 8000);
    ...
    +    \Drupal::service('schema.data')->setInstalledVersion('update_test_postupdate', 8001);
    

    same

  11. +++ b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
    @@ -112,7 +112,7 @@ public function testRequirements() {
    +    \Drupal::service('schema.data')->setInstalledVersion('update_script_test', \Drupal::service('schema.data')->getInstalledVersion('update_script_test') - 1);
    
    @@ -195,12 +195,12 @@ public function testSuccessfulUpdateFunctionality() {
    +    $schema_version = \Drupal::service('schema.data')->getInstalledVersion('update_script_test', TRUE);
    ...
    +    \Drupal::service('schema.data')->setInstalledVersion('update_script_test', $schema_version - 1);
    +    $schema_version = \Drupal::service('schema.data')->getInstalledVersion('update_script_test', TRUE);
    
    @@ -254,12 +254,12 @@ public function testSuccessfulMultilingualUpdateFunctionality() {
    +    $schema_version = \Drupal::service('schema.data')->getInstalledVersion('update_script_test', TRUE);
    ...
    +    \Drupal::service('schema.data')->setInstalledVersion('update_script_test', $schema_version - 1);
    +    $schema_version = \Drupal::service('schema.data')->getInstalledVersion('update_script_test', TRUE);
    

    same

  12. +++ b/core/modules/system/tests/src/Functional/Update/UpdateScriptTest.php
    @@ -290,12 +290,13 @@ public function testSuccessfulMultilingualUpdateFunctionality() {
    +    $schema_version = \Drupal::service('schema.data')->getInstalledVersion('update_script_test');
    ...
    +    \Drupal::service('schema.data')->setInstalledVersion('update_script_test', $schema_version - 1);
    +    $schema_version = \Drupal::service('schema.data')->getInstalledVersion('update_script_test', TRUE);
    

    same

  13. +++ b/core/modules/system/tests/src/Functional/Update/UpdatesWith7xTest.php
    @@ -39,11 +39,11 @@ protected function setUp() {
    +    $this->assertEqual(\Drupal::service('schema.data')->getInstalledVersion('update_test_with_7x'), 8000);
    ...
    +    \Drupal::service('schema.data')->setInstalledVersion('update_test_with_7x', 7110);
    
    +++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
    @@ -142,7 +142,7 @@ public function testDependencyResolution() {
    +      $this->assertEqual(\Drupal::service('schema.data')->getInstalledVersion($module), SCHEMA_UNINSTALLED, "$module module was uninstalled.");
    
    @@ -193,7 +193,7 @@ public function testUninstallProfileDependency() {
    +    $this->assertEqual(\Drupal::service('schema.data')->getInstalledVersion($dependency), SCHEMA_UNINSTALLED, "$dependency module was uninstalled.");
    

    same (sorry for listing them all, but different files)

larowlan’s picture

We can inject this, but it would most likely be a BC break on the constructor, so probably would require setter injection. Would require a setter and then in the createInstance factory method, call the setter (entity handlers use a createInstance factory method, not create).

Actually, wouldn't require a setter because php scope.

  public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
    $return = new static(
      $entity_type,
      $container->get('database'),
      $container->get('entity.manager'),
      $container->get('cache.entity'),
      $container->get('language_manager')
    );
    $return->schema = $container->get('schema.data');
    return $return;
}

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

MerryHamster’s picture

StatusFileSize
new47.72 KB
new5.36 KB

Here is an only reroll

MerryHamster’s picture

Status: Needs work » Needs review
martin107’s picture

StatusFileSize
new47.7 KB

I would still like this to go in ... so Reroll.

mile23’s picture

Status: Needs review » Needs work
Issue tags: +Needs change record updates, +Needs followup
  1. +++ b/core/core.services.yml
    @@ -418,14 +418,15 @@ services:
    +  schema.data:
    

    Doesn't match the CR.

  2. +++ b/core/includes/schema.inc
    @@ -24,38 +29,18 @@
    + * @deprecated in Drupal 8.5.x, will be removed before Drupal 9.
    

    Change to 8.6.x, and needs @see for CR. Same for other @deprecated annotations.

We should either add @trigger_error() to deprecated functions or file a follow-up if we think it'll be too disruptive.

It'd also be great to have a basic unit/kernel type test of SchemaData just so we have some sanity checks. I can't find any unit-ish tests of the functions we're deprecating or any tests of the subsystem, though maybe I don't know exactly where to look.

martin107’s picture

Assigned: Unassigned » martin107

There are lots of unprocessed review comments ....

I think the very first next step is break the patch into two as per the issue summary.

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new26.96 KB
new22.07 KB

This change is just cutting out "hunks" for one of the following functions

drupal_get_installed_schema_version()
drupal_set_installed_schema_version()
drupal_install_schema()
drupal_uninstall_schema()

There is lots of good work cut out ( about 50 % ) but that is going into the already created side issue.

Status: Needs review » Needs work

The last submitted patch, 136: 2124069-136.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mile23’s picture

Thanks, @martin107.

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new21.75 KB
new3.87 KB

A) [ this covers #128.1, #134.1 and #134.2 ]

Fixed up deprecation notices and triggers - split change record into 2 separate ones.

Just for reference here is the new which belongs to the other issue

https://www.drupal.org/node/2970993

The original change record now refers to schema.data not schema.manager - but the whole thing needs some TLC which I think is best done as we get close to RTBC.

B) Fixed up some tests.

There is a place to refactor _drupal_schema_initialize() ....
as it is only called from within methods such as drupal_uninstall_schema()
I think the place is within the other issue

Still todo:-

I am going to divert my time to getting the skeleton of the other issue into shape ... just so I don't drop some work on the floor.
There is lots of unresolved substance from #128
The whole test thing needs consideration.
I think we need to whitelist some deprecation notices... but I will let testbot speak.
More is coming from me...

Status: Needs review » Needs work

The last submitted patch, 139: 2124069-139.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mile23’s picture

The testbot says this 1,043 times:

  1x: drupal_get_schema_versions() is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Instead, you should \Drupal::service('schema.data')->getFieldValue($info, $value). See https://www.drupal.org/node/2444417.

So....

+++ b/core/includes/schema.inc
@@ -24,38 +31,22 @@
+  @trigger_error('drupal_get_schema_versions() is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Instead, you should \Drupal::service(\'schema.data\')->getVersions(). See https://www.drupal.org/node/2444417.', E_USER_DEPRECATED);

@@ -215,21 +208,15 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
+  @trigger_error('drupal_get_schema_versions() is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Instead, you should \Drupal::service(\'schema.data\')->getFieldValue($info, $value). See https://www.drupal.org/node/2444417.', E_USER_DEPRECATED);

Yah let's throw the error in a follow-up rather than whitelisting, so we don't go into (more) technical debt. #2959269: [meta] Core should not trigger deprecated code except in tests and during updates

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new28.07 KB
new7.58 KB

Thanks Mile23, It is awkward to carry on a conversation from september 2017.. but #128.3 and #129

the BC issue

Every \Drupal::service() type call in SqlContentEntityStorage and SqlContentEntityschema has a @todo next to it saying "must directly inject" ...

for example #2332857: Decide how secondary entity handlers (like storage_schema) should be instantiated

If it is a BC change then I favour deprecating the whole service and inventing a new name ... given the amount of outstanding @todos this could be very silly .. similarNameOne and then similarNameTwo is just bad.

So my response is to just directly inject here.. then depending on the reviews create a "one ring to bind them all issue" so that we can encapsulate the concerns from many issues and invent a new name for the service, just once.... I hope that does not ruffle anyones feathers.

If there is a BC change ... then WebForm is likely to be broken.

I am not finished yet... I am at the point at which I want to see testbot has to say....

mile23’s picture

Yah I'll just stay quiet for a while. :-)

Just happy we're killing includes.

Status: Needs review » Needs work

The last submitted patch, 142: 2124069-141.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

berdir’s picture

+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -160,11 +169,14 @@ public function getFieldStorageDefinitions() {
    *   The cache backend to be used.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
+   * @param \Drupal\Core\Schema\SchemaDataInterface $schema_data
+   *   The database schema service.
    */
-  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, LanguageManagerInterface $language_manager) {
+  public function __construct(EntityTypeInterface $entity_type, Connection $database, EntityManagerInterface $entity_manager, CacheBackendInterface $cache, LanguageManagerInterface $language_manager, SchemaDataInterface $schema_data) {
     parent::__construct($entity_type, $entity_manager, $cache);
     $this->database = $database;
     $this->languageManager = $language_manager;
+    $this->schemaData = $schema_data;
     $this->initTableLayout();

The trick to avoid breaking subclasses (of which those kind of base classes usually have a lot) is to make the new argument optional and then fall back to \Drupal::service() in the constructor.

Then it won't break anything if not passed in. In the passed we just wrote it as "$schema_data ?: \Drupal::service()", but you might want to do a if/else so you can do a @trigger_error() in the else case.

See also https://drupal.stackexchange.com/questions/260560/why-is-this-property-o...

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new30.07 KB
new5.6 KB

Thank you both for all the expert advice.

I appreciate that https://www.drupal.org/core/deprecation insists on standardised text ..

in this case deprecating .. means that parameters will not longer be optional and therefore enforced

Please note I have had to deviate from standard text.

Lets see what testbot says to this.

Status: Needs review » Needs work

The last submitted patch, 146: 2124069-146.patch, failed testing. View results

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new30.15 KB
new2.63 KB

a few if comparisons, needed to be refined.

berdir’s picture

+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
@@ -169,14 +169,24 @@ public function getFieldStorageDefinitions() {
+    }
+    else {
+      @trigger_error('$schema_data will no longer be an *OPTIONAL* paramter, deprecated since version 8.6.0 and will be *ENFORCED* in 9.0.0.  See https://www.drupal.org/node/2444417.', E_USER_DEPRECATED);

I think the *OPTIONAL* and *ENFORCED* is a bit too much emphasis, just optional/enforced should be enough :)

Status: Needs review » Needs work

The last submitted patch, 148: 2124069-148.patch, failed testing. View results

martin107’s picture

Assigned: martin107 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new32.27 KB
new3.07 KB

a)

just optional/enforced should be enough

In the cold light of a new day .. yes it does look like I was laying it on a bit thick...

Here is the cloest sample, suggested, text from https://www.drupal.org/core/deprecation

@trigger_error('The concept of container scopes is deprecated since version 8.0.0 and will be removed in 9.0.0. Omit the third parameter. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);

Enforced is also the wrong word ... as we all know that there ain't no party like a liz lemon party -- 'cos a liz lemon party is mandatory

https://www.youtube.com/watch?v=V1HkkNp5a2c

so this is what I went with

@trigger_error('$schema_data: null is deprecated since version 8.6.0 and will be mandatory in 9.0.0. See https://www.drupal.org/node/2444417.', E_USER_DEPRECATED);

b) I have fix up the broken test [ SqlContentEntityStorageSchemaTest ]

----

From #134

It'd also be great to have a basic unit/kernel type test of SchemaData

That is the next step here... SqlContentEntityStorageSchemaTest is a interesting read, which I plan to copy a lot from

but in juggling my time, I am determined not to drop 50% on the patch on the floor ( see #136 )
so I am temporarily unassigning myself -- while I work on the splinter issue.

Status: Needs review » Needs work

The last submitted patch, 151: 2124069-150.patch, failed testing. View results

martin107’s picture

StatusFileSize
new37.22 KB
new4.94 KB

All tests should pass now.

martin107’s picture

Issue tags: -Needs followup
StatusFileSize
new13.74 KB
new35.36 KB

A) Removed stray install methods -- which have moved to a splinter issue.

B) Added unit testing. See SchemaDataTest.

C) One method can be static --- so I am updated it. see SchemaData::getFIeldValue()

I think all the todo list is empty... and this is ready.

martin107’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 154: 2124069-154.patch, failed testing. View results

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new35.4 KB
new300 bytes

Ah butterfingers - the last change I made -- did not make it into the patch

Status: Needs review » Needs work

The last submitted patch, 157: 2124069-157.patch, failed testing. View results

martin107’s picture

I am not sure what I am doing wrong

the new test was developed using

./vendor/bin/phpunit -c core -vvv -debug ./core/tests/Drupal/KernelTests/Core/Schema/SchemaDataTest.php

and locally for me ... passes.

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new291 bytes
new35.38 KB

"Unexpected item in the bagging area" .. er I mean unit test found with kernel test.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

voleger’s picture

Issue tags: +Needs reroll
martin107’s picture

Issue tags: -Needs reroll
StatusFileSize
new35.8 KB

@voleger thanks for pointing that out.

rerolled.

andypost’s picture

  1. +++ b/core/core.services.yml
    @@ -418,14 +418,15 @@ services:
    -
    +  schema.data:
    ...
         class: Drupal\Component\Serialization\Yaml
    -
    

    any reason to touch empty lines?

  2. +++ b/core/includes/schema.inc
    @@ -12,8 +15,13 @@
    + * @deprecated in Drupal 8.6.x, will be removed before Drupal 9.
    
    @@ -24,38 +32,21 @@
    + * @deprecated in Drupal 8.6.x, will be removed before Drupal 9.
    ...
    +  @trigger_error('drupal_get_schema_versions() is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.0. Instead, you should \Drupal::service(\'schema.data\')->getVersions(). See https://www.drupal.org/node/2444417.', E_USER_DEPRECATED);
    
    @@ -215,21 +206,15 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
    + * @deprecated in Drupal 8.6.x, will be removed before Drupal 9.
    

    I bet it should be 8.7.0

  3. +++ b/core/includes/schema.inc
    @@ -24,38 +32,21 @@
    +  // The new method returns an empty array instead of FALSE as before.
    +  if ($versions === []) {
    +    return FALSE;
    
    +++ b/core/includes/update.inc
    @@ -313,8 +313,8 @@ function update_get_update_list() {
    +    $updates = \Drupal::service('schema.data')->getVersions($module);
    +    if ($updates !== []) {
    
    @@ -450,8 +450,8 @@ function update_get_update_function_list($starting_updates) {
    +    $updates = \Drupal::service('schema.data')->getVersions($module);
    +    if ($updates !== []) {
    
    +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,62 @@
    +   * @return array
    +   *   If the module has updates, an array of available updates sorted by
    +   *   version. Otherwise, an empty array.
    +   */
    +  public function getVersions($module);
    
    +++ b/core/modules/system/system.install
    @@ -722,8 +722,8 @@ function system_requirements($phase) {
    +      $updates = \Drupal::service('schema.data')->getVersions($module);
    +      if ($updates !== []) {
    

    As new method always returns array probably better to simplify conditions

  4. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,115 @@
    +class SchemaData implements SchemaDataInterface {
    ...
    +   * A static cache of schema currentVersions per module.
    ...
    +  protected $allVersions = [];
    

    This variable needs dependency serialization trait to be never stored in serialized data

Status: Needs review » Needs work

The last submitted patch, 163: 2124069-163.patch, failed testing. View results

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new8.54 KB
new39.74 KB

@andypost thank for so a careful review

(1)

any reason to touch empty lines?

None ... restored.

(2)

I bet it should be 8.7.0

yes .. this patch is long in the tooth... fixed.

(3)

As new method always returns array probably better to simplify conditions

This is the section ... I want to talk about

A) drupal_get_schema_versions() maintains to old legacy mixed return type ..."Otherwise, FALSE"
Out of sync contrib modules need to be fed the old behaviour so I think we want to keep the if in place here.

otherwise fixed.

4) Fixed

Also locally, the failing test now passes

andypost’s picture

StatusFileSize
new26 KB
new21.99 KB

Slightly reworked patch

- service needed only for \Drupal\Core\Schema\SchemaDataInterface::getVersions so should use injection
- SQL entity storage can use static call of \Drupal\Core\Schema\SchemaDataInterface::getFieldValue this way we keep BC and this method actually does not need any injection
- cleaned deprecation messages & some code clean-up

martin107’s picture

That was a good cleanup

andypost++

claudiu.cristea’s picture

Status: Needs review » Needs work

Nice work. Nits:

  1. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,170 @@
    +<?php
    

    I'm not sure that we don't need a @file block here.

  2. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,170 @@
    +    $module_handler = $this->getMock(ModuleHandlerInterface::class);
    ...
    +    $module_handler = $this->getMock(ModuleHandlerInterface::class);
    

    ::getMock() is deprecated.

  3. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,170 @@
    +    $nid = SchemaData::getFieldValue($info['nid'], '1.001');
    

    What is the purpose of this line?

  4. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,170 @@
    +      'getFieldValue() - serial value: cast to int.'
    ...
    +      'getFieldValue() - int value: cast to int.'
    ...
    +      'getFieldValue() - not_null handling: Cannot be null.'
    ...
    +      'getFieldValue() - not_null handling: Can be null.'
    ...
    +      'getFieldValue() - float value: cast to float.'
    

    I cannot find the page/docs, but I'm sure that somewhere is stated that we should avoid assert messages because, sometimes, they might confuse and make hard to understand a potential failure.

Also, needs CR update.

andypost’s picture

Assigned: Unassigned » andypost
Issue summary: View changes
Related issues: +#2820696: Allow schema inspection for all tables created with a valid schema

Updated IS & change record, drupal_schema_get_field_value() probably could be moved to \Drupal\Core\Database\Schema cos it strictly about field values not schema and there's related issue #2820696: Allow schema inspection for all tables created with a valid schema

Also drupal_get_module_schema() should be covered in the issue but instead of get() I think better to introduce getModule() according its arguments

@claudiu.cristea #169.1 according core standards namespaced classes should not use @file
https://www.drupal.org/docs/develop/standards/api-documentation-and-comm...

The @file doc block MUST be present for all PHP files, with one exception: files that contain a namespaced class/interface/trait, whose file name is the class name with a .php extension, and whose file path is closely related to the namespace (under PSR-4 or a similar standard), SHOULD NOT have a @file documentation block.

andypost’s picture

Assigned: andypost » Unassigned
Status: Needs work » Needs review
StatusFileSize
new9.01 KB
new22.42 KB

I renamed the method to castValue() - it is what it does also extended tests and addressed #169 review

Change record needs update after there will be agreement on naming and placement of SchemaData service

voleger’s picture

StatusFileSize
new22.4 KB

Rerolled

berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -59,14 +67,17 @@ class ModuleInstaller implements ModuleInstallerInterface {
        */
    -  public function __construct($root, ModuleHandlerInterface $module_handler, DrupalKernelInterface $kernel) {
    +  public function __construct($root, ModuleHandlerInterface $module_handler, DrupalKernelInterface $kernel, SchemaDataInterface $schema) {
         $this->root = $root;
         $this->moduleHandler = $module_handler;
         $this->kernel = $kernel;
    +    $this->schema = $schema;
       }
    

    Should do the thing with = NULL and then falling back to the service with a @trigger_error()

  2. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,116 @@
    + */
    +class SchemaData implements SchemaDataInterface {
    +
    +  use DependencySerializationTrait;
    +
    

    A service shouldn't have to use this trait, is this necessary to make test pass? we might need to inject it into something that uses it instead.

  3. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,224 @@
    +/**
    + * Simulates a hook_update_N function.
    + *
    + * When filtered this will pass through.
    + */
    +function undertest_update_3000() {
    +
    +}
    

    the docblock on these functions read a bit strange, a review from a native speaker would be good, but I imagine it can be simplifed to something like:

    * A valid update function.
    * An incorrectly named update function.

martin107’s picture

Assigned: Unassigned » martin107

>A service shouldn't have to use this trait, is this necessary to make test pass? we might need to inject it into something that uses it instead.

After a little investigating it seems I introduced DependencySerializationTrait in #166 - see interdiff-2124069-163-166_0.txt

[ It is a bit disconcerting when you think that you are the policeman hunting criminals but then you discover that you are just revisiting the scene of your own crime ]

The two tests failing before that patch were in SqlContentEntityStorageTest

I will try and sort this out tomorrow... but I am posting now 'cos I don't want anyone else to spend time working out the whodunnit..

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new22.57 KB
new3.39 KB

Regarding #173

1) Fixed - NULL and @trigger added

2) "A service shouldn't have to use this trait...."

When I remove the unwanted trait

SqlContentEntityStorageTest passes locally

The new test SchemaDataTest passes.

I can no longer justify its inclusion .. so lets see if testbot passes without it.

3) When I look at the language the "...will be rejected" text is a information bearing addition. The "...will pass through" does not give any extra information over what can be seen by reading the code.

So I have removed those lines.

/**
* Simulates a hook_update_N function.
*
* When filtered this will be rejected.
*/

+ * Simulates a hook_update_N function.
+ *
+ * When filtered this will pass through.
+ */

----

in addition the #173

I have fixed a minor coding standard nit regarding line length ( > 80 chars )

kim.pepper’s picture

  1. +++ b/core/includes/schema.inc
    @@ -12,8 +15,13 @@
    + * @deprecated in Drupal 8.7.x, will be removed before Drupal 9.0.0.
    
    @@ -24,38 +32,17 @@
    + * @deprecated in Drupal 8.7.x, will be removed before Drupal 9.0.0.
    ...
    +  @trigger_error('drupal_get_schema_versions() is deprecated in Drupal 8.7.x and will be removed before Drupal 9.0.0. Use \Drupal\Core\Schema\SchemaDataInterface::getVersions() instead. See https://www.drupal.org/node/2444417.', E_USER_DEPRECATED);
    
    @@ -215,21 +202,15 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
    + * @deprecated in Drupal 8.7.x, will be removed before Drupal 9.0.0.
    

    This should be a specific version, ie. 8.7.0.

  2. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -59,14 +67,23 @@ class ModuleInstaller implements ModuleInstallerInterface {
    +    if ($schema instanceof SchemaDataInterface) {
    

    We can just check for NULL here as our typehinting should cover whether $schema is an instance of SchemaDataInterface.

  3. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,114 @@
    +  public static function castValue(array $info, $value) {
    

    I'm not sure about the design decision of putting static utility methods on a service class. Do we do this in other places in core?

martin107’s picture

StatusFileSize
new23.11 KB
new10.77 KB

Regaring #176

1) Fixed .. thanks my mistake

2) Done.... I am just a person who wears both belt and braces.

3) I think this is a good idea.

Almost done ... this is where I need to start a conversation to complete the task

castValue() was moved into the Drupal utility component section under

Drupal\Core\Utility\SchemaTypecaster::castValue()

No other utility component has a unit test and I need to find a home in the directory structure for what should be cut out of SchemaDataTest

as SchemaTypeCasterTest :-

testCastValue()
providerSchemaCastValue()

Sorry to get hung up on something so trivial but there seems several likely places for a new Test directory and test namespace suggestions please?

Status: Needs review » Needs work

The last submitted patch, 177: 2124069-177.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new23.04 KB
new893 bytes

small fixes.

Status: Needs review » Needs work

The last submitted patch, 179: 2124069-179.patch, failed testing. View results

kim.pepper’s picture

Lots of Error: Class 'Drupal\Core\Schema\SchemaTypecaster' not found

Should it be Drupal\Component\Utility\SchemaTypecaster ?

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new23.05 KB
new1.27 KB

Thanks ... and Ah crap I should have done more testing after moving things about.

Status: Needs review » Needs work

The last submitted patch, 182: interdiff-2124069-179-182.patch, failed testing. View results

martin107’s picture

Status: Needs work » Needs review
StatusFileSize
new23.61 KB
new5.26 KB

My question in #177 was foolish .. there is a unambiguous home for the new test .

So it is trivial to complete #176.3

Both parts of the separated test pass locally now.

martin107’s picture

Assigned: martin107 » Unassigned

As a parting comment I was paranoid enough to check if the test infrastructure was picking up the new test. [ in the past I have seen several issues resolving an observation that test xyx was, due to namespacing errors, not actually being run ]

so here is the relevant text copied from a testbot run


Utility.Drupal\Tests\Component\Utility\SchemaTypecasterTest
✓ - testCastValue with data set #0
✓ - testCastValue with data set #1
✓ - testCastValue with data set #2
✓ - testCastValue with data set #3
✓ - testCastValue with data set #4
✓ - testCastValue with data set #5
✓ - testCastValue with data set #6
✓ - testCastValue with data set #7
✓ - testCastValue with data set #8
✓ - testCastValue with data set #9
✓ - testCastValue with data set #10
✓ - testCastValue with data set #11

andypost’s picture

StatusFileSize
new14.53 KB
new32.01 KB

Removed usage of deprecated SCHEMA_UNINSTALLED constant
Clean-up messages & fix namespaces for SchemaTypecaster
Working to add deprecation tests

andypost’s picture

StatusFileSize
new1.91 KB
new33.93 KB

And tests added

andypost’s picture

Looking on usage of SCHEMA_UNINSTALLED I think should go to schema.installer in #2908886: Split off schema management out of schema.inc

andypost’s picture

StatusFileSize
new8.79 KB
new26.25 KB

Removed constant

kim.pepper’s picture

Re: #189 makes sense to keep the SCHEMA_UNINSTALLED constant with SchemaInstaller. +1

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

voleger’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/core/includes/schema.inc
@@ -24,38 +26,17 @@
+ * @deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0.

+1 for rtbc, if we are ok to go in 8.7.0

voleger’s picture

voleger’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/includes/schema.inc
@@ -24,38 +26,17 @@
+ * @deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0.
...
+  @trigger_error('drupal_get_schema_versions() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Schema\SchemaDataInterface::getVersions() instead. See https://www.drupal.org/node/2444417', E_USER_DEPRECATED);

@@ -215,21 +196,15 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
+ * @deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0.
...
+  @trigger_error('drupal_schema_get_field_value() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Component\Utility\SchemaTypecaster::castValue($info, $value) instead. See https://www.drupal.org/node/2444417', E_USER_DEPRECATED);

+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -59,14 +67,21 @@ class ModuleInstaller implements ModuleInstallerInterface {
+      @trigger_error('\Drupal\Core\Schema\SchemaDataInterface became an optional dependency of this class in Drupal 8.7.0 and will be required before Drupal 9.0.0. See https://www.drupal.org/project/drupal/issues/2124069.', E_USER_DEPRECATED);

+++ b/core/tests/Drupal/KernelTests/Core/Database/SchemaLegacyTest.php
@@ -0,0 +1,47 @@
+   * @expectedDeprecation drupal_get_schema_versions() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Schema\SchemaDataInterface::getVersions() instead. See https://www.drupal.org/node/2444417
...
+   * @expectedDeprecation drupal_schema_get_field_value() is deprecated in Drupal 8.7.0 and will be removed before Drupal 9.0.0. Use \Drupal\Component\Utility\SchemaTypecaster::castValue($info, $value) instead. See https://www.drupal.org/node/2444417

*8.8.0

martin107’s picture

Assigned: Unassigned » martin107

Yep, we have missed the window, 8.8.0 it is... patch coming.

martin107’s picture

Assigned: martin107 » Unassigned
Status: Needs work » Needs review
StatusFileSize
new26.23 KB
new5.08 KB

Sorted.

martin107’s picture

Sorted.

voleger’s picture

Status: Needs review » Reviewed & tested by the community

+1 for rtbc

kim.pepper’s picture

Looking good! Just a few nitpicks:

  1. +++ b/core/lib/Drupal/Component/Utility/SchemaTypecaster.php
    @@ -0,0 +1,44 @@
    +   * into an integer column, but PostgreSQL PDO does not. Look up the schema
    +   * information and use that to correctly typecast the value.
    

    We're not looking up schema info in here, as we are providing it. Maybe just "Use the schema info..."

  2. +++ b/core/lib/Drupal/Component/Utility/SchemaTypecaster.php
    @@ -0,0 +1,44 @@
    +   * @param array $info
    

    Can we document what the array keys are? Or point to the docs with a @see?

  3. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -43,6 +44,13 @@ class ModuleInstaller implements ModuleInstallerInterface {
    +  protected $schema;
    

    Can we rename the variable to $schemaData

  4. +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,40 @@
    +  public function get($module, $table = NULL);
    

    Can we call this getSchemaData(), getData(), getSpecification() or getSchema() ?

voleger’s picture

StatusFileSize
new26.25 KB

Just reroll

voleger’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new26.98 KB
new7.71 KB

Addressed #119
Also added documentation for possible types of the value in SchemaTypecaster.

kim.pepper’s picture

Thanks for addressing the feedback.

This issue is still tagged with 'Needs change record updates', otherwise +1 to RTBC.

kim.pepper’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs change record updates

Updated the CR so RTBC

claudiu.cristea’s picture

Status: Reviewed & tested by the community » Needs review

This looks nice. However, I still have some points:

  1. +++ b/core/includes/schema.inc
    @@ -24,38 +26,17 @@
     function drupal_get_schema_versions($module) {
    -  $updates = &drupal_static(__FUNCTION__, NULL);
    
    +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,96 @@
    +  /**
    +   * A static cache of schema currentVersions per module.
    +   *
    +   * @var array
    +   */
    +  protected $allVersions = [];
    

    What if a contrib or custom module is doing?

    drupal_static_reset('drupal_get_schema_versions')
    

    The current API allows the internal cache clear but I see the new service has no method to reset the internal memory cache. I think we should allow that.

    Also we should deprecate the usage of drupal_static_reset() with 'drupal_get_schema_versions' as parameter. You can check #3038908: Deprecate node_access_view_all_nodes() as an example on how is possible to deprecate that usage. Also, that would need a deprecation legacy test.

  2. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -59,14 +67,21 @@ class ModuleInstaller implements ModuleInstallerInterface {
    +      @trigger_error('\Drupal\Core\Schema\SchemaDataInterface became an optional dependency of this class in Drupal 8.8.0 and will be required before Drupal 9.0.0. See https://www.drupal.org/project/drupal/issues/2124069.', E_USER_DEPRECATED);
    

    Let's test also this deprecation message in the legacy test.

  3. +++ b/core/tests/Drupal/KernelTests/Core/Database/SchemaLegacyTest.php
    @@ -0,0 +1,47 @@
    +    $this->assertEquals(FALSE, drupal_get_schema_versions('system'));
    

    s/assertEquals(FALSE, ...)/assertFalse(...)

  4. +++ b/core/tests/Drupal/KernelTests/Core/Database/SchemaLegacyTest.php
    @@ -0,0 +1,47 @@
    +    $expected = \Drupal::service('schema.data')->getVersions($module);
    

    In Kernel test, using `$this->container->get()` is safe.

  5. +++ b/core/tests/Drupal/Tests/Component/Utility/SchemaTypecasterTest.php
    @@ -0,0 +1,133 @@
    +class SchemaTypecasterTest extends TestCase {
    
    +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,101 @@
    +class SchemaDataTest extends UnitTestCase {
    

    Nice! Tha means we didn't have coverage till now.

  6. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,101 @@
    +    $this->assertSame($expected, $actual, 'getVersions() filtered hook_update_functions as expected');
    ...
    +    $this->assertSame($expected, $actual, 'get() returned the correct schema');
    

    The difference between PHPUnit and Simpletest assert curtom messages is that in the case of PHPUnit we describe the failure, not the success. Either fix the message or simply get rid of it.

claudiu.cristea’s picture

Status: Needs review » Needs work
kim.pepper’s picture

Assigned: Unassigned » kim.pepper
kim.pepper’s picture

Assigned: kim.pepper » Unassigned
Status: Needs work » Needs review
StatusFileSize
new6.12 KB
new29.23 KB

Fixes for #204

  1. Fixed. Followed the pattern of deprecation in drupal_static_reset()
  2. Fixed. We don't have a legacy test for ModuleInstaller so I created one.
  3. Fixed
  4. Fixed
  5. Great!
  6. Fixed
claudiu.cristea’s picture

Status: Needs review » Needs work

Looks good, just a nit:

+++ b/core/lib/Drupal/Component/Utility/SchemaTypecaster.php
@@ -0,0 +1,67 @@
+ * Encapsulates Drupal's Typecating strategy.

This description looks weird to me, could we make it more specific? Also there's a typo: s/Typecating/typecasting. I also believe that lowercase is better for the 1st letter.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new470 bytes
new29.24 KB

Thanks. Updated the wording to something more readable.

claudiu.cristea’s picture

Status: Needs review » Reviewed & tested by the community

Perfect.

claudiu.cristea’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +@deprecated, +Needs reroll
kostyashupenko’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new29.23 KB
kim.pepper’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/includes/schema.inc
@@ -215,21 +196,15 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
 function drupal_schema_get_field_value(array $info, $value) {
-  // Preserve legal NULL values.
-  if (isset($value) || !empty($info['not null'])) {
-    if ($info['type'] == 'int' || $info['type'] == 'serial') {
-      $value = (int) $value;
-    }
-    elseif ($info['type'] == 'float') {
-      $value = (float) $value;
-    }
-    elseif (!is_array($value)) {
-      $value = (string) $value;
-    }
-  }
-  return $value;
+  @trigger_error('drupal_schema_get_field_value() is deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0. Use \Drupal\Component\Utility\SchemaTypecaster::castValue($info, $value) instead. See https://www.drupal.org/node/2444417', E_USER_DEPRECATED);
+  return SchemaTypecaster::castValue($info, $value);
 }

I don't think this belongs in a component class its just not that generic. Looking at http://grep.xnddx.ru/search?text=drupal_schema_get_field_value&filename= - the portfolio theme and a red-herring its a copy of core - and looking a core usages this method exists for one purpose - that's to solve issues in Sql entity storage with it's handling of values. I think we should consider moving it to be part of that and not generic schema API.

alexpott’s picture

+++ b/core/core.services.yml
@@ -430,6 +430,9 @@ services:
+  schema.data:

schema is new core service prefix. And it is also a very overloaded word in Drupal. Perhaps we should do database.schema or database.schema.data as a service name?

amateescu’s picture

Regarding #214, let's make it a static method on SqlContentEntityStorageSchema, marked as @internal.

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new30.38 KB
new22.23 KB

Re: #214 and #216Moved to SqlContentEntityStorageSchema and updated tests.

Re: #215 changed to 'database.schema.data'

Status: Needs review » Needs work

The last submitted patch, 217: 2124069-217.patch, failed testing. View results

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new30.39 KB
new739 bytes

Missed a change to 'database.schema.data'.

amateescu’s picture

Looks great! Just one minor nit left:

+++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
@@ -35,6 +35,26 @@ class SqlContentEntityStorageSchema implements DynamicallyFieldableEntityStorage
+  const INT = 'int';
...
+  const SERIAL = 'serial';
...
+  const FLOAT = 'float';
...
+  const VARCHAR = 'varchar';

I don't think we should introduce constants for these values, they are coming from the database schema API, so that would be the place where they should be defined.

But that's out of scope here..

kim.pepper’s picture

StatusFileSize
new29.53 KB
new4.04 KB

Thanks @amateescu. Fixes #22.

amateescu’s picture

  1. +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,45 @@
    +namespace Drupal\Core\Schema;
    ...
    +  public function getSpecification($module, $table = NULL);
    

    I was surprised to see a 'top level' Schema namespace. At first, I thought a namespace like \Drupal\Core\Database\Schema would be more appropriate, but the $module argument of the getSpecification method makes me think this needs to be in the module/extension system somewhere (maybe module_installer?), and probably renamed to something like getTableSchemaSpecification().

  2. +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,45 @@
    +  public function getVersions($module);
    

    I think this should be a part of the new service introduced in #2908886: Split off schema management out of schema.inc, because it doesn't have anything to do with the Database Schema API..

IMO, we need more architectural discussion/decisions here.

How about opening a separate issue for deprecating drupal_schema_get_field_value() in favor of the new SqlContentEntityStorageSchema::castValue() method? That part of the patch was at least agreed upon by Entity system maintainers.

andypost’s picture

andypost’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
vacho’s picture

Issue tags: -Needs reroll
StatusFileSize
new23.69 KB

For contributing to this cause: patch rerolled

kim.pepper’s picture

Status: Needs work » Needs review
alexpott’s picture

Status: Needs review » Needs work
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -59,14 +67,21 @@ class ModuleInstaller implements ModuleInstallerInterface {
+    $this->schemaData = $schema_data;

Now we're adding a new service to this class we need to take of re-injecting this service after a module install. See \Drupal\Core\Extension\ModuleInstaller::updateKernel()

It's possible that someone overrides the schema data service in a module and doing this also means that the static caches in the service are cleared.

Also drupal_get_module_schema() is supposed to be handled by this issue but although we're adding the method to the schema service we're not using it.

kim.pepper’s picture

Issue summary: View changes
Status: Needs work » Needs review
StatusFileSize
new36.94 KB
new14.52 KB

Thanks @alexpott.

  1. Fixed in updateKernel(). Is there anywhere else this needs to be taken care of?
  2. Deprecated drupal_get_module_schema() and converted uses of it to the new service.

Status: Needs review » Needs work

The last submitted patch, 228: 2124069-228.patch, failed testing. View results

kim.pepper’s picture

Status: Needs work » Needs review
StatusFileSize
new37.07 KB
new2.85 KB

I think the fail was due to keeping a reference to the service, while the container got refreshed.

Status: Needs review » Needs work

The last submitted patch, 230: 2124069-230.patch, failed testing. View results

kim.pepper’s picture

I was wrong. Not sure about that fail.

andypost’s picture

Status: Needs work » Needs review
StatusFileSize
new2.52 KB
new37.14 KB

It looks like some caching issue, btw patch removes useless return and converts test back to service

Status: Needs review » Needs work

The last submitted patch, 233: 2124069-233.patch, failed testing. View results

voleger’s picture

StatusFileSize
new37.17 KB
new37.25 KB
new5.51 KB

Rerolled
FIxed CS issues with deprecation messages.

andypost’s picture

+++ b/core/includes/schema.inc
@@ -154,22 +133,15 @@ function drupal_uninstall_schema($module) {
+ * @deprecated in drupal:8.8.0 and will be removed from drupal:9.0.0. Use
+ *   \Drupal\Core\Schema\SchemaDataInterface::getSpecification() instead.
...
 function drupal_get_module_schema($module, $table = NULL) {
...
+  return \Drupal::service('database.schema.data')->getSpecification($module, $table);

The same time `drupal_get_module_schema()` is deprecated in #2908886: Split off schema management out of schema.inc so it makes sense to decide where it should live

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

andypost’s picture

Issue summary: View changes

updated summary a bit

cburschka’s picture

Assigned: Unassigned » cburschka
cburschka’s picture

Assigned: cburschka » Unassigned
Status: Needs work » Needs review
StatusFileSize
new27.67 KB

Forward-merging across e376116380 (a commit near the date of the last patch)..9.1.x.

(This needs other fix-ups besides the reroll though.)

cburschka’s picture

StatusFileSize
new27.68 KB
new5.45 KB

Update deprecation notices (8.8.0/9.0.0 -> 9.1.0/10.0.0).

cburschka’s picture

+++ b/core/modules/system/system.install
@@ -808,7 +809,7 @@ function system_requirements($phase) {
-      $requirements['update']['description'] = t('Some modules have database schema updates to install. You should run the <a href=":update">database update script</a> immediately.', [':update' => Url::fromRoute('system.db_update')->toString()]);
+      $requirements['update']['description'] = t('Some modules have database schema_data updates to install. You should run the <a href=":update">database update script</a> immediately.', [':update' => Url::fromRoute('system.db_update')->toString()]);

Not sure I understand the reason for this string change.

The last submitted patch, 241: 2124069-241.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 242: 2124069-242.patch, failed testing. View results

cburschka’s picture

Status: Needs work » Needs review
StatusFileSize
new28.21 KB
new707 bytes

Removed a deprecated usage in update.inc

cburschka’s picture

Reverted all changes relating to drupal_get_module_schema(), which per the issue summary is now handled by #2908886: Split off schema management out of schema.inc.

cburschka’s picture

StatusFileSize
new22.48 KB
new6.21 KB
cburschka’s picture

StatusFileSize
new20.76 KB
new2.92 KB

Also removed SchemaData::getSpecification(), which was where drupal_get_module_schema() would have been moved.

andypost’s picture

@cburschka thank you! Btw I see core using update.post_update_registry service with factory to register "post updates" , code inside looks pretty same and I'm ++to keep them similar - maybe instead of schemaData use UpdateSchemaRegistry?

cburschka’s picture

StatusFileSize
new26.54 KB
new9.83 KB

(moved drupal_get_installed_schema_version and drupal_set_installed_schema_version).

To be clear, do you mean a class rename of \Drupal\Core\Schema\SchemaData -> \Drupal\Core\Update\UpdateSchemaRegistry and a service rename of database.schema.data -> update.schema_registry?

cburschka’s picture

StatusFileSize
new53.56 KB
new31.32 KB

Replaced all the calls to the deprecated functions.

update_set_schema() made me notice that our resetCache() function breaks the normal pattern of resetting static caches:

function update_set_schema($module, $schema_version) {
  \Drupal::keyValue('system.schema')->set($module, $schema_version);
  \Drupal::service('extension.list.profile')->reset();
  \Drupal::service('extension.list.module')->reset();
  \Drupal::service('extension.list.theme_engine')->reset();
  \Drupal::service('extension.list.theme')->reset();
  \Drupal::service('database.schema.data')->resetCache();
}
andypost’s picture

Related issues: +#3143713: drupal_get_schema_versions() should return integer versions
StatusFileSize
new1.48 KB
new53.65 KB

It affects related #3143713: drupal_get_schema_versions() should return integer versions

Patch fixes tests and CS

1) Drupal\Tests\filter\Functional\FilterFormatAccessTest::testFormatPermissions
TypeError: Argument 2 passed to Drupal\Core\Schema\SchemaData::__construct() must implement interface Drupal\Core\KeyValueStore\KeyValueFactoryInterface, instance of Drupal\Core\Cache\MemoryBackend given
cburschka’s picture

Ooh, duh, I forgot to update the service arguments. :D

Status: Needs review » Needs work

The last submitted patch, 253: 2124069-253.patch, failed testing. View results

cburschka’s picture

Status: Needs work » Needs review
StatusFileSize
new53.65 KB
new1.07 KB

Fixed variable types in unit test (schema versions are strings, not ints).

andypost’s picture

StatusFileSize
new1.75 KB
new53.65 KB

It is integer and that's great that test now covers it, making #3143713: drupal_get_schema_versions() should return integer versions obsolete

andypost’s picture

StatusFileSize
new1.27 KB
new53.69 KB

Moreover it could be set now in typed interface

cburschka’s picture

StatusFileSize
new53.69 KB
new600 bytes

In that case, the mocked key-value data also needs to be changed.

The last submitted patch, 257: 2124069-257.patch, failed testing. View results

The last submitted patch, 258: 2124069-258.patch, failed testing. View results

The last submitted patch, 259: 2124069-259.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 260: 2124069-260.patch, failed testing. View results

cburschka’s picture

Status: Needs work » Needs review
StatusFileSize
new53.68 KB
new649 bytes

Also in ::testGeVersions()

andypost’s picture

Just commented in #3143713: drupal_get_schema_versions() should return integer versions to wait for this issue, we could add todo to used upgrade path in follow up.

I find it pretty solid and mostly no conflicts with #2908886: Split off schema management out of schema.inc

Naming is only leftover to fix, thanks a lot to @cburschka

Status: Needs review » Needs work

The last submitted patch, 265: 2124069-265.patch, failed testing. View results

cburschka’s picture

Status: Needs work » Needs review
StatusFileSize
new53.68 KB
new596 bytes

Fixed the remaining test failure.

catch’s picture

andypost’s picture

Related issues: +#2547507: Consider adding hook_update_early_N() support

There's another registry postponed #2547507: Consider adding hook_update_early_N() support

Better to keep them one place - only parsers of functions and ordering of post update hooks is different from schema update hooks

daffie’s picture

Status: Needs review » Needs work
  1. +++ b/core/includes/schema.inc
    @@ -101,11 +74,15 @@ function drupal_get_installed_schema_version($module, $reset = FALSE, $array = F
    + *   Use \Drupal\Core\Schema\SchemaDataInterface::getInstalledVersion() instead.
    ...
     function drupal_set_installed_schema_version($module, $version) {
    ...
    +  \Drupal::service('database.schema.data')->setInstalledVersion($module, $version);
    

    Should be setInstalledVersion() instead of getInstalledVersion() in the docblock.

  2. +++ b/core/includes/update.inc
    @@ -639,7 +644,7 @@ function update_is_missing($module, $number, $update_functions) {
    diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    
    diff --git a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    index 696203a6c5..48dcdc5ac4 100644
    
    index 696203a6c5..48dcdc5ac4 100644
    --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    
    --- a/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    
    +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    @@ -14,10 +14,10 @@
    
    @@ -14,10 +14,10 @@
     use Drupal\Core\Entity\EntityBundleListenerInterface;
     use Drupal\Core\Entity\EntityFieldManagerInterface;
     use Drupal\Core\Entity\EntityInterface;
    -use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
    -use Drupal\Core\Entity\EntityTypeManagerInterface;
     use Drupal\Core\Entity\EntityStorageException;
    +use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
     use Drupal\Core\Entity\EntityTypeInterface;
    +use Drupal\Core\Entity\EntityTypeManagerInterface;
     use Drupal\Core\Entity\Query\QueryInterface;
     use Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface;
     use Drupal\Core\Field\FieldDefinitionInterface;
    

    This hunk is out of scope for this issue.

  3. +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorageSchema.php
    @@ -6,10 +6,10 @@
     use Drupal\Core\DependencyInjection\DependencySerializationTrait;
     use Drupal\Core\Entity\ContentEntityTypeInterface;
     use Drupal\Core\Entity\EntityFieldManagerInterface;
    -use Drupal\Core\Entity\EntityTypeManagerInterface;
     use Drupal\Core\Entity\EntityPublishedInterface;
     use Drupal\Core\Entity\EntityStorageException;
     use Drupal\Core\Entity\EntityTypeInterface;
    +use Drupal\Core\Entity\EntityTypeManagerInterface;
     use Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException;
     use Drupal\Core\Entity\Schema\DynamicallyFieldableEntityStorageSchemaInterface;
     use Drupal\Core\Field\BaseFieldDefinition;
    

    This hunk is out of scope for this issue.

  4. +++ b/core/modules/system/tests/src/Functional/UpdateSystem/UpdateScriptTest.php
    @@ -662,12 +672,12 @@ public function testMaintenanceModeLink() {
    -    $schema_version = drupal_get_installed_schema_version('update_script_test', TRUE);
    ...
    +    $schema_version = $this->schemaData->getInstalledVersion('update_script_test');
    

    We are missing a call to resetCache().

  5. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -59,14 +67,21 @@ class ModuleInstaller implements ModuleInstallerInterface {
    +      @trigger_error('Calling ModuleInstaller::__construct() without the $schema_data argument is deprecated in drupal:9.1.0. The $schema_data argument will be required in drupal:10.0.0.. See https://www.drupal.org/project/drupal/issues/2124069.', E_USER_DEPRECATED);
    
    +++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerDeprecationTest.php
    @@ -0,0 +1,28 @@
    +   * @expectedDeprecation Calling ModuleInstaller::__construct() without the $schema_data argument is deprecated in drupal:9.1.0. The $schema_data argument will be required in drupal:10.0.0.. See https://www.drupal.org/project/drupal/issues/2124069.
    

    In deprecation messages we do not write "drupal:9.1.0.". Instead we use "drupal:9.1.0" without the dot on the end.

  6. This patch adds 5 trigger_error() deprecation messages and adds only one deprecation message tests. 4 more deprecation message tests need to be added.
  7. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,138 @@
    +    // Only undertest_update_X - passes through the filter.
    +    $expected = [1, 20, 3000];
    +    $actual = $schema_data->getVersions($module_name);
    +
    +    $this->assertSame($expected, $actual);
    

    How does this work. Can somebody explain this to me. Please add documentation with the explanation to the patch.

cburschka’s picture

StatusFileSize
new6.37 KB
new6.37 KB

Addressed 1-5.

In (5), I assume you meant the extra dot after 10.0.0, since the dot after 9.1.0 is a sentence period.

+   * @expectedDeprecation Calling ModuleInstaller::__construct() without the $schema_data argument is deprecated in drupal:9.1.0. The $schema_data argument will be required in drupal:10.0.0.. See https://www.drupal.org/project/drupal/issues/2124069.

Still needs the extra tests (6).

Looking over the code mentioned in (7)...

It appears that the test defines a fake module drupal\tests\core\schema\undertest, and declares hook_update_N() functions for it in its own file, which are (due to the namespace) fully qualified as Drupal\Tests\Core\Schema\undertest_update_N() (which is converted to lowercase by get_defined_functions()) and therefore found by the service when looking for drupal\tests\core\schema\undertest_update_(\d+).

This doesn't really look right. It gives the tested class input which is technically not valid, and "works" because the service does not validate it at all. However, testing it with a real module would require a kernel, so it can't be done with a unit test...

cburschka’s picture

StatusFileSize
new53.2 KB

Uploaded the interdiff twice instead of the patch.

andypost’s picture

Status: Needs work » Needs review
StatusFileSize
new832 bytes
new53.17 KB

Re-roll after #3143713: drupal_get_schema_versions() should return integer versions

Also reverted #273.4 - reset cache no longer needed (as we get rid of old implementation)

Status: Needs review » Needs work

The last submitted patch, 274: 2124069-274.patch, failed testing. View results

cburschka’s picture

Status: Needs work » Needs review
StatusFileSize
new53.98 KB
new828 bytes

Updating a newly added drupal_get_schema_versions() call.

alexpott’s picture

Status: Needs review » Needs work
  1. +++ b/core/includes/update.inc
    @@ -160,7 +162,7 @@ function update_set_schema($module, $schema_version) {
    -  drupal_static_reset('drupal_get_installed_schema_version');
    +  \Drupal::service('database.schema.data')->resetCache();
    

    Instead of doing this how about calling \Drupal::service('database.schema.data')->setInstalledVersion($module, $schema_version); - then we can remove \Drupal::keyValue('system.schema')->set($module, $schema_version);

    Also this method update_set_schema() looks interesting and a bit dodgy.

  2. +++ b/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php
    @@ -9,13 +9,13 @@
     use Drupal\Core\Database\DatabaseExceptionWrapper;
     use Drupal\Core\Database\SchemaException;
     use Drupal\Core\Entity\ContentEntityInterface;
    +use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
    +use Drupal\Core\Entity\EntityTypeManagerInterface;
     use Drupal\Core\Entity\ContentEntityStorageBase;
     use Drupal\Core\Entity\ContentEntityTypeInterface;
     use Drupal\Core\Entity\EntityBundleListenerInterface;
     use Drupal\Core\Entity\EntityFieldManagerInterface;
     use Drupal\Core\Entity\EntityInterface;
    -use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
    -use Drupal\Core\Entity\EntityTypeManagerInterface;
     use Drupal\Core\Entity\EntityStorageException;
     use Drupal\Core\Entity\EntityTypeInterface;
     use Drupal\Core\Entity\Query\QueryInterface;
    

    Not in scope changes and in-correct as far as I can see.

  3. +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
    @@ -293,7 +308,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
    -        drupal_set_installed_schema_version($module, $version);
    +        \Drupal::service('database.schema.data')->setInstalledVersion($module, $version);
    
    @@ -514,7 +529,7 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
    -    drupal_get_installed_schema_version(NULL, TRUE);
    

    If we're injecting it then we should use it. Also now that the service is in the container it get rebuilt on module install and uninstall. I'm pretty sure that the resetCache is not needed.

  4. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,126 @@
    +    $this->moduleHandler = $module_handler;
    ...
    +      foreach ($this->moduleHandler->getModuleList() as $loaded_module => $filename) {
    +        $this->allVersions[$loaded_module] = [];
    +      }
    

    It's not necessary to inject the module handler for a list of installed modules. We can use the '%container.modules%' parameter. Less dependencies ftw.

  5. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,126 @@
    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function getInstalledVersion($module = NULL) {
    
    +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,50 @@
    +   * @return string|int|array
    +   *   The currently installed schema version, or SCHEMA_UNINSTALLED if the
    +   *   module is not installed.
    +   *   If $module is not set, information for all modules is returned.
    +   */
    +  public function getInstalledVersion($module = NULL);
    

    I think this now always an int when you provide a module name - there was a recent fix for this.

    Also I think we should split out getting all modules and getting a single module into different functions. Then when we decide to implement return types - and actually we could here already because this is all new - then it's simple.

    Plus I think we we should use string typehints now the minimum PHP version is 7.3.

  6. +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,50 @@
    +  public function setInstalledVersion($module, int $version);
    

    If we're using int here we definitely should use string everywhere else.

  7. +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,50 @@
    +  /**
    +   * Resets the static cache.
    +   */
    +  public function resetCache();
    

    I'm not convinced that this is actually necessary in any of the runtime implementations. I think we can add it as deprecated and to be removed in Drupal 10. We need it for the BC layer.

  8. +++ b/core/tests/Drupal/Tests/Core/Schema/SchemaDataTest.php
    @@ -0,0 +1,138 @@
    +function undertest_update_3000() {
    ...
    +function undertest_update_1() {
    ...
    +function undertest_update_20() {
    ...
    +function undertest_update_1234_failed() {
    ...
    +    $module_name = 'drupal\tests\core\schema\undertest';
    ...
    +    // Only undertest_update_X - passes through the filter.
    

    undertest is not an english word - can we make this "under_test"

andypost’s picture

StatusFileSize
new3.07 KB
new53.11 KB

Fixes for #277 (1-2-3) to make sure cache reset is not required

andypost’s picture

StatusFileSize
new6.31 KB
new52.94 KB

Address #277 few more (only #5 needs work - split getter method)

4) as only module names needed, replaced (thanks, learned)
6) added string type-hint to $module
7) marked as @internal but it's used only in tests now - if we cache function names parsing
8) replaced

Looks #7 may need more work to unify function parsing with
- core/lib/Drupal/Core/Theme/Registry.php
- core/lib/Drupal/Core/Update/UpdateRegistry.php

Both using pretty similar pattern with get_defined_functions()

kim.pepper’s picture

Nit:

+++ b/core/modules/system/system.install
@@ -808,7 +809,7 @@ function system_requirements($phase) {
+      $requirements['update']['description'] = t('Some modules have database schema_data updates to install. You should run the <a href=":update">database update script</a> immediately.', [':update' => Url::fromRoute('system.db_update')->toString()]);

If this a find/replace error?

andypost’s picture

StatusFileSize
new1.41 KB
new52.16 KB

Fix #280 + one more nit in the same file

andypost’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: +Needs issue summary update
StatusFileSize
new8.17 KB
new52.13 KB

Addressed #277-5 - added type-hints and removed usage without module argument (there was only 2)

Additionally renamed getVersions() to getAvailableUpdates() because it actually parsing update functions

andypost’s picture

StatusFileSize
new1.04 KB
new52.33 KB

Quick fix

The last submitted patch, 282: 2124069-282.patch, failed testing. View results

Status: Needs review » Needs work

The last submitted patch, 283: 2124069-283.patch, failed testing. View results

andypost’s picture

Status: Needs work » Needs review
StatusFileSize
new6.29 KB
new52.43 KB

Fix broken tests and improve docs

Also changed injection into ModulesUninstallForm

Now it needs deprecation testing to be added

Status: Needs review » Needs work

The last submitted patch, 286: 2124069-286.patch, failed testing. View results

andypost’s picture

Status: Needs work » Needs review
StatusFileSize
new657 bytes
new53.07 KB

It helped to uncover bug in upgrade tests!

When module installed it's not enough to update core.extension, it needs to setup schema (now?)

The test fails because
Schema information for module <em class="placeholder">action</em> was missing from the database. You should manually review the module updates and your database to check if any updates have been skipped up to, and including, <em class="placeholder">action_update_8000()</em>.

alexpott’s picture

Status: Needs review » Needs work
  1. +++ b/core/core.services.yml
    @@ -448,6 +448,9 @@ services:
    +  database.schema.data:
    

    I think this name is unnecessarily confusing with database schema. It's the module schema version number service. I think we should name think and the class more like \Drupal\Core\Update\UpdateRegistry and update.post_update_registry. Something like update.update_N_registry.

    In fact there's functionality in \Drupal\Core\Update\UpdateRegistry that is extremely similar to the functionality here.

  2. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,121 @@
    +  /**
    +   * {@inheritdoc}
    +   */
    +  public function getAvailableUpdates($module) {
    
    +++ b/core/lib/Drupal/Core/Schema/SchemaDataInterface.php
    @@ -0,0 +1,51 @@
    +   * @return array
    +   *   If the module has updates, an array of available updates sorted by
    +   *   version. Otherwise, an empty array.
    +   */
    +  public function getAvailableUpdates($module);
    

    string $module

  3. +++ b/core/modules/system/tests/src/Functional/UpdateSystem/UpdateScriptTest.php
    @@ -63,6 +63,13 @@ class UpdateScriptTest extends BrowserTestBase {
    +  /**
    +   * The database.schema.data service.
    +   *
    +   * @var \Drupal\Core\Schema\SchemaDataInterface
    +   */
    +  protected $schemaData;
    

    Services should not be attached as properties to functional tests. This means they can out of date with the container. This is especially true in a update test.

    And then...

    +++ b/core/modules/system/tests/src/Functional/UpdateSystem/UpdateScriptTest.php
    @@ -142,7 +150,7 @@ public function testRequirements() {
    -    drupal_set_installed_schema_version('update_script_test', drupal_get_installed_schema_version('update_script_test') - 1);
    +    $this->schemaData->setInstalledVersion('update_script_test', $this->schemaData->getInstalledVersion('update_script_test') - 1);
    
    @@ -551,12 +559,13 @@ public function testSuccessfulUpdateFunctionality() {
    +    $this->schemaData->resetCache();
    +    $schema_version = $this->schemaData->getInstalledVersion('update_script_test');
    ...
    -    drupal_set_installed_schema_version('update_script_test', $schema_version - 1);
    -    $schema_version = drupal_get_installed_schema_version('update_script_test', TRUE);
    +    $this->schemaData->setInstalledVersion('update_script_test', $schema_version - 1);
    +    $schema_version = $this->schemaData->getInstalledVersion('update_script_test');
    
    @@ -616,12 +625,13 @@ public function testSuccessfulMultilingualUpdateFunctionality() {
    -    $schema_version = drupal_get_installed_schema_version('update_script_test', TRUE);
    +    $this->schemaData->resetCache();
    +    $schema_version = $this->schemaData->getInstalledVersion('update_script_test');
    ...
    -    drupal_set_installed_schema_version('update_script_test', $schema_version - 1);
    -    $schema_version = drupal_get_installed_schema_version('update_script_test', TRUE);
    +    $this->schemaData->setInstalledVersion('update_script_test', $schema_version - 1);
    +    $schema_version = $this->schemaData->getInstalledVersion('update_script_test');
    
    @@ -676,12 +686,12 @@ public function testMaintenanceModeLink() {
    -    $schema_version = drupal_get_installed_schema_version('update_script_test');
    +    $schema_version = $this->schemaData->getInstalledVersion('update_script_test');
    ...
    -    drupal_set_installed_schema_version('update_script_test', $schema_version - 1);
    -    $schema_version = drupal_get_installed_schema_version('update_script_test', TRUE);
    +    $this->schemaData->setInstalledVersion('update_script_test', $schema_version - 1);
    +    $schema_version = $this->schemaData->getInstalledVersion('update_script_test');
    

    Fix all of these to use \Drupal::service() and remove the resetCache() calls.

  4. +++ b/core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBaseTest.php
    @@ -97,8 +99,11 @@ public function testUpdateHookN() {
    +    /** @var \Drupal\Core\Schema\SchemaDataInterface $schema_data */
    +    $schema_data = \Drupal::service('database.schema.data');
    +    $schema_data->resetCache();
    +    $this->assertEqual($schema_data->getInstalledVersion('update_test_schema'), 8001);
    +    $this->assertEqual($schema_data->getInstalledVersion('update_test_semver_update_n'), 8001);
    

    Are we sure the resetCache is necessary here? I'd love to not add the resetCache functionality.

  5. +++ b/core/tests/Drupal/Tests/UpdatePathTestTrait.php
    @@ -60,7 +60,7 @@ protected function runUpdates($update_url = NULL) {
    -      drupal_get_installed_schema_version(NULL, TRUE);
    +      \Drupal::service('database.schema.data')->resetCache();
    

    This should not be necessary anymore. The container has been rebuilt. We need to move the update checking code after the container rebuild that happens in $this->resetAll()

andypost’s picture

StatusFileSize
new10.65 KB
new52.87 KB

Address #279 (2-5) looks this only 2 places where static cache needs invalidation (both using $this->resetCache() now

Also resetCache() is not removed in the patch. I wanna check make sure no other places left

andypost’s picture

Status: Needs work » Needs review
StatusFileSize
new801 bytes
new53 KB

After updates test needs fresh service instance

The last submitted patch, 290: 2124069-290.patch, failed testing. View results

andypost’s picture

StatusFileSize
new1.03 KB
new52.77 KB

Removal of resetCache()

The last submitted patch, 291: 2124069-291.patch, failed testing. View results

alexpott’s picture

  1. Yay to removing the resetCache() functionality - very nice to not be depending on this type of functionality. @andypost++
  2. +++ b/core/core.services.yml
    @@ -448,6 +448,9 @@ services:
    +  database.schema.data:
    

    Still need to fix this name.

  3. +++ b/core/includes/bootstrap.inc
    @@ -621,6 +621,13 @@ function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
    +  switch ($name) {
    +    case 'drupal_get_schema_versions':
    +    case 'drupal_get_installed_schema_version':
    +      @trigger_error("Using drupal_static_reset() with '{$name}' as parameter is deprecated in drupal:9.1.0 and will be removed before drupal:10.0.0. Use \Drupal\Core\Schema\SchemaDataInterface::resetCache() instead. See https://www.drupal.org/node/2444417.", E_USER_DEPRECATED);
    +      \Drupal::service('database.schema.data')->resetCache();
    +      return;
    +  }
    

    I think we can remove this now. There's no replacement. We could sayremove the call to resetCache() and say that a container rebuild is what you want in the very very unlikely case you need this.

    http://grep.xnddx.ru/search?text=drupal_get_schema_versions&filename=

    http://grep.xnddx.ru/search?text=drupal_get_installed_schema_version&fil...

    There are some calls to drupal_get_installed_schema_version() that want to reset the cache but they are either from obsolete Drupal 8 modules or extremely dodgy.

  4. +++ b/core/includes/schema.inc
    @@ -72,26 +51,23 @@ function drupal_get_schema_versions($module) {
    +    \Drupal::service('database.schema.data')->resetCache();
    

    This needs remooving.

  5. +++ b/core/lib/Drupal/Core/Schema/SchemaData.php
    @@ -0,0 +1,113 @@
    +/**
    + * Provides database updates schema handling.
    + */
    +class SchemaData implements SchemaDataInterface {
    

    I still think that this needs to be named in a way that reflects that this is a hook_update_N repository and module schema info service. And not that much to do with database schema.

andypost’s picture

Status: Needs review » Needs work

@alexpott thank you a lot for helping with reviews! Will roll new patch tonight

For naming I think better to use pattern from UpdateRegistry but it doing much more then registry... So maybe UpdateSchemaRegistry also it strange to have static cache when no way to reset it... so "factory" sounds a way ahead

Moreover after so many iterations it looks like the most of usages doing loop through all schema numbers, so static cache is micro-optimization (to get all values in one query, but some places needs to update few keys) - it makes sense to keep, that's why thinking about factory pattern instead.

Additionally I'm a bit confused inheritance in #2901418: Add hook_post_config_import_NAME after config import - not sure so many "abilities" needed for registry!
The common part of it is
- functions parser (update hooks, post updates) - name and sorting vary
- strict interface to set updates - numbers in "update_N" and strings for "post_update_NAME"
- static cache of all "registered values" (because used mostly in core to iterate over all list)

The issue (comment #288) with \Drupal\Tests\action\Functional\Update\ActionConfigTest is because \Drupal\Tests\UpdatePathTestTrait::runUpdates() adds new module to module handler but does not register schema

So as actions were partially enabled (not registered initial schema version) and _update_fix_missing_schema() is not called from the trait the test fails.

It needs own issue to be filed if scope creeps...

alexpott’s picture

@andypost it'd be great to avoid the word schema. hook_update_dependencies() / hook_update_last_removed do not use the word schema at all and the hook_update_N() documentation (which needs an update for the multi-version compatible module / semver changes) never mentions schema with respect to what N is.

Also let's not call it a factory if it not actually a factory. A factory is something that produces other objects - it doesn't have anything to do with statics. Also there are plenty of services which have protected properties with no way to clear them other than rebuilding the container.

I definitely think a follow-up to discuss whether the static is at all useful is worth it because I'm not convinved.

alexpott’s picture

+++ b/core/lib/Drupal/Core/Schema/SchemaData.php
@@ -0,0 +1,113 @@
+      unset($module_updates);

Why are we adding this unset? It doesn't seem required and it wasn't in the original code. Ah I see #74. Hmmm. That feels like a tricky rule to apply everywhere to core. If we're going to change this how about to something like https://3v4l.org/9gefJ

voleger’s picture

Rerolled #293

voleger’s picture

Status: Needs work » Needs review

Moved service Schema -> Update namespace. Used factory pattern to instantiate the service instance.

Used \Drupal\Core\Update\VersioningUpdateRegistry class name (feel free to suggest more correct name) and defined update.update_registry service.

The class \Drupal\Core\Update\UpdateRegistry used for defined update.post_update_registry service.

So there may be some confusion between service definitions and used class names.

See an updated MR

voleger’s picture

Updated the deprecation messages and addressed the items left.

Needs review

andypost’s picture

I find it RTBC but needs other eyes on naming and action test fix

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

daffie’s picture

Status: Needs review » Needs work

Added a number of comments on the MR, therefore setting the issue back to NW.

andypost’s picture

change record needs update as IS

zviryatko’s picture

What the point of using \Drupal::keyValue('system.schema')->getAll() instead of newly added \Drupal::service('update.update_registry')->getAllInstalledVersions()? In some places it still using direct access:

+++ b/core/includes/install.inc
@@ -81,7 +81,7 @@
-  foreach (drupal_get_installed_schema_version(NULL, FALSE, TRUE) as $module => $schema_version) {
+  foreach (\Drupal::keyValue('system.schema')->getAll() as $module => $schema_version) {

Again, it uses both - direct and indirect access:

+++ b/core/includes/update.inc
@@ -107,6 +107,8 @@ function _update_fix_missing_schema() {
   $versions = \Drupal::keyValue('system.schema')->getAll();
   $module_handler = \Drupal::moduleHandler();
   $enabled_modules = $module_handler->getModuleList();
+  /** @var \Drupal\Core\Update\VersioningUpdateRegistry $update_registry */
+  $update_registry = \Drupal::service('update.update_registry');
+++ b/core/includes/update.inc
@@ -345,7 +346,9 @@ function update_get_update_list() {
   // Make sure that the system module is first in the list of updates.
   $ret = ['system' => []];
 
-  $modules = drupal_get_installed_schema_version(NULL, FALSE, TRUE);
+  $modules = \Drupal::keyValue('system.schema')->getAll();
+  /** @var \Drupal\Core\Update\VersioningUpdateRegistry $update_registry */
+  $update_registry = \Drupal::service('update.update_registry');

It means that there officially two ways to get modules schema version - direct and cached, probably it is better to leave only one way or make it very explicit? But it may still require removing the local cached variable in "@update.update_registry" as I've mentioned in the previous comment.

Very similar issue with the modules list:

+++ b/core/lib/Drupal/Core/Update/VersioningUpdateRegistryFactory.php
+  public function create() {
+    return new VersioningUpdateRegistry(array_keys($this->container->get('module_handler')->getModuleList()), $this->container->get('keyvalue')->get('system.schema'));
+  }

it getting list of modules from @module_handler which is mutable (see \Drupal\Core\Extension\ModuleInstaller::uninstall and \Drupal\Core\Extension\ModuleInstaller::install) and it means when you call module uninstall it will change modules list in runtime but the local variable won't be changed, it is also explains why tests fails.

As a solution it may require the same thing - get rid of local variables and call dependencies directly.

voleger’s picture

Status: Needs work » Needs review

Thanks for the feedback. Addressed all requested changes.

longwave’s picture

#3210502: Convert UpdateDescriptionTest to a kernel test just snuck in which calls drupal_set_installed_schema_version() so will need updating here.

daffie’s picture

Status: Needs review » Needs work

The testbot is failing Drupal\Tests\Core\Update\VersioningUpdateRegistryTest

longwave’s picture

While reviewing I noticed the existence of update_set_schema(), did some investigating and opened #3210900: Deprecate update_set_schema() for removal

andypost’s picture

Status: Needs work » Needs review

Rebased

daffie’s picture

Status: Needs review » Needs work

The testbot is failing.

longwave’s picture

FILE: /var/www/html/core/includes/schema.inc
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 72 | ERROR | [x] Data types in @var tags need to be fully namespaced
andypost’s picture

Status: Needs work » Needs review

Still needs review for naming and updates for IS/CR

andypost’s picture

Looks it it's easier to squash commits instead of merging/rebasing conflicts

voleger’s picture

Title: Convert schema.inc to a service » Convert schema.inc to a update.update_registry service (VersioningUpdateRegistry)

Rebased and ready for the review

voleger’s picture

Title: Convert schema.inc to a update.update_registry service (VersioningUpdateRegistry) » Convert schema.inc to the update.update_registry service (VersioningUpdateRegistry)
longwave’s picture

The real unfortunate thing here is Drupal\Core\Update\UpdateRegistry being badly named - should we spin off a new issue to rename that to PostUpdateRegistry which will avoid future confusion between the two classes?

VersioningUpdateRegistry is OK but not great as I don't think we have ever used that name anywhere else? Other than "hook_update_N" do we have a name for these type of updates? Is UpdateHookRegistry better? Or SchemaVersionUpdateRegistry?

daffie’s picture

Status: Needs review » Needs work

There are a number of unresolved threads.

catch’s picture

UpdateHookRegistry better?

This seems better to me. If we eventually have some kind of non-hook update system that relies on schema numbering the same way, it would end up outdated, but a lot would have to change at the same time so that seems fine.

Or SchemaVersionUpdateRegistry?

This seems good as well.

Also agreed on renaming UpdateRegistry - could be a new issue though I think.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

daffie’s picture

The patch looks good to me.
It just needs updating to 9.3 for the deprecations, after that it is for me RTBC.

voleger’s picture

Status: Needs work » Needs review

Addressed last review comment.

longwave’s picture

Are we going to rename VersioningUpdateRegistry to something else, as per #321/#323?

daffie’s picture

Status: Needs review » Needs work

The remarks of @catch needs to be addressed.

voleger’s picture

Status: Needs work » Needs review

Addressed #327

daffie’s picture

Status: Needs review » Needs work

The testbot is failing.

longwave’s picture

Status: Needs work » Needs review

Merged 9.3.x, fixed test failure.

voleger’s picture

Title: Convert schema.inc to the update.update_registry service (VersioningUpdateRegistry) » Convert schema.inc to the update.update_hook_registry service (UpdateHookRegistry)

Looks good for me. I can't move to RTBC as I worked on the MR.
Also updated the title to represent the current class and service name.

andypost’s picture

It still needs summary and CR updates

daffie’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community
Issue tags: -Needs issue summary update

Updated the IS and the CR.
All the changes look good to me.
The new methods have already testing in core and new testing is added.
The deprecated function are correctly deprecated and have testing for it.
For me it is RTBC.

daffie’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs reroll

The MR is not mergeable. Please do not change the MR to a patch file.

longwave’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll

Fixed merge conflict.

daffie’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC.

  • catch committed a25c727 on 9.3.x
    Issue #2124069 by voleger, andypost, martin107, damiankloip, cburschka,...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 9.3.x, thanks!

Status: Fixed » Closed (fixed)

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