17db96d56Sopenharmony_ciimport sqlite3 as sqlite
27db96d56Sopenharmony_ciimport unittest
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci
57db96d56Sopenharmony_ciclass BackupTests(unittest.TestCase):
67db96d56Sopenharmony_ci    def setUp(self):
77db96d56Sopenharmony_ci        cx = self.cx = sqlite.connect(":memory:")
87db96d56Sopenharmony_ci        cx.execute('CREATE TABLE foo (key INTEGER)')
97db96d56Sopenharmony_ci        cx.executemany('INSERT INTO foo (key) VALUES (?)', [(3,), (4,)])
107db96d56Sopenharmony_ci        cx.commit()
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ci    def tearDown(self):
137db96d56Sopenharmony_ci        self.cx.close()
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci    def verify_backup(self, bckcx):
167db96d56Sopenharmony_ci        result = bckcx.execute("SELECT key FROM foo ORDER BY key").fetchall()
177db96d56Sopenharmony_ci        self.assertEqual(result[0][0], 3)
187db96d56Sopenharmony_ci        self.assertEqual(result[1][0], 4)
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci    def test_bad_target(self):
217db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
227db96d56Sopenharmony_ci            self.cx.backup(None)
237db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
247db96d56Sopenharmony_ci            self.cx.backup()
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ci    def test_bad_target_filename(self):
277db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
287db96d56Sopenharmony_ci            self.cx.backup('some_file_name.db')
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci    def test_bad_target_same_connection(self):
317db96d56Sopenharmony_ci        with self.assertRaises(ValueError):
327db96d56Sopenharmony_ci            self.cx.backup(self.cx)
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_ci    def test_bad_target_closed_connection(self):
357db96d56Sopenharmony_ci        bck = sqlite.connect(':memory:')
367db96d56Sopenharmony_ci        bck.close()
377db96d56Sopenharmony_ci        with self.assertRaises(sqlite.ProgrammingError):
387db96d56Sopenharmony_ci            self.cx.backup(bck)
397db96d56Sopenharmony_ci
407db96d56Sopenharmony_ci    def test_bad_source_closed_connection(self):
417db96d56Sopenharmony_ci        bck = sqlite.connect(':memory:')
427db96d56Sopenharmony_ci        source = sqlite.connect(":memory:")
437db96d56Sopenharmony_ci        source.close()
447db96d56Sopenharmony_ci        with self.assertRaises(sqlite.ProgrammingError):
457db96d56Sopenharmony_ci            source.backup(bck)
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci    def test_bad_target_in_transaction(self):
487db96d56Sopenharmony_ci        bck = sqlite.connect(':memory:')
497db96d56Sopenharmony_ci        bck.execute('CREATE TABLE bar (key INTEGER)')
507db96d56Sopenharmony_ci        bck.executemany('INSERT INTO bar (key) VALUES (?)', [(3,), (4,)])
517db96d56Sopenharmony_ci        with self.assertRaises(sqlite.OperationalError) as cm:
527db96d56Sopenharmony_ci            self.cx.backup(bck)
537db96d56Sopenharmony_ci        if sqlite.sqlite_version_info < (3, 8, 8):
547db96d56Sopenharmony_ci            self.assertEqual(str(cm.exception), 'target is in transaction')
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci    def test_keyword_only_args(self):
577db96d56Sopenharmony_ci        with self.assertRaises(TypeError):
587db96d56Sopenharmony_ci            with sqlite.connect(':memory:') as bck:
597db96d56Sopenharmony_ci                self.cx.backup(bck, 1)
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci    def test_simple(self):
627db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
637db96d56Sopenharmony_ci            self.cx.backup(bck)
647db96d56Sopenharmony_ci            self.verify_backup(bck)
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci    def test_progress(self):
677db96d56Sopenharmony_ci        journal = []
687db96d56Sopenharmony_ci
697db96d56Sopenharmony_ci        def progress(status, remaining, total):
707db96d56Sopenharmony_ci            journal.append(status)
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
737db96d56Sopenharmony_ci            self.cx.backup(bck, pages=1, progress=progress)
747db96d56Sopenharmony_ci            self.verify_backup(bck)
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci        self.assertEqual(len(journal), 2)
777db96d56Sopenharmony_ci        self.assertEqual(journal[0], sqlite.SQLITE_OK)
787db96d56Sopenharmony_ci        self.assertEqual(journal[1], sqlite.SQLITE_DONE)
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci    def test_progress_all_pages_at_once_1(self):
817db96d56Sopenharmony_ci        journal = []
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci        def progress(status, remaining, total):
847db96d56Sopenharmony_ci            journal.append(remaining)
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
877db96d56Sopenharmony_ci            self.cx.backup(bck, progress=progress)
887db96d56Sopenharmony_ci            self.verify_backup(bck)
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci        self.assertEqual(len(journal), 1)
917db96d56Sopenharmony_ci        self.assertEqual(journal[0], 0)
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ci    def test_progress_all_pages_at_once_2(self):
947db96d56Sopenharmony_ci        journal = []
957db96d56Sopenharmony_ci
967db96d56Sopenharmony_ci        def progress(status, remaining, total):
977db96d56Sopenharmony_ci            journal.append(remaining)
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
1007db96d56Sopenharmony_ci            self.cx.backup(bck, pages=-1, progress=progress)
1017db96d56Sopenharmony_ci            self.verify_backup(bck)
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci        self.assertEqual(len(journal), 1)
1047db96d56Sopenharmony_ci        self.assertEqual(journal[0], 0)
1057db96d56Sopenharmony_ci
1067db96d56Sopenharmony_ci    def test_non_callable_progress(self):
1077db96d56Sopenharmony_ci        with self.assertRaises(TypeError) as cm:
1087db96d56Sopenharmony_ci            with sqlite.connect(':memory:') as bck:
1097db96d56Sopenharmony_ci                self.cx.backup(bck, pages=1, progress='bar')
1107db96d56Sopenharmony_ci        self.assertEqual(str(cm.exception), 'progress argument must be a callable')
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ci    def test_modifying_progress(self):
1137db96d56Sopenharmony_ci        journal = []
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci        def progress(status, remaining, total):
1167db96d56Sopenharmony_ci            if not journal:
1177db96d56Sopenharmony_ci                self.cx.execute('INSERT INTO foo (key) VALUES (?)', (remaining+1000,))
1187db96d56Sopenharmony_ci                self.cx.commit()
1197db96d56Sopenharmony_ci            journal.append(remaining)
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
1227db96d56Sopenharmony_ci            self.cx.backup(bck, pages=1, progress=progress)
1237db96d56Sopenharmony_ci            self.verify_backup(bck)
1247db96d56Sopenharmony_ci
1257db96d56Sopenharmony_ci            result = bck.execute("SELECT key FROM foo"
1267db96d56Sopenharmony_ci                                 " WHERE key >= 1000"
1277db96d56Sopenharmony_ci                                 " ORDER BY key").fetchall()
1287db96d56Sopenharmony_ci            self.assertEqual(result[0][0], 1001)
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci        self.assertEqual(len(journal), 3)
1317db96d56Sopenharmony_ci        self.assertEqual(journal[0], 1)
1327db96d56Sopenharmony_ci        self.assertEqual(journal[1], 1)
1337db96d56Sopenharmony_ci        self.assertEqual(journal[2], 0)
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci    def test_failing_progress(self):
1367db96d56Sopenharmony_ci        def progress(status, remaining, total):
1377db96d56Sopenharmony_ci            raise SystemError('nearly out of space')
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci        with self.assertRaises(SystemError) as err:
1407db96d56Sopenharmony_ci            with sqlite.connect(':memory:') as bck:
1417db96d56Sopenharmony_ci                self.cx.backup(bck, progress=progress)
1427db96d56Sopenharmony_ci        self.assertEqual(str(err.exception), 'nearly out of space')
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ci    def test_database_source_name(self):
1457db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
1467db96d56Sopenharmony_ci            self.cx.backup(bck, name='main')
1477db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
1487db96d56Sopenharmony_ci            self.cx.backup(bck, name='temp')
1497db96d56Sopenharmony_ci        with self.assertRaises(sqlite.OperationalError) as cm:
1507db96d56Sopenharmony_ci            with sqlite.connect(':memory:') as bck:
1517db96d56Sopenharmony_ci                self.cx.backup(bck, name='non-existing')
1527db96d56Sopenharmony_ci        self.assertIn("unknown database", str(cm.exception))
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ci        self.cx.execute("ATTACH DATABASE ':memory:' AS attached_db")
1557db96d56Sopenharmony_ci        self.cx.execute('CREATE TABLE attached_db.foo (key INTEGER)')
1567db96d56Sopenharmony_ci        self.cx.executemany('INSERT INTO attached_db.foo (key) VALUES (?)', [(3,), (4,)])
1577db96d56Sopenharmony_ci        self.cx.commit()
1587db96d56Sopenharmony_ci        with sqlite.connect(':memory:') as bck:
1597db96d56Sopenharmony_ci            self.cx.backup(bck, name='attached_db')
1607db96d56Sopenharmony_ci            self.verify_backup(bck)
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ciif __name__ == "__main__":
1647db96d56Sopenharmony_ci    unittest.main()
165