class DatabaseUtilities(object):

    def __init__(self):
        self.db_instance = config.get_database_instance()
        self.db_create = DatabaseCreate()
    
    def delete_all_tables(self):
        """ Used only for unit tests. It was put here so the database itself did not have distructive code in it """
        for table in self.db_instance.get_table_names():
            self.delete_table(table)
        self.db_instance.commit()
        
    def delete_table(self, table):
        self.db_instance.execute('DROP TABLE %s' % table)

    def create_some_test_well_royalty_masters(self):
        if 'WellRoyaltyMaster' not in self.db_instance.get_table_names():
            self.db_create.well_royalty_master()
            
        statement = """
            INSERT INTO WellRoyaltyMaster VALUES(1, '2010-01-01 00:00:00', '9999-12-31 23:59:59.000005',
                'SKWI111062705025W300','SK','Oil','res1','New Oil', 'Heavy', 0, '2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'HORIZONTAL','Some Note');
            INSERT INTO WellRoyaltyMaster VALUES(2, '2011-11-01 00:00:00', '9999-12-31 23:59:59.000005',
                'SKWI112062705025W300','SK','Oil','res1','Third Tier Oil', 'Southwest',0,'2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'HORIZONTAL','Some Note');
            INSERT INTO WellRoyaltyMaster VALUES(3, '2004-10-01 00:00:00', '9999-12-31 23:59:59.000005',
                'SKWI113062705025W300','SK','Oil','res1','Fourth Tier Oil','Other', 0,'2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'VERTICAL','Some Note');
            INSERT INTO WellRoyaltyMaster VALUES(4, '2013-01-01 00:00:00', '2016-12-31 23:59:59.000005',
                'SKWI114062705025W300','SK','Oil','res1','Old Oil', 'Other', 0,'2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'VERTICAL','Some Note');
        """
        
        self.db_instance.execute_statement(statement)

    def create_some_test_lease_royalty_masters(self):
        if 'LeaseRoyaltyMaster' not in self.db_instance.get_table_names():
            self.db_create.lease_royalty_master()

        statement = """
            INSERT INTO LeaseRoyaltyMaster VALUES(1, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 'All',
            'SKProvCrownVar,GORR', 0.12, 0.02, 'SaskWellHead', 'Y', 'Y', 'Y',
            'mprod,250,2,300,3,400,4,500,5,0,6',
            NULL, 0, 50, 50, NULL)
        """

        self.db_instance.execute_statement(statement)

    def create_some_test_well_lease_link(self):
        if 'WellLeaseLink' not in self.db_instance.get_table_names():
            self.db_create.well_lease_link()
        statement = """
            INSERT INTO WellLeaseLink VALUES(1, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 1, 1, 1.0);
            INSERT INTO WellLeaseLink VALUES(2, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 2, 1, 1.0);
            INSERT INTO WellLeaseLink VALUES(3, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 3, 1, 1.0);
            INSERT INTO WellLeaseLink VALUES(4, '2001-01-08 00:00:00', '2015-01-01 00:00:00', 4, 1, 1.0);

        """

        self.db_instance.execute_statement(statement)

    def create_some_test_monthly(self):
        if 'Monthly' not in self.db_instance.get_table_names():
            self.db_create.monthly()

        statement = """
            INSERT INTO Monthly Values(4, '2015-09-29 00:00:00', 201501, 1,
                'OIL', 2, 740, 100, "Payor1", 100.0, 221.123456, 2.123455, 0.123455, 0.0);
            INSERT INTO Monthly Values(5, '2015-09-29 00:00:00', 201501, 4,
                'OIL', 2, 740, 100, "Payor1", 50.0, 221.123456, 2.123455, 0.123455, 0.0);
            INSERT INTO Monthly Values(6, '2015-09-29 00:00:00', 201501, 4,
                'OIL', 2, 740, 100, "Payor1", 50.0, 221.123456, 2.123455, 0.123455, 0.0);
        """
        self.db_instance.execute_statement(statement)

    def create_calc(self):
        if 'Calc' not in self.db_instance.get_table_names():
            self.db_create.calc()

    def create_some_test_leases(self):
        if 'Lease' not in self.db_instance.get_table_names():
            self.db_create.lease()
        statement = """
            INSERT INTO Lease VALUES(1,'2001-01-08 00:00:00', '2016-01-07 00:00:00', 'OL', 'SK', 7022, 123, NULL);
            INSERT INTO Lease VALUES(2,'1994-07-09 00:00:00', '2014-07-08 00:00:00', 'OL', 'SK', 7332, 123, NULL);
            INSERT INTO Lease VALUES(3,'1998-06-18 00:00:00', '2014-03-31 00:00:00', 'OL', 'SK', 7022, 123, NULL);
            INSERT INTO Lease VALUES(4,'1998-06-18 00:00:00', '2015-01-01 00:00:00', 'OL', 'SK', 7022, 123, NULL);
        """
        self.db_instance.execute_statement(statement)

    def create_some_test_econdata(self):
        if 'ECONdata' not in self.db_instance.get_table_names():
            self.db_create.econ_data()
        statement = """
            INSERT INTO ECONData VALUES(39,'Jan.',201501,181,223,262,
                0.0934,2.34,23.12,1734,21.73,502,27.11,626,0.1085,2.71,
                26.84,2013,32.38,747,38.94,899,0.1181,2.95,29.22,2192,35.58,821,40.54,936,52.3,1207);
        """
        self.db_instance.execute_statement(statement)

    def create_some_test_rtp_info(self):
        if 'RPTInfo' not in self.db_instance.get_table_names():
            self.db_create.rpt_info()
        statement = """
            insert into RTPInfo values (1, 'SKWI111062705025W300', 'OIL', '2001-01-08 00:00:00', '2016-01-07 00:00:00',
                'Payor1', 'MinOwership',100);
            insert into RTPInfo values (2, 'SKWI114062705025W300', 'OIL', '2001-01-08 00:00:00', '2016-01-07 00:00:00',
                'Payor1', 'MinOwership',100);
        """
        self.db_instance.execute_statement(statement)
