DBD-SQLite2

 view release on metacpan or  search on metacpan

vacuum.c  view on Meta::CPAN

** This callback is used to transfer PRAGMA settings from one database
** to the other.  The value in argv[0] should be passed to a pragma
** identified by ((vacuumStruct*)pArg)->zPragma.
*/
static int vacuumCallback3(void *pArg, int argc, char **argv, char **NotUsed){
  vacuumStruct *p = (vacuumStruct*)pArg;
  char zBuf[200];
  assert( argc==1 );
  if( argv==0 ) return 0;
  assert( argv[0]!=0 );
  assert( strlen(p->zPragma)<100 );
  assert( strlen(argv[0])<30 );
  sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
  p->rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
  return p->rc;
}

/*
** Generate a random name of 20 character in length.
*/
static void randomName(unsigned char *zBuf){
  static const unsigned char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789";
  int i;
  sqliteRandomness(20, zBuf);
  for(i=0; i<20; i++){
    zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
  }
}
#endif

/*
** The non-standard VACUUM command is used to clean up the database,
** collapse free space, etc.  It is modelled after the VACUUM command
** in PostgreSQL.
**
** In version 1.0.x of SQLite, the VACUUM command would call
** gdbm_reorganize() on all the database tables.  But beginning
** with 2.0.0, SQLite no longer uses GDBM so this command has
** become a no-op.
*/
void sqliteVacuum(Parse *pParse, Token *pTableName){
  Vdbe *v = sqliteGetVdbe(pParse);
  sqliteVdbeAddOp(v, OP_Vacuum, 0, 0);
  return;
}

/*
** This routine implements the OP_Vacuum opcode of the VDBE.
*/
int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
#if !defined(SQLITE_OMIT_VACUUM) || SQLITE_OMIT_VACUUM
  const char *zFilename;  /* full pathname of the database file */
  int nFilename;          /* number of characters  in zFilename[] */
  char *zTemp = 0;        /* a temporary file in same directory as zFilename */
  sqlite *dbNew = 0;      /* The new vacuumed database */
  int rc = SQLITE_OK;     /* Return code from service routines */
  int i;                  /* Loop counter */
  char *zErrMsg;          /* Error message */
  vacuumStruct sVac;      /* Information passed to callbacks */

  /* These are all of the pragmas that need to be transferred over
  ** to the new database */
  static const char *zPragma[] = {
     "default_synchronous",
     "default_cache_size",
     /* "default_temp_store", */
  };

  if( db->flags & SQLITE_InTrans ){
    sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction", 
       (char*)0);
    return SQLITE_ERROR;
  }
  if( db->flags & SQLITE_Interrupt ){
    return SQLITE_INTERRUPT;
  }
  memset(&sVac, 0, sizeof(sVac));

  /* Get the full pathname of the database file and create two
  ** temporary filenames in the same directory as the original file.
  */
  zFilename = sqliteBtreeGetFilename(db->aDb[0].pBt);
  if( zFilename==0 ){
    /* This only happens with the in-memory database.  VACUUM is a no-op
    ** there, so just return */
    return SQLITE_OK;
  }
  nFilename = strlen(zFilename);
  zTemp = sqliteMalloc( nFilename+100 );
  if( zTemp==0 ) return SQLITE_NOMEM;
  strcpy(zTemp, zFilename);
  for(i=0; i<10; i++){
    zTemp[nFilename] = '-';
    randomName((unsigned char*)&zTemp[nFilename+1]);
    if( !sqliteOsFileExists(zTemp) ) break;
  }
  if( i>=10 ){
    sqliteSetString(pzErrMsg, "unable to create a temporary database file "
       "in the same directory as the original database", (char*)0);
    goto end_of_vacuum;
  }

  
  dbNew = sqlite_open(zTemp, 0, &zErrMsg);
  if( dbNew==0 ){
    sqliteSetString(pzErrMsg, "unable to open a temporary database at ",
       zTemp, " - ", zErrMsg, (char*)0);
    goto end_of_vacuum;
  }
  if( (rc = execsql(pzErrMsg, db, "BEGIN"))!=0 ) goto end_of_vacuum;
  if( (rc = execsql(pzErrMsg, dbNew, "PRAGMA synchronous=off; BEGIN"))!=0 ){
    goto end_of_vacuum;
  }
  
  sVac.dbOld = db;
  sVac.dbNew = dbNew;
  sVac.pzErrMsg = pzErrMsg;
  for(i=0; rc==SQLITE_OK && i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
    char zBuf[200];



( run in 3.765 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )