SQLite

Check-in [f92405afb6]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Simplify wording of backup API error message. Decapitalize some other error messages. (CVS 6256)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: f92405afb649b698b735b423cd9195d4f8f137c9
User & Date: drh 2009-02-04 17:40:58.000
Context
2009-02-04
19:16
If the truncate operation fails in journalmode=TRUNCATE, do not fall back to overwriting the journal header with zeros. Simply fail the operation. (CVS 6257) (check-in: d4af60e52a user: drh tags: trunk)
17:40
Simplify wording of backup API error message. Decapitalize some other error messages. (CVS 6256) (check-in: f92405afb6 user: drh tags: trunk)
16:56
The sqlite3_backup_init() interface must lock the destination in case it needs to change the error message. (CVS 6255) (check-in: 572378d3a2 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/backup.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_backup_XXX() 
** API functions and the related features.
**
** $Id: backup.c,v 1.6 2009/02/04 16:56:19 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"

/* Macro to find the minimum of two numeric values.
*/
#ifndef MIN







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_backup_XXX() 
** API functions and the related features.
**
** $Id: backup.c,v 1.7 2009/02/04 17:40:58 drh Exp $
*/
#include "sqliteInt.h"
#include "btreeInt.h"

/* Macro to find the minimum of two numeric values.
*/
#ifndef MIN
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  ** a malfunction or a deadlock.
  */
  sqlite3_mutex_enter(pSrcDb->mutex);
  sqlite3_mutex_enter(pDestDb->mutex);

  if( pSrcDb==pDestDb ){
    sqlite3Error(
        pDestDb, SQLITE_ERROR, "Source and destination handles must be distinct"
    );
    p = 0;
  }else {
    /* Allocate space for a new sqlite3_backup object */
    p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
    if( !p ){
      sqlite3Error(pDestDb, SQLITE_NOMEM, 0);







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
  ** a malfunction or a deadlock.
  */
  sqlite3_mutex_enter(pSrcDb->mutex);
  sqlite3_mutex_enter(pDestDb->mutex);

  if( pSrcDb==pDestDb ){
    sqlite3Error(
        pDestDb, SQLITE_ERROR, "source and destination must be distinct"
    );
    p = 0;
  }else {
    /* Allocate space for a new sqlite3_backup object */
    p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup));
    if( !p ){
      sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
Changes to src/main.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.526 2009/02/04 03:59:25 shane Exp $
*/
#include "sqliteInt.h"

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
#ifdef SQLITE_ENABLE_RTREE







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.527 2009/02/04 17:40:58 drh Exp $
*/
#include "sqliteInt.h"

#ifdef SQLITE_ENABLE_FTS3
# include "fts3.h"
#endif
#ifdef SQLITE_ENABLE_RTREE
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
  ** some prepared statements internally.
  */
  sqlite3VtabRollback(db);

  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "Unable to close due to unfinalised statements");
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_BUSY;
  }
  assert( sqlite3SafetyCheckSickOrOk(db) );

  for(j=0; j<db->nDb; j++){
    Btree *pBt = db->aDb[j].pBt;
    if( pBt && sqlite3BtreeIsInBackup(pBt) ){
      sqlite3Error(db, SQLITE_BUSY, 
          "Unable to close due to unfinished backup operation");
      sqlite3_mutex_leave(db->mutex);
      return SQLITE_BUSY;
    }
  }

  /* Free any outstanding Savepoint structures. */
  sqlite3CloseSavepoints(db);







|









|







595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
  ** some prepared statements internally.
  */
  sqlite3VtabRollback(db);

  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "unable to close due to unfinalised statements");
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_BUSY;
  }
  assert( sqlite3SafetyCheckSickOrOk(db) );

  for(j=0; j<db->nDb; j++){
    Btree *pBt = db->aDb[j].pBt;
    if( pBt && sqlite3BtreeIsInBackup(pBt) ){
      sqlite3Error(db, SQLITE_BUSY, 
          "unable to close due to unfinished backup operation");
      sqlite3_mutex_leave(db->mutex);
      return SQLITE_BUSY;
    }
  }

  /* Free any outstanding Savepoint structures. */
  sqlite3CloseSavepoints(db);
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
  ** is being overridden/deleted but there are no active VMs, allow the
  ** operation to continue but invalidate all precompiled statements.
  */
  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
  if( p && p->iPrefEnc==enc && p->nArg==nArg ){
    if( db->activeVdbeCnt ){
      sqlite3Error(db, SQLITE_BUSY, 
        "Unable to delete/modify user-function due to active statements");
      assert( !db->mallocFailed );
      return SQLITE_BUSY;
    }else{
      sqlite3ExpirePreparedStatements(db);
    }
  }








|







