Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem involving session objects and attached databases. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sessions |
Files: | files | file ages | folders |
SHA1: |
ad91d30073a8faa7eb064dd2e1cc4d22 |
User & Date: | dan 2011-03-19 19:19:26.000 |
Context
2011-03-20
| ||
11:20 | Documentation format updates to sqlite3session.h. (check-in: f227f60210 user: dan tags: sessions) | |
2011-03-19
| ||
19:19 | Fix a problem involving session objects and attached databases. (check-in: ad91d30073 user: dan tags: sessions) | |
18:46 | Fix a bug in changeset generation code. (check-in: 825df75ba4 user: dan tags: sessions) | |
Changes
Changes to ext/session/session2.test.
︙ | ︙ | |||
30 31 32 33 34 35 36 | proc do_common_sql {sql} { execsql $sql db execsql $sql db2 } proc xConflict args { return "OMIT" } | | > | | | 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | proc do_common_sql {sql} { execsql $sql db execsql $sql db2 } proc xConflict args { return "OMIT" } proc do_then_apply_sql {sql {dbname main}} { sqlite3session S db $dbname db eval "SELECT name FROM $dbname.sqlite_master WHERE type = 'table'" { S attach $name } db eval $sql sqlite3changeset_apply db2 [S changeset] xConflict S delete } |
︙ | ︙ | |||
167 168 169 170 171 172 173 | } 10 { BEGIN; DELETE FROM t1 WHERE 1; ROLLBACK; } } { | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | } 10 { BEGIN; DELETE FROM t1 WHERE 1; ROLLBACK; } } { do_then_apply_sql $sql do_test 1.$tn { compare_db db db2 } {} } # The following block of tests is similar to the last, except that the # session object is recording changes made to an attached database. The # main database contains a table of the same name as the table being # modified within the attached db. # test_reset forcedelete test.db3 sqlite3 db3 test.db3 do_test 2.0 { execsql { ATTACH 'test.db3' AS 'aux'; CREATE TABLE t1(a, b PRIMARY KEY); CREATE TABLE t2(x, y, z); CREATE TABLE t3(a); CREATE TABLE aux.t1(a PRIMARY KEY, b); CREATE TABLE aux.t2(a, b INTEGER PRIMARY KEY); CREATE TABLE aux.t3(a, b, c, PRIMARY KEY(a, b)); } execsql { CREATE TABLE t1(a PRIMARY KEY, b); CREATE TABLE t2(a, b INTEGER PRIMARY KEY); CREATE TABLE t3(a, b, c, PRIMARY KEY(a, b)); } db2 } {} foreach {tn sql} { 1 { INSERT INTO aux.t1 VALUES(1, 2) } 2 { INSERT INTO aux.t2 VALUES(1, NULL); INSERT INTO aux.t2 VALUES(2, NULL); INSERT INTO aux.t2 VALUES(3, NULL); DELETE FROM aux.t2 WHERE a = 2; INSERT INTO aux.t2 VALUES(4, NULL); UPDATE aux.t2 SET b=0 WHERE b=1; } 3 { INSERT INTO aux.t3 SELECT *, NULL FROM aux.t2 } 4 { INSERT INTO aux.t3 SELECT a||a, b||b, NULL FROM aux.t3; DELETE FROM aux.t3 WHERE rowid%2; } 5 { UPDATE aux.t3 SET c = a||b } 6 { UPDATE aux.t1 SET a = 32 } 7 { INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; DELETE FROM aux.t1 WHERE (rowid%3)==0; } 8 { BEGIN; INSERT INTO aux.t1 SELECT randomblob(32), randomblob(32) FROM aux.t1; ROLLBACK; } 9 { BEGIN; UPDATE aux.t1 SET b = 'xxx'; ROLLBACK; } 10 { BEGIN; DELETE FROM aux.t1 WHERE 1; ROLLBACK; } } { do_then_apply_sql $sql aux do_test 2.$tn { compare_db db3 db2 } {} } catch {db3 close} finish_test |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 | } sqlite3_free(buf2.aBuf); } } static int sessionSelectStmt( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ int nCol, const char **azCol, u8 *abPK, sqlite3_stmt **ppStmt ){ int rc = SQLITE_OK; int i; const char *zSep = ""; SessionBuffer buf = {0, 0, 0}; sessionAppendStr(&buf, "SELECT * FROM ", &rc); sessionAppendIdent(&buf, zTab, &rc); sessionAppendStr(&buf, " WHERE ", &rc); for(i=0; i<nCol; i++){ if( abPK[i] ){ sessionAppendStr(&buf, zSep, &rc); sessionAppendIdent(&buf, azCol[i], &rc); sessionAppendStr(&buf, " = ?", &rc); | > > > | 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 | } sqlite3_free(buf2.aBuf); } } static int sessionSelectStmt( sqlite3 *db, /* Database handle */ const char *zDb, /* Database name */ const char *zTab, /* Table name */ int nCol, const char **azCol, u8 *abPK, sqlite3_stmt **ppStmt ){ int rc = SQLITE_OK; int i; const char *zSep = ""; SessionBuffer buf = {0, 0, 0}; sessionAppendStr(&buf, "SELECT * FROM ", &rc); sessionAppendIdent(&buf, zDb, &rc); sessionAppendStr(&buf, ".", &rc); sessionAppendIdent(&buf, zTab, &rc); sessionAppendStr(&buf, " WHERE ", &rc); for(i=0; i<nCol; i++){ if( abPK[i] ){ sessionAppendStr(&buf, zSep, &rc); sessionAppendIdent(&buf, azCol[i], &rc); sessionAppendStr(&buf, " = ?", &rc); |
︙ | ︙ | |||
1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 | ** this call will be a no-op. */ *pnChangeset = 0; *ppChangeset = 0; rc = pSession->rc; for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ int nCol = pTab->nCol; /* Local copy of member variable */ u8 *abPK = pTab->abPK; /* Local copy of member variable */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); sessionAppendVarint(&buf, nCol, &rc); | > | | > | 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 | ** this call will be a no-op. */ *pnChangeset = 0; *ppChangeset = 0; rc = pSession->rc; for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; int nCol = pTab->nCol; /* Local copy of member variable */ u8 *abPK = pTab->abPK; /* Local copy of member variable */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ /* Write a table header */ sessionAppendByte(&buf, 'T', &rc); sessionAppendVarint(&buf, nCol, &rc); sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc); /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ rc = sessionSelectStmt( db, pSession->zDb, zName, nCol, pTab->azCol, abPK, &pSel); } if( rc==SQLITE_OK && nCol!=sqlite3_column_count(pSel) ){ rc = SQLITE_SCHEMA; } nNoop = buf.nBuf; |
︙ | ︙ | |||
1938 1939 1940 1941 1942 1943 1944 | ** pointing to the prepared version of the SQL statement. */ static int sessionSelectRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ | | > | 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 | ** pointing to the prepared version of the SQL statement. */ static int sessionSelectRow( sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ return sessionSelectStmt( db, "main", zTab, p->nCol, p->azCol, p->abPK, &p->pSelect); } /* ** Formulate and prepare an INSERT statement to add a record to table zTab. ** For example: ** ** INSERT INTO main."zTab" VALUES(?1, ?2, ?3 ...); |
︙ | ︙ |