1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

Store primary key definitions for modified tables in changesets. Add the sqlite3changeset_pk() API to extract this data from a changeset iterator.

FossilOrigin-Name: 54298ee5ed183d1f1c49524f25e8ae1407f3d4b5
This commit is contained in:
dan
2011-03-24 11:22:59 +00:00
parent 9a48bf528d
commit 244593c846
8 changed files with 132 additions and 75 deletions

View File

@ -39,6 +39,7 @@ struct sqlite3_changeset_iter {
int nCol; /* Number of columns in zTab */
int op; /* Current operation */
int bIndirect; /* True if current change was indirect */
u8 *abPK; /* Primary key array */
sqlite3_value **apValue; /* old.* and new.* values */
};
@ -1357,6 +1358,7 @@ int sqlite3session_changeset(
/* Write a table header */
sessionAppendByte(&buf, 'T', &rc);
sessionAppendVarint(&buf, nCol, &rc);
sessionAppendBlob(&buf, pTab->abPK, nCol, &rc);
sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc);
/* Build and compile a statement to execute: */
@ -1575,6 +1577,8 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){
if( c=='T' ){
int nByte; /* Bytes to allocate for apValue */
aChange += sessionVarintGet(aChange, &p->nCol);
p->abPK = (u8 *)aChange;
aChange += p->nCol;
p->zTab = (char *)aChange;
aChange += (strlen((char *)aChange) + 1);
p->op = *(aChange++);
@ -1611,7 +1615,7 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){
}
/*
** The following three functions extract information on the current change
** The following function extracts information on the current change
** from a changeset iterator. They may only be called after changeset_next()
** has returned SQLITE_ROW.
*/
@ -1629,6 +1633,16 @@ int sqlite3changeset_op(
return SQLITE_OK;
}
int sqlite3changeset_pk(
sqlite3_changeset_iter *pIter, /* Iterator object */
unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */
int *pnCol /* OUT: Number of entries in output array */
){
*pabPK = pIter->abPK;
if( pnCol ) *pnCol = pIter->nCol;
return SQLITE_OK;
}
/*
** This function may only be called while the iterator is pointing to an
** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
@ -1764,7 +1778,15 @@ int sqlite3changeset_invert(
u8 eType = aIn[i];
switch( eType ){
case 'T': {
/* A 'table' record consists of:
**
** * A constant 'T' character,
** * Number of columns in said table (a varint),
** * An array of nCol bytes (abPK),
** * A nul-terminated table name.
*/
int nByte = 1 + sessionVarintGet(&aIn[i+1], &nCol);
nByte += nCol;
nByte += 1 + strlen((char *)&aIn[i+nByte]);
memcpy(&aOut[i], &aIn[i], nByte);
i += nByte;