mirror of
https://github.com/ansible-collections/community.mysql.git
synced 2025-04-04 17:50:32 -07:00
mysql_info - add table count to the databases returned values (#691)
* Add tables count per database * Add integrations tests * Deduplicate tests between main and new task file
This commit is contained in:
parent
d613fa1993
commit
9057637844
4 changed files with 202 additions and 116 deletions
3
changelogs/fragments/591-mysql_info-db_tables_count.yml
Normal file
3
changelogs/fragments/591-mysql_info-db_tables_count.yml
Normal file
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
minor_changes:
|
||||
- mysql_info - adds the count of tables for each database to the returned values. It is possible to exclude this new field using the ``db_table_count`` exclusion filter. (https://github.com/ansible-collections/community.mysql/pull/691)
|
|
@ -35,7 +35,7 @@ options:
|
|||
exclude_fields:
|
||||
description:
|
||||
- List of fields which are not needed to collect.
|
||||
- "Supports elements: C(db_size). Unsupported elements will be ignored."
|
||||
- "Supports elements: C(db_size), C(db_table_count). Unsupported elements will be ignored."
|
||||
type: list
|
||||
elements: str
|
||||
version_added: '0.1.0'
|
||||
|
@ -204,13 +204,19 @@ databases:
|
|||
returned: if not excluded by filter
|
||||
type: dict
|
||||
sample:
|
||||
- { "mysql": { "size": 656594 }, "information_schema": { "size": 73728 } }
|
||||
- { "mysql": { "size": 656594, "tables": 31 }, "information_schema": { "size": 73728, "tables": 79 } }
|
||||
contains:
|
||||
size:
|
||||
description: Database size in bytes.
|
||||
returned: if not excluded by filter
|
||||
type: dict
|
||||
sample: { 'size': 656594 }
|
||||
tables:
|
||||
description: Count of tables and views in that database.
|
||||
returned: if not excluded by filter
|
||||
type: dict
|
||||
sample: { 'tables': 12 }
|
||||
version_added: '3.11.0'
|
||||
settings:
|
||||
description: Global settings (variables) information.
|
||||
returned: if not excluded by filter
|
||||
|
@ -656,40 +662,39 @@ class MySQL_Info(object):
|
|||
|
||||
def __get_databases(self, exclude_fields, return_empty_dbs):
|
||||
"""Get info about databases."""
|
||||
if not exclude_fields:
|
||||
query = ('SELECT table_schema AS "name", '
|
||||
'SUM(data_length + index_length) AS "size" '
|
||||
'FROM information_schema.TABLES GROUP BY table_schema')
|
||||
else:
|
||||
if 'db_size' in exclude_fields:
|
||||
query = ('SELECT table_schema AS "name" '
|
||||
'FROM information_schema.TABLES GROUP BY table_schema')
|
||||
|
||||
res = self.__exec_sql(query)
|
||||
def is_field_included(field_name):
|
||||
return not exclude_fields or 'db_{}'.format(field_name) not in exclude_fields
|
||||
|
||||
if res:
|
||||
for db in res:
|
||||
self.info['databases'][db['name']] = {}
|
||||
def create_db_info(db_data):
|
||||
info = {}
|
||||
if is_field_included('size'):
|
||||
info['size'] = int(db_data.get('size', 0) or 0)
|
||||
if is_field_included('table_count'):
|
||||
info['tables'] = int(db_data.get('tables', 0) or 0)
|
||||
return info
|
||||
|
||||
if not exclude_fields or 'db_size' not in exclude_fields:
|
||||
if db['size'] is None:
|
||||
db['size'] = 0
|
||||
# Build the main query
|
||||
query_parts = ['SELECT table_schema AS "name"']
|
||||
if is_field_included('size'):
|
||||
query_parts.append('SUM(data_length + index_length) AS "size"')
|
||||
if is_field_included('table_count'):
|
||||
query_parts.append('COUNT(table_name) as "tables"')
|
||||
|
||||
self.info['databases'][db['name']]['size'] = int(db['size'])
|
||||
query = "{} FROM information_schema.TABLES GROUP BY table_schema".format(", ".join(query_parts))
|
||||
|
||||
# If empty dbs are not needed in the returned dict, exit from the method
|
||||
if not return_empty_dbs:
|
||||
return None
|
||||
# Get and process databases with tables
|
||||
databases = self.__exec_sql(query) or []
|
||||
for db in databases:
|
||||
self.info['databases'][db['name']] = create_db_info(db)
|
||||
|
||||
# Add info about empty databases (issue #65727):
|
||||
res = self.__exec_sql('SHOW DATABASES')
|
||||
if res:
|
||||
for db in res:
|
||||
if db['Database'] not in self.info['databases']:
|
||||
self.info['databases'][db['Database']] = {}
|
||||
|
||||
if not exclude_fields or 'db_size' not in exclude_fields:
|
||||
self.info['databases'][db['Database']]['size'] = 0
|
||||
# Handle empty databases if requested
|
||||
if return_empty_dbs:
|
||||
empty_databases = self.__exec_sql('SHOW DATABASES') or []
|
||||
for db in empty_databases:
|
||||
db_name = db['Database']
|
||||
if db_name not in self.info['databases']:
|
||||
self.info['databases'][db_name] = create_db_info({})
|
||||
|
||||
def __exec_sql(self, query, ddl=False):
|
||||
"""Execute SQL.
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
---
|
||||
|
||||
- module_defaults:
|
||||
community.mysql.mysql_db: &mysql_defaults
|
||||
login_user: "{{ mysql_user }}"
|
||||
login_password: "{{ mysql_password }}"
|
||||
login_host: "{{ mysql_host }}"
|
||||
login_port: "{{ mysql_primary_port }}"
|
||||
community.mysql.mysql_query: *mysql_defaults
|
||||
community.mysql.mysql_info: *mysql_defaults
|
||||
community.mysql.mysql_user: *mysql_defaults
|
||||
|
||||
block:
|
||||
|
||||
# ================================ Prepare ==============================
|
||||
- name: Mysql_info databases | Prepare | Create databases
|
||||
community.mysql.mysql_db:
|
||||
name:
|
||||
- db_tables_count_empty
|
||||
- db_tables_count_1
|
||||
- db_tables_count_2
|
||||
- db_only_views # https://github.com/ansible-Getions/community.mysql/issues/204
|
||||
state: present
|
||||
|
||||
- name: Mysql_info databases | Prepare | Create tables
|
||||
community.mysql.mysql_query:
|
||||
query:
|
||||
- >-
|
||||
CREATE TABLE IF NOT EXISTS db_tables_count_1.t1
|
||||
(id int, name varchar(9))
|
||||
- >-
|
||||
CREATE TABLE IF NOT EXISTS db_tables_count_2.t1
|
||||
(id int, name1 varchar(9))
|
||||
- >-
|
||||
CREATE TABLE IF NOT EXISTS db_tables_count_2.t2
|
||||
(id int, name1 varchar(9))
|
||||
- >-
|
||||
CREATE VIEW db_only_views.v_today (today) AS SELECT CURRENT_DATE
|
||||
|
||||
# ================================== Tests ==============================
|
||||
|
||||
- name: Mysql_info databases | Get all non-empty databases fields
|
||||
community.mysql.mysql_info:
|
||||
filter:
|
||||
- databases
|
||||
register: result
|
||||
failed_when:
|
||||
- >
|
||||
result.databases['db_tables_count_1'].size != 16384 or
|
||||
result.databases['db_tables_count_1'].tables != 1 or
|
||||
result.databases['db_tables_count_2'].size != 32768 or
|
||||
result.databases['db_tables_count_2'].tables != 2 or
|
||||
result.databases['db_only_views'].size != 0 or
|
||||
result.databases['db_only_views'].tables != 1 or
|
||||
'db_tables_count_empty' in result.databases | dict2items
|
||||
| map(attribute='key')
|
||||
|
||||
- name: Mysql_info databases | Get all dbs fields except db_size
|
||||
community.mysql.mysql_info:
|
||||
filter:
|
||||
- databases
|
||||
exclude_fields:
|
||||
- db_size
|
||||
register: result
|
||||
failed_when:
|
||||
- >
|
||||
result.databases['db_tables_count_1'].size is defined or
|
||||
result.databases['db_tables_count_1'].tables != 1 or
|
||||
result.databases['db_tables_count_2'].size is defined or
|
||||
result.databases['db_tables_count_2'].tables != 2 or
|
||||
result.databases['db_only_views'].size is defined or
|
||||
result.databases['db_only_views'].tables != 1 or
|
||||
'db_tables_count_empty' in result.databases | dict2items
|
||||
| map(attribute='key')
|
||||
|
||||
# 'unsupported' element is passed to check that an unsupported value
|
||||
# won't break anything (will be ignored regarding to the module's
|
||||
# documentation).
|
||||
- name: Mysql_info databases | Get all dbs fields with unsupported value
|
||||
community.mysql.mysql_info:
|
||||
filter:
|
||||
- databases
|
||||
exclude_fields:
|
||||
- db_size
|
||||
- unsupported
|
||||
register: result
|
||||
failed_when:
|
||||
- >
|
||||
result.databases['db_tables_count_1'].size is defined or
|
||||
result.databases['db_tables_count_1'].tables != 1 or
|
||||
result.databases['db_tables_count_2'].size is defined or
|
||||
result.databases['db_tables_count_2'].tables != 2 or
|
||||
result.databases['db_only_views'].size is defined or
|
||||
result.databases['db_only_views'].tables != 1 or
|
||||
'db_tables_count_empty' in result.databases | dict2items
|
||||
| map(attribute='key')
|
||||
|
||||
- name: Mysql_info databases | Get all dbs fields except tables
|
||||
community.mysql.mysql_info:
|
||||
filter:
|
||||
- databases
|
||||
exclude_fields:
|
||||
- db_table_count
|
||||
register: result
|
||||
failed_when:
|
||||
- >
|
||||
result.databases['db_tables_count_1'].size != 16384 or
|
||||
result.databases['db_tables_count_1'].tables is defined or
|
||||
result.databases['db_tables_count_2'].size != 32768 or
|
||||
result.databases['db_tables_count_2'].tables is defined or
|
||||
result.databases['db_only_views'].size != 0 or
|
||||
result.databases['db_only_views'].tables is defined or
|
||||
'db_tables_count_empty' in result.databases | dict2items
|
||||
| map(attribute='key')
|
||||
|
||||
- name: Mysql_info databases | Get all dbs even empty ones
|
||||
community.mysql.mysql_info:
|
||||
filter:
|
||||
- databases
|
||||
return_empty_dbs: true
|
||||
register: result
|
||||
failed_when:
|
||||
- >
|
||||
result.databases['db_tables_count_1'].size != 16384 or
|
||||
result.databases['db_tables_count_1'].tables != 1 or
|
||||
result.databases['db_tables_count_2'].size != 32768 or
|
||||
result.databases['db_tables_count_2'].tables != 2 or
|
||||
result.databases['db_only_views'].size != 0 or
|
||||
result.databases['db_only_views'].tables != 1 or
|
||||
result.databases['db_tables_count_empty'].size != 0 or
|
||||
result.databases['db_tables_count_empty'].tables != 0
|
||||
|
||||
- name: Mysql_info databases | Get all dbs even empty ones without size
|
||||
community.mysql.mysql_info:
|
||||
filter:
|
||||
- databases
|
||||
exclude_fields:
|
||||
- db_size
|
||||
return_empty_dbs: true
|
||||
register: result
|
||||
failed_when:
|
||||
- >
|
||||
result.databases['db_tables_count_1'].size is defined or
|
||||
result.databases['db_tables_count_1'].tables != 1 or
|
||||
result.databases['db_tables_count_2'].size is defined or
|
||||
result.databases['db_tables_count_2'].tables != 2 or
|
||||
result.databases['db_only_views'].size is defined or
|
||||
result.databases['db_only_views'].tables != 1 or
|
||||
result.databases['db_tables_count_empty'].size is defined or
|
||||
result.databases['db_tables_count_empty'].tables != 0
|
||||
|
||||
# ================================== Cleanup ============================
|
||||
|
||||
- name: Mysql_info databases | Cleanup databases
|
||||
community.mysql.mysql_db:
|
||||
name:
|
||||
- db_tables_count_empty
|
||||
- db_tables_count_1
|
||||
- db_tables_count_2
|
||||
- db_only_views
|
||||
state: absent
|
|
@ -132,94 +132,11 @@
|
|||
- result.global_status is not defined
|
||||
- result.users is not defined
|
||||
|
||||
# Test exclude_fields: db_size
|
||||
# 'unsupported' element is passed to check that an unsupported value
|
||||
# won't break anything (will be ignored regarding to the module's documentation).
|
||||
- name: Collect info about databases excluding their sizes
|
||||
mysql_info:
|
||||
<<: *mysql_params
|
||||
filter:
|
||||
- databases
|
||||
exclude_fields:
|
||||
- db_size
|
||||
- unsupported
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- result is not changed
|
||||
- result.databases != {}
|
||||
- result.databases.mysql == {}
|
||||
|
||||
########################################################
|
||||
# Issue #65727, empty databases must be in returned dict
|
||||
#
|
||||
- name: Create empty database acme
|
||||
mysql_db:
|
||||
<<: *mysql_params
|
||||
name: acme
|
||||
|
||||
- name: Collect info about databases
|
||||
mysql_info:
|
||||
<<: *mysql_params
|
||||
filter:
|
||||
- databases
|
||||
return_empty_dbs: true
|
||||
register: result
|
||||
|
||||
# Check acme is in returned dict
|
||||
- assert:
|
||||
that:
|
||||
- result is not changed
|
||||
- result.databases.acme.size == 0
|
||||
- result.databases.mysql != {}
|
||||
|
||||
- name: Collect info about databases excluding their sizes
|
||||
mysql_info:
|
||||
<<: *mysql_params
|
||||
filter:
|
||||
- databases
|
||||
exclude_fields:
|
||||
- db_size
|
||||
return_empty_dbs: true
|
||||
register: result
|
||||
|
||||
# Check acme is in returned dict
|
||||
- assert:
|
||||
that:
|
||||
- result is not changed
|
||||
- result.databases.acme == {}
|
||||
- result.databases.mysql == {}
|
||||
|
||||
- name: Remove acme database
|
||||
mysql_db:
|
||||
<<: *mysql_params
|
||||
name: acme
|
||||
state: absent
|
||||
|
||||
- include_tasks: issue-28.yml
|
||||
|
||||
# https://github.com/ansible-collections/community.mysql/issues/204
|
||||
- name: Create database containing only views
|
||||
mysql_db:
|
||||
<<: *mysql_params
|
||||
name: allviews
|
||||
|
||||
- name: Create view
|
||||
mysql_query:
|
||||
<<: *mysql_params
|
||||
login_db: allviews
|
||||
query: 'CREATE VIEW v_today (today) AS SELECT CURRENT_DATE'
|
||||
|
||||
- name: Fetch info
|
||||
mysql_info:
|
||||
<<: *mysql_params
|
||||
register: result
|
||||
|
||||
- name: Check
|
||||
assert:
|
||||
that:
|
||||
- result.databases.allviews.size == 0
|
||||
- name: Import tasks file to tests tables count in database filter
|
||||
ansible.builtin.import_tasks:
|
||||
file: filter_databases.yml
|
||||
|
||||
- name: Import tasks file to tests users_info filter
|
||||
ansible.builtin.import_tasks:
|
||||
|
|
Loading…
Add table
Reference in a new issue