class DatabaseUtilities(object):
    def __init__(self):
        self.db_instance = config.get_database_instance()
        self.db_create = DatabaseCreate()

    def table_exists(self, name):
        tables = self.db_instance.get_table_names()
        if name not in tables:
            return False
        return True

    def delete_all_tables(self):
        """ Used only for unit tests. It was put here so the database itself did not have distructive code in it """
        for table in self.db_instance.get_table_names():
            # print('!!! DELETING !!!')
            logging.info('Deleting table %s' % table)
            self.delete_table(table)
        self.db_instance.commit()

    def delete_table(self, table):
        self.db_instance.execute('DROP TABLE %s' % table)

    def create_some_test_well_royalty_masters(self):
        if 'WellRoyaltyMaster' not in self.db_instance.get_table_names():
            self.db_create.well_royalty_master()

        statement = """
            INSERT INTO WellRoyaltyMaster VALUES(1, '2010-01-01 00:00:00', '9999-12-31 23:59:59.000005',
                'SKWI111062705025W300','SK', NULL, 'Oil','res1','New', 'Heavy', 0, '2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'HORIZONTAL','Some Note');
            INSERT INTO WellRoyaltyMaster VALUES(2, '2011-11-01 00:00:00', '9999-12-31 23:59:59.000005',
                'SKWI112062705025W300','SK', NULL,'Oil','res1','Third Tier', 'Southwest',0,'2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'HORIZONTAL','Some Note');
            INSERT INTO WellRoyaltyMaster VALUES(3, '2004-10-01 00:00:00', '9999-12-31 23:59:59.000005',
                'SKWI113062705025W300','SK', NULL,'Oil','res1','Fourth Tier','Other', 0,'2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'VERTICAL','Some Note');
            INSERT INTO WellRoyaltyMaster VALUES(4, '2013-01-01 00:00:00', '2016-12-31 23:59:59.000005',
                'SKWI114062705025W300','SK', NULL,'Oil','res1','Old', 'Other', 0,'2014-12-01 00:00:00',1.0,
                '9999-12-31 23:59:59.000005', 'VERTICAL','Some Note');
        """

        self.db_instance.execute_statement(statement)

    def create_some_test_lease_royalty_masters(self):
        if 'LeaseRoyaltyMaster' not in self.db_instance.get_table_names():
            self.db_create.lease_royalty_master()

        statement = """
            INSERT INTO LeaseRoyaltyMaster VALUES(1, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 'All',
            'SKProvCrownVar,GORR', 0.12, 0.02,
            'price', 'price', 'price',
            NULL, NULL, NULL,
            'prod', 'sales', 'prod',
            'sales', 'sales', 'sales', 'sales',
            'mprod,250,%.02,300,%.03,400,%.04,500,%.05,0,%.06',
            'mprod,250,%.02,300,%.03,400,%.04,500,%.05,0,%.06',
            NULL, 0, 50, 50, NULL)
        """

        self.db_instance.execute_statement(statement)

    def create_some_test_entity_lease_link(self):
        if 'WellLeaseLink' not in self.db_instance.get_table_names():
            self.db_create.entity_lease_link()
        statement = """
            INSERT INTO EntityLeaseLink VALUES(1, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 'Well', 1, 1, 1.0);
            INSERT INTO EntityLeaseLink VALUES(2, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 'Well', 2, 1, 1.0);
            INSERT INTO EntityLeaseLink VALUES(3, '2001-01-08 00:00:00', '2016-01-07 00:00:00', 'Well', 3, 1, 1.0);
            INSERT INTO EntityLeaseLink VALUES(4, '2001-01-08 00:00:00', '2015-01-01 00:00:00', 'Well', 4, 1, 1.0);

        """

        self.db_instance.execute_statement(statement)

    def create_some_test_monthly(self):
        if 'Monthly' not in self.db_instance.get_table_names():
            self.db_create.monthly()

        statement = """
            INSERT INTO Monthly Values(1, 20150929, 201501, 'Well', 1,
                'OIL', "Payor1", 2, 740, 100, 90.0, 26.2, 0, 221.123456, 2.123455, 0.123455, 0.0);
            INSERT INTO Monthly Values(2, 20150929, 201501, 'Well', 4,
                'OIL', "Payor1", 2, 740, 100, 90.0, 35.61, 0, 221.123456, 2.123455, 0.123455, 0.0);
            INSERT INTO Monthly Values(4, 20150929, 201501, 'Well', 4,
                'OIL', "Payor1", 2, 740, 100, 90.0, 27.55, 0, 221.123456, 2.123455, 0.123455, 0.0);
        """
        self.db_instance.execute_statement(statement)

    def create_orphin_monthly(self):
        statement = """
            INSERT INTO Monthly Values(37, 20150929, 201501, 'Well', 1,
                'Stuff', "Payor1", 2, 740, 100, 0, 221.123456, 2.123455, 0.123455, 0.0);
        """
        self.db_instance.execute_statement(statement)

    def create_calc(self):
        if 'Calc' not in self.db_instance.get_table_names():
            self.db_create.calc()

    def create_some_test_leases(self):
        if 'Lease' not in self.db_instance.get_table_names():
            self.db_create.lease()
        statement = """
            INSERT INTO Lease VALUES(1,'2001-01-08 00:00:00', '2016-01-07 00:00:00', 'OL', 'SK', 7022, 123, NULL);
            INSERT INTO Lease VALUES(2,'1994-07-09 00:00:00', '2014-07-08 00:00:00', 'OL', 'SK', 7332, 123, NULL);
            INSERT INTO Lease VALUES(3,'1998-06-18 00:00:00', '2014-03-31 00:00:00', 'OL', 'SK', 7022, 123, NULL);
            INSERT INTO Lease VALUES(4,'1998-06-18 00:00:00', '2015-01-01 00:00:00', 'OL', 'SK', 7022, 123, NULL);
        """
        self.db_instance.execute_statement(statement)

    def create_some_test_econoil(self):
        if 'ECONOil' not in self.db_instance.get_table_names():
            self.db_create.econ_oil()
        statement = """
            INSERT INTO ECONOil VALUES(39,'Jan.',201501,181,223,262,
                0.0934,2.34,23.12,1734,21.73,502,27.11,626,0.1085,2.71,
                26.84,2013,32.38,747,38.94,899,0.1181,2.95,29.22,2192,35.58,821,40.54,936,52.3,1207);
        """
        self.db_instance.execute_statement(statement)

    def create_some_test_econgas(self):
        if 'ABEnergyOil' not in self.db_instance.get_table_names():
            self.db_create.econ_gas()
        statement = """
            INSERT INTO ECONGas VALUES(13,'Jan.',201501,0.1199,3,24.67,1596,0.1443,33.31,1922,0.16,36.92,2130,
                0.2071,47.78,2756);
        """
        self.db_instance.execute_statement(statement)

    def create_some_test_ab_energy_oil(self):
        if 'ECONGas' not in self.db_instance.get_table_names():
            self.db_create.ab_energy_oil()
        statement = """
            INSERT INTO ABEnergyOil VALUES(1,'Sept.',201609,100,200,300,400);
        """
        self.db_instance.execute_statement(statement)

    def create_some_test_rtp_info(self):
        if 'RTPInfo' not in self.db_instance.get_table_names():
            self.db_create.rtp_info()
        statement = """
            insert into RTPInfo values (1, 'SKWI111062705025W300', 'OIL', '2001-01-08 00:00:00', '2016-01-07 00:00:00',
                'Payor1', 'MinOwership',100);
            insert into RTPInfo values (2, 'SKWI114062705025W300', 'OIL', '2001-01-08 00:00:00', '2016-01-07 00:00:00',
                'Payor1', 'MinOwership',100);
        """
        self.db_instance.execute_statement(statement)

    def delete_lookups(self):
        if not self.table_exists("Lookups"):
            self.db_create.lookups()
        else:
            statement = """
                delete from Lookups;
            """
            self.db_instance.execute_statement(statement)

    def insert_lookups(self, name, prod_month, value):
        statement = "insert into Lookups (Name, ProdMonth, Value) values('" + name + "'," + str(
            prod_month) + ',' + str(value) + ');'
        self.db_instance.execute_statement(statement)
