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 test1.c. */
21int getDbPointer(Tcl_Interp *, const char *, sqlite3 **);
22const char *sqlite3TestErrorName(int);
23
24static 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      const char *zCmdName;
65      Tcl_CmdInfo cmdInfo;
66      zCmdName = Tcl_GetString(objv[0]);
67      Tcl_GetCommandInfo(interp, zCmdName, &cmdInfo);
68      cmdInfo.deleteProc = 0;
69      Tcl_SetCommandInfo(interp, zCmdName, &cmdInfo);
70      Tcl_DeleteCommand(interp, zCmdName);
71
72      rc = sqlite3_backup_finish(p);
73      Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
74      break;
75    }
76
77    case BACKUP_STEP: {
78      int nPage;
79      if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &nPage) ){
80        return TCL_ERROR;
81      }
82      rc = sqlite3_backup_step(p, nPage);
83      Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC);
84      break;
85    }
86
87    case BACKUP_REMAINING:
88      Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_remaining(p)));
89      break;
90
91    case BACKUP_PAGECOUNT:
92      Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_backup_pagecount(p)));
93      break;
94  }
95
96  return TCL_OK;
97}
98
99static void backupTestFinish(ClientData clientData){
100  sqlite3_backup *pBackup = (sqlite3_backup *)clientData;
101  sqlite3_backup_finish(pBackup);
102}
103
104/*
105**     sqlite3_backup CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME
106**
107*/
108static int backupTestInit(
109  ClientData clientData,
110  Tcl_Interp *interp,
111  int objc,
112  Tcl_Obj *const*objv
113){
114  sqlite3_backup *pBackup;
115  sqlite3 *pDestDb;
116  sqlite3 *pSrcDb;
117  const char *zDestName;
118  const char *zSrcName;
119  const char *zCmd;
120
121  if( objc!=6 ){
122    Tcl_WrongNumArgs(
123      interp, 1, objv, "CMDNAME DESTHANDLE DESTNAME SRCHANDLE SRCNAME"
124    );
125    return TCL_ERROR;
126  }
127
128  zCmd = Tcl_GetString(objv[1]);
129  getDbPointer(interp, Tcl_GetString(objv[2]), &pDestDb);
130  zDestName = Tcl_GetString(objv[3]);
131  getDbPointer(interp, Tcl_GetString(objv[4]), &pSrcDb);
132  zSrcName = Tcl_GetString(objv[5]);
133
134  pBackup = sqlite3_backup_init(pDestDb, zDestName, pSrcDb, zSrcName);
135  if( !pBackup ){
136    Tcl_AppendResult(interp, "sqlite3_backup_init() failed", 0);
137    return TCL_ERROR;
138  }
139
140  Tcl_CreateObjCommand(interp, zCmd, backupTestCmd, pBackup, backupTestFinish);
141  Tcl_SetObjResult(interp, objv[1]);
142  return TCL_OK;
143}
144
145int Sqlitetestbackup_Init(Tcl_Interp *interp){
146  Tcl_CreateObjCommand(interp, "sqlite3_backup", backupTestInit, 0, 0);
147  return TCL_OK;
148}
149