From a0494ec4d341455a4be5ec35ed6aa6983d2ebb46 Mon Sep 17 00:00:00 2001 From: Shawn Davis Date: Thu, 17 Sep 2020 11:04:44 -0400 Subject: [PATCH] Added mysql overlay. --- VERSION.txt | 2 +- docs/generate_command_signatures.py | 9 +- docs/source/_data/cloc.csv | 4 +- docs/source/_includes/overlays.rst | 492 ++++++++++++++++++++++++- scripttease/cli/__init__.py | 4 +- scripttease/library/overlays/centos.py | 2 + scripttease/library/overlays/mysql.py | 262 +++++++++++++ scripttease/library/overlays/ubuntu.py | 2 + scripttease/version.py | 9 +- tests/test_library_overlays_mysql.py | 76 ++++ 10 files changed, 849 insertions(+), 13 deletions(-) create mode 100644 scripttease/library/overlays/mysql.py create mode 100644 tests/test_library_overlays_mysql.py diff --git a/VERSION.txt b/VERSION.txt index 880c0dd..08b33a8 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -6.4.3-d \ No newline at end of file +6.4.4-d \ No newline at end of file diff --git a/docs/generate_command_signatures.py b/docs/generate_command_signatures.py index 6befdb2..997f66e 100755 --- a/docs/generate_command_signatures.py +++ b/docs/generate_command_signatures.py @@ -13,6 +13,7 @@ sys.path.append("../") from scripttease.library.overlays.common import COMMON_MAPPINGS from scripttease.library.overlays.centos import MAPPINGS as CENTOS_MAPPINGS from scripttease.library.overlays.django import DJANGO_MAPPINGS +from scripttease.library.overlays.mysql import MYSQL_MAPPINGS from scripttease.library.overlays.pgsql import PGSQL_MAPPINGS from scripttease.library.overlays.posix import POSIX_MAPPINGS from scripttease.library.overlays.ubuntu import MAPPINGS as UBUNTU_MAPPINGS @@ -105,6 +106,10 @@ print_heading("Django") print_description("Django commands are available to all overlays.") print_mapping(DJANGO_MAPPINGS) +print_heading("MySQL") +print_description("MySQL commands.") +print_mapping(MYSQL_MAPPINGS) + print_heading("Postgres") print_description("Postgres commands.") print_mapping(PGSQL_MAPPINGS) @@ -119,7 +124,7 @@ exclude_from_centos.update(PGSQL_MAPPINGS) exclude_from_centos.update(POSIX_MAPPINGS) print_heading("Cent OS") print_description("The Cent OS overlay incorporates commands specific to that platform as well as commands from " - "common, Django, Postgres, and POSIX.") + "common, Django, MySQL, Postgres, and POSIX.") print_mapping(CENTOS_MAPPINGS, excludes=exclude_from_centos) exclude_from_ubuntu = COMMON_MAPPINGS.copy() @@ -128,5 +133,5 @@ exclude_from_ubuntu.update(PGSQL_MAPPINGS) exclude_from_ubuntu.update(POSIX_MAPPINGS) print_heading("Ubuntu") print_description("The Ubuntu overlay incorporates commands specific to that platform as well as commands from " - "common, Django, Postgres, and POSIX.") + "common, Django, MySQL, Postgres, and POSIX.") print_mapping(UBUNTU_MAPPINGS, excludes=exclude_from_ubuntu) diff --git a/docs/source/_data/cloc.csv b/docs/source/_data/cloc.csv index f9173c7..03e375f 100644 --- a/docs/source/_data/cloc.csv +++ b/docs/source/_data/cloc.csv @@ -1,3 +1,3 @@ files,language,blank,comment,code -21,Python,928,813,1516 -21,SUM,928,813,1516 +22,Python,998,887,1639 +22,SUM,998,887,1639 diff --git a/docs/source/_includes/overlays.rst b/docs/source/_includes/overlays.rst index ce2d34c..f99d3ec 100644 --- a/docs/source/_includes/overlays.rst +++ b/docs/source/_includes/overlays.rst @@ -196,6 +196,172 @@ Apply database migrations. django.migrate: venv: None +MySQL +===== + +MySQL commands. + +mysql.create +------------ + +Create a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- owner (str): The owner (user/role name) of the new database. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.create command] + mysql.create: database + host: localhost + owner: None + password: None + port: 3306 + user: root + +mysql.drop +---------- + +Drop (remove) a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.drop command] + mysql.drop: database + host: localhost + password: None + port: 3306 + user: root + +mysql.dump +---------- + +Dump (export) a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.dump command] + mysql.dump: database + file_name: None + host: localhost + inserts: False + password: None + port: 3306 + user: root + +mysql.exists +------------ + +Determine if a MySQL database exists. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.exists command] + mysql.exists: database + host: localhost + password: None + port: 3306 + user: root + +mysql.grant +----------- + +Grant privileges to a user. + +- to (str): The user name to which privileges are granted. +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- privileges (str): The privileges to be granted. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.grant command] + mysql.grant: to + database: None + host: localhost + password: None + port: 3306 + privileges: ALL + user: root + +mysql.sql +--------- + +Execute a MySQL statement. + +- sql (str): The SQL to run. +- database (str): The name of the database. +- host (str): The host name. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.sql command] + mysql.sql: sql + database: default + host: localhost + password: None + port: 3306 + user: root + +mysql.user +---------- + +Work with a MySQL user. + +- name (str): The user name. +- host (str): The host name. +- op (str): The operation to perform: ``create``, ``drop``, ``exists``. +- passwd (str): The password for a new user. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.user command] + mysql.user: name + host: localhost + op: create + passwd: None + password: None + port: 3306 + user: root + Postgres ======== @@ -910,7 +1076,7 @@ Write to a file. Cent OS ======= -The Cent OS overlay incorporates commands specific to that platform as well as commands from common, Django, Postgres, and POSIX. +The Cent OS overlay incorporates commands specific to that platform as well as commands from common, Django, MySQL, Postgres, and POSIX. apache ------ @@ -938,6 +1104,167 @@ Install a system-level package. [run install command] install: name +mysql.create +------------ + +Create a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- owner (str): The owner (user/role name) of the new database. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.create command] + mysql.create: database + host: localhost + owner: None + password: None + port: 3306 + user: root + +mysql.drop +---------- + +Drop (remove) a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.drop command] + mysql.drop: database + host: localhost + password: None + port: 3306 + user: root + +mysql.dump +---------- + +Dump (export) a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.dump command] + mysql.dump: database + file_name: None + host: localhost + inserts: False + password: None + port: 3306 + user: root + +mysql.exists +------------ + +Determine if a MySQL database exists. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.exists command] + mysql.exists: database + host: localhost + password: None + port: 3306 + user: root + +mysql.grant +----------- + +Grant privileges to a user. + +- to (str): The user name to which privileges are granted. +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- privileges (str): The privileges to be granted. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.grant command] + mysql.grant: to + database: None + host: localhost + password: None + port: 3306 + privileges: ALL + user: root + +mysql.sql +--------- + +Execute a MySQL statement. + +- sql (str): The SQL to run. +- database (str): The name of the database. +- host (str): The host name. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.sql command] + mysql.sql: sql + database: default + host: localhost + password: None + port: 3306 + user: root + +mysql.user +---------- + +Work with a MySQL user. + +- name (str): The user name. +- host (str): The host name. +- op (str): The operation to perform: ``create``, ``drop``, ``exists``. +- passwd (str): The password for a new user. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.user command] + mysql.user: name + host: localhost + op: create + passwd: None + password: None + port: 3306 + user: root + reload ------ @@ -1058,7 +1385,7 @@ Create or remove a user. Ubuntu ====== -The Ubuntu overlay incorporates commands specific to that platform as well as commands from common, Django, Postgres, and POSIX. +The Ubuntu overlay incorporates commands specific to that platform as well as commands from common, Django, MySQL, Postgres, and POSIX. apache ------ @@ -1137,6 +1464,167 @@ Install a system-level package. [run install command] install: name +mysql.create +------------ + +Create a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- owner (str): The owner (user/role name) of the new database. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.create command] + mysql.create: database + host: localhost + owner: None + password: None + port: 3306 + user: root + +mysql.drop +---------- + +Drop (remove) a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.drop command] + mysql.drop: database + host: localhost + password: None + port: 3306 + user: root + +mysql.dump +---------- + +Dump (export) a MySQL database. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.dump command] + mysql.dump: database + file_name: None + host: localhost + inserts: False + password: None + port: 3306 + user: root + +mysql.exists +------------ + +Determine if a MySQL database exists. + +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.exists command] + mysql.exists: database + host: localhost + password: None + port: 3306 + user: root + +mysql.grant +----------- + +Grant privileges to a user. + +- to (str): The user name to which privileges are granted. +- database (str): The database name. +- host (str): The database host name or IP address. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number of the MySQL service running on the host. +- privileges (str): The privileges to be granted. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.grant command] + mysql.grant: to + database: None + host: localhost + password: None + port: 3306 + privileges: ALL + user: root + +mysql.sql +--------- + +Execute a MySQL statement. + +- sql (str): The SQL to run. +- database (str): The name of the database. +- host (str): The host name. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.sql command] + mysql.sql: sql + database: default + host: localhost + password: None + port: 3306 + user: root + +mysql.user +---------- + +Work with a MySQL user. + +- name (str): The user name. +- host (str): The host name. +- op (str): The operation to perform: ``create``, ``drop``, ``exists``. +- passwd (str): The password for a new user. +- password (str): The password for the user with sufficient access privileges to execute the command. +- port (int): The TCP port number. +- user (str): The name of the user with sufficient access privileges to execute the command. + + +.. code-block:: ini + + [run mysql.user command] + mysql.user: name + host: localhost + op: create + passwd: None + password: None + port: 3306 + user: root + reload ------ diff --git a/scripttease/cli/__init__.py b/scripttease/cli/__init__.py index 7b85f70..c131441 100644 --- a/scripttease/cli/__init__.py +++ b/scripttease/cli/__init__.py @@ -3,7 +3,7 @@ from argparse import ArgumentParser, RawDescriptionHelpFormatter from commonkit.logging import LoggingHelper from ..constants import LOGGER_NAME -from ..version import VERSION +from ..version import DATE as VERSION_DATE, VERSION from . import initialize from . import subcommands @@ -19,7 +19,7 @@ def main_command(): """Process script configurations.""" __author__ = "Shawn Davis " - __date__ = "2020-07-23" + __date__ = VERSION_DATE __help__ = """NOTES This command is used to parse configuration files and output the commands. diff --git a/scripttease/library/overlays/centos.py b/scripttease/library/overlays/centos.py index 9c87002..8c4af5c 100644 --- a/scripttease/library/overlays/centos.py +++ b/scripttease/library/overlays/centos.py @@ -4,6 +4,7 @@ from commonkit import split_csv from ..commands import Command, Template from .common import COMMON_MAPPINGS from .django import DJANGO_MAPPINGS +from .mysql import MYSQL_MAPPINGS from .pgsql import PGSQL_MAPPINGS from .posix import POSIX_MAPPINGS, Function @@ -275,5 +276,6 @@ MAPPINGS = { MAPPINGS.update(COMMON_MAPPINGS) MAPPINGS.update(DJANGO_MAPPINGS) +MAPPINGS.update(MYSQL_MAPPINGS) MAPPINGS.update(PGSQL_MAPPINGS) MAPPINGS.update(POSIX_MAPPINGS) diff --git a/scripttease/library/overlays/mysql.py b/scripttease/library/overlays/mysql.py new file mode 100644 index 0000000..8461532 --- /dev/null +++ b/scripttease/library/overlays/mysql.py @@ -0,0 +1,262 @@ +# Imports + +from ..commands import Command + +# Exports + +__all__ = ( + "MYSQL_MAPPINGS", + "mysql_create", + "mysql_drop", + "mysql_dump", + "mysql_exec", + "mysql_exists", + "mysql_grant", + "mysql_user", +) + +# Functions + + +def _get_mysql_command(host="localhost", name="mysql", password=None, port=3306, user="root"): + a = list() + a.append("%s --user=%s" % (name, user)) + a.append("--host=%s" % host) + a.append("--port=%s" % port) + + if password: + a.append('--password="%s"' % password) + + return a + + +def mysql_create(database, host="localhost", owner=None, password=None, port=3306, user="root", **kwargs): + """Create a MySQL database. + + - database (str): The database name. + - host (str): The database host name or IP address. + - password (str): The password for the user with sufficient access privileges to execute the command. + - owner (str): The owner (user/role name) of the new database. + - port (int): The TCP port number of the MySQL service running on the host. + - user (str): The name of the user with sufficient access privileges to execute the command. + + """ + kwargs.setdefault("comment", "create the %s mysql database" % database) + + # MySQL commands always run without sudo because the --user may be provided. + kwargs['sudo'] = False + + # Assemble the command. + a = _get_mysql_command(host=host, name="mysqladmin", password=password, port=port, user=user) + a.append("create %s" % database) + + if owner: + grant = mysql_grant( + owner, + database=database, + host=host, + password=password, + port=port, + user=user, + ) + a.append("&& %s" % grant.get_statement(suppress_comment=True)) + + return Command(" ".join(a), **kwargs) + + +def mysql_drop(database, host="localhost", password=None, port=3306, user="root", **kwargs): + """Drop (remove) a MySQL database. + + - database (str): The database name. + - host (str): The database host name or IP address. + - password (str): The password for the user with sufficient access privileges to execute the command. + - port (int): The TCP port number of the MySQL service running on the host. + - user (str): The name of the user with sufficient access privileges to execute the command. + + """ + kwargs.setdefault("comment", "remove the %s mysql database" % database) + + # MySQL commands always run without sudo because the --user may be provided. + kwargs['sudo'] = False + + # Assemble the command. + a = _get_mysql_command(host=host, name="mysqladmin", password=password, port=port, user=user) + a.append("drop %s" % database) + + return Command(" ".join(a), **kwargs) + + +def mysql_dump(database, file_name=None, host="localhost", inserts=False, password=None, port=3306, user="root", + **kwargs): + """Dump (export) a MySQL database. + + - database (str): The database name. + - host (str): The database host name or IP address. + - password (str): The password for the user with sufficient access privileges to execute the command. + - port (int): The TCP port number of the MySQL service running on the host. + - user (str): The name of the user with sufficient access privileges to execute the command. + + """ + kwargs.setdefault("comment", "dump the %s mysql database" % database) + + # MySQL commands always run without sudo because the --user may be provided. + # kwargs['sudo'] = False + + # Assemble the command. + a = _get_mysql_command(host=host, name="mysqldump", password=password, port=port, user=user) + + # if data_only: + # a.append("--no-create-info") + # elif schema_only: + # a.append("--no-data") + # else: + # pass + + if inserts: + a.append("--complete-inserts") + + a.append(database) + + _file_name = file_name or "%s.sql" % database + a.append("> %s" % _file_name) + + return Command(" ".join(a), **kwargs) + + +def mysql_exec(sql, database="default", host="localhost", password=None, port=3306, user="root", **kwargs): + """Execute a MySQL statement. + + - sql (str): The SQL to run. + - database (str): The name of the database. + - host (str): The host name. + - password (str): The password for the user with sufficient access privileges to execute the command. + - port (int): The TCP port number. + - user (str): The name of the user with sufficient access privileges to execute the command. + + """ + kwargs['sudo'] = False + kwargs.setdefault("comment", "execute mysql statement") + + a = _get_mysql_command(host=host, password=password, port=port, user=user) + a.append('--execute="%s"' % sql) + a.append(database) + + return Command(" ".join(a), **kwargs) + + +def mysql_exists(database, host="localhost", password=None, port=3306, user="root", **kwargs): + """Determine if a MySQL database exists. + + - database (str): The database name. + - host (str): The database host name or IP address. + - password (str): The password for the user with sufficient access privileges to execute the command. + - port (int): The TCP port number of the MySQL service running on the host. + - user (str): The name of the user with sufficient access privileges to execute the command. + + """ + kwargs.setdefault("comment", "determine if the %s mysql database exists" % database) + kwargs.setdefault("register", "mysql_database_exists") + + # MySQL commands always run without sudo because the --user may be provided. + kwargs['sudo'] = False + + # Assemble the command. + a = _get_mysql_command(host=host, password=password, port=port, user=user) + + sql = "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '%s'" % database + a.append('--execute="%s"' % sql) + + return Command(" ".join(a), **kwargs) + + +def mysql_grant(to, database=None, host="localhost", password=None, port=3306, privileges="ALL", user="root", **kwargs): + """Grant privileges to a user. + + - to (str): The user name to which privileges are granted. + - database (str): The database name. + - host (str): The database host name or IP address. + - password (str): The password for the user with sufficient access privileges to execute the command. + - port (int): The TCP port number of the MySQL service running on the host. + - privileges (str): The privileges to be granted. + - user (str): The name of the user with sufficient access privileges to execute the command. + + """ + kwargs.setdefault("comment", "grant mysql privileges to %s" % to) + + a = _get_mysql_command(host=host, password=password, port=port, user=user) + + # See https://dev.mysql.com/doc/refman/5.7/en/grant.html + _database = database or "*" + sql = "GRANT %(privileges)s ON %(database)s.* TO '%(user)s'@'%(host)s'" % { + 'database': _database, + 'host': host, + 'privileges': privileges, + 'user': to, + } + a.append('--execute="%s"' % sql) + + return Command(" ".join(a)) + + +def mysql_user(name, host="localhost", op="create", passwd=None, password=None, port=3306, user="root", **kwargs): + """Work with a MySQL user. + + - name (str): The user name. + - host (str): The host name. + - op (str): The operation to perform: ``create``, ``drop``, ``exists``. + - passwd (str): The password for a new user. + - password (str): The password for the user with sufficient access privileges to execute the command. + - port (int): The TCP port number. + - user (str): The name of the user with sufficient access privileges to execute the command. + + """ + kwargs['sudo'] = False + if op == "create": + kwargs.setdefault("comment", "create %s mysql user" % name) + + a = _get_mysql_command(host=host, password=password, port=port, user=user) + sql = "CREATE USER IF NOT EXISTS '%(user)s'@'%(host)s'" % { + 'host': host, + 'user': name, + } + if passwd: + sql += " IDENTIFIED BY PASSWORD('%s')" % passwd + + a.append('--execute="%s"' % sql) + + return Command(" ".join(a), **kwargs) + elif op == "drop": + kwargs.setdefault("comment", "drop %s mysql user" % name) + + a = _get_mysql_command(host=host, password=password, port=port, user=user) + + sql = "DROP USER IF EXISTS '%(user)s'@'%(host)s'" % { + 'host': host, + 'user': name, + } + a.append('--execute="%s"' % sql) + + return Command(" ".join(a), **kwargs) + elif op == "exists": + kwargs.setdefault("comment", "determine if %s mysql user exists" % name) + kwargs.setdefault("register", "mysql_user_exists") + + a = _get_mysql_command(host=host, password=password, port=port, user=user) + + sql = "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '%s')" % name + a.append('--execute="%s"' % sql) + + return Command(" ".join(a), **kwargs) + else: + raise NameError("Unrecognized or unsupported MySQL user operation: %s" % op) + + +MYSQL_MAPPINGS = { + 'mysql.create': mysql_create, + 'mysql.drop': mysql_drop, + 'mysql.dump': mysql_dump, + 'mysql.exists': mysql_exists, + 'mysql.grant': mysql_grant, + 'mysql.sql': mysql_exec, + 'mysql.user': mysql_user, +} diff --git a/scripttease/library/overlays/ubuntu.py b/scripttease/library/overlays/ubuntu.py index 7083c0a..093ab05 100644 --- a/scripttease/library/overlays/ubuntu.py +++ b/scripttease/library/overlays/ubuntu.py @@ -4,6 +4,7 @@ from commonkit import split_csv from ..commands import Command, Template from .common import COMMON_MAPPINGS from .django import DJANGO_MAPPINGS +from .mysql import MYSQL_MAPPINGS from .pgsql import PGSQL_MAPPINGS from .posix import POSIX_MAPPINGS, Function @@ -332,5 +333,6 @@ MAPPINGS = { MAPPINGS.update(COMMON_MAPPINGS) MAPPINGS.update(DJANGO_MAPPINGS) +MAPPINGS.update(MYSQL_MAPPINGS) MAPPINGS.update(PGSQL_MAPPINGS) MAPPINGS.update(POSIX_MAPPINGS) diff --git a/scripttease/version.py b/scripttease/version.py index 20cfe1e..3d6fa39 100644 --- a/scripttease/version.py +++ b/scripttease/version.py @@ -1,4 +1,5 @@ -VERSION = "6.4.3-d" -major = 6 -minor = 4 -patch = 3 +DATE = "2020-09-17" +VERSION = "6.4.4-d" +MAJOR = 6 +MINOR = 4 +PATCH = 4 diff --git a/tests/test_library_overlays_mysql.py b/tests/test_library_overlays_mysql.py new file mode 100644 index 0000000..a5cdcca --- /dev/null +++ b/tests/test_library_overlays_mysql.py @@ -0,0 +1,76 @@ +import pytest +from scripttease.library.overlays.mysql import * + + +def test_mysql_create(): + c = mysql_create("testing", owner="bob", password="P455W0rD") + s = c.get_statement() + assert "mysqladmin" in s + assert '--password="P455W0rD"' in s + assert "--host=" in s + assert "--port=" in s + assert "create testing" in s + assert '--execute="GRANT ALL ON testing.* TO \'bob\'@\'localhost\'"' in s + + +def test_mysql_drop(): + c = mysql_drop("testing") + s = c.get_statement() + assert "mysqladmin" in s + assert "drop testing" in s + + +def test_mysql_dump(): + c = mysql_dump("testing", inserts=True) + s = c.get_statement() + assert "mysqldump" in s + assert "--complete-inserts" in s + assert "> testing.sql" in s + + +def test_mysql_exec(): + c = mysql_exec("SELECT * FROM projects", database="testing") + s = c.get_statement() + assert "mysql" in s + assert "--execute=" in s + assert '"SELECT * FROM projects"' in s + + +def test_mysql_exists(): + c = mysql_exists("testing") + s = c.get_statement() + assert "mysql" in s + assert "mysql_database_exists" in s + + +def test_mysql_grant(): + c = mysql_grant("bob", database="testing") + s = c.get_statement() + assert "mysql" in s + assert "GRANT" in s + assert "testing.*" in s + assert "'bob'@'localhost'" in s + + +def test_mysql_user(): + c = mysql_user("bob", passwd="secret") + s = c.get_statement() + assert "mysql" in s + assert "CREATE USER IF NOT EXISTS" in s + assert "'bob'@'localhost'" in s + assert "IDENTIFIED BY PASSWORD('secret')" in s + + c = mysql_user("bob", op="drop", passwd="secret") + s = c.get_statement() + assert "mysql" in s + assert "DROP USER IF EXISTS" in s + assert "'bob'@'localhost'" in s + + c = mysql_user("bob", op="exists", passwd="secret") + s = c.get_statement() + assert "mysql" in s + assert "mysql_user_exists" in s + assert "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = 'bob')" in s + + with pytest.raises(NameError): + mysql_user("bob", op="nonexistent")