class SqliteDatabaseTest(unittest.TestCase):

    def setUp(self):
        self.assertEqual('unittest', config.get_environment())  # Destructive Tests must run in unittest environment
        self.dbi = config.get_database_instance()
        self.db = config.get_database()
        self.dbu = DatabaseUtilities()
        self.db_create = DatabaseCreate()

        self.dbu.delete_all_tables()
        
    def test_to_db_value(self):
        self.assertEqual('123', self.db.to_db_value(123))
        self.assertEqual("'asdf'", self.db.to_db_value("asdf"))
        self.assertEqual('123.45', self.db.to_db_value(123.45))
        self.assertEqual('1', self.db.to_db_value(True))
        self.assertEqual('0', self.db.to_db_value(False))
        self.assertEqual('null', self.db.to_db_value(None))
        
    def test_get_data_structure(self):
        ds = self.db.get_data_structure('WhatEver')
        self.assertEqual('WhatEver', ds._table_name)

    def test_select(self):
        self.dbu.create_some_test_well_royalty_masters()
        self.dbu.create_some_test_leases()
        
        self.assertIsNotNone(self.db.select('WellRoyaltyMaster', RoyaltyClassification='New Oil'))
        self.assertEqual(len(self.db.select('WellRoyaltyMaster', Prov='SK', Classification='Other')), 2)
        self.assertEqual(len(self.db.select('WellRoyaltyMaster')), 4)
        self.assertRaises(AppError, self.db.select, 'WrongTable')
        self.assertRaises(AppError, self.db.select, 'WrongTable', WrongAttr='WhoCares')
        self.assertRaises(AppError, self.db.select, 'Well', Foo='bar')
        self.assertEqual(len(self.db.select('Lease')), 4)
        self.assertEqual(len(self.db.select('Lease', Prov='SK')), 4)
        self.assertEqual(len(self.db.select('WellRoyaltyMaster', ID=1000)), 0)

    def test_select_date_effective(self):

        self.dbu.create_some_test_well_royalty_masters()
        self.assertEqual(4, len(self.db.select('WellRoyaltyMaster')))
        self.assertEqual(1, len(self.db.select('WellRoyaltyMaster', Date=datetime(2009, 1, 1, 12, 0, 0))))
        self.assertEqual(2, len(self.db.select('WellRoyaltyMaster', Date=datetime(2010, 9, 1, 12, 0, 0))))
        self.assertEqual(3, len(self.db.select('WellRoyaltyMaster', Date=datetime(2012, 1, 1, 12, 0, 0))))
        self.assertEqual(3, len(self.db.select('WellRoyaltyMaster', Date=datetime(2017, 1, 1, 12, 0, 0))))

        # WRITE TEST FOR SELECT1
        
    def test_update(self):
        self.dbu.create_some_test_well_royalty_masters()

        # change all types of attributes, read another record and then read the record again to make sure
        # the changes were made.
        well = self.db.select('WellRoyaltyMaster', ID=2)
        well[0].WellEvent = 'Changed'
        well[0].LeaseID = 100
        well[0].CommencementDate = '2016-02-01 00:00:00'
        well[0].WellType = None
        self.db.update(well[0])
        well = self.db.select('WellRoyaltyMaster', ID=1)
        self.assertEqual(well[0].ID, 1)
        self.assertEqual(well[0].WellEvent, 'SKWI111062705025W300')
        well = self.db.select('WellRoyaltyMaster', ID=2)
        self.assertEqual(well[0].ID, 2)
        self.assertEqual(well[0].WellEvent, 'Changed')
        self.assertEqual(well[0].CommencementDate, datetime(2016, 2, 1, 0, 0))
        self.assertEqual(well[0].WellType, None)

        ds = DataStructure()
        self.assertRaises(AttributeError, self.db.update, ds)
        
        ds._table_name = 'WellRoyaltyMaster'
        self.assertRaises(AttributeError, self.db.update, ds)
        ds.ID = 100
        self.assertRaises(AppError, self.db.update, ds)

    def test_insert(self):
        self.db_create.well_royalty_master()
        
        well = DataStructure()
        well.WellEvent = 'WellEvent for this well'
        # Should raise this error since we need to get the structure from the database
        self.assertRaises(TypeError, self.db.insert)

        well = self.db.get_data_structure('WellRoyaltyMaster')
        well.WellEvent = 'WellEvent for this well'
        self.db.insert(well)
        self.assertEqual(well.ID, 1)
        
        well = self.db.get_data_structure('WellRoyaltyMaster')
        well.WellEvent = 'Different WellEvent for this well'
        self.db.insert(well)
        self.assertEqual(well.ID, 2)
        
        well = self.db.select('WellRoyaltyMaster', ID=1)
        self.assertEqual(well[0].ID, 1)
        self.assertEqual(well[0].WellEvent, 'WellEvent for this well')
        
        well = self.db.get_data_structure('WellRoyaltyMaster')
        well.WellEvent = 'Next Well WellEvent'
        well.ID = 10
        self.db.insert(well)
        
        well = self.db.select('WellRoyaltyMaster', ID=1)
        self.assertEqual(well[0].ID, 1)
        self.assertEqual(well[0].WellEvent, 'WellEvent for this well')
        
        well = self.db.select('WellRoyaltyMaster', ID=10)
        self.assertEqual(well[0].ID, 10)
        self.assertEqual(well[0].WellEvent, 'Next Well WellEvent')

        well = self.db.get_data_structure('WellRoyaltyMaster')
        well.WellEvent = 'Just One More'
        self.db.insert(well)
        self.assertEqual(well.ID, 11)

        well = self.db.get_data_structure('WellRoyaltyMaster')
        well.BadAttr = 'Just another value'
        self.assertRaises(AppError, self.db.insert, well)
        
        # if the ID is None,Blank,or zero we shold still be able to insert a record
        well = self.db.get_data_structure('WellRoyaltyMaster')
        well.ID = None
        well.WellEvent = 'Just One More'
        self.db.insert(well)
        self.assertEqual(well.ID, 12)
        well.ID = 0
        self.db.insert(well)
        self.assertEqual(well.ID, 13)
        well.ID = ''
        self.db.insert(well)
        self.assertEqual(well.ID, 14)

    def test_delete(self):
        self.dbu.create_some_test_well_royalty_masters()

        self.assertEqual(4, len(self.db.select('WellRoyaltyMaster')))
                         
        self.db.delete('WellRoyaltyMaster', 2)
        self.assertEqual(3, len(self.db.select('WellRoyaltyMaster')))
        self.assertEqual(0, len(self.db.select('WellRoyaltyMaster', ID=2)))

    def test_count(self):
        self.dbu.create_some_test_well_royalty_masters()
        self.assertEqual(1, self.db.count('WellRoyaltyMaster', ID=1))
        self.assertEqual(4, self.db.count('WellRoyaltyMaster'))

    def test_date_format(self):
        self.dbu.create_some_test_well_royalty_masters()
        
        well = self.db.select('WellRoyaltyMaster', ID=1)
        self.assertTrue(isinstance(well[0].CommencementDate, datetime))