951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
  ** is being overridden/deleted but there are no active VMs, allow the
  ** operation to continue but invalidate all precompiled statements.
  */
  p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
  if( p && p->iPrefEnc==enc && p->nArg==nArg ){
    if( db->activeVdbeCnt ){
      sqlite3Error(db, SQLITE_BUSY, 
        "unable to delete/modify user-function due to active statements");
      assert( !db->mallocFailed );
      return SQLITE_BUSY;
    }else{
      sqlite3ExpirePreparedStatements(db);
    }
  }

1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
  ** are no active VMs, invalidate any pre-compiled statements.
  */
  nName = sqlite3Strlen(db, zName);
  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 0);
  if( pColl && pColl->xCmp ){
    if( db->activeVdbeCnt ){
      sqlite3Error(db, SQLITE_BUSY, 
        "Unable to delete/modify collation sequence due to active statements");
      return SQLITE_BUSY;
    }
    sqlite3ExpirePreparedStatements(db);

    /* If collation sequence pColl was created directly by a call to
    ** sqlite3_create_collation, and not generated by synthCollSeq(),
    ** then any copies made by synthCollSeq() need to be invalidated.







|







1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
  ** are no active VMs, invalidate any pre-compiled statements.
  */
  nName = sqlite3Strlen(db, zName);
  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 0);
  if( pColl && pColl->xCmp ){
    if( db->activeVdbeCnt ){
      sqlite3Error(db, SQLITE_BUSY, 
        "unable to delete/modify collation sequence due to active statements");
      return SQLITE_BUSY;
    }
    sqlite3ExpirePreparedStatements(db);

    /* If collation sequence pColl was created directly by a call to
    ** sqlite3_create_collation, and not generated by synthCollSeq(),
    ** then any copies made by synthCollSeq() need to be invalidated.
Changes to test/backup.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2008 January 30
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite3_backup_XXX API.
#
# $Id: backup.test,v 1.1 2009/02/03 16:51:25 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#---------------------------------------------------------------------
# Test organization:
#













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2008 January 30
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite3_backup_XXX API.
#
# $Id: backup.test,v 1.2 2009/02/04 17:40:58 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

#---------------------------------------------------------------------
# Test organization:
#
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
} {B}
do_test backup-4.3.2 {
  db2 cache flush
  sqlite3_close db2
} {SQLITE_BUSY}
do_test backup-4.3.3 {
  sqlite3_errmsg db2
} {Unable to close due to unfinished backup operation}
do_test backup-4.3.4 {
  B step 50
} {SQLITE_DONE}
do_test backup-4.3.5 {
  B finish
} {SQLITE_OK}

do_test backup-4.4.1 {
  set rc [catch {sqlite3_backup B db main db aux1}]
  list $rc [sqlite3_errcode db] [sqlite3_errmsg db]
} {1 SQLITE_ERROR {Source and destination handles must be distinct}}
db close
db2 close

do_test backup-4.5.1 {
  catch { file delete -force test.db }
  sqlite3 db test.db
  sqlite3 db2 :memory:







|










|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
} {B}
do_test backup-4.3.2 {
  db2 cache flush
  sqlite3_close db2
} {SQLITE_BUSY}
do_test backup-4.3.3 {
  sqlite3_errmsg db2
} {unable to close due to unfinished backup operation}
do_test backup-4.3.4 {
  B step 50
} {SQLITE_DONE}
do_test backup-4.3.5 {
  B finish
} {SQLITE_OK}

do_test backup-4.4.1 {
  set rc [catch {sqlite3_backup B db main db aux1}]
  list $rc [sqlite3_errcode db] [sqlite3_errmsg db]
} {1 SQLITE_ERROR {source and destination must be distinct}}
db close
db2 close

do_test backup-4.5.1 {
  catch { file delete -force test.db }
  sqlite3 db test.db
  sqlite3 db2 :memory:
Changes to test/schema.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file tests the various conditions under which an SQLITE_SCHEMA
# error should be returned.
#
# $Id: schema.test,v 1.8 2007/10/09 08:29:33 danielk1977 Exp $

#---------------------------------------------------------------------
# When any of the following types of SQL statements or actions are 
# executed, all pre-compiled statements are invalidated. An attempt
# to execute an invalidated statement always returns SQLITE_SCHEMA.
#
# CREATE/DROP TABLE...................................schema-1.*







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file tests the various conditions under which an SQLITE_SCHEMA
# error should be returned.
#
# $Id: schema.test,v 1.9 2009/02/04 17:40:58 drh Exp $

#---------------------------------------------------------------------
# When any of the following types of SQL statements or actions are 
# executed, all pre-compiled statements are invalidated. An attempt
# to execute an invalidated statement always returns SQLITE_SCHEMA.
#
# CREATE/DROP TABLE...................................schema-1.*
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  sqlite_delete_function $::DB tstfunc
} {SQLITE_BUSY}
do_test schema-11.3 {
  set rc [catch {
    db function tstfunc {}
  } msg]
  list $rc $msg
} {1 {Unable to delete/modify user-function due to active statements}}
do_test schema-11.4 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}
do_test schema-11.5 {
  db collate tstcollate {}
  set sql {SELECT * FROM abc}
  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
  sqlite3_step $::STMT
} {SQLITE_ROW}
do_test schema-11.6 {
  sqlite_delete_collation $::DB tstcollate
} {SQLITE_BUSY}
do_test schema-11.7 {
  set rc [catch {
    db collate tstcollate {}
  } msg]
  list $rc $msg
} {1 {Unable to delete/modify collation sequence due to active statements}}
do_test schema-11.8 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}

# The following demonstrates why statements need to be expired whenever
# there is a rollback (explicit or otherwise).
#







|

















|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
  sqlite_delete_function $::DB tstfunc
} {SQLITE_BUSY}
do_test schema-11.3 {
  set rc [catch {
    db function tstfunc {}
  } msg]
  list $rc $msg
} {1 {unable to delete/modify user-function due to active statements}}
do_test schema-11.4 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}
do_test schema-11.5 {
  db collate tstcollate {}
  set sql {SELECT * FROM abc}
  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
  sqlite3_step $::STMT
} {SQLITE_ROW}
do_test schema-11.6 {
  sqlite_delete_collation $::DB tstcollate
} {SQLITE_BUSY}
do_test schema-11.7 {
  set rc [catch {
    db collate tstcollate {}
  } msg]
  list $rc $msg
} {1 {unable to delete/modify collation sequence due to active statements}}
do_test schema-11.8 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}

# The following demonstrates why statements need to be expired whenever
# there is a rollback (explicit or otherwise).
#
Changes to test/schema2.test.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file tests the various conditions under which an SQLITE_SCHEMA
# error should be returned.  This is a copy of schema.test that
# has been altered to use sqlite3_prepare_v2 instead of sqlite3_prepare
#
# $Id: schema2.test,v 1.3 2007/10/09 08:29:33 danielk1977 Exp $

#---------------------------------------------------------------------
# When any of the following types of SQL statements or actions are 
# executed, all pre-compiled statements are invalidated. An attempt
# to execute an invalidated statement always returns SQLITE_SCHEMA.
#
# CREATE/DROP TABLE...................................schema2-1.*







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file tests the various conditions under which an SQLITE_SCHEMA
# error should be returned.  This is a copy of schema.test that
# has been altered to use sqlite3_prepare_v2 instead of sqlite3_prepare
#
# $Id: schema2.test,v 1.4 2009/02/04 17:40:58 drh Exp $

#---------------------------------------------------------------------
# When any of the following types of SQL statements or actions are 
# executed, all pre-compiled statements are invalidated. An attempt
# to execute an invalidated statement always returns SQLITE_SCHEMA.
#
# CREATE/DROP TABLE...................................schema2-1.*
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  sqlite_delete_function $::DB tstfunc
} {SQLITE_BUSY}
do_test schema2-11.3 {
  set rc [catch {
    db function tstfunc {}
  } msg]
  list $rc $msg
} {1 {Unable to delete/modify user-function due to active statements}}
do_test schema2-11.4 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}
do_test schema2-11.5 {
  db collate tstcollate {}
  set sql {SELECT * FROM abc}
  set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 TAIL]
  sqlite3_step $::STMT
} {SQLITE_ROW}
do_test schema2-11.6 {
  sqlite_delete_collation $::DB tstcollate
} {SQLITE_BUSY}
do_test schema2-11.7 {
  set rc [catch {
    db collate tstcollate {}
  } msg]
  list $rc $msg
} {1 {Unable to delete/modify collation sequence due to active statements}}
do_test schema2-11.8 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}

finish_test







|

















|





310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  sqlite_delete_function $::DB tstfunc
} {SQLITE_BUSY}
do_test schema2-11.3 {
  set rc [catch {
    db function tstfunc {}
  } msg]
  list $rc $msg
} {1 {unable to delete/modify user-function due to active statements}}
do_test schema2-11.4 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}
do_test schema2-11.5 {
  db collate tstcollate {}
  set sql {SELECT * FROM abc}
  set ::STMT [sqlite3_prepare_v2 $::DB $sql -1 TAIL]
  sqlite3_step $::STMT
} {SQLITE_ROW}
do_test schema2-11.6 {
  sqlite_delete_collation $::DB tstcollate
} {SQLITE_BUSY}
do_test schema2-11.7 {
  set rc [catch {
    db collate tstcollate {}
  } msg]
  list $rc $msg
} {1 {unable to delete/modify collation sequence due to active statements}}
do_test schema2-11.8 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}

finish_test