Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

Commit

Permalink
Getting the mysql tests to cleanup, on par w/ sqlite3
Browse files Browse the repository at this point in the history
  • Loading branch information
vegitron committed Mar 13, 2015
1 parent 17f39ee commit 11534ae
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 4 deletions.
11 changes: 11 additions & 0 deletions sqlshare_rest/backend/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ def create_db_user(self, username, password):
def create_db_schema(self, username, schema):
self._not_implemented("create_db_schema")

def remove_db_user(self, db_username):
self._not_implemented("remove_db_user")

def remove_schema(self, schema):
self._not_implemented("remove_schema")

def remove_user(self, username):
model = User.objects.get(username=username)
self.remove_db_user(model.db_username)
self.remove_schema(model.schema)

def _not_implemented(self, message):
raise NotImplementedError("%s not implemented in %s" % (message, self))

Expand Down
61 changes: 60 additions & 1 deletion sqlshare_rest/backend/mysql.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,64 @@
from sqlshare_rest.backend.base import DBInterface
from sqlshare_rest.models import User
from django.db import connection
import re
import md5

# grant create user on *.* to <user>
# grant create on *.* to <user>
# grant drop on *.* to <user>


class MySQLBackend(DBInterface):
pass
def create_db_user(self, username, password):
cursor = connection.cursor()
cursor.execute("CREATE USER %s IDENTIFIED BY %s", (username, password))
return

def get_db_username(self, user):
# MySQL only allows 16 character names. Take the md5sum of the
# username, and hope it's unique enough.
test_value = "meta_%s" % (md5.new(user).hexdigest()[:11])

try:
existing = User.objects.get(db_username=test_value)
msg = "Hashed DB Username already exists! " \
"Existing: %s, New: %s" % (exists.username, user)
raise Exception(msg)

except User.DoesNotExist:
# Perfect!
pass

return test_value

def get_db_schema(self, user):
# stripped down schema name - prevent quoting issues
return re.sub('[^a-zA-Z0-9]', '_', user)

# Maybe this could become separate files at some point?
def create_db_schema(self, username, schema):
cursor = connection.cursor()
# MySQL doesn't allow placeholders on the db name here.
# This is protected by the get_db_schema method, which only allows
# a-z, 0-9, and _.
cursor.execute("CREATE DATABASE %s" % schema)

def remove_db_user(self, user):
cursor = connection.cursor()
# MySQL doesn't let the username be a placeholder in DROP USER.
cursor.execute("DROP USER %s" % (user))
return

def remove_schema(self, schema):
cursor = connection.cursor()
# MySQL doesn't allow placeholders on the db name here.
# This is protected by the get_db_schema method, which only allows
# a-z, 0-9, and _.
schema = self.get_db_schema(schema)
cursor.execute("DROP DATABASE %s" % schema)

def run_query(self, sql, username):
cursor = connection.cursor()
cursor.execute(sql)
return cursor.fetchall()
2 changes: 1 addition & 1 deletion sqlshare_rest/backend/sqlite3.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def create_db_user(self, username, password):
return

# Maybe this could become separate files at some point?
def create_db_schema(self, username, password):
def create_db_schema(self, db_username, schema_name):
return

def run_query(self, sql, username):
Expand Down
4 changes: 2 additions & 2 deletions sqlshare_rest/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
class User(models.Model):
""" A cached reference to a database user """
username = models.CharField(max_length=200, db_index=True, unique=True)
schema = models.CharField(max_length=200)
db_username = models.CharField(max_length=250)
schema = models.CharField(max_length=200, unique=True)
db_username = models.CharField(max_length=250, db_index=True, unique=True)
# db_password = EncryptedCharField(max_length=200)
db_password = models.CharField(max_length=200)

Expand Down
26 changes: 26 additions & 0 deletions sqlshare_rest/test/backend/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,31 @@
class TestMySQLBackend(TestCase):

def test_create_user(self):
self.remove_users.append("test_user_tcu1")
backend = get_backend()
user = backend.get_user("test_user_tcu1")

def test_run_query(self):
self.remove_users.append("test_user_trq1")
backend = get_backend()
user = backend.get_user("test_user_trq1")
result = backend.run_query("select (5)", user)
self.assertEquals(len(result), 1)
self.assertEquals(result[0][0], 5)

result = backend.run_query('select (10) union select ("a")', user)
self.assertEquals(len(result), 2)
self.assertEquals(result[0][0], '10')
self.assertEquals(result[1][0], "a")

def setUp(self):
self.remove_users = []

def tearDown(self):
backend = get_backend()

for user in self.remove_users:
try:
backend.remove_user(user)
except Exception as ex:
print "Error deleting user: ", ex

0 comments on commit 11534ae

Please sign in to comment.