Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More testing of ATTACH and DETACH. (CVS 899) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
51f515f28cb1cc3e8f0c3531724dc887 |
User & Date: | drh 2003-04-05 16:56:29.000 |
Context
2003-04-06
| ||
20:44 | Simplify the BTree interface by shortening names. Added two new methods for accessing the current filename and for changing the name of the database file. (CVS 900) (check-in: 185d8dc8d0 user: drh tags: trunk) | |
2003-04-05
| ||
16:56 | More testing of ATTACH and DETACH. (CVS 899) (check-in: 51f515f28c user: drh tags: trunk) | |
03:42 | Begin testing the new ATTACH and DETACH commands. (CVS 898) (check-in: 7a0f8024a1 user: drh tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
21 22 23 24 25 26 27 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | ** COPY ** VACUUM ** BEGIN TRANSACTION ** COMMIT ** ROLLBACK ** PRAGMA ** ** $Id: build.c,v 1.141 2003/04/05 16:56:29 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> /* ** This routine is called when a new SQL statement is beginning to ** be parsed. Check to see if the schema for the database needs |
︙ | ︙ | |||
2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 | sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0); sqliteVdbeAddOp(v, OP_Callback, 3, 0); ++i; pIdx = pIdx->pNext; } } }else #ifndef NDEBUG if( sqliteStrICmp(zLeft, "parser_trace")==0 ){ extern void sqliteParserTrace(FILE*, char *); if( getBoolean(zRight) ){ sqliteParserTrace(stdout, "parser: "); }else{ | > > > > > > > > > > > > > > > > > > | 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 | sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0); sqliteVdbeAddOp(v, OP_Callback, 3, 0); ++i; pIdx = pIdx->pNext; } } }else if( sqliteStrICmp(zLeft, "database_list")==0 ){ int i; static VdbeOp indexListPreface[] = { { OP_ColumnName, 0, 0, "seq"}, { OP_ColumnName, 1, 0, "name"}, }; sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface); for(i=0; i<db->nDb; i++){ if( db->aDb[i].pBt==0 ) continue; assert( db->aDb[i].zName!=0 ); sqliteVdbeAddOp(v, OP_Integer, i, 0); sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeChangeP3(v, -1, db->aDb[i].zName, P3_STATIC); sqliteVdbeAddOp(v, OP_Callback, 2, 0); } }else #ifndef NDEBUG if( sqliteStrICmp(zLeft, "parser_trace")==0 ){ extern void sqliteParserTrace(FILE*, char *); if( getBoolean(zRight) ){ sqliteParserTrace(stdout, "parser: "); }else{ |
︙ | ︙ | |||
2669 2670 2671 2672 2673 2674 2675 2676 2677 | sqlite *db; if( pParse->explain ) return; db = pParse->db; if( db->file_format<4 ){ sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an " "older format master database", 0); return; } | > | > | 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 | sqlite *db; if( pParse->explain ) return; db = pParse->db; if( db->file_format<4 ){ sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an " "older format master database", 0); pParse->rc = SQLITE_ERROR; return; } if( db->nDb>=MAX_ATTACHED+2 ){ sqliteErrorMsg(pParse, "too many attached databases - max %d", MAX_ATTACHED); pParse->rc = SQLITE_ERROR; return; } if( db->aDb==db->aDbStatic ){ aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ |
︙ | ︙ | |||
2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 | zName = 0; sqliteSetNString(&zName, pDbname->z, pDbname->n, 0); if( zName==0 ) return; sqliteDequote(zName); for(i=0; i<db->nDb; i++){ if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){ sqliteErrorMsg(pParse, "database %z is already in use", zName); return; } } aNew->zName = zName; zFile = 0; sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0); if( zFile==0 ) return; sqliteDequote(zFile); rc = sqliteBtreeOpen(zFile, 0, MAX_PAGES, &aNew->pBt); if( rc ){ sqliteErrorMsg(pParse, "unable to open database: %s", zFile); } sqliteFree(zFile); db->flags &= ~SQLITE_Initialized; if( pParse->nErr ) return; rc = sqliteInit(pParse->db, &pParse->zErrMsg); if( rc ){ sqliteResetInternalSchema(db, 0); pParse->nErr++; } } /* ** This routine is called by the parser to process a DETACH statement: ** ** DETACH DATABASE dbname | > > > | 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 | zName = 0; sqliteSetNString(&zName, pDbname->z, pDbname->n, 0); if( zName==0 ) return; sqliteDequote(zName); for(i=0; i<db->nDb; i++){ if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){ sqliteErrorMsg(pParse, "database %z is already in use", zName); db->nDb--; pParse->rc = SQLITE_ERROR; return; } } aNew->zName = zName; zFile = 0; sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0); if( zFile==0 ) return; sqliteDequote(zFile); rc = sqliteBtreeOpen(zFile, 0, MAX_PAGES, &aNew->pBt); if( rc ){ sqliteErrorMsg(pParse, "unable to open database: %s", zFile); } sqliteFree(zFile); db->flags &= ~SQLITE_Initialized; if( pParse->nErr ) return; rc = sqliteInit(pParse->db, &pParse->zErrMsg); if( rc ){ sqliteResetInternalSchema(db, 0); pParse->nErr++; pParse->rc = SQLITE_ERROR; } } /* ** This routine is called by the parser to process a DETACH statement: ** ** DETACH DATABASE dbname |
︙ | ︙ | |||
2744 2745 2746 2747 2748 2749 2750 | if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break; } if( i>=db->nDb ){ sqliteErrorMsg(pParse, "no such database: %T", pDbname); return; } if( i<2 ){ | | | > > > > > | > | 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 | if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break; } if( i>=db->nDb ){ sqliteErrorMsg(pParse, "no such database: %T", pDbname); return; } if( i<2 ){ sqliteErrorMsg(pParse, "cannot detach database %T", pDbname); return; } sqliteBtreeClose(db->aDb[i].pBt); db->aDb[i].pBt = 0; sqliteResetInternalSchema(db, i); db->nDb--; if( i<db->nDb ){ db->aDb[i] = db->aDb[db->nDb]; memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0])); sqliteResetInternalSchema(db, i); } } |
Changes to test/attach.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # | | > | | > | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # # $Id: attach.test,v 1.2 2003/04/05 16:56:30 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl for {set i 2} {$i<=15} {incr i} { file delete -force test$i.db file delete -force test$i.db-journal } do_test attach-1.1 { execsql { CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(3,4); SELECT * FROM t1; } } {1 2 3 4} do_test attach-1.2 { sqlite db2 test2.db execsql { CREATE TABLE t2(x,y); INSERT INTO t2 VALUES(1,'x'); INSERT INTO t2 VALUES(2,'y'); SELECT * FROM t2; } db2 } {1 x 2 y} do_test attach-1.3 { execsql { ATTACH DATABASE 'test2.db' AS two; SELECT * FROM two.t2; } } {1 x 2 y} |
︙ | ︙ | |||
61 62 63 64 65 66 67 | } } {1 {no such table: t2}} do_test attach-1.7 { catchsql { SELECT * FROM two.t2; } } {1 {no such table: two.t2}} | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | } } {1 {no such table: t2}} do_test attach-1.7 { catchsql { SELECT * FROM two.t2; } } {1 {no such table: two.t2}} do_test attach-1.8 { catchsql { ATTACH DATABASE 'test3.db' AS three; } } {1 {cannot attach empty database: three}} do_test attach-1.9 { catchsql { SELECT * FROM three.sqlite_master; } } {1 {no such table: three.sqlite_master}} do_test attach-1.10 { catchsql { DETACH DATABASE three; } } {1 {no such database: three}} do_test attach-1.11 { execsql { ATTACH 'test.db' AS db2; ATTACH 'test.db' AS db3; ATTACH 'test.db' AS db4; ATTACH 'test.db' AS db5; ATTACH 'test.db' AS db6; ATTACH 'test.db' AS db7; ATTACH 'test.db' AS db8; ATTACH 'test.db' AS db9; } } {} do_test attach-1.11b { execsql { PRAGMA database_list; } } {0 main 1 temp 2 db2 3 db3 4 db4 5 db5 6 db6 7 db7 8 db8 9 db9} do_test attach-1.12 { catchsql { ATTACH 'test.db' as db2; } } {1 {database db2 is already in use}} do_test attach-1.13 { catchsql { ATTACH 'test.db' as db5; } } {1 {database db5 is already in use}} do_test attach-1.14 { catchsql { ATTACH 'test.db' as db9; } } {1 {database db9 is already in use}} do_test attach-1.15 { catchsql { ATTACH 'test.db' as main; } } {1 {database main is already in use}} do_test attach-1.16 { catchsql { ATTACH 'test.db' as temp; } } {1 {database temp is already in use}} do_test attach-1.17 { catchsql { ATTACH 'test.db' as MAIN; } } {1 {database MAIN is already in use}} do_test attach-1.18 { catchsql { ATTACH 'test.db' as db10; ATTACH 'test.db' as db11; } } {0 {}} do_test attach-1.19 { catchsql { ATTACH 'test.db' as db12; } } {1 {too many attached databases - max 10}} do_test attach-1.20 { execsql { DETACH db5; PRAGMA database_list; } } {0 main 1 temp 2 db2 3 db3 4 db4 5 db11 6 db6 7 db7 8 db8 9 db9 10 db10} do_test attach-1.21 { catchsql { ATTACH 'test.db' as db12; } } {0 {}} do_test attach-1.22 { catchsql { ATTACH 'test.db' as db13; } } {1 {too many attached databases - max 10}} do_test attach-1.23 { catchsql { DETACH db14; } } {1 {no such database: db14}} do_test attach-1.24 { catchsql { DETACH db12; } } {0 {}} do_test attach-1.25 { catchsql { DETACH db12; } } {1 {no such database: db12}} do_test attach-1.26 { catchsql { DETACH main; } } {1 {cannot detach database main}} do_test attach-1.27 { catchsql { DETACH Temp; } } {1 {cannot detach database Temp}} do_test attach-1.28 { catchsql { DETACH db11; DETACH db10; DETACH db9; DETACH db8; DETACH db7; DETACH db6; DETACH db4; DETACH db3; DETACH db2; } } {0 {}} do_test attach-1.29 { execsql { PRAGMA database_list } } {0 main 1 temp} for {set i 2} {$i<=15} {incr i} { catch {db$i close} } finish_test |