xref: /sqlite-3.40.0/src/test_backup.c (revision e3147332)
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 #include "tcl.h"
17 #include <sqlite3.h>
18 #include <assert.h>
19 
20 /* These functions are implemented in main.c. */
21 extern const char *sqlite3ErrName(int);
22 
23 /* These functions are implemented in test1.c. */
24 extern int getDbPointer(Tcl_Interp *, const char *, sqlite3 **);
25 
26 static int backupTestCmd(
27   ClientData clientData,
28   Tcl_Interp *interp,
29   int objc,
30   Tcl_Obj *const*objv
31 ){
32   enum BackupSubCommandEnum {
33     BACKUP_STEP, BACKUP_FINISH, BACKUP_REMAINING, BACKUP_PAGECOUNT
34   };
35   struct BackupSubCommand {
36     const char *zCmd;
37     enum BackupSubCommandEnum eCmd;
38     int nArg;
39     const char *zArg;
40   } aSub[] = {
41     {"step",      BACKUP_STEP      , 1, "npage" },
42     {"finish",    BACKUP_FINISH    , 0, ""      },
43     {"remaining", BACKUP_REMAINING , 0, ""      },
44     {"pagecount", BACKUP_PAGECOUNT , 0, ""      },
45     {0, 0, 0, 0}
46   };
47 
48   sqlite3_backup *p = (sqlite3_backup *)clientData;
49   int iCmd;
50   int rc;
51 
52   rc = Tcl_GetIndexFromObjStruct(
53       interp, objv[1], aSub, sizeof(aSub[0]), "option", 0, &iCmd
54   );
55   if( rc!=TCL_OK ){
56     return rc;
57   }
58   if( objc!=(2 + aSub[iCmd].nArg) ){
59     Tcl_WrongNumArgs(interp, 2, objv, aSub[iCmd].zArg);
60     return TCL_ERROR;
61   }
62 
63   switch( aSub[iCmd].eCmd ){
64 
65     case BACKUP_FINISH: {
66       const char *zCmdName;
67       Tcl_CmdInfo cmdInfo;
68       zCmdName = Tcl_GetString(objv[0]);
69       Tcl_GetCommandInfo(interp, zCmdName, &cmdInfo);
70       cmdInfo.deleteProc = 0;
71       Tcl_SetCommandInfo(interp, zCmdName, &cmdInfo);
72       Tcl_DeleteCommand(interp, zCmdName);
73 
74       rc = sqlite3_backup_finish(p);
75       Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
76       break;
77     }
78 
79     case BACKUP_STEP: {
80       int nPage;
81       if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &nPage) ){
82         return TCL_ERROR;
83       }
84       rc = sqlite3_backup_step(p, nPage);
85       Tcl_SetResult(interp, (char *)sqlite3ErrName(rc), TCL_STATIC);
86       break;
87     }
88 
89     case BACKUP_REMAINING:
90       Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_remaining(p)));
91       break;
92 
93     case BACKUP_PAGECOUNT:
94       Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_pagecount(p)));
95       break;
96   }
97 
98   return TCL_OK;
99 }
100 
101 static void backupTestFinish(ClientData clientData){
102   sqlite3_backup *pBackup = (sqlite3_backup *)clientData;
103   sqlite3_backup_finish(pBackup);
104 }
105 
106 /*
107 **     sqlite3_backup CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME
108 **
109 */
110 static int backupTestInit(
111   ClientData clientData,
112   Tcl_Interp *interp,
113   int objc,
114   Tcl_Obj *const*objv
115 ){
116   sqlite3_backup *pBackup;
117   sqlite3 *pDestDb;
118   sqlite3 *pSrcDb;
119   const char *zDestName;
120   const char *zSrcName;
121   const char *zCmd;
122 
123   if( objc!=6 ){
124     Tcl_WrongNumArgs(
125       interp, 1, objv, "CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME"
126     );
127     return TCL_ERROR;
128   }
129 
130   zCmd = Tcl_GetString(objv[1]);
131   getDbPointer(interp, Tcl_GetString(objv[2]), &pDestDb);
132   zDestName = Tcl_GetString(objv[3]);
133   getDbPointer(interp, Tcl_GetString(objv[4]), &pSrcDb);
134   zSrcName = Tcl_GetString(objv[5]);
135 
136   pBackup = sqlite3_backup_init(pDestDb, zDestName, pSrcDb, zSrcName);
137   if( !pBackup ){
138     Tcl_AppendResult(interp, "sqlite3_backup_init() failed", 0);
139     return TCL_ERROR;
140   }
141 
142   Tcl_CreateObjCommand(interp, zCmd, backupTestCmd, pBackup, backupTestFinish);
143   Tcl_SetObjResult(interp, objv[1]);
144   return TCL_OK;
145 }
146 
147 int Sqlitetestbackup_Init(Tcl_Interp *interp){
148   Tcl_CreateObjCommand(interp, "sqlite3_backup", backupTestInit, 0, 0);
149   return TCL_OK;
150 }
151