mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +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:
@ -88,14 +88,14 @@ do_test 2.1.1 {
|
|||||||
execsql { INSERT INTO t1 VALUES(3, 'Thonburi') }
|
execsql { INSERT INTO t1 VALUES(3, 'Thonburi') }
|
||||||
} {}
|
} {}
|
||||||
do_changeset_test 2.1.2 S {
|
do_changeset_test 2.1.2 S {
|
||||||
{INSERT t1 0 {} {i 1 t Sukhothai}}
|
{INSERT t1 0 X. {} {i 1 t Sukhothai}}
|
||||||
{INSERT t1 0 {} {i 2 t Ayutthaya}}
|
{INSERT t1 0 X. {} {i 2 t Ayutthaya}}
|
||||||
{INSERT t1 0 {} {i 3 t Thonburi}}
|
{INSERT t1 0 X. {} {i 3 t Thonburi}}
|
||||||
}
|
}
|
||||||
do_changeset_invert_test 2.1.3 S {
|
do_changeset_invert_test 2.1.3 S {
|
||||||
{DELETE t1 0 {i 1 t Sukhothai} {}}
|
{DELETE t1 0 X. {i 1 t Sukhothai} {}}
|
||||||
{DELETE t1 0 {i 2 t Ayutthaya} {}}
|
{DELETE t1 0 X. {i 2 t Ayutthaya} {}}
|
||||||
{DELETE t1 0 {i 3 t Thonburi} {}}
|
{DELETE t1 0 X. {i 3 t Thonburi} {}}
|
||||||
}
|
}
|
||||||
do_test 2.1.4 { S delete } {}
|
do_test 2.1.4 { S delete } {}
|
||||||
|
|
||||||
@ -105,14 +105,14 @@ do_test 2.2.1 {
|
|||||||
execsql { DELETE FROM t1 WHERE 1 }
|
execsql { DELETE FROM t1 WHERE 1 }
|
||||||
} {}
|
} {}
|
||||||
do_changeset_test 2.2.2 S {
|
do_changeset_test 2.2.2 S {
|
||||||
{DELETE t1 0 {i 1 t Sukhothai} {}}
|
{DELETE t1 0 X. {i 1 t Sukhothai} {}}
|
||||||
{DELETE t1 0 {i 2 t Ayutthaya} {}}
|
{DELETE t1 0 X. {i 2 t Ayutthaya} {}}
|
||||||
{DELETE t1 0 {i 3 t Thonburi} {}}
|
{DELETE t1 0 X. {i 3 t Thonburi} {}}
|
||||||
}
|
}
|
||||||
do_changeset_invert_test 2.2.3 S {
|
do_changeset_invert_test 2.2.3 S {
|
||||||
{INSERT t1 0 {} {i 1 t Sukhothai}}
|
{INSERT t1 0 X. {} {i 1 t Sukhothai}}
|
||||||
{INSERT t1 0 {} {i 2 t Ayutthaya}}
|
{INSERT t1 0 X. {} {i 2 t Ayutthaya}}
|
||||||
{INSERT t1 0 {} {i 3 t Thonburi}}
|
{INSERT t1 0 X. {} {i 3 t Thonburi}}
|
||||||
}
|
}
|
||||||
do_test 2.2.4 { S delete } {}
|
do_test 2.2.4 { S delete } {}
|
||||||
|
|
||||||
@ -131,19 +131,19 @@ do_test 2.3.1 {
|
|||||||
} {}
|
} {}
|
||||||
|
|
||||||
do_changeset_test 2.3.2 S {
|
do_changeset_test 2.3.2 S {
|
||||||
{INSERT t1 0 {} {i 10 t Sukhothai}}
|
{INSERT t1 0 X. {} {i 10 t Sukhothai}}
|
||||||
{DELETE t1 0 {i 1 t Sukhothai} {}}
|
{DELETE t1 0 X. {i 1 t Sukhothai} {}}
|
||||||
{UPDATE t1 0 {i 2 t Ayutthaya} {{} {} t Surin}}
|
{UPDATE t1 0 X. {i 2 t Ayutthaya} {{} {} t Surin}}
|
||||||
{DELETE t1 0 {i 3 t Thonburi} {}}
|
{DELETE t1 0 X. {i 3 t Thonburi} {}}
|
||||||
{INSERT t1 0 {} {i 20 t Thapae}}
|
{INSERT t1 0 X. {} {i 20 t Thapae}}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_changeset_invert_test 2.3.3 S {
|
do_changeset_invert_test 2.3.3 S {
|
||||||
{DELETE t1 0 {i 10 t Sukhothai} {}}
|
{DELETE t1 0 X. {i 10 t Sukhothai} {}}
|
||||||
{INSERT t1 0 {} {i 1 t Sukhothai}}
|
{INSERT t1 0 X. {} {i 1 t Sukhothai}}
|
||||||
{UPDATE t1 0 {{} {} t Surin} {i 2 t Ayutthaya}}
|
{UPDATE t1 0 X. {{} {} t Surin} {i 2 t Ayutthaya}}
|
||||||
{INSERT t1 0 {} {i 3 t Thonburi}}
|
{INSERT t1 0 X. {} {i 3 t Thonburi}}
|
||||||
{DELETE t1 0 {i 20 t Thapae} {}}
|
{DELETE t1 0 X. {i 20 t Thapae} {}}
|
||||||
}
|
}
|
||||||
do_test 2.3.4 { S delete } {}
|
do_test 2.3.4 { S delete } {}
|
||||||
|
|
||||||
|
@ -41,13 +41,13 @@ do_iterator_test 1.1 t1 {
|
|||||||
DELETE FROM t1 WHERE a = 'i';
|
DELETE FROM t1 WHERE a = 'i';
|
||||||
INSERT INTO t1 VALUES('ii', 'two');
|
INSERT INTO t1 VALUES('ii', 'two');
|
||||||
} {
|
} {
|
||||||
{DELETE t1 0 {t i t one} {}}
|
{DELETE t1 0 X. {t i t one} {}}
|
||||||
{INSERT t1 0 {} {t ii t two}}
|
{INSERT t1 0 X. {} {t ii t two}}
|
||||||
}
|
}
|
||||||
do_iterator_test 1.2 t1 {
|
do_iterator_test 1.2 t1 {
|
||||||
INSERT INTO t1 VALUES(1.5, 99.9)
|
INSERT INTO t1 VALUES(1.5, 99.9)
|
||||||
} {
|
} {
|
||||||
{INSERT t1 0 {} {f 1.5 f 99.9}}
|
{INSERT t1 0 X. {} {f 1.5 f 99.9}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -228,15 +228,15 @@ foreach {tn sql changeset} {
|
|||||||
INSERT INTO t1 VALUES(NULL);
|
INSERT INTO t1 VALUES(NULL);
|
||||||
INSERT INTO t1 VALUES(456);
|
INSERT INTO t1 VALUES(456);
|
||||||
} {
|
} {
|
||||||
{INSERT t1 0 {} {i 456}}
|
{INSERT t1 0 X {} {i 456}}
|
||||||
{INSERT t1 0 {} {i 123}}
|
{INSERT t1 0 X {} {i 123}}
|
||||||
}
|
}
|
||||||
|
|
||||||
2 {
|
2 {
|
||||||
UPDATE t1 SET a = NULL;
|
UPDATE t1 SET a = NULL;
|
||||||
} {
|
} {
|
||||||
{DELETE t1 0 {i 456} {}}
|
{DELETE t1 0 X {i 456} {}}
|
||||||
{DELETE t1 0 {i 123} {}}
|
{DELETE t1 0 X {i 123} {}}
|
||||||
}
|
}
|
||||||
|
|
||||||
3 { DELETE FROM t1 } { }
|
3 { DELETE FROM t1 } { }
|
||||||
@ -244,14 +244,14 @@ foreach {tn sql changeset} {
|
|||||||
4 {
|
4 {
|
||||||
INSERT INTO t3 VALUES(NULL, NULL)
|
INSERT INTO t3 VALUES(NULL, NULL)
|
||||||
} {
|
} {
|
||||||
{INSERT t3 0 {} {n {} i 1}}
|
{INSERT t3 0 .X {} {n {} i 1}}
|
||||||
}
|
}
|
||||||
|
|
||||||
5 { INSERT INTO t2 VALUES(1, 2, NULL) } { }
|
5 { INSERT INTO t2 VALUES(1, 2, NULL) } { }
|
||||||
6 { INSERT INTO t2 VALUES(1, NULL, 3) } { }
|
6 { INSERT INTO t2 VALUES(1, NULL, 3) } { }
|
||||||
7 { INSERT INTO t2 VALUES(1, NULL, NULL) } { }
|
7 { INSERT INTO t2 VALUES(1, NULL, NULL) } { }
|
||||||
8 { INSERT INTO t2 VALUES(1, 2, 3) } { {INSERT t2 0 {} {i 1 i 2 i 3}} }
|
8 { INSERT INTO t2 VALUES(1, 2, 3) } { {INSERT t2 0 .XX {} {i 1 i 2 i 3}} }
|
||||||
9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 0 {i 1 i 2 i 3} {}} }
|
9 { DELETE FROM t2 WHERE 1 } { {DELETE t2 0 .XX {i 1 i 2 i 3} {}} }
|
||||||
|
|
||||||
} {
|
} {
|
||||||
do_iterator_test 4.$tn {t1 t2 t3} $sql $changeset
|
do_iterator_test 4.$tn {t1 t2 t3} $sql $changeset
|
||||||
@ -269,14 +269,14 @@ do_execsql_test 5.0 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach {tn sql changeset} {
|
foreach {tn sql changeset} {
|
||||||
1 { INSERT INTO t1 VALUES(35) } { {INSERT t1 0 {} {i 35}} }
|
1 { INSERT INTO t1 VALUES(35) } { {INSERT t1 0 X {} {i 35}} }
|
||||||
2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 0 {} {i 36 i 37}} }
|
2 { INSERT INTO t2 VALUES(36, 37) } { {INSERT t2 0 .X {} {i 36 i 37}} }
|
||||||
3 {
|
3 {
|
||||||
DELETE FROM t1 WHERE 1;
|
DELETE FROM t1 WHERE 1;
|
||||||
UPDATE t2 SET x = 34;
|
UPDATE t2 SET x = 34;
|
||||||
} {
|
} {
|
||||||
{UPDATE t2 0 {i 36 i 37} {i 34 {} {}}}
|
{UPDATE t2 0 .X {i 36 i 37} {i 34 {} {}}}
|
||||||
{DELETE t1 0 {i 35} {}}
|
{DELETE t1 0 X {i 35} {}}
|
||||||
}
|
}
|
||||||
} {
|
} {
|
||||||
do_iterator_test 5.$tn * $sql $changeset
|
do_iterator_test 5.$tn * $sql $changeset
|
||||||
@ -314,9 +314,9 @@ do_iterator_test 6.1.1 * {
|
|||||||
SELECT indirect(0);
|
SELECT indirect(0);
|
||||||
INSERT INTO t1 VALUES(3, 'three', 'iii');
|
INSERT INTO t1 VALUES(3, 'three', 'iii');
|
||||||
} {
|
} {
|
||||||
{INSERT t1 0 {} {i 1 t one t i}}
|
{INSERT t1 0 X.. {} {i 1 t one t i}}
|
||||||
{INSERT t1 1 {} {i 2 t two t ii}}
|
{INSERT t1 1 X.. {} {i 2 t two t ii}}
|
||||||
{INSERT t1 0 {} {i 3 t three t iii}}
|
{INSERT t1 0 X.. {} {i 3 t three t iii}}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_iterator_test 6.1.2 * {
|
do_iterator_test 6.1.2 * {
|
||||||
@ -324,7 +324,7 @@ do_iterator_test 6.1.2 * {
|
|||||||
UPDATE t1 SET c = 'I' WHERE a = 1;
|
UPDATE t1 SET c = 'I' WHERE a = 1;
|
||||||
SELECT indirect(0);
|
SELECT indirect(0);
|
||||||
} {
|
} {
|
||||||
{UPDATE t1 1 {i 1 {} {} t i} {{} {} {} {} t I}}
|
{UPDATE t1 1 X.. {i 1 {} {} t i} {{} {} {} {} t I}}
|
||||||
}
|
}
|
||||||
do_iterator_test 6.1.3 * {
|
do_iterator_test 6.1.3 * {
|
||||||
SELECT indirect(1);
|
SELECT indirect(1);
|
||||||
@ -332,7 +332,7 @@ do_iterator_test 6.1.3 * {
|
|||||||
SELECT indirect(0);
|
SELECT indirect(0);
|
||||||
UPDATE t1 SET c = 'o' WHERE a = 1;
|
UPDATE t1 SET c = 'o' WHERE a = 1;
|
||||||
} {
|
} {
|
||||||
{UPDATE t1 0 {i 1 {} {} t I} {{} {} {} {} t o}}
|
{UPDATE t1 0 X.. {i 1 {} {} t I} {{} {} {} {} t o}}
|
||||||
}
|
}
|
||||||
do_iterator_test 6.1.4 * {
|
do_iterator_test 6.1.4 * {
|
||||||
SELECT indirect(0);
|
SELECT indirect(0);
|
||||||
@ -340,7 +340,7 @@ do_iterator_test 6.1.4 * {
|
|||||||
SELECT indirect(1);
|
SELECT indirect(1);
|
||||||
UPDATE t1 SET c = 'i' WHERE a = 1;
|
UPDATE t1 SET c = 'i' WHERE a = 1;
|
||||||
} {
|
} {
|
||||||
{UPDATE t1 0 {i 1 {} {} t o} {{} {} {} {} t i}}
|
{UPDATE t1 0 X.. {i 1 {} {} t o} {{} {} {} {} t i}}
|
||||||
}
|
}
|
||||||
do_iterator_test 6.1.4 * {
|
do_iterator_test 6.1.4 * {
|
||||||
SELECT indirect(1);
|
SELECT indirect(1);
|
||||||
@ -348,14 +348,14 @@ do_iterator_test 6.1.4 * {
|
|||||||
SELECT indirect(1);
|
SELECT indirect(1);
|
||||||
UPDATE t1 SET c = 'I' WHERE a = 1;
|
UPDATE t1 SET c = 'I' WHERE a = 1;
|
||||||
} {
|
} {
|
||||||
{UPDATE t1 1 {i 1 {} {} t i} {{} {} {} {} t I}}
|
{UPDATE t1 1 X.. {i 1 {} {} t i} {{} {} {} {} t I}}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_iterator_test 6.1.5 * {
|
do_iterator_test 6.1.5 * {
|
||||||
INSERT INTO t2 VALUES(1, 'x');
|
INSERT INTO t2 VALUES(1, 'x');
|
||||||
} {
|
} {
|
||||||
{INSERT t2 0 {} {i 1 t x}}
|
{INSERT t2 0 X. {} {i 1 t x}}
|
||||||
{INSERT t2 1 {} {i 2 n {}}}
|
{INSERT t2 1 X. {} {i 2 n {}}}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_iterator_test 6.1.6 * {
|
do_iterator_test 6.1.6 * {
|
||||||
@ -364,8 +364,8 @@ do_iterator_test 6.1.6 * {
|
|||||||
SELECT indirect(0);
|
SELECT indirect(0);
|
||||||
UPDATE t2 SET y = 'y' WHERE x>2;
|
UPDATE t2 SET y = 'y' WHERE x>2;
|
||||||
} {
|
} {
|
||||||
{INSERT t2 0 {} {i 3 t y}}
|
{INSERT t2 0 X. {} {i 3 t y}}
|
||||||
{INSERT t2 0 {} {i 4 t y}}
|
{INSERT t2 0 X. {} {i 4 t y}}
|
||||||
}
|
}
|
||||||
|
|
||||||
do_iterator_test 6.1.7 * {
|
do_iterator_test 6.1.7 * {
|
||||||
@ -374,7 +374,7 @@ do_iterator_test 6.1.7 * {
|
|||||||
SELECT indirect(0);
|
SELECT indirect(0);
|
||||||
INSERT INTO t2 VALUES(4, 'new');
|
INSERT INTO t2 VALUES(4, 'new');
|
||||||
} {
|
} {
|
||||||
{UPDATE t2 0 {i 4 t y} {{} {} t new}}
|
{UPDATE t2 0 X. {i 4 t y} {{} {} t new}}
|
||||||
}
|
}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
@ -243,9 +243,9 @@ do_faultsim_test 5 -faults oom* -body {
|
|||||||
set x [list]
|
set x [list]
|
||||||
sqlite3session_foreach c $::inverse { lappend x $c }
|
sqlite3session_foreach c $::inverse { lappend x $c }
|
||||||
foreach c {
|
foreach c {
|
||||||
{DELETE t1 0 {t xxx t yyy} {}}
|
{DELETE t1 0 .X {t xxx t yyy} {}}
|
||||||
{INSERT t1 0 {} {t string i 1}}
|
{INSERT t1 0 .X {} {t string i 1}}
|
||||||
{UPDATE t1 0 {i 20 {} {}} {i 4 i 2}}
|
{UPDATE t1 0 .X {i 20 {} {}} {i 4 i 2}}
|
||||||
} { lappend y $c }
|
} { lappend y $c }
|
||||||
if {$x != $y} { error "changeset no good" }
|
if {$x != $y} { error "changeset no good" }
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ struct sqlite3_changeset_iter {
|
|||||||
int nCol; /* Number of columns in zTab */
|
int nCol; /* Number of columns in zTab */
|
||||||
int op; /* Current operation */
|
int op; /* Current operation */
|
||||||
int bIndirect; /* True if current change was indirect */
|
int bIndirect; /* True if current change was indirect */
|
||||||
|
u8 *abPK; /* Primary key array */
|
||||||
sqlite3_value **apValue; /* old.* and new.* values */
|
sqlite3_value **apValue; /* old.* and new.* values */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1357,6 +1358,7 @@ int sqlite3session_changeset(
|
|||||||
/* Write a table header */
|
/* Write a table header */
|
||||||
sessionAppendByte(&buf, 'T', &rc);
|
sessionAppendByte(&buf, 'T', &rc);
|
||||||
sessionAppendVarint(&buf, nCol, &rc);
|
sessionAppendVarint(&buf, nCol, &rc);
|
||||||
|
sessionAppendBlob(&buf, pTab->abPK, nCol, &rc);
|
||||||
sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc);
|
sessionAppendBlob(&buf, (u8 *)zName, strlen(zName)+1, &rc);
|
||||||
|
|
||||||
/* Build and compile a statement to execute: */
|
/* Build and compile a statement to execute: */
|
||||||
@ -1575,6 +1577,8 @@ int sqlite3changeset_next(sqlite3_changeset_iter *p){
|
|||||||
if( c=='T' ){
|
if( c=='T' ){
|
||||||
int nByte; /* Bytes to allocate for apValue */
|
int nByte; /* Bytes to allocate for apValue */
|
||||||
aChange += sessionVarintGet(aChange, &p->nCol);
|
aChange += sessionVarintGet(aChange, &p->nCol);
|
||||||
|
p->abPK = (u8 *)aChange;
|
||||||
|
aChange += p->nCol;
|
||||||
p->zTab = (char *)aChange;
|
p->zTab = (char *)aChange;
|
||||||
aChange += (strlen((char *)aChange) + 1);
|
aChange += (strlen((char *)aChange) + 1);
|
||||||
p->op = *(aChange++);
|
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()
|
** from a changeset iterator. They may only be called after changeset_next()
|
||||||
** has returned SQLITE_ROW.
|
** has returned SQLITE_ROW.
|
||||||
*/
|
*/
|
||||||
@ -1629,6 +1633,16 @@ int sqlite3changeset_op(
|
|||||||
return SQLITE_OK;
|
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
|
** This function may only be called while the iterator is pointing to an
|
||||||
** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
|
** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()).
|
||||||
@ -1764,7 +1778,15 @@ int sqlite3changeset_invert(
|
|||||||
u8 eType = aIn[i];
|
u8 eType = aIn[i];
|
||||||
switch( eType ){
|
switch( eType ){
|
||||||
case 'T': {
|
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);
|
int nByte = 1 + sessionVarintGet(&aIn[i+1], &nCol);
|
||||||
|
nByte += nCol;
|
||||||
nByte += 1 + strlen((char *)&aIn[i+nByte]);
|
nByte += 1 + strlen((char *)&aIn[i+nByte]);
|
||||||
memcpy(&aOut[i], &aIn[i], nByte);
|
memcpy(&aOut[i], &aIn[i], nByte);
|
||||||
i += nByte;
|
i += nByte;
|
||||||
|
@ -341,6 +341,37 @@ int sqlite3changeset_op(
|
|||||||
int *pbIndirect /* OUT: True for an 'indirect' change */
|
int *pbIndirect /* OUT: True for an 'indirect' change */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Obtain The Primary Key Definition Of A Table
|
||||||
|
**
|
||||||
|
** For each modified table, a changeset includes the following:
|
||||||
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> The number of columns in the table, and
|
||||||
|
** <li> Which of those columns make up the tables PRIMARY KEY.
|
||||||
|
** </ul>
|
||||||
|
**
|
||||||
|
** This function is used to find which columns comprise the PRIMARY KEY of
|
||||||
|
** the table modified by the change that iterator pIter currently points to.
|
||||||
|
** If successful, *pabPK is set to point to an array of nCol entries, where
|
||||||
|
** nCol is the number of columns in the table. Elements of *pabPK are set to
|
||||||
|
** 0x01 if the corresponding column is part of the tables primary key, or
|
||||||
|
** 0x00 if it is not.
|
||||||
|
**
|
||||||
|
** If argumet pnCol is not NULL, then *pnCol is set to the number of columns
|
||||||
|
** in the table.
|
||||||
|
**
|
||||||
|
** If this function is called when the iterator does not point to a valid
|
||||||
|
** entry, SQLITE_MISUSE is returned and the output variables zeroed. Otherwise,
|
||||||
|
** SQLITE_OK is returned and the output variables populated as described
|
||||||
|
** above.
|
||||||
|
*/
|
||||||
|
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 */
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Obtain old.* Values From A Changeset Iterator
|
** CAPI3REF: Obtain old.* Values From A Changeset Iterator
|
||||||
**
|
**
|
||||||
|
@ -408,6 +408,10 @@ static int test_sqlite3session_foreach(
|
|||||||
Tcl_Obj *pNew; /* Vector of new.* values */
|
Tcl_Obj *pNew; /* Vector of new.* values */
|
||||||
int bIndirect;
|
int bIndirect;
|
||||||
|
|
||||||
|
char *zPK;
|
||||||
|
unsigned char *abPK;
|
||||||
|
int i;
|
||||||
|
|
||||||
sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect);
|
sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect);
|
||||||
pVar = Tcl_NewObj();
|
pVar = Tcl_NewObj();
|
||||||
Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(
|
Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(
|
||||||
@ -415,9 +419,19 @@ static int test_sqlite3session_foreach(
|
|||||||
op==SQLITE_UPDATE ? "UPDATE" :
|
op==SQLITE_UPDATE ? "UPDATE" :
|
||||||
"DELETE", -1
|
"DELETE", -1
|
||||||
));
|
));
|
||||||
|
|
||||||
Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1));
|
Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1));
|
||||||
Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect));
|
Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect));
|
||||||
|
|
||||||
|
zPK = ckalloc(nCol+1);
|
||||||
|
memset(zPK, 0, nCol+1);
|
||||||
|
sqlite3changeset_pk(pIter, &abPK, 0);
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
zPK[i] = (abPK[i] ? 'X' : '.');
|
||||||
|
}
|
||||||
|
Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zPK, -1));
|
||||||
|
ckfree(zPK);
|
||||||
|
|
||||||
pOld = Tcl_NewObj();
|
pOld = Tcl_NewObj();
|
||||||
if( op!=SQLITE_INSERT ){
|
if( op!=SQLITE_INSERT ){
|
||||||
int i;
|
int i;
|
||||||
|
34
manifest
34
manifest
@ -1,8 +1,5 @@
|
|||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
C Store\sprimary\skey\sdefinitions\sfor\smodified\stables\sin\schangesets.\sAdd\sthe\ssqlite3changeset_pk()\sAPI\sto\sextract\sthis\sdata\sfrom\sa\schangeset\siterator.
|
||||||
Hash: SHA1
|
D 2011-03-24T11:22:59
|
||||||
|
|
||||||
C Merge\sin\sall\sthe\slatest\schanges\sfrom\sthe\strunk,\sand\sespecially\sthe\sinterface\nchanges\sto\sthe\sSystemCall\smethods\sof\sthe\sVFS.
|
|
||||||
D 2011-03-23T22:48:46.969
|
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -102,13 +99,13 @@ F ext/rtree/rtree_util.tcl 06aab2ed5b826545bf215fff90ecb9255a8647ea
|
|||||||
F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
|
F ext/rtree/sqlite3rtree.h 1af0899c63a688e272d69d8e746f24e76f10a3f0
|
||||||
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
|
||||||
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
|
||||||
F ext/session/session1.test bca38efbc34c0cdecc10e599246962860e3f664b
|
F ext/session/session1.test b2da15b9d727d7f4e5fe95599b32b92d93b5a970
|
||||||
F ext/session/session2.test b0d305ee1397d7c17f9743126f636e97ddf88542
|
F ext/session/session2.test 8da094318ac88953478c43d0bfb0aa723ee0e379
|
||||||
F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28
|
F ext/session/session_common.tcl fb91560b6dbd086010df8b3a137a452f1ac21a28
|
||||||
F ext/session/sessionfault.test 4489a49d2d44c74c24251d5802b2cc011dbdac21
|
F ext/session/sessionfault.test d7e6154a30e85622d0733b1a1e3c63e9b8b7004b
|
||||||
F ext/session/sqlite3session.c 0c2e8f6a6d9872943edd04d0a19bf7b05db9df83
|
F ext/session/sqlite3session.c 886827f10de75576baf9f9d860414fa155e1c8c1
|
||||||
F ext/session/sqlite3session.h 000c1ed86322d9d8e8118cd5ba815269aac608f2
|
F ext/session/sqlite3session.h 8d3e00c0a2e323e6f47b1204ec9ff714ca3bee4a
|
||||||
F ext/session/test_session.c 0fcfbd51e3f5885b958fbc8cdd8cba01b85b8b16
|
F ext/session/test_session.c e0f500ec5e20478afc2c7998133e8acea7ec5104
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7
|
F main.mk ae0868e05c76eaa8a0ae3d6927a949b1c8e810d7
|
||||||
@ -926,14 +923,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 1feaf2d35fd9ec777319717ae2c2929d66fe7baa e059152adce3a8fb693f082b82b5669a238c8d6f
|
P 9c3a6e479988e96086bef00c79dbce508a14da0d
|
||||||
R b36ce5552543fc5931a9682eb2d51184
|
R f502a856cffb82507c875b00a2fb9d4d
|
||||||
U drh
|
U dan
|
||||||
Z 274ed2e4f92b071af1545dccfb5f4fc3
|
Z 3fdb3d84abab55a6e9fe1eeceb839a7c
|
||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
|
||||||
|
|
||||||
iD8DBQFNinjSoxKgR168RlERAnfoAJ4yQL1bxQ/2pBGeyDlRWD9l+4WVNwCfXQdV
|
|
||||||
nYGZvp774EBPS1/20z/kF+M=
|
|
||||||
=eCFJ
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
|
@ -1 +1 @@
|
|||||||
9c3a6e479988e96086bef00c79dbce508a14da0d
|
54298ee5ed183d1f1c49524f25e8ae1407f3d4b5
|
Reference in New Issue
Block a user