00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "sqliteInt.h"
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
00027 Db *aNew;
00028 int rc, i;
00029 char *zFile, *zName;
00030 sqlite *db;
00031 Vdbe *v;
00032
00033 v = sqliteGetVdbe(pParse);
00034 sqliteVdbeAddOp(v, OP_Halt, 0, 0);
00035 if( pParse->explain ) return;
00036 db = pParse->db;
00037 if( db->file_format<4 ){
00038 sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an "
00039 "older format master database", 0);
00040 pParse->rc = SQLITE_ERROR;
00041 return;
00042 }
00043 if( db->nDb>=MAX_ATTACHED+2 ){
00044 sqliteErrorMsg(pParse, "too many attached databases - max %d",
00045 MAX_ATTACHED);
00046 pParse->rc = SQLITE_ERROR;
00047 return;
00048 }
00049
00050 zFile = 0;
00051 sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
00052 if( zFile==0 ) return;
00053 sqliteDequote(zFile);
00054 #ifndef SQLITE_OMIT_AUTHORIZATION
00055 if( sqliteAuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
00056 sqliteFree(zFile);
00057 return;
00058 }
00059 #endif
00060
00061 zName = 0;
00062 sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
00063 if( zName==0 ) return;
00064 sqliteDequote(zName);
00065 for(i=0; i<db->nDb; i++){
00066 if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
00067 sqliteErrorMsg(pParse, "database %z is already in use", zName);
00068 pParse->rc = SQLITE_ERROR;
00069 sqliteFree(zFile);
00070 return;
00071 }
00072 }
00073
00074 if( db->aDb==db->aDbStatic ){
00075 aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
00076 if( aNew==0 ) return;
00077 memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
00078 }else{
00079 aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
00080 if( aNew==0 ) return;
00081 }
00082 db->aDb = aNew;
00083 aNew = &db->aDb[db->nDb++];
00084 memset(aNew, 0, sizeof(*aNew));
00085 sqliteHashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
00086 sqliteHashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
00087 sqliteHashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
00088 sqliteHashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
00089 aNew->zName = zName;
00090 rc = sqliteBtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
00091 if( rc ){
00092 sqliteErrorMsg(pParse, "unable to open database: %s", zFile);
00093 }
00094 #if SQLITE_HAS_CODEC
00095 {
00096 extern int sqliteCodecAttach(sqlite*, int, void*, int);
00097 char *zKey = 0;
00098 int nKey;
00099 if( pKey && pKey->z && pKey->n ){
00100 sqliteSetNString(&zKey, pKey->z, pKey->n, 0);
00101 sqliteDequote(zKey);
00102 nKey = strlen(zKey);
00103 }else{
00104 zKey = 0;
00105 nKey = 0;
00106 }
00107 sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
00108 }
00109 #endif
00110 sqliteFree(zFile);
00111 db->flags &= ~SQLITE_Initialized;
00112 if( pParse->nErr ) return;
00113 if( rc==SQLITE_OK ){
00114 rc = sqliteInit(pParse->db, &pParse->zErrMsg);
00115 }
00116 if( rc ){
00117 int i = db->nDb - 1;
00118 assert( i>=2 );
00119 if( db->aDb[i].pBt ){
00120 sqliteBtreeClose(db->aDb[i].pBt);
00121 db->aDb[i].pBt = 0;
00122 }
00123 sqliteResetInternalSchema(db, 0);
00124 pParse->nErr++;
00125 pParse->rc = SQLITE_ERROR;
00126 }
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136 void sqliteDetach(Parse *pParse, Token *pDbname){
00137 int i;
00138 sqlite *db;
00139 Vdbe *v;
00140 Db *pDb;
00141
00142 v = sqliteGetVdbe(pParse);
00143 sqliteVdbeAddOp(v, OP_Halt, 0, 0);
00144 if( pParse->explain ) return;
00145 db = pParse->db;
00146 for(i=0; i<db->nDb; i++){
00147 pDb = &db->aDb[i];
00148 if( pDb->pBt==0 || pDb->zName==0 ) continue;
00149 if( strlen(pDb->zName)!=pDbname->n ) continue;
00150 if( sqliteStrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
00151 }
00152 if( i>=db->nDb ){
00153 sqliteErrorMsg(pParse, "no such database: %T", pDbname);
00154 return;
00155 }
00156 if( i<2 ){
00157 sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
00158 return;
00159 }
00160 #ifndef SQLITE_OMIT_AUTHORIZATION
00161 if( sqliteAuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
00162 return;
00163 }
00164 #endif
00165 sqliteBtreeClose(pDb->pBt);
00166 pDb->pBt = 0;
00167 sqliteFree(pDb->zName);
00168 sqliteResetInternalSchema(db, i);
00169 if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
00170 db->nDb--;
00171 if( i<db->nDb ){
00172 db->aDb[i] = db->aDb[db->nDb];
00173 memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0]));
00174 sqliteResetInternalSchema(db, i);
00175 }
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185 int sqliteFixInit(
00186 DbFixer *pFix,
00187 Parse *pParse,
00188 int iDb,
00189 const char *zType,
00190 const Token *pName
00191 ){
00192 sqlite *db;
00193
00194 if( iDb<0 || iDb==1 ) return 0;
00195 db = pParse->db;
00196 assert( db->nDb>iDb );
00197 pFix->pParse = pParse;
00198 pFix->zDb = db->aDb[iDb].zName;
00199 pFix->zType = zType;
00200 pFix->pName = pName;
00201 return 1;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 int sqliteFixSrcList(
00219 DbFixer *pFix,
00220 SrcList *pList
00221 ){
00222 int i;
00223 const char *zDb;
00224
00225 if( pList==0 ) return 0;
00226 zDb = pFix->zDb;
00227 for(i=0; i<pList->nSrc; i++){
00228 if( pList->a[i].zDatabase==0 ){
00229 pList->a[i].zDatabase = sqliteStrDup(zDb);
00230 }else if( sqliteStrICmp(pList->a[i].zDatabase,zDb)!=0 ){
00231 sqliteErrorMsg(pFix->pParse,
00232 "%s %z cannot reference objects in database %s",
00233 pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n),
00234 pList->a[i].zDatabase);
00235 return 1;
00236 }
00237 if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
00238 if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
00239 }
00240 return 0;
00241 }
00242 int sqliteFixSelect(
00243 DbFixer *pFix,
00244 Select *pSelect
00245 ){
00246 while( pSelect ){
00247 if( sqliteFixExprList(pFix, pSelect->pEList) ){
00248 return 1;
00249 }
00250 if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
00251 return 1;
00252 }
00253 if( sqliteFixExpr(pFix, pSelect->pWhere) ){
00254 return 1;
00255 }
00256 if( sqliteFixExpr(pFix, pSelect->pHaving) ){
00257 return 1;
00258 }
00259 pSelect = pSelect->pPrior;
00260 }
00261 return 0;
00262 }
00263 int sqliteFixExpr(
00264 DbFixer *pFix,
00265 Expr *pExpr
00266 ){
00267 while( pExpr ){
00268 if( sqliteFixSelect(pFix, pExpr->pSelect) ){
00269 return 1;
00270 }
00271 if( sqliteFixExprList(pFix, pExpr->pList) ){
00272 return 1;
00273 }
00274 if( sqliteFixExpr(pFix, pExpr->pRight) ){
00275 return 1;
00276 }
00277 pExpr = pExpr->pLeft;
00278 }
00279 return 0;
00280 }
00281 int sqliteFixExprList(
00282 DbFixer *pFix,
00283 ExprList *pList
00284 ){
00285 int i;
00286 if( pList==0 ) return 0;
00287 for(i=0; i<pList->nExpr; i++){
00288 if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
00289 return 1;
00290 }
00291 }
00292 return 0;
00293 }
00294 int sqliteFixTriggerStep(
00295 DbFixer *pFix,
00296 TriggerStep *pStep
00297 ){
00298 while( pStep ){
00299 if( sqliteFixSelect(pFix, pStep->pSelect) ){
00300 return 1;
00301 }
00302 if( sqliteFixExpr(pFix, pStep->pWhere) ){
00303 return 1;
00304 }
00305 if( sqliteFixExprList(pFix, pStep->pExprList) ){
00306 return 1;
00307 }
00308 pStep = pStep->pNext;
00309 }
00310 return 0;
00311 }