@@ -1601,7 +1601,6 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
16011601/*[clinic end generated code: output=306a3e6a38c36334 input=30ae45fc420bfd3b]*/
16021602{
16031603 int rc ;
1604- int callback_error = 0 ;
16051604 int sleep_ms = (int )(sleep * 1000.0 );
16061605 sqlite3 * bck_conn ;
16071606 sqlite3_backup * bck_handle ;
@@ -1643,60 +1642,50 @@ pysqlite_connection_backup_impl(pysqlite_Connection *self,
16431642 bck_handle = sqlite3_backup_init (bck_conn , "main" , self -> db , name );
16441643 Py_END_ALLOW_THREADS
16451644
1646- if (bck_handle ) {
1647- do {
1648- Py_BEGIN_ALLOW_THREADS
1649- rc = sqlite3_backup_step (bck_handle , pages );
1650- Py_END_ALLOW_THREADS
1645+ if (bck_handle == NULL) {
1646+ _pysqlite_seterror (bck_conn , NULL );
1647+ return NULL ;
1648+ }
16511649
1652- if (progress != Py_None ) {
1653- PyObject * res ;
1654-
1655- res = PyObject_CallFunction (progress , "iii" , rc ,
1656- sqlite3_backup_remaining (bck_handle ),
1657- sqlite3_backup_pagecount (bck_handle ));
1658- if (res == NULL ) {
1659- /* User's callback raised an error: interrupt the loop and
1660- propagate it. */
1661- callback_error = 1 ;
1662- rc = -1 ;
1663- } else {
1664- Py_DECREF (res );
1665- }
1666- }
1650+ do {
1651+ Py_BEGIN_ALLOW_THREADS
1652+ rc = sqlite3_backup_step (bck_handle , pages );
1653+ Py_END_ALLOW_THREADS
16671654
1668- /* Sleep for a while if there are still further pages to copy and
1669- the engine could not make any progress */
1670- if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED ) {
1655+ if (progress != Py_None ) {
1656+ int remaining = sqlite3_backup_remaining (bck_handle );
1657+ int pagecount = sqlite3_backup_pagecount (bck_handle );
1658+ PyObject * res = PyObject_CallFunction (progress , "iii" , rc ,
1659+ remaining , pagecount );
1660+ if (res == NULL ) {
1661+ /* Callback failed: abort backup and bail. */
16711662 Py_BEGIN_ALLOW_THREADS
1672- sqlite3_sleep ( sleep_ms );
1663+ sqlite3_backup_finish ( bck_handle );
16731664 Py_END_ALLOW_THREADS
1665+ return NULL ;
16741666 }
1675- } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED );
1676-
1677- Py_BEGIN_ALLOW_THREADS
1678- rc = sqlite3_backup_finish (bck_handle );
1679- Py_END_ALLOW_THREADS
1680- } else {
1681- rc = _pysqlite_seterror (bck_conn , NULL );
1682- }
1667+ Py_DECREF (res );
1668+ }
16831669
1684- if (!callback_error && rc != SQLITE_OK ) {
1685- /* We cannot use _pysqlite_seterror() here because the backup APIs do
1686- not set the error status on the connection object, but rather on
1687- the backup handle. */
1688- if (rc == SQLITE_NOMEM ) {
1689- (void )PyErr_NoMemory ();
1690- } else {
1691- PyErr_SetString (pysqlite_OperationalError , sqlite3_errstr (rc ));
1670+ /* Sleep for a while if there are still further pages to copy and
1671+ the engine could not make any progress */
1672+ if (rc == SQLITE_BUSY || rc == SQLITE_LOCKED ) {
1673+ Py_BEGIN_ALLOW_THREADS
1674+ sqlite3_sleep (sleep_ms );
1675+ Py_END_ALLOW_THREADS
16921676 }
1693- }
1677+ } while ( rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED );
16941678
1695- if (!callback_error && rc == SQLITE_OK ) {
1696- Py_RETURN_NONE ;
1697- } else {
1679+ Py_BEGIN_ALLOW_THREADS
1680+ rc = sqlite3_backup_finish (bck_handle );
1681+ Py_END_ALLOW_THREADS
1682+
1683+ if (rc != SQLITE_OK ) {
1684+ _pysqlite_seterror (bck_conn , NULL );
16981685 return NULL ;
16991686 }
1687+
1688+ Py_RETURN_NONE ;
17001689}
17011690
17021691/*[clinic input]
0 commit comments