Problem/Motivation
hook_schema() creates a strong dependency between module installation and services provided by modules. This means for example that we have to use KernetTestBase::installSchema() in kernel tests.
We have an existing pattern in core which avoids this, the ::ensureTableExists() pattern. With this, services are responsible for creating their database schema on demand. Some examples: https://api.drupal.org/api/drupal/9.3.x/search/ensureTableExists
Steps to reproduce
Proposed resolution
Apply this pattern to more core services. Eventually deprecate hook_schema() once it's no longer used in core.
At the same time, look at adding a more formal API:
#2371709: [PP-x] Move the on-demand-table creation into the database API
Note that #2665216: Deprecate Drupal\Core\Database\Connection::nextId() and the {sequences} table and schema removes a hook_schema() implementation by replacing it with key value.
Remaining tasks
Open issues to replace the following hook_schema() implementations, focusing on modules which will not be deprecated for removal in Drupal 11.
system_schema() - #3428565: Implement lazy database creation for sessions
layout_builder_schema()
search_schema()
user_schema()
node_schema()
locale_schema()
ban_schema() - #3379255: [PP-1] Replace ban_schema() implementation with ::ensureTableExists()
help_topics_schema()
forum_schema()
book_schema()
history_schema()
tracker_schema()
dblog_schema()
shortcut_schema()
comment_schema()
file_schema()
workspaces_schema()
Once all core hook_schema() usages have been converted, consider opening a follow-up to deprecate hook_schema() itself.
Comments
Comment #6
andypostOnly one issue left in summary, probably could be closed
Comment #7
catchI think we need more child issues, there is still the following hook_schema() implementations in core:
layout_build_schema()
search_schema()
user_schema()
node_schema()
locale_schema()
ban_schema()
help_topics_schema()
forum_schema()
book_schema()
history_schema()
tracker_schema()
dblog_schema()
shortcut_schema()
comment_schema()
file_schema()
workspaces_schema()
Some of these modules are slated for removal so it might be more efficient for us to deprecate the modules rather than refactoring, but several aren't.
Comment #8
andyposthelp topics will be moved to help but that's for purpose of search
comment statistics IIRC there's #2318875: Redo CommentStatisticsInterface
the same is for history and taxonomy
So yep, makes sense to keep
Comment #9
catchAdded the list to the issue summary.
Comment #10
nlisgo commentedComment #11
nlisgo commentedI've started on #3379255: [PP-1] Replace ban_schema() implementation with ::ensureTableExists().
It would be great to get some help on this one and then we have a template on how to approach the others. I need a little support to understand how to hook up the process to delete the table once the module is uninstalled.
Comment #12
nlisgo commentedI reached out for some support on slack regarding an approach to tear down tables when modules are uninstalled. This process needs to be clearer before we progress. The current implementations of this approach have all been for core services so we don't need to support tear down. This is obviously a necessity for any implementations within a module.
Hat tip: @berdir (for your support on slack)
Comment #13
nlisgo commentedUpdate from @catch on slack:
Comment #14
catchOpened #3428565: Implement lazy database creation for sessions
Comment #15
catchComment #16
nicxvan commentedComment #17
nicxvan commentedThe ban module change is ready.
I have to say wrapping every call in an ensure table exists feels really cumbersome do we think #2371709: [PP-x] Move the on-demand-table creation into the database API makes this transparent?
Is probably better to resolve that first then.
Comment #19
penyaskitoDone this for canvas (#3585192: Don't rely on hook_schema for canvas notifications table). Agree with @nicxvan that #2371709 is necessary, or at least some helpers should be provided. The patterns are quite common, but at the moment this can't be done without some boilerplate.