4 use Consolidation\Config\ConfigInterface;
5 use Drush\Utils\StringUtils;
8 * Note: when using this trait, also implement ConfigAwareInterface/ConfigAwareTrait.
12 trait SqlTableSelectionTrait
16 * Given a list of all tables, expand the convert the wildcards in the
17 * option-provided lists into a list of actual table names.
19 * @param array $options An options array as passed to an Annotated Command.
20 * @param array $all_tables A list of all eligible tables.
23 * An array of tables with each table name in the appropriate
24 * element of the array.
26 public function getExpandedTableSelection($options, $all_tables)
28 $table_selection = $this->getTableSelection($options);
29 // Get the existing table names in the specified database.
30 if (isset($table_selection['skip'])) {
31 $table_selection['skip'] = $this->expandAndFilterTables($table_selection['skip'], $all_tables);
33 if (isset($table_selection['structure'])) {
34 $table_selection['structure'] = $this->expandAndFilterTables($table_selection['structure'], $all_tables);
36 if (isset($table_selection['tables'])) {
37 $table_selection['tables'] = $this->expandAndFilterTables($table_selection['tables'], $all_tables);
39 return $table_selection;
43 * Given the table names in the input array that may contain wildcards (`*`),
44 * expand the table names so that the array returned only contains table names
45 * that exist in the database.
47 * @param array $tables
48 * An array of table names where the table names may contain the
49 * `*` wildcard character.
50 * @param array $db_tables
51 * The list of tables present in a database.
53 * An array of tables with non-existant tables removed.
55 public function expandAndFilterTables($tables, $db_tables)
57 $expanded_tables = $this->ExpandWildcardTables($tables, $db_tables);
58 $tables = $this->filterTables(array_merge($tables, $expanded_tables), $db_tables);
59 $tables = array_unique($tables);
65 * Expand wildcard tables.
67 * @param array $tables
68 * An array of table names, some of which may contain wildcards (`*`).
69 * @param array $db_tables
70 * An array with all the existing table names in the current database.
72 * $tables array with wildcards resolved to real table names.
74 public function expandWildcardTables($tables, $db_tables)
76 // Table name expansion based on `*` wildcard.
77 $expanded_db_tables = [];
78 foreach ($tables as $k => $table) {
79 // Only deal with table names containing a wildcard.
80 if (strpos($table, '*') !== false) {
81 $pattern = '/^' . str_replace('*', '.*', $table) . '$/i';
82 // Merge those existing tables which match the pattern with the rest of
83 // the expanded table names.
84 $expanded_db_tables += preg_grep($pattern, $db_tables);
87 return $expanded_db_tables;
93 * @param array $tables
94 * An array of table names to filter.
95 * @param array $db_tables
96 * An array with all the existing table names in the current database.
98 * An array with only valid table names (i.e. all of which actually exist in
101 public function filterTables($tables, $db_tables)
103 // Ensure all the tables actually exist in the database.
104 foreach ($tables as $k => $table) {
105 if (!in_array($table, $db_tables)) {
114 * Construct an array that places table names in appropriate
115 * buckets based on whether the table is to be skipped, included
116 * for structure only, or have structure and data dumped.
117 * The keys of the array are:
118 * - skip: tables to be skipped completed in the dump
119 * - structure: tables to only have their structure i.e. DDL dumped
120 * - tables: tables to have structure and data dumped
123 * An array of table names with each table name in the appropriate
124 * element of the array.
126 public function getTableSelection($options)
128 // Skip large core tables if instructed. Used by 'sql-drop/sql-dump/sql-sync' commands.
129 $skip_tables = $this->getRawTableList('skip-tables', $options);
130 // Skip any structure-tables as well.
131 $structure_tables = $this->getRawTableList('structure-tables', $options);
132 // Dump only the specified tables. Takes precedence over skip-tables and structure-tables.
133 $tables = $this->getRawTableList('tables', $options);
135 return ['skip' => $skip_tables, 'structure' => $structure_tables, 'tables' => $tables];
139 * Consult the specified options and return the list of tables specified.
142 * The option name to check: skip-tables, structure-tables
143 * or tables. This function will check both *-key and *-list.
144 * @param array $options An options array as passed to an Annotated Command.
146 * Returns an array of tables based on the first option
147 * found, or an empty array if there were no matches.
149 public function getRawTableList($option_name, $options)
151 $key_list = StringUtils::csvToArray($options[$option_name . '-key']);
152 foreach ($key_list as $key) {
153 $all_tables = $this->getConfig()->get('sql.' . $option_name, []);
154 if (array_key_exists($key, $all_tables)) {
155 return $all_tables[$key];
157 if ($option_name != 'tables') {
158 $all_tables = $this->getConfig()->get('sql.tables', []);
159 if (array_key_exists($key, $all_tables)) {
160 return $all_tables[$key];
164 $table_list = $options[$option_name . '-list'];
165 if (!empty($table_list)) {
166 return StringUtils::csvToArray($table_list);