0

I have been installing and uninstalling modules on my site and I am starting to run into problems involving re installing previously disabled modules. The install script is finding old database tables from previous module installations and is refusing to install. For some of these modules, there is no 'uninstall' option. Is there a good way to determine which database table are associated with each module? I'm looking for a method of discovery or an online list.

marked as duplicate by Pierre.Vriens 7 Sep 30 '17 at 17:23

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • I answered about method of discovery. Requests for online resources are off-topic here. – Mołot Apr 11 '14 at 13:48
4

I am unaware of an automated way to check for orphaned tables. Before the Schema API was rolled out in Drupal 7, people would use the Schema module. This had a hook_requirements() in it that would do this check and list orphaned tables on the status report.

You could make your own automated test. The procedure would be something like

  • Do a SHOW TABLES query to get the list of all of the tables.
  • Query the {system} table to get a list of all modules, both enabled and disabled
  • Loop through the modules, and then use drupal_get_schema_unprocessed() to get the module's schema. From this, build up a list of tables.
  • Do an array difference between the list you just built and the list from SHOW TABLES. This should be all tables that aren't owned by a module that is enabled or disabled.

Something like this:

$alltables = db_query('SHOW TABLES')->fetchCol();

$modules = db_query("SELECT name FROM {system} WHERE type = 'module'")->fetchCol();

$accountedfor = array();

foreach ($modules as $module) {
  $schema = drupal_get_schema_unprocessed($module);

  if (!empty($schema)) {
    $accountedfor = array_merge($accountedfor, array_keys($schema));
  }
}

// tables not accounted for by hook_schema() from enabled and disabled modules

$orphaned = array_diff($alltables, $accountedfor);

This ignore the intricacies of table prefixes, multiple catalogs, and sharing catalogs between applications.

Use at your own risk.

1

I've encountered trouble using the uninstall on a few modules even when hook_schema was used. you could try 1) searching for the module in the 'system' table of your database and setting its status to 0 to disable it. 2) look through the module's file contents for hook_schema function (usually it will be in a {modulename}.install file) This function should allow you to figure out which tables were added to the database when the module was enabled, and to drop them manually if needed.

0

For what you are trying to do, the Schema API is your friend. Check it out at https://drupal.org/developing/api/schema.

Pay a close attention to the function drupal_get_schema($table = NULL, $rebuild = FALSE)

Running that function without parameters will return every DB table created using the Schema API. But the returned information will not show the modules ... it just shows the tables and their fields' definitions. But if you are willing to dig deeper, you can clone the drupal_get_schema() function a adjust it a little so that the return value is indexed using the modules' names.

The following loop shows how Drupal is already looping through the list of all the modules that implement the hook_schema()

...
// Invoke hook_schema for all modules.
foreach (module_implements('schema') as $module) {
  // Cast the result of hook_schema() to an array, as a NULL return value
  // would cause array_merge() to set the $schema variable to NULL as well.
  // That would break modules which use $schema further down the line.
  $current = (array) module_invoke($module, 'schema');
  _drupal_initialize_schema($module, $current);
  $schema = array_merge($schema, $current);
}
...

I haven't tested the following, but it can give you what you need. Just replace the loop using this new version of it. And remember not to modify the core. Copy the entire function in your own code and do the changes there. The modified loop is...

...
// Invoke hook_schema for all modules.
foreach (module_implements('schema') as $module) {
  // Cast the result of hook_schema() to an array, as a NULL return value
  // would cause array_merge() to set the $schema variable to NULL as well.
  // That would break modules which use $schema further down the line.
  $current = array($module => (array) module_invoke($module, 'schema'));
  _drupal_initialize_schema($module, $current);
  $schema = array_merge($schema, $current);
}
...

If a crappy module is creating it's own DB tables using a direct query, than that would be defeating the purpose of the API and you will not be able to get those using the Schema API.

Not the answer you're looking for? Browse other questions tagged or ask your own question.