"""
MySQL
=====

This module provides high-level tools for installing a MySQL server
and creating MySQL users and databases.

"""

from fabric.api import hide, prompt, settings

from fabtools.mysql import (
    create_database,
    create_user,
    database_exists,
    user_exists,
)
from fabtools.system import UnsupportedFamily, distrib_family

from fabtools.require.service import started


def server(version=None, password=None):
    """
    Require a MySQL server to be installed and running.

    Example::

        from fabtools import require

        require.mysql.server(password='s3cr3t')

    """
    family = distrib_family()
    if family == 'debian':
        _server_debian(version, password)
    else:
        raise UnsupportedFamily(supported=['debian'])


def _server_debian(version, password):

    from fabtools.deb import is_installed, preseed_package
    from fabtools.require.deb import package as require_deb_package

    if version:
        pkg_name = 'mysql-server-%s' % version
    else:
        pkg_name = 'mysql-server'

    if not is_installed(pkg_name):
        if password is None:
            password = prompt('Please enter password for MySQL user "root":')

        with settings(hide('running')):
            preseed_package('mysql-server', {
                'mysql-server/root_password': ('password', password),
                'mysql-server/root_password_again': ('password', password),
            })

        require_deb_package(pkg_name)

    started('mysql')


def user(name, password, **kwargs):
    """
    Require a MySQL user.

    Extra arguments will be passed to :py:func:`fabtools.mysql.create_user`.

    Example::

        from fabric.api import settings
        from fabtools import require

        with settings(mysql_user='root', mysql_password='s3cr3t'):
            require.mysql.user('dbuser', 'somerandomstring')

    """
    if not user_exists(name, **kwargs):
        create_user(name, password, **kwargs)


def database(name, **kwargs):
    """
    Require a MySQL database.

    Extra arguments will be passed to :py:func:`fabtools.mysql.create_database`.

    Example::

        from fabric.api import settings
        from fabtools import require

        with settings(mysql_user='root', mysql_password='s3cr3t'):
            require.mysql.database('myapp', owner='dbuser')

    """
    if not database_exists(name, **kwargs):
        create_database(name, **kwargs)

@@ -124,16 +124,41 @@
 .%0A%0A%22%22%22%0A%0A
+from pipes import quote%0A%0A
 from fab
@@ -185,16 +185,21 @@
  prompt,
+ run,
  setting
@@ -289,16 +289,27 @@
 exists,%0A
+    query,%0A
     user
@@ -380,16 +380,55 @@
 b_family
+%0Afrom fabtools.utils import run_as_root
 %0A%0Afrom f
@@ -783,16 +783,87 @@
 ssword)%0A
+    elif family == 'redhat':%0A        _server_redhat(version, password)%0A
     else
@@ -915,16 +915,26 @@
 'debian'
+, 'redhat'
 %5D)%0A%0A%0Adef
@@ -1655,24 +1655,968 @@
 ('mysql')%0A%0A%0A
+def _server_redhat(version, password):%0A%0A    from fabtools.require.rpm import package as require_rpm_package%0A%0A    require_rpm_package('mysql-server')%0A    run_as_root('chkconfig --levels 235 mysqld on')%0A    run_as_root('service mysqld start')%0A    _require_root_password(password)%0A%0A%0Adef _require_root_password(password):%0A    quoted_password = quote(password)%0A    if not _is_root_password_set(quoted_password):%0A        _set_root_password(quoted_password)%0A%0A%0Adef _is_root_password_set(quoted_password):%0A    cmd = 'mysql --user=root --password=%7Bpassword%7D --execute=%22select 1;%22'.format(password=quoted_password)%0A    res = run(cmd, quiet=True)%0A    return res.succeeded%0A%0A%0Adef _set_root_password(quoted_password):%0A    run('/usr/bin/mysqladmin --user=root password %7Bpassword%7D'.format(password=quoted_password))%0A    run('/usr/bin/mysqladmin --user=root --password=%7Bpassword%7D -h localhost.localdomain password %7Bpassword%7D'.format(password=quoted_password))%0A%0A%0A
 def user(nam

Add RedHat support for MySQL [#197]