modernc.org/cc@v1.0.1/v2/testdata/_sqlite/ext/rbu/rbu.c (about)

     1  /*
     2  ** 2014 August 30
     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  ** This file contains a command-line application that uses the RBU 
    14  ** extension. See the usage() function below for an explanation.
    15  */
    16  
    17  #include "sqlite3rbu.h"
    18  #include <stdio.h>
    19  #include <stdlib.h>
    20  #include <string.h>
    21  
    22  /*
    23  ** Print a usage message and exit.
    24  */
    25  void usage(const char *zArgv0){
    26    fprintf(stderr, 
    27  "Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n"
    28  "\n"
    29  "Where options are:\n"
    30  "\n"
    31  "    -step NSTEP\n"
    32  "    -vacuum\n"
    33  "\n"
    34  "  If the -vacuum switch is not present, argument RBU-DB must be an RBU\n"
    35  "  database containing an update suitable for target database TARGET-DB.\n"
    36  "  Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n"
    37  "  RBU, and RBU-DB is used as the state database for the vacuum (refer to\n"
    38  "  API documentation for details).\n"
    39  "\n"
    40  "  If NSTEP is set to less than or equal to zero (the default value), this \n"
    41  "  program attempts to perform the entire update or vacuum operation before\n"
    42  "  exiting\n"
    43  "\n"
    44  "  If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
    45  "  to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
    46  "  after the NSTEP'th call is made, the state is saved in the database RBU-DB\n"
    47  "  and the program exits. Subsequent invocations of this (or any other RBU)\n"
    48  "  application will use this state to resume applying the RBU update to the\n"
    49  "  target db.\n"
    50  "\n"
    51  , zArgv0);
    52    exit(1);
    53  }
    54  
    55  void report_default_vfs(){
    56    sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
    57    fprintf(stdout, "default vfs is \"%s\"\n", pVfs->zName);
    58  }
    59  
    60  void report_rbu_vfs(sqlite3rbu *pRbu){
    61    sqlite3 *db = sqlite3rbu_db(pRbu, 0);
    62    if( db ){
    63      char *zName = 0;
    64      sqlite3_file_control(db, "main", SQLITE_FCNTL_VFSNAME, &zName);
    65      if( zName ){
    66        fprintf(stdout, "using vfs \"%s\"\n", zName);
    67      }else{
    68        fprintf(stdout, "vfs name not available\n");
    69      }
    70      sqlite3_free(zName);
    71    }
    72  }
    73  
    74  int main(int argc, char **argv){
    75    int i;
    76    const char *zTarget;            /* Target database to apply RBU to */
    77    const char *zRbu;               /* Database containing RBU */
    78    char zBuf[200];                 /* Buffer for printf() */
    79    char *zErrmsg;                  /* Error message, if any */
    80    sqlite3rbu *pRbu;               /* RBU handle */
    81    int nStep = 0;                  /* Maximum number of step() calls */
    82    int bVacuum = 0;
    83    int rc;
    84    sqlite3_int64 nProgress = 0;
    85    int nArgc = argc-2;
    86  
    87    if( argc<3 ) usage(argv[0]);
    88    for(i=1; i<nArgc; i++){
    89      const char *zArg = argv[i];
    90      int nArg = strlen(zArg);
    91      if( nArg>1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){
    92        bVacuum = 1;
    93      }else if( nArg>1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i<nArg-1 ){
    94        i++;
    95        nStep = atoi(argv[i]);
    96      }else{
    97        usage(argv[0]);
    98      }
    99    }
   100  
   101    zTarget = argv[argc-2];
   102    zRbu = argv[argc-1];
   103  
   104    report_default_vfs();
   105  
   106    /* Open an RBU handle. A vacuum handle if -vacuum was specified, or a
   107    ** regular RBU update handle otherwise.  */
   108    if( bVacuum ){
   109      pRbu = sqlite3rbu_vacuum(zTarget, zRbu);
   110    }else{
   111      pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
   112    }
   113    report_rbu_vfs(pRbu);
   114  
   115    /* If nStep is less than or equal to zero, call
   116    ** sqlite3rbu_step() until either the RBU has been completely applied
   117    ** or an error occurs. Or, if nStep is greater than zero, call
   118    ** sqlite3rbu_step() a maximum of nStep times.  */
   119    for(i=0; (nStep<=0 || i<nStep) && sqlite3rbu_step(pRbu)==SQLITE_OK; i++);
   120    nProgress = sqlite3rbu_progress(pRbu);
   121    rc = sqlite3rbu_close(pRbu, &zErrmsg);
   122  
   123    /* Let the user know what happened. */
   124    switch( rc ){
   125      case SQLITE_OK:
   126        sqlite3_snprintf(sizeof(zBuf), zBuf,
   127            "SQLITE_OK: rbu update incomplete (%lld operations so far)\n",
   128            nProgress
   129        );
   130        fprintf(stdout, "%s", zBuf);
   131        break;
   132  
   133      case SQLITE_DONE:
   134        sqlite3_snprintf(sizeof(zBuf), zBuf,
   135            "SQLITE_DONE: rbu update completed (%lld operations)\n",
   136            nProgress
   137        );
   138        fprintf(stdout, "%s", zBuf);
   139        break;
   140  
   141      default:
   142        fprintf(stderr, "error=%d: %s\n", rc, zErrmsg);
   143        break;
   144    }
   145  
   146    sqlite3_free(zErrmsg);
   147    return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1;
   148  }