diff options
Diffstat (limited to 'mycli/packages/special/dbcommands.py')
-rw-r--r-- | mycli/packages/special/dbcommands.py | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/mycli/packages/special/dbcommands.py b/mycli/packages/special/dbcommands.py new file mode 100644 index 0000000..ed90e4c --- /dev/null +++ b/mycli/packages/special/dbcommands.py @@ -0,0 +1,157 @@ +import logging +import os +import platform +from mycli import __version__ +from mycli.packages.special import iocommands +from mycli.packages.special.utils import format_uptime +from .main import special_command, RAW_QUERY, PARSED_QUERY +from pymysql import ProgrammingError + +log = logging.getLogger(__name__) + + +@special_command('\\dt', '\\dt[+] [table]', 'List or describe tables.', + arg_type=PARSED_QUERY, case_sensitive=True) +def list_tables(cur, arg=None, arg_type=PARSED_QUERY, verbose=False): + if arg: + query = 'SHOW FIELDS FROM {0}'.format(arg) + else: + query = 'SHOW TABLES' + log.debug(query) + cur.execute(query) + tables = cur.fetchall() + status = '' + if cur.description: + headers = [x[0] for x in cur.description] + else: + return [(None, None, None, '')] + + if verbose and arg: + query = 'SHOW CREATE TABLE {0}'.format(arg) + log.debug(query) + cur.execute(query) + status = cur.fetchone()[1] + + return [(None, tables, headers, status)] + +@special_command('\\l', '\\l', 'List databases.', arg_type=RAW_QUERY, case_sensitive=True) +def list_databases(cur, **_): + query = 'SHOW DATABASES' + log.debug(query) + cur.execute(query) + if cur.description: + headers = [x[0] for x in cur.description] + return [(None, cur, headers, '')] + else: + return [(None, None, None, '')] + +@special_command('status', '\\s', 'Get status information from the server.', + arg_type=RAW_QUERY, aliases=('\\s', ), case_sensitive=True) +def status(cur, **_): + query = 'SHOW GLOBAL STATUS;' + log.debug(query) + try: + cur.execute(query) + except ProgrammingError: + # Fallback in case query fail, as it does with Mysql 4 + query = 'SHOW STATUS;' + log.debug(query) + cur.execute(query) + status = dict(cur.fetchall()) + + query = 'SHOW GLOBAL VARIABLES;' + log.debug(query) + cur.execute(query) + variables = dict(cur.fetchall()) + + # prepare in case keys are bytes, as with Python 3 and Mysql 4 + if (isinstance(list(variables)[0], bytes) and + isinstance(list(status)[0], bytes)): + variables = {k.decode('utf-8'): v.decode('utf-8') for k, v + in variables.items()} + status = {k.decode('utf-8'): v.decode('utf-8') for k, v + in status.items()} + + # Create output buffers. + title = [] + output = [] + footer = [] + + title.append('--------------') + + # Output the mycli client information. + implementation = platform.python_implementation() + version = platform.python_version() + client_info = [] + client_info.append('mycli {0},'.format(__version__)) + client_info.append('running on {0} {1}'.format(implementation, version)) + title.append(' '.join(client_info) + '\n') + + # Build the output that will be displayed as a table. + output.append(('Connection id:', cur.connection.thread_id())) + + query = 'SELECT DATABASE(), USER();' + log.debug(query) + cur.execute(query) + db, user = cur.fetchone() + if db is None: + db = '' + + output.append(('Current database:', db)) + output.append(('Current user:', user)) + + if iocommands.is_pager_enabled(): + if 'PAGER' in os.environ: + pager = os.environ['PAGER'] + else: + pager = 'System default' + else: + pager = 'stdout' + output.append(('Current pager:', pager)) + + output.append(('Server version:', '{0} {1}'.format( + variables['version'], variables['version_comment']))) + output.append(('Protocol version:', variables['protocol_version'])) + + if 'unix' in cur.connection.host_info.lower(): + host_info = cur.connection.host_info + else: + host_info = '{0} via TCP/IP'.format(cur.connection.host) + + output.append(('Connection:', host_info)) + + query = ('SELECT @@character_set_server, @@character_set_database, ' + '@@character_set_client, @@character_set_connection LIMIT 1;') + log.debug(query) + cur.execute(query) + charset = cur.fetchone() + output.append(('Server characterset:', charset[0])) + output.append(('Db characterset:', charset[1])) + output.append(('Client characterset:', charset[2])) + output.append(('Conn. characterset:', charset[3])) + + if 'TCP/IP' in host_info: + output.append(('TCP port:', cur.connection.port)) + else: + output.append(('UNIX socket:', variables['socket'])) + + output.append(('Uptime:', format_uptime(status['Uptime']))) + + # Print the current server statistics. + stats = [] + stats.append('Connections: {0}'.format(status['Threads_connected'])) + if 'Queries' in status: + stats.append('Queries: {0}'.format(status['Queries'])) + stats.append('Slow queries: {0}'.format(status['Slow_queries'])) + stats.append('Opens: {0}'.format(status['Opened_tables'])) + stats.append('Flush tables: {0}'.format(status['Flush_commands'])) + stats.append('Open tables: {0}'.format(status['Open_tables'])) + if 'Queries' in status: + queries_per_second = int(status['Queries']) / int(status['Uptime']) + stats.append('Queries per second avg: {:.3f}'.format( + queries_per_second)) + stats = ' '.join(stats) + footer.append('\n' + stats) + + footer.append('--------------') + return [('\n'.join(title), output, '', '\n'.join(footer))] |