xref: /sqlite-3.40.0/src/test_backup.c (revision 52b1dbb5)
1 /*
2 ** 2009 January 28
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 *************************************************************************
12 ** This file contains test logic for the sqlite3_backup() interface.
13 **
14 */
15 
16 #if defined(INCLUDE_SQLITE_TCL_H)
17 #  include "sqlite_tcl.h"
18 #else
19 #  include "tcl.h"
20 #endif
21 #include "sqlite3.h"
22 #include <assert.h>
23 
24 /* These functions are implemented in main.c. */
25 extern const char *sqlite3ErrName(int);
26 
27 /* These functions are implemented in test1.c. */
28 extern int getDbPointer(Tcl_Interp *, const char *, sqlite3 **);
29 
30 static int backupTestCmd(
31   ClientData clientData,
32   Tcl_Interp *interp,
33   int objc,
34   Tcl_Obj *const*objv
35 ){
36   enum BackupSubCommandEnum {
37     BACKUP_STEP, BACKUP_FINISH, BACKUP_REMAINING, BACKUP_PAGECOUNT
38   };
39   struct BackupSubCommand {
40     const char *zCmd;
41     enum BackupSubCommandEnum eCmd;
42     int nArg;
43     const char *zArg;
44   } aSub[] = {
45     {"step",      BACKUP_STEP      , 1, "npage" },
46     {"finish",    BACKUP_FINISH    , 0, ""      },
47     {"remaining", BACKUP_REMAINING , 0, ""      },
48     {"pagecount", BACKUP_PAGECOUNT , 0, ""      },
49     {0, 0, 0, 0}
50   };
51 
52   sqlite3_backup *p = (sqlite3_backup *)clientData;
53   int iCmd;
54   int rc;
55 
56   rc = Tcl_GetIndexFromObjStruct(
57       interp, objv[1], aSub, sizeof(aSub[0]), "option", 0, &iCmd
58   );
59   if( rc!=TCL_OK ){
60     return rc;
61   }
62   if( objc!=(2 + aSub[iCmd].nArg) ){
63     Tcl_WrongNumArgs(interp, 2, objv, aSub[iCmd].zArg);
64     return TCL_ERROR;
65   }
66 
67   switch( aSub[iCmd].eCmd ){
68 
69     case BACKUP_FINISH: {
70       const char *zCmdName;
71       Tcl_CmdInfo cmdInfo;
72       zCmdName = Tcl_GetString(objv[0]);
73       Tcl_GetCommandInfo(interp, zCmdName, &cmdInfo);
74       cmdInfo.deleteProc = 0;
75       Tcl_SetCommandInfo(interp, zCmdName, &cmdInfo);
76       Tcl_DeleteCommand(interp, zCmdName);
77 
78       rc = sqlite3_backup_finish(p);
79       Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
80       break;
81     }
82 
83     case BACKUP_STEP: {
84       int nPage;
85       if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &nPage) ){
86         return TCL_ERROR;
87       }
88       rc = sqlite3_backup_step(p, nPage);
89       Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
90       break;
91     }
92 
93     case BACKUP_REMAINING:
94       Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_remaining(p)));
95       break;
96 
97     case BACKUP_PAGECOUNT:
98       Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_pagecount(p)));
99       break;
100   }
101 
102   return TCL_OK;
103 }
104 
105 static void backupTestFinish(ClientData clientData){
106   sqlite3_backup *pBackup = (sqlite3_backup *)clientData;
107   sqlite3_backup_finish(pBackup);
108 }
109 
110 /*
111 **     sqlite3_backup CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME
112 **
113 */
114 static int backupTestInit(
115   ClientData clientData,
116   Tcl_Interp *interp,
117   int objc,
118   Tcl_Obj *const*objv
119 ){
120   sqlite3_backup *pBackup;
121   sqlite3 *pDestDb;
122   sqlite3 *pSrcDb;
123   const char *zDestName;
124   const char *zSrcName;
125   const char *zCmd;
126 
127   if( objc!=6 ){
128     Tcl_WrongNumArgs(
129       interp, 1, objv, "CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME"
130     );
131     return TCL_ERROR;
132   }
133 
134   zCmd = Tcl_GetString(objv[1]);
135   getDbPointer(interp, Tcl_GetString(objv[2]), &pDestDb);
136   zDestName = Tcl_GetString(objv[3]);
137   getDbPointer(interp, Tcl_GetString(objv[4]), &pSrcDb);
138   zSrcName = Tcl_GetString(objv[5]);
139 
140   pBackup = sqlite3_backup_init(pDestDb, zDestName, pSrcDb, zSrcName);
141   if( !pBackup ){
142     Tcl_AppendResult(interp, "sqlite3_backup_init() failed", 0);
143     return TCL_ERROR;
144   }
145 
146   Tcl_CreateObjCommand(interp, zCmd, backupTestCmd, pBackup, backupTestFinish);
147   Tcl_SetObjResult(interp, objv[1]);
148   return TCL_OK;
149 }
150 
151 int Sqlitetestbackup_Init(Tcl_Interp *interp){
152   Tcl_CreateObjCommand(interp, "sqlite3_backup", backupTestInit, 0, 0);
153   return TCL_OK;
154 }
155