engine/sqlite/src/attach.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2003 April 6
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** This file contains code used to implement the ATTACH and DETACH commands.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
** $Id: attach.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
#ifndef SQLITE_OMIT_ATTACH
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
** Resolve an expression that was part of an ATTACH or DETACH statement. This
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
** is slightly different from resolving a normal SQL expression, because simple
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
** identifiers are treated as strings, not possible column names or aliases.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
** i.e. if the parser sees:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
**     ATTACH DATABASE abc AS def
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
** it treats the two expressions as literal strings 'abc' and 'def' instead of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
** looking for columns of the same name.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
** This only applies to the root node of pExpr, so the statement:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
**     ATTACH DATABASE abc||def AS 'db2'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
** will fail because neither abc or def can be resolved.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
  int rc = SQLITE_OK;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
  if( pExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
    if( pExpr->op!=TK_ID ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
      rc = sqlite3ExprResolveNames(pName, pExpr);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
      if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
        sqlite3ErrorMsg(pName->pParse, "invalid name: \"%T\"", &pExpr->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
        return SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
      pExpr->op = TK_STRING;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
  return rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
** An SQL user-function registered to do the work of an ATTACH statement. The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
** three arguments to the function come directly from an attach statement:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
**     ATTACH DATABASE x AS y KEY z
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
**     SELECT sqlite_attach(x, y, z)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
** third argument.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
static void attachFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
  int rc = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
  sqlite3 *db = (sqlite3 *)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
  const char *zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
  const char *zFile;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
  Db *aNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
  char *zErrDyn = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
  char zErr[128];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
  zFile = (const char *)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
  zName = (const char *)sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
  if( zFile==0 ) zFile = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
  if( zName==0 ) zName = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  /* Check for the following errors:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
  **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
  **     * Too many attached databases,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
  **     * Transaction currently open
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
  **     * Specified database name already being used.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
  if( db->nDb>=SQLITE_MAX_ATTACHED+2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
    sqlite3_snprintf(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
      sizeof(zErr), zErr, "too many attached databases - max %d", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
      SQLITE_MAX_ATTACHED
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
    goto attach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
  if( !db->autoCommit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
    sqlite3_snprintf(sizeof(zErr), zErr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
                     "cannot ATTACH database within transaction");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
    goto attach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
  for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
    char *z = db->aDb[i].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
    if( z && zName && sqlite3StrICmp(z, zName)==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
      sqlite3_snprintf(sizeof(zErr), zErr, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
                       "database %s is already in use", zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
      goto attach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
  /* Allocate the new entry in the db->aDb[] array and initialise the schema
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
  ** hash tables.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
  if( db->aDb==db->aDbStatic ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
    aNew = (Db*)sqlite3_malloc( sizeof(db->aDb[0])*3 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
    if( aNew==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
    memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
    aNew = (Db*)sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
    if( aNew==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
    } 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
  db->aDb = aNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
  aNew = &db->aDb[db->nDb++];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
  memset(aNew, 0, sizeof(*aNew));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
  /* Open the database file. If the btree is successfully opened, use
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
  ** it to obtain the database schema. At this point the schema may
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
  ** or may not be initialised.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
  rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
                           db->openFlags | SQLITE_OPEN_MAIN_DB,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
                           &aNew->pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
    aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
    if( !aNew->pSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
      rc = SQLITE_NOMEM;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
      sqlite3_snprintf(sizeof(zErr), zErr, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
        "attached databases must use the same text encoding as main database");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
      goto attach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
    sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
  aNew->zName = sqlite3DbStrDup(db, zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
  aNew->safety_level = 3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
#if SQLITE_HAS_CODEC
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
  {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
    extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
    int nKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
    char *zKey;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
    int t = sqlite3_value_type(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
    switch( t ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
      case SQLITE_INTEGER:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
      case SQLITE_FLOAT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
        zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
        rc = SQLITE_ERROR;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
        
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
      case SQLITE_TEXT:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
      case SQLITE_BLOB:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
        nKey = sqlite3_value_bytes(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
        zKey = (char *)sqlite3_value_blob(argv[2]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
      case SQLITE_NULL:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
        /* No key specified.  Use the key from the main database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
        sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
        break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
  /* If the file was opened successfully, read the schema for the new database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
  ** If this fails, or if opening the file failed, then close the file and 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
  ** remove the entry from the db->aDb[] array. i.e. put everything back the way
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
  ** we found it.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
  if( rc==SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
    sqlite3SafetyOn(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
    rc = sqlite3Init(db, &zErrDyn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
    sqlite3SafetyOff(db);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
  if( rc ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
    int iDb = db->nDb - 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
    assert( iDb>=2 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
    if( db->aDb[iDb].pBt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
      sqlite3BtreeClose(db->aDb[iDb].pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
      db->aDb[iDb].pBt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
      db->aDb[iDb].pSchema = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
    sqlite3ResetInternalSchema(db, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
    db->nDb = iDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
      sqlite3_snprintf(sizeof(zErr),zErr, "out of memory");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
    }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
      sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
    goto attach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
  return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
attach_error:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
  /* Return an error if we get here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
  if( zErrDyn ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
    sqlite3_result_error(context, zErrDyn, -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
    sqlite3_free(zErrDyn);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
  }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
    zErr[sizeof(zErr)-1] = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
    sqlite3_result_error(context, zErr, -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
** An SQL user-function registered to do the work of an DETACH statement. The
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
** three arguments to the function come directly from a detach statement:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
**     DETACH DATABASE x
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
**     SELECT sqlite_detach(x)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
static void detachFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  const char *zName = (const char *)sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
  sqlite3 *db = (sqlite3 *)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
  Db *pDb = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
  char zErr[128];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
  if( zName==0 ) zName = "";
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
  for(i=0; i<db->nDb; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
    pDb = &db->aDb[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
    if( pDb->pBt==0 ) continue;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
    if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  if( i>=db->nDb ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
    sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
    goto detach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
  if( i<2 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
    sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
    goto detach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  if( !db->autoCommit ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
    sqlite3_snprintf(sizeof(zErr), zErr,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
                     "cannot DETACH database within transaction");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
    goto detach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
    sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
    goto detach_error;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
  sqlite3BtreeClose(pDb->pBt);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
  pDb->pBt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
  pDb->pSchema = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
  sqlite3ResetInternalSchema(db, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
  return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
detach_error:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
  sqlite3_result_error(context, zErr, -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
** This procedure generates VDBE code for a single invocation of either the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
** sqlite_detach() or sqlite_attach() SQL user functions.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
static void codeAttach(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
  Parse *pParse,       /* The parser context */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
  int type,            /* Either SQLITE_ATTACH or SQLITE_DETACH */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  const char *zFunc,   /* Either "sqlite_attach" or "sqlite_detach */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
  int nFunc,           /* Number of args to pass to zFunc */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
  Expr *pAuthArg,      /* Expression to pass to authorization callback */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
  Expr *pFilename,     /* Name of database file */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
  Expr *pDbname,       /* Name of the database to use internally */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
  Expr *pKey           /* Database key for encryption extension */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
  int rc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
  NameContext sName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
  Vdbe *v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
  FuncDef *pFunc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
  sqlite3* db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
#ifndef SQLITE_OMIT_AUTHORIZATION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
  assert( db->mallocFailed || pAuthArg );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
  if( pAuthArg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
    char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
    if( !zAuthArg ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
      goto attach_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
    rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
    sqlite3_free(zAuthArg);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
    if(rc!=SQLITE_OK ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
      goto attach_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
#endif /* SQLITE_OMIT_AUTHORIZATION */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
  memset(&sName, 0, sizeof(NameContext));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
  sName.pParse = pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
  if( 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
  ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
    pParse->nErr++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
    goto attach_end;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
  sqlite3ExprCode(pParse, pFilename);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
  sqlite3ExprCode(pParse, pDbname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
  sqlite3ExprCode(pParse, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
  assert( v || db->mallocFailed );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
  if( v ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
    sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
    pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
    sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
    ** statement only). For DETACH, set it to false (expire all existing
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
    ** statements).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
    sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
attach_end:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
  sqlite3ExprDelete(pFilename);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
  sqlite3ExprDelete(pDbname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
  sqlite3ExprDelete(pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
** Called by the parser to compile a DETACH statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
**     DETACH pDbname
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
void sqlite3Detach(Parse *pParse, Expr *pDbname){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
  codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
** Called by the parser to compile an ATTACH statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
**     ATTACH p AS pDbname KEY pKey
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
  codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
#endif /* SQLITE_OMIT_ATTACH */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
** Register the functions sqlite_attach and sqlite_detach.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
void sqlite3AttachFunctions(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
#ifndef SQLITE_OMIT_ATTACH
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
  static const int enc = SQLITE_UTF8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
  sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
  sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
** Initialize a DbFixer structure.  This routine must be called prior
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
** to passing the structure to one of the sqliteFixAAAA() routines below.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
** The return value indicates whether or not fixation is required.  TRUE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
** means we do need to fix the database references, FALSE means we do not.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
int sqlite3FixInit(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
  DbFixer *pFix,      /* The fixer to be initialized */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
  Parse *pParse,      /* Error messages will be written here */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
  int iDb,            /* This is the database that must be used */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
  const char *zType,  /* "view", "trigger", or "index" */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
  const Token *pName  /* Name of the view, trigger, or index */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
  sqlite3 *db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
  if( iDb<0 || iDb==1 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
  db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
  assert( db->nDb>iDb );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
  pFix->pParse = pParse;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
  pFix->zDb = db->aDb[iDb].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
  pFix->zType = zType;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
  pFix->pName = pName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
  return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
** The following set of routines walk through the parse tree and assign
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
** a specific database to all table references where the database name
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
** was left unspecified in the original SQL statement.  The pFix structure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
** must have been initialized by a prior call to sqlite3FixInit().
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
** These routines are used to make sure that an index, trigger, or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
** view in one database does not refer to objects in a different database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
** (Exception: indices, triggers, and views in the TEMP database are
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
** allowed to refer to anything.)  If a reference is explicitly made
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
** to an object in a different database, an error message is added to
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
** pParse->zErrMsg and these routines return non-zero.  If everything
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
** checks out, these routines return 0.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
int sqlite3FixSrcList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
  DbFixer *pFix,       /* Context of the fixation */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
  SrcList *pList       /* The Source list to check and modify */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
  const char *zDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
  SrcList::SrcList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
  if( pList==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
  zDb = pFix->zDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
    if( pItem->zDatabase==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
      pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
    }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
      sqlite3ErrorMsg(pFix->pParse,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
         "%s %T cannot reference objects in database %s",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
         pFix->zType, pFix->pName, pItem->zDatabase);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
    if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
    if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
int sqlite3FixSelect(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
  DbFixer *pFix,       /* Context of the fixation */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
  Select *pSelect      /* The SELECT statement to be fixed to one database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
  while( pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
    if( sqlite3FixExprList(pFix, pSelect->pEList) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
    if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
    if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
    if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
    pSelect = pSelect->pPrior;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
int sqlite3FixExpr(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
  DbFixer *pFix,     /* Context of the fixation */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
  Expr *pExpr        /* The expression to be fixed to one database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
  while( pExpr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
    if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
    if( sqlite3FixExprList(pFix, pExpr->pList) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
    if( sqlite3FixExpr(pFix, pExpr->pRight) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
    pExpr = pExpr->pLeft;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
int sqlite3FixExprList(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
  DbFixer *pFix,     /* Context of the fixation */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
  ExprList *pList    /* The expression to be fixed to one database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
  ExprList::ExprList_item *pItem;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
  if( pList==0 ) return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
  for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
    if( sqlite3FixExpr(pFix, pItem->pExpr) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
int sqlite3FixTriggerStep(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
  DbFixer *pFix,     /* Context of the fixation */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
  TriggerStep *pStep /* The trigger step be fixed to one database */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
  while( pStep ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
    if( sqlite3FixSelect(pFix, pStep->pSelect) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
    if( sqlite3FixExpr(pFix, pStep->pWhere) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
    if( sqlite3FixExprList(pFix, pStep->pExprList) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
      return 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
    pStep = pStep->pNext;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
  return 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
#endif