class SqliteDatabaseTest(unittest.TestCase):
    def setUp(self):
        self.assertEqual("unittest", config.get_environment())  # Destructive Tests must run in unittest environment
        self.dbi = config.get_database_instance()
        self.db = config.get_database()
        self.dbu = DatabaseUtilities()
        self.db_create = DatabaseCreate()

        self.dbu.delete_all_tables()

    def test_to_db_value(self):
        self.assertEqual("123", self.db.to_db_value(123))
        self.assertEqual('"asdf"', self.db.to_db_value("asdf"))
        self.assertEqual("123.45", self.db.to_db_value(123.45))
        self.assertEqual("1", self.db.to_db_value(True))
        self.assertEqual("0", self.db.to_db_value(False))
        self.assertEqual("null", self.db.to_db_value(None))

    def test_get_data_structure(self):
        ds = self.db.get_data_structure("WhatEver")
        self.assertEqual("WhatEver", ds._table_name)

    def test_select(self):
        self.dbu.create_some_test_well_royalty_masters()
        self.dbu.create_some_test_leases()

        self.assertIsNotNone(self.db.select("WellRoyaltyMaster", RoyaltyClassification="New Oil"))
        self.assertEqual(len(self.db.select("WellRoyaltyMaster", Prov="SK", Classification="Other")), 2)
        self.assertEqual(len(self.db.select("WellRoyaltyMaster")), 4)
        self.assertRaises(AppError, self.db.select, "WrongTable")
        self.assertRaises(AppError, self.db.select, "WrongTable", WrongAttr="WhoCares")
        self.assertRaises(AppError, self.db.select, "Well", Foo="bar")
        self.assertEqual(len(self.db.select("Lease")), 4)
        self.assertEqual(len(self.db.select("Lease", Prov="SK")), 4)
        self.assertEqual(len(self.db.select("WellRoyaltyMaster", ID=1000)), 0)

    def test_select_date_effective(self):

        self.dbu.create_some_test_well_royalty_masters()
        self.assertEqual(4, len(self.db.select("WellRoyaltyMaster")))
        self.assertEqual(1, len(self.db.select("WellRoyaltyMaster", Date=datetime(2009, 1, 1, 12, 0, 0))))
        self.assertEqual(2, len(self.db.select("WellRoyaltyMaster", Date=datetime(2010, 9, 1, 12, 0, 0))))
        self.assertEqual(3, len(self.db.select("WellRoyaltyMaster", Date=datetime(2012, 1, 1, 12, 0, 0))))
        self.assertEqual(3, len(self.db.select("WellRoyaltyMaster", Date=datetime(2017, 1, 1, 12, 0, 0))))

        # WRITE TEST FOR SELECT1

    def test_update(self):
        self.dbu.create_some_test_well_royalty_masters()

        # change all types of attributes, read another record and then read the record again to make sure
        # the changes were made.
        well = self.db.select("WellRoyaltyMaster", ID=2)
        well[0].WellEvent = "Changed"
        well[0].LeaseID = 100
        well[0].CommencementDate = "2016-02-01 00:00:00"
        well[0].WellType = None
        self.db.update(well[0])
        well = self.db.select("WellRoyaltyMaster", ID=1)
        self.assertEqual(well[0].ID, 1)
        self.assertEqual(well[0].WellEvent, "SKWI111062705025W300")
        well = self.db.select("WellRoyaltyMaster", ID=2)
        self.assertEqual(well[0].ID, 2)
        self.assertEqual(well[0].WellEvent, "Changed")
        self.assertEqual(well[0].CommencementDate, datetime(2016, 2, 1, 0, 0))
        self.assertEqual(well[0].WellType, None)

        ds = DataStructure()
        self.assertRaises(AttributeError, self.db.update, ds)

        ds._table_name = "WellRoyaltyMaster"
        self.assertRaises(AttributeError, self.db.update, ds)
        ds.ID = 100
        self.assertRaises(AppError, self.db.update, ds)

    def test_insert(self):
        self.db_create.well_royalty_master()

        well = DataStructure()
        well.WellEvent = "WellEvent for this well"
        # Should raise this error since we need to get the structure from the database
        self.assertRaises(TypeError, self.db.insert)

        well = self.db.get_data_structure("WellRoyaltyMaster")
        well.WellEvent = "WellEvent for this well"
        self.db.insert(well)
        self.assertEqual(well.ID, 1)

        well = self.db.get_data_structure("WellRoyaltyMaster")
        well.WellEvent = "Different WellEvent for this well"
        self.db.insert(well)
        self.assertEqual(well.ID, 2)

        well = self.db.select("WellRoyaltyMaster", ID=1)
        self.assertEqual(well[0].ID, 1)
        self.assertEqual(well[0].WellEvent, "WellEvent for this well")

        well = self.db.get_data_structure("WellRoyaltyMaster")
        well.WellEvent = "Next Well WellEvent"
        well.ID = 10
        self.db.insert(well)

        well = self.db.select("WellRoyaltyMaster", ID=1)
        self.assertEqual(well[0].ID, 1)
        self.assertEqual(well[0].WellEvent, "WellEvent for this well")

        well = self.db.select("WellRoyaltyMaster", ID=10)
        self.assertEqual(well[0].ID, 10)
        self.assertEqual(well[0].WellEvent, "Next Well WellEvent")

        well = self.db.get_data_structure("WellRoyaltyMaster")
        well.WellEvent = "Just One More"
        self.db.insert(well)
        self.assertEqual(well.ID, 11)

        well = self.db.get_data_structure("WellRoyaltyMaster")
        well.BadAttr = "Just another value"
        self.assertRaises(AppError, self.db.insert, well)

        # if the ID is None,Blank,or zero we shold still be able to insert a record
        well = self.db.get_data_structure("WellRoyaltyMaster")
        well.ID = None
        well.WellEvent = "Just One More"
        self.db.insert(well)
        self.assertEqual(well.ID, 12)
        well.ID = 0
        self.db.insert(well)
        self.assertEqual(well.ID, 13)
        well.ID = ""
        self.db.insert(well)
        self.assertEqual(well.ID, 14)

    def test_delete(self):
        self.dbu.create_some_test_well_royalty_masters()

        self.assertEqual(4, len(self.db.select("WellRoyaltyMaster")))

        self.db.delete("WellRoyaltyMaster", 2)
        self.assertEqual(3, len(self.db.select("WellRoyaltyMaster")))
        self.assertEqual(0, len(self.db.select("WellRoyaltyMaster", ID=2)))

    def test_count(self):
        self.dbu.create_some_test_well_royalty_masters()
        self.assertEqual(1, self.db.count("WellRoyaltyMaster", ID=1))
        self.assertEqual(4, self.db.count("WellRoyaltyMaster"))

    def test_date_format(self):
        self.dbu.create_some_test_well_royalty_masters()

        well = self.db.select("WellRoyaltyMaster", ID=1)
        self.assertTrue(isinstance(well[0].CommencementDate, datetime))