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