import unittest

from mygrations.formats.mysql.file_reader.create_parser import create_parser
class test_table_difference(unittest.TestCase):
    def _get_parsers(self):
        a = create_parser()
        a.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id)
            );
        """
        )

        b = create_parser()
        b.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id),
            KEY tasks_account_id (account_id),
            KEY task (task,account_id)
            );
        """
        )

        return (a, b)

    def test_drop_keys(self):
        (a, b) = self._get_parsers()

        # if we subtract b from a we should get some drop column queries in one alter statement
        operations = b.to(a)
        self.assertEquals(1, len(operations))
        self.assertEquals('ALTER TABLE `tasks` DROP KEY `tasks_account_id`, DROP KEY `task`;', str(operations[0]))

    def test_add_keys(self):
        (a, b) = self._get_parsers()

        # if we subtract b from a we should get some drop column queries in one alter statement
        operations = a.to(b)
        self.assertEquals(1, len(operations))
        self.assertEquals(
            'ALTER TABLE `tasks` ADD KEY `tasks_account_id` (`account_id`), ADD KEY `task` (`task`,`account_id`);',
            str(operations[0])
        )

    def test_change_keys(self):
        a = create_parser()
        a.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id),
            KEY tasks_account_id (account_id)
            );
        """
        )

        b = create_parser()
        b.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id),
            KEY tasks_account_id (account_id,id,task)
            );
        """
        )

        # if we subtract b from a we should get some drop column queries in one alter statement
        operations = a.to(b)
        self.assertEquals(1, len(operations))
        self.assertEquals(
            'ALTER TABLE `tasks` DROP KEY `tasks_account_id`, ADD KEY `tasks_account_id` (`account_id`,`id`,`task`);',
            str(operations[0])
        )

    def test_add_remove_change(self):
        a = create_parser()
        a.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id),
            KEY unchanged (task),
            KEY tasks_task (task),
            KEY tasks_account_id (account_id)
            );
        """
        )

        b = create_parser()
        b.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id),
            KEY unchanged (task),
            KEY task_id (task,id),
            KEY tasks_account_id (account_id,id,task)
            );
        """
        )

        # if we subtract b from a we should get some drop column queries in one alter statement
        operations = a.to(b)
        self.assertEquals(1, len(operations))
        self.assertEquals(
            'ALTER TABLE `tasks` ADD KEY `task_id` (`task`,`id`), DROP KEY `tasks_task`, DROP KEY `tasks_account_id`, ADD KEY `tasks_account_id` (`account_id`,`id`,`task`);',
            str(operations[0])
        )

    def test_unique_keys(self):
        a = create_parser()
        a.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id),
            UNIQUE KEY unchanged (account_id),
            UNIQUE KEY uniq_account_id (account_id),
            unique key uniq_task (task)
            );
        """
        )

        b = create_parser()
        b.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id),
            UNIQUE KEY unchanged (account_id),
            UNIQUE KEY uniq_account_id (account_id,id),
            unique key added (task)
            );
        """
        )

        operations = a.to(b)
        self.assertEquals(1, len(operations))
        self.assertEquals(
            'ALTER TABLE `tasks` ADD UNIQUE KEY `added` (`task`), DROP KEY `uniq_task`, DROP KEY `uniq_account_id`, ADD UNIQUE KEY `uniq_account_id` (`account_id`,`id`);',
            str(operations[0])
        )

    def test_primary_key(self):
        a = create_parser()
        a.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL
            );
        """
        )

        b = create_parser()
        b.parse(
            """CREATE TABLE `tasks` (
            `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
            `account_id` int(10) DEFAULT NULL,
            `task` varchar(255) DEFAULT NULL,
            PRIMARY KEY (id)
            );
        """
        )

        operations = a.to(b)
        self.assertEquals(1, len(operations))
        self.assertEquals('ALTER TABLE `tasks` ADD PRIMARY KEY (`id`);', str(operations[0]))

        operations = b.to(a)
        self.assertEquals(1, len(operations))
        self.assertEquals('ALTER TABLE `tasks` DROP PRIMARY KEY;', str(operations[0]))
