Files
@ 29e10c6a1551
Branch filter:
Location: rattail-project/rattail/rattail/fablib/mysql.py
29e10c6a1551
6.0 KiB
text/x-python
Add email attachment MIME type for MS Word .doc files
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | # -*- coding: utf-8; -*-
################################################################################
#
# Rattail -- Retail Software Framework
# Copyright © 2010-2018 Lance Edgar
#
# This file is part of Rattail.
#
# Rattail is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# Rattail. If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
"""
Fabric Library for MySQL
"""
from __future__ import unicode_literals, absolute_import
from fabric.api import sudo, hide, get, put, abort, local, run, settings
from fabric.contrib.files import sed
from rattail.fablib import apt, make_deploy
deploy = make_deploy(__file__)
def install(password):
"""
Install the MySQL database service
"""
deploy('mysql/debconf.mako', 'debconf', context={'password': password})
sudo('debconf-set-selections debconf')
sudo('rm debconf')
apt.install('mysql-server')
deploy('mysql/my.cnf.mako', '/root/.my.cnf', mode='0600', context={'password': password})
def is_mariadb():
"""
Returns boolean indicating if MySQL server is actually MariaDB.
"""
with settings(warn_only=True):
result = run('mysql --version')
if result.failed:
return False
if "MariaDB" in result:
return True
return False
def restart():
"""
Restart the MySQL database service
"""
sudo('service mysql restart')
def set_bind_address(address):
"""
Configure the 'bind-address' setting with the given value.
"""
sed('/etc/mysql/my.cnf', '^bind-address.*', 'bind-address = {}'.format(address), use_sudo=True)
def user_exists(name, host='localhost'):
"""
Determine if a given MySQL user exists.
"""
user = sql("SELECT User FROM user WHERE User = '{0}' and Host = '{1}'".format(name, host), database='mysql')
return user == name
def create_user(name, host='localhost', password=None, checkfirst=True):
"""
Create a MySQL user account.
"""
if not checkfirst or not user_exists(name, host):
sql("CREATE USER '{0}'@'{1}';".format(name, host))
if password:
with hide('running'):
sql("SET PASSWORD FOR '{0}'@'{1}' = PASSWORD('{2}');".format(
name, host, password))
def drop_user(name, host='localhost'):
"""
Drop a MySQL user account.
"""
sql("drop user '{0}'@'{1}'".format(name, host))
def db_exists(name):
"""
Determine if a given MySQL database exists.
"""
db = sql("SELECT SCHEMA_NAME FROM SCHEMATA WHERE SCHEMA_NAME = '{0}'".format(name), database='information_schema')
return db == name
def table_exists(name, database):
"""
Determine if a given table exists within the given MySQL database.
"""
table = sql("SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA = '{0}' AND TABLE_NAME = '{1}'".format(database, name), database='information_schema')
return table == name
def create_db(name, checkfirst=True, user=None):
"""
Create a MySQL database.
"""
if not checkfirst or not db_exists(name):
sudo('mysqladmin create {0}'.format(name))
if user:
grant_access(name, user)
def drop_db(name, checkfirst=True):
"""
Drop a MySQL database.
"""
if not checkfirst or db_exists(name):
sudo('mysqladmin drop --force {0}'.format(name))
def grant_access(dbname, username):
"""
Grant full access to the given database for the given user. Note that the
username should be given in MySQL's native format, e.g. 'myuser@localhost'.
"""
sql('grant all on `{0}`.* to {1}'.format(dbname, username))
def sql(sql, database=''):
"""
Execute some SQL.
"""
# some crazy quoting required here, see also
# http://stackoverflow.com/a/1250279
sql = sql.replace("'", "'\"'\"'")
return sudo("mysql --execute='{}' --batch --skip-column-names {}".format(sql, database))
def download_db(name, destination=None):
"""
Download a database from the "current" server.
"""
if destination is None:
destination = './{0}.sql.gz'.format(name)
sudo('mysqldump --result-file={0}.sql {0}'.format(name))
sudo('gzip --force {0}.sql'.format(name))
get('{0}.sql.gz'.format(name), destination)
sudo('rm {0}.sql.gz'.format(name))
def restore_db(name, source=None, user=None):
"""
Upload and restore a database to the current server
"""
if not source:
source = '{}.sql.gz'.format(name)
put(source, '{}.sql.gz'.format(name))
sudo('gunzip --force {}.sql.gz'.format(name))
drop_db(name)
create_db(name, user=user)
sudo('mysql --execute="source {0}.sql" {0}'.format(name))
sudo('rm {}.sql'.format(name))
def clone_db(name, download, user='rattail', force=False):
"""
Clone a MySQL database from a (presumably live) server
:param name: Name of the database.
:param force: Whether the target database should be forcibly dropped, if it
exists already.
"""
if db_exists(name):
if force:
drop_db(name, checkfirst=False)
else:
abort("Database '{}' already exists! (pass force=true to override)".format(name))
create_db(name, checkfirst=False)
# obtain database dump from live server
download('{}.sql.gz'.format(name), user=user)
# upload database dump to target server
put('{}.sql.gz'.format(name))
local('rm {}.sql.gz'.format(name))
# restore database on target server
run('gunzip --force {}.sql.gz'.format(name))
sudo('mysql {0} < {0}.sql'.format(name))
run('rm {}.sql'.format(name))
|