engine/sqlite/src/attach.cpp
author skip
Thu, 25 Feb 2010 14:29:19 +0000
changeset 2 29cda98b007e
permissions -rw-r--r--
Initial import of Podcatcher from the Bergamot project
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