Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the sqlite3_snapshot_cmp() API. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | snapshot-cmp |
Files: | files | file ages | folders |
SHA1: | c698a21af740ca1019c3a771fb83e569 |
User & Date: | dan 2016-04-11 19:59:52 |
Context
2016-04-12
| ||
15:14 | Update the documentation for sqlite3_snapshot_cmp() to make the circumstances under which the comparison is valid clearer. Add tests for the same. Closed-Leaf check-in: 8fc83474 user: dan tags: snapshot-cmp | |
2016-04-11
| ||
19:59 | Add the sqlite3_snapshot_cmp() API. check-in: c698a21a user: dan tags: snapshot-cmp | |
19:01 | Performance optimization to sqlite3Dequote() and its callers. check-in: 9efe2265 user: drh tags: trunk | |
Changes
Changes to src/sqlite.h.in.
8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 |
** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** ** The [sqlite3_snapshot_free()] interface is only available when the ** SQLITE_ENABLE_SNAPSHOT compile-time option is used. */ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif /* _SQLITE3_H_ */ |
> > > > > > > > > > > > > > > > > > > > > |
8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 |
** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** ** The [sqlite3_snapshot_free()] interface is only available when the ** SQLITE_ENABLE_SNAPSHOT compile-time option is used. */ SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** CAPI3REF: Compare the ages of two snapshot handles. ** EXPERIMENTAL ** ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages ** of two valid snapshot handles. ** ** If the two snapshot handles are not associated with the same database ** file, the results are undefined. If either of the snapshot handles ** is no longer valid because the database snapshot they refer to has been ** destroyed by a checkpoint, the results are undefined. ** ** Otherwise, this API returns a negative value if P1 refers to an older ** snapshot than P2, zero if the two handles refer to the same database ** snapshot, and a positive value if P1 is a newer snapshot than P2. */ SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( sqlite3_snapshot *p1, sqlite3_snapshot *p2 ); /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif #ifdef __cplusplus } /* End of the 'extern "C"' block */ #endif #endif /* _SQLITE3_H_ */ |
Changes to src/test1.c.
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
....
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
|
}
pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
sqlite3_snapshot_free(pSnapshot);
return TCL_OK;
}
#endif /* SQLITE_ENABLE_SNAPSHOT */
/*
** Usage: sqlite3_next_stmt DB STMT
**
** Return the next statment in sequence after STMT.
*/
static int test_next_stmt(
void * clientData,
................................................................................
{ "sqlite3_config_sqllog", test_config_sqllog, 0 },
#endif
{ "vfs_current_time_int64", vfsCurrentTimeInt64, 0 },
#ifdef SQLITE_ENABLE_SNAPSHOT
{ "sqlite3_snapshot_get", test_snapshot_get, 0 },
{ "sqlite3_snapshot_open", test_snapshot_open, 0 },
{ "sqlite3_snapshot_free", test_snapshot_free, 0 },
#endif
};
static int bitmask_size = sizeof(Bitmask)*8;
static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
int i;
extern int sqlite3_sync_count, sqlite3_fullsync_count;
extern int sqlite3_opentemp_count;
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
....
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
|
} pSnapshot = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); sqlite3_snapshot_free(pSnapshot); return TCL_OK; } #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_SNAPSHOT /* ** Usage: sqlite3_snapshot_cmp SNAPSHOT1 SNAPSHOT2 */ static int test_snapshot_cmp( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ int res; sqlite3_snapshot *p1; sqlite3_snapshot *p2; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "SNAPSHOT1 SNAPSHOT2"); return TCL_ERROR; } p1 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[1])); p2 = (sqlite3_snapshot*)sqlite3TestTextToPtr(Tcl_GetString(objv[2])); res = sqlite3_snapshot_cmp(p1, p2); Tcl_SetObjResult(interp, Tcl_NewIntObj(res)); return TCL_OK; } #endif /* SQLITE_ENABLE_SNAPSHOT */ /* ** Usage: sqlite3_next_stmt DB STMT ** ** Return the next statment in sequence after STMT. */ static int test_next_stmt( void * clientData, ................................................................................ { "sqlite3_config_sqllog", test_config_sqllog, 0 }, #endif { "vfs_current_time_int64", vfsCurrentTimeInt64, 0 }, #ifdef SQLITE_ENABLE_SNAPSHOT { "sqlite3_snapshot_get", test_snapshot_get, 0 }, { "sqlite3_snapshot_open", test_snapshot_open, 0 }, { "sqlite3_snapshot_free", test_snapshot_free, 0 }, { "sqlite3_snapshot_cmp", test_snapshot_cmp, 0 }, #endif }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; |
Changes to src/wal.c.
3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 |
} /* Try to open on pSnapshot when the next read-transaction starts */ void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ pWal->pSnapshot = (WalIndexHdr*)pSnapshot; } #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_ZIPVFS /* ** If the argument is not NULL, it points to a Wal object that holds a ** read-lock. This function returns the database page-size if it is known, ** or zero if it is not (or if pWal is NULL). |
> > > > > > > > > > > > > > > > > |
3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 |
} /* Try to open on pSnapshot when the next read-transaction starts */ void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ pWal->pSnapshot = (WalIndexHdr*)pSnapshot; } /* ** Return a +ve value if snapshot p1 is newer than p2. A -ve value if ** p1 is older than p2 and zero if p1 and p2 are the same snapshot. */ int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ WalIndexHdr *pHdr1 = (WalIndexHdr*)p1; WalIndexHdr *pHdr2 = (WalIndexHdr*)p2; /* aSalt[0] is a copy of the value stored in the wal file header. It ** is incremented each time the wal file is restarted. */ if( pHdr1->aSalt[0]<pHdr2->aSalt[0] ) return -1; if( pHdr1->aSalt[0]>pHdr2->aSalt[0] ) return +1; if( pHdr1->mxFrame<pHdr2->mxFrame ) return -1; if( pHdr1->mxFrame>pHdr2->mxFrame ) return +1; return 0; } #endif /* SQLITE_ENABLE_SNAPSHOT */ #ifdef SQLITE_ENABLE_ZIPVFS /* ** If the argument is not NULL, it points to a Wal object that holds a ** read-lock. This function returns the database page-size if it is known, ** or zero if it is not (or if pWal is NULL). |
Changes to test/snapshot.test.
360 361 362 363 364 365 366 367 368 |
db2 close sqlite3 db2 test.db db2 eval "BEGIN" list [catch {sqlite3_snapshot_open db2 main $::snapshot} msg] $msg } {1 SQLITE_ERROR} sqlite3_snapshot_free $snapshot finish_test |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
db2 close sqlite3 db2 test.db db2 eval "BEGIN" list [catch {sqlite3_snapshot_open db2 main $::snapshot} msg] $msg } {1 SQLITE_ERROR} sqlite3_snapshot_free $snapshot #------------------------------------------------------------------------- # The following tests investigate the sqlite3_snapshot_cmp() API. # catch { db2 close } reset_db do_execsql_test 7.1 { PRAGMA journal_mode = wal; CREATE TABLE t1(x); } wal do_test 7.1.2 { execsql { BEGIN ; PRAGMA application_id } set p1 [sqlite3_snapshot_get db main] execsql { INSERT INTO t1 VALUES(10); COMMIT; } execsql { BEGIN ; PRAGMA application_id } set p2 [sqlite3_snapshot_get db main] execsql COMMIT sqlite3_snapshot_cmp $p1 $p2 } {-1} do_test 7.1.3 { sqlite3_snapshot_cmp $p2 $p1 } {1} do_test 7.1.4 { list [sqlite3_snapshot_cmp $p1 $p1] [sqlite3_snapshot_cmp $p2 $p2] } {0 0} sqlite3_snapshot_free $p1 sqlite3_snapshot_free $p2 finish_test |