Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improve coverage of session module a bit more. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | sessions |
Files: | files | file ages | folders |
SHA1: |
4255a9f609c4fd43582a0874143eabe2 |
User & Date: | dan 2011-03-25 19:06:10.000 |
Context
2011-03-30
| ||
02:03 | Merge in all the latest changes from trunk. (check-in: b11d941e92 user: drh tags: sessions) | |
2011-03-25
| ||
19:06 | Improve coverage of session module a bit more. (check-in: 4255a9f609 user: dan tags: sessions) | |
10:52 | Improve coverage of session module code. (check-in: 666123c8d0 user: dan tags: sessions) | |
Changes
Changes to ext/session/session2.test.
︙ | ︙ | |||
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | do_iterator_test 1.1 t1 { DELETE FROM t1 WHERE a = 'i'; INSERT INTO t1 VALUES('ii', 'two'); } { {DELETE t1 0 X. {t i t one} {}} {INSERT t1 0 X. {} {t ii t two}} } do_iterator_test 1.2 t1 { INSERT INTO t1 VALUES(1.5, 99.9) } { {INSERT t1 0 X. {} {f 1.5 f 99.9}} } # Execute each of the following blocks of SQL on database [db1]. Collect # changes using a session object. Apply the resulting changeset to # database [db2]. Then check that the contents of the two databases are # identical. # | > > > > > > > > > > > > | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | do_iterator_test 1.1 t1 { DELETE FROM t1 WHERE a = 'i'; INSERT INTO t1 VALUES('ii', 'two'); } { {DELETE t1 0 X. {t i t one} {}} {INSERT t1 0 X. {} {t ii t two}} } do_iterator_test 1.2 t1 { INSERT INTO t1 VALUES(1.5, 99.9) } { {INSERT t1 0 X. {} {f 1.5 f 99.9}} } do_iterator_test 1.3 t1 { UPDATE t1 SET b = 100.1 WHERE a = 1.5; UPDATE t1 SET b = 99.9 WHERE a = 1.5; } { } do_iterator_test 1.4 t1 { UPDATE t1 SET b = 100.1 WHERE a = 1.5; } { {UPDATE t1 0 X. {f 1.5 f 99.9} {{} {} f 100.1}} } # Execute each of the following blocks of SQL on database [db1]. Collect # changes using a session object. Apply the resulting changeset to # database [db2]. Then check that the contents of the two databases are # identical. # |
︙ | ︙ | |||
516 517 518 519 520 521 522 | set changeset [changeset_from_sql { INSERT INTO t1 VALUES('x', 1) }] sqlite3changeset_apply db2 $changeset xConflict } {} do_test 9.3 { execsql { SELECT * FROM t1 } db2 } {x 2} | > | > > > > > > > > > > > > > > > > > > > > > > > > > | 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 | set changeset [changeset_from_sql { INSERT INTO t1 VALUES('x', 1) }] sqlite3changeset_apply db2 $changeset xConflict } {} do_test 9.3 { execsql { SELECT * FROM t1 } db2 } {x 2} #------------------------------------------------------------------------- # test_reset db function enable [list S enable] do_common_sql { CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES('x', 'X'); } do_iterator_test 10.1 t1 { INSERT INTO t1 VALUES('y', 'Y'); SELECT enable(0); INSERT INTO t1 VALUES('z', 'Z'); SELECT enable(1); } { {INSERT t1 0 X. {} {t y t Y}} } sqlite3session S db main do_execsql_test 10.2 { SELECT enable(0); SELECT enable(-1); SELECT enable(1); SELECT enable(-1); } {0 0 1 1} S delete finish_test |
Changes to ext/session/session3.test.
︙ | ︙ | |||
142 143 144 145 146 147 148 | DROP TABLE t2; CREATE TABLE t2(a, b PRIMARY KEY); } S attach t2 execsql { INSERT INTO t2 VALUES(1, 2); DROP TABLE t2; | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | DROP TABLE t2; CREATE TABLE t2(a, b PRIMARY KEY); } S attach t2 execsql { INSERT INTO t2 VALUES(1, 2); DROP TABLE t2; CREATE TABLE t2(a PRIMARY KEY, b); } list [catch { S changeset } msg] $msg } {1 SQLITE_SCHEMA} do_test 2.4 { S delete sqlite3session S db main |
︙ | ︙ |
Changes to ext/session/session4.test.
︙ | ︙ | |||
55 56 57 58 59 60 61 62 | } do_test 1.2 { set x [binary format "ca*" 0 [string range $changeset 1 end]] list [catch { sqlite3changeset_invert $x } msg] $msg } {1 SQLITE_CORRUPT} finish_test | > > > > > | 55 56 57 58 59 60 61 62 63 64 65 66 67 | } do_test 1.2 { set x [binary format "ca*" 0 [string range $changeset 1 end]] list [catch { sqlite3changeset_invert $x } msg] $msg } {1 SQLITE_CORRUPT} do_test 1.3 { set x [binary format "ca*" 0 [string range $changeset 1 end]] list [catch { sqlite3changeset_apply db $x xConflict } msg] $msg } {1 SQLITE_CORRUPT} finish_test |
Changes to ext/session/sessionfault.test.
︙ | ︙ | |||
41 42 43 44 45 46 47 | do_faultsim_test 1.1 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen sqlite3 db2 test.db2 } -body { do_then_apply_sql { | | | | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | do_faultsim_test 1.1 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen sqlite3 db2 test.db2 } -body { do_then_apply_sql { INSERT INTO t1 VALUES('a string value', 8, 9); UPDATE t1 SET c = 10 WHERE a = 1; DELETE FROM t1 WHERE a = 4; } } -test { faultsim_test_result {0 {}} {1 SQLITE_NOMEM} faultsim_integrity_check if {$testrc==0} { compare_db db db2 } } do_faultsim_test 1.2 -faults oom-* -prep { catch {db2 close} catch {db close} faultsim_restore_and_reopen } -body { sqlite3session S db main S attach * execsql { INSERT INTO t1 VALUES('a string value', 8, 9); UPDATE t1 SET c = 10 WHERE a = 1; DELETE FROM t1 WHERE a = 4; } set ::changeset [S changeset] set {} {} } -test { catch { S delete } |
︙ | ︙ |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
1177 1178 1179 1180 1181 1182 1183 | if( dVal==sqlite3_column_double(pStmt, i) ) break; } } bChanged = 1; break; } | < | > | 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 | if( dVal==sqlite3_column_double(pStmt, i) ) break; } } bChanged = 1; break; } default: { int nByte; int nHdr = 1 + sessionVarintGet(&pCsr[1], &nByte); assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); nAdvance = nHdr + nByte; if( eType==sqlite3_column_type(pStmt, i) && nByte==sqlite3_column_bytes(pStmt, i) && 0==memcmp(&pCsr[nHdr], sqlite3_column_blob(pStmt, i), nByte) ){ break; } |
︙ | ︙ | |||
1256 1257 1258 1259 1260 1261 1262 | return rc; } static int sessionSelectBind( sqlite3_stmt *pSelect, int nCol, u8 *abPK, | | < | | | 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 | return rc; } static int sessionSelectBind( sqlite3_stmt *pSelect, int nCol, u8 *abPK, SessionChange *pChange ){ int i; int rc = SQLITE_OK; u8 *a = pChange->aRecord; for(i=0; i<nCol && rc==SQLITE_OK; i++){ int eType = *a++; switch( eType ){ case SQLITE_NULL: assert( abPK[i]==0 ); break; case SQLITE_INTEGER: { if( abPK[i] ){ i64 iVal = sessionGetI64(a); rc = sqlite3_bind_int64(pSelect, i+1, iVal); } |
︙ | ︙ | |||
1301 1302 1303 1304 1305 1306 1307 | if( abPK[i] ){ rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT); } a += n; break; } | | > | 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 | if( abPK[i] ){ rc = sqlite3_bind_text(pSelect, i+1, (char *)a, n, SQLITE_TRANSIENT); } a += n; break; } default: { int n; assert( eType==SQLITE_BLOB ); a += sessionVarintGet(a, &n); if( abPK[i] ){ rc = sqlite3_bind_blob(pSelect, i+1, a, n, SQLITE_TRANSIENT); } a += n; break; } |
︙ | ︙ | |||
1333 1334 1335 1336 1337 1338 1339 | void **ppChangeset /* OUT: Buffer containing changeset */ ){ sqlite3 *db = pSession->db; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ int rc; /* Return code */ | < < > | > > > > | 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 | void **ppChangeset /* OUT: Buffer containing changeset */ ){ sqlite3 *db = pSession->db; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ int rc; /* Return code */ /* Zero the output variables in case an error occurs. If this session ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), ** this call will be a no-op. */ *pnChangeset = 0; *ppChangeset = 0; if( pSession->rc ) return pSession->rc; rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); if( rc!=SQLITE_OK ) return rc; sqlite3_mutex_enter(sqlite3_db_mutex(db)); for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; int nCol; /* Number of columns in table */ u8 *abPK; /* Primary key array */ const char **azCol = 0; /* Table columns */ |
︙ | ︙ | |||
1371 1372 1373 1374 1375 1376 1377 | /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ rc = sessionSelectStmt( db, pSession->zDb, zName, nCol, azCol, abPK, &pSel); } | < < < < | < | | | | | | | | | | | | | | | | | | | < > | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 | /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ rc = sessionSelectStmt( db, pSession->zDb, zName, nCol, azCol, abPK, &pSel); } nNoop = buf.nBuf; for(i=0; i<pTab->nChange && rc==SQLITE_OK; i++){ SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ rc = sessionSelectBind(pSel, nCol, abPK, p); if( sqlite3_step(pSel)==SQLITE_ROW ){ int iCol; if( p->bInsert ){ sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); for(iCol=0; iCol<nCol; iCol++){ sessionAppendCol(&buf, pSel, iCol, &rc); } }else{ sessionAppendUpdate(&buf, pSel, p, abPK, &rc); } }else if( !p->bInsert ){ /* A DELETE change */ sessionAppendByte(&buf, SQLITE_DELETE, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); sessionAppendBlob(&buf, p->aRecord, p->nRecord, &rc); } if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); } } } sqlite3_finalize(pSel); if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } sqlite3_free(azCol); } } if( rc==SQLITE_OK ){ *pnChangeset = buf.nBuf; *ppChangeset = buf.aBuf; }else{ sqlite3_free(buf.aBuf); } sqlite3_exec(db, "RELEASE changeset", 0, 0, 0); sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } /* ** Enable or disable the session object passed as the first argument. */ |
︙ | ︙ |
Changes to ext/session/test_session.c.
︙ | ︙ | |||
81 82 83 84 85 86 87 | case 2: /* delete */ Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); break; case 3: { /* enable */ int val; | | | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | case 2: /* delete */ Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); break; case 3: { /* enable */ int val; if( Tcl_GetIntFromObj(interp, objv[2], &val) ) return TCL_ERROR; val = sqlite3session_enable(pSession, val); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(val)); break; } case 4: { /* indirect */ int val; |
︙ | ︙ | |||
432 433 434 435 436 437 438 439 440 441 442 443 444 445 | rc = sqlite3changeset_start(&pIter, nChangeSet, pChangeSet); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ int nCol; /* Number of columns in table */ int op; /* SQLITE_INSERT, UPDATE or DELETE */ const char *zTab; /* Name of table change applies to */ Tcl_Obj *pVar; /* Tcl value to set $VARNAME to */ Tcl_Obj *pOld; /* Vector of old.* values */ Tcl_Obj *pNew; /* Vector of new.* values */ int bIndirect; | > | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | rc = sqlite3changeset_start(&pIter, nChangeSet, pChangeSet); if( rc!=SQLITE_OK ){ return test_session_error(interp, rc); } while( SQLITE_ROW==sqlite3changeset_next(pIter) ){ int nCol; /* Number of columns in table */ int nCol2; /* Number of columns in table */ int op; /* SQLITE_INSERT, UPDATE or DELETE */ const char *zTab; /* Name of table change applies to */ Tcl_Obj *pVar; /* Tcl value to set $VARNAME to */ Tcl_Obj *pOld; /* Vector of old.* values */ Tcl_Obj *pNew; /* Vector of new.* values */ int bIndirect; |
︙ | ︙ | |||
456 457 458 459 460 461 462 | )); Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); zPK = ckalloc(nCol+1); memset(zPK, 0, nCol+1); | | > | 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 | )); Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1)); Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect)); zPK = ckalloc(nCol+1); memset(zPK, 0, nCol+1); sqlite3changeset_pk(pIter, &abPK, &nCol2); assert( nCol==nCol2 ); for(i=0; i<nCol; i++){ zPK[i] = (abPK[i] ? 'X' : '.'); } Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zPK, -1)); ckfree(zPK); pOld = Tcl_NewObj(); |
︙ | ︙ |