mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Add new sessions function sqlite3changeset_apply_v3() and its streaming equivalent. This allows changesets to be filtered on a per-change basis, not just per-table.
FossilOrigin-Name: 10ebd7a119ef1985755ef143a941fbaed1b5ca1c8a71e011c8bbc70e383fd337
This commit is contained in:
88
ext/session/sessionI.test
Normal file
88
ext/session/sessionI.test
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# 2015 July 14
|
||||||
|
#
|
||||||
|
# The author disclaims copyright to this source code. In place of
|
||||||
|
# a legal notice, here is a blessing:
|
||||||
|
#
|
||||||
|
# May you do good and not evil.
|
||||||
|
# May you find forgiveness for yourself and forgive others.
|
||||||
|
# May you share freely, never taking more than you give.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
#
|
||||||
|
|
||||||
|
if {![info exists testdir]} {
|
||||||
|
set testdir [file join [file dirname [info script]] .. .. test]
|
||||||
|
}
|
||||||
|
source [file join [file dirname [info script]] session_common.tcl]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
ifcapable !session {finish_test; return}
|
||||||
|
|
||||||
|
set testprefix sessionI
|
||||||
|
|
||||||
|
forcedelete test.db2
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
|
||||||
|
do_test 1.0 {
|
||||||
|
do_common_sql {
|
||||||
|
CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
|
||||||
|
}
|
||||||
|
} {}
|
||||||
|
|
||||||
|
set C [changeset_from_sql {
|
||||||
|
INSERT INTO t1 VALUES(1, 'one');
|
||||||
|
INSERT INTO t1 VALUES(2, 'two');
|
||||||
|
INSERT INTO t1 VALUES(3, 'three');
|
||||||
|
INSERT INTO t1 VALUES(4, 'four');
|
||||||
|
INSERT INTO t1 VALUES(5, 'five');
|
||||||
|
INSERT INTO t1 VALUES(6, 'six');
|
||||||
|
}]
|
||||||
|
|
||||||
|
do_execsql_test 1.1 {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} {
|
||||||
|
1 one 2 two 3 three 4 four 5 five 6 six
|
||||||
|
}
|
||||||
|
|
||||||
|
proc xFilter {data} {
|
||||||
|
foreach {op tname flag pk old new} $data {}
|
||||||
|
if {$op=="INSERT"} {
|
||||||
|
set ipk [lindex $new 1]
|
||||||
|
return [expr $ipk % 2]
|
||||||
|
}
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
proc xConflict {args} {
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3changeset_apply_v3 db2 $C xConflict xFilter
|
||||||
|
|
||||||
|
do_execsql_test -db db2 1.2 {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} {
|
||||||
|
1 one 3 three 5 five
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test -db db2 1.3 {
|
||||||
|
DELETE FROM t1
|
||||||
|
}
|
||||||
|
sqlite3changeset_apply_v3 db2 $C xConflict
|
||||||
|
|
||||||
|
do_execsql_test -db db2 1.4 {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} {
|
||||||
|
1 one 2 two 3 three 4 four 5 five 6 six
|
||||||
|
}
|
||||||
|
|
||||||
|
proc xFilter2 {data} {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
do_execsql_test -db db2 1.5 {
|
||||||
|
DELETE FROM t1
|
||||||
|
}
|
||||||
|
sqlite3changeset_apply_v3 db2 $C xConflict xFilter2
|
||||||
|
do_execsql_test -db db2 1.6 {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} { }
|
||||||
|
|
||||||
|
finish_test
|
@ -5182,6 +5182,10 @@ static int sessionChangesetApply(
|
|||||||
void *pCtx, /* Copy of sixth arg to _apply() */
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
const char *zTab /* Table name */
|
const char *zTab /* Table name */
|
||||||
),
|
),
|
||||||
|
int(*xFilterIter)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
sqlite3_changeset_iter *p
|
||||||
|
),
|
||||||
int(*xConflict)(
|
int(*xConflict)(
|
||||||
void *pCtx, /* Copy of fifth arg to _apply() */
|
void *pCtx, /* Copy of fifth arg to _apply() */
|
||||||
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||||
@ -5322,6 +5326,9 @@ static int sessionChangesetApply(
|
|||||||
** next change. A log message has already been issued. */
|
** next change. A log message has already been issued. */
|
||||||
if( schemaMismatch ) continue;
|
if( schemaMismatch ) continue;
|
||||||
|
|
||||||
|
/* If this is a call to apply_v3(), invoke xFilterIter here. */
|
||||||
|
if( xFilterIter && 0==xFilterIter(pCtx, pIter) ) continue;
|
||||||
|
|
||||||
rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
|
rc = sessionApplyOneWithRetry(db, pIter, &sApply, xConflict, pCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5389,6 +5396,87 @@ static int sessionChangesetApply(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function is called by all six sqlite3changeset_apply() variants:
|
||||||
|
**
|
||||||
|
** + sqlite3changeset_apply()
|
||||||
|
** + sqlite3changeset_apply_v2()
|
||||||
|
** + sqlite3changeset_apply_v3()
|
||||||
|
** + sqlite3changeset_apply_strm()
|
||||||
|
** + sqlite3changeset_apply_strm_v2()
|
||||||
|
** + sqlite3changeset_apply_strm_v3()
|
||||||
|
**
|
||||||
|
** Arguments passed to this function are as follows:
|
||||||
|
**
|
||||||
|
** db:
|
||||||
|
** Database handle to apply changeset to main database of.
|
||||||
|
**
|
||||||
|
** nChangeset/pChangeset:
|
||||||
|
** These are both passed zero for the streaming variants. For the normal
|
||||||
|
** apply() functions, these are passed the size of and the buffer containing
|
||||||
|
** the changeset, respectively.
|
||||||
|
**
|
||||||
|
** xInput/pIn:
|
||||||
|
** These are both passed zero for the normal variants. For the streaming
|
||||||
|
** apply() functions, these are passed the input callback and context
|
||||||
|
** pointer, respectively.
|
||||||
|
**
|
||||||
|
** xFilter:
|
||||||
|
** The filter function as passed to apply() or apply_v2() (to filter by
|
||||||
|
** table name), if any. This is always NULL for apply_v3() calls.
|
||||||
|
**
|
||||||
|
** xFilterIter:
|
||||||
|
** The filter function as passed to apply_v3(), if any.
|
||||||
|
**
|
||||||
|
** xConflict:
|
||||||
|
** The conflict handler callback (must not be NULL).
|
||||||
|
**
|
||||||
|
** pCtx:
|
||||||
|
** The context pointer passed to the xFilter and xConflict handler callbacks.
|
||||||
|
**
|
||||||
|
** ppRebase, pnRebase:
|
||||||
|
** Zero for apply(). The rebase changeset output pointers, if any, for
|
||||||
|
** apply_v2() and apply_v3().
|
||||||
|
**
|
||||||
|
** flags:
|
||||||
|
** Zero for apply(). The flags parameter for apply_v2() and apply_v3().
|
||||||
|
*/
|
||||||
|
static int sessionChangesetApplyV23(
|
||||||
|
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||||
|
int nChangeset, /* Size of changeset in bytes */
|
||||||
|
void *pChangeset, /* Changeset blob */
|
||||||
|
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
||||||
|
void *pIn, /* First arg for xInput */
|
||||||
|
int(*xFilter)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
const char *zTab /* Table name */
|
||||||
|
),
|
||||||
|
int(*xFilterIter)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing current change */
|
||||||
|
),
|
||||||
|
int(*xConflict)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||||
|
),
|
||||||
|
void *pCtx, /* First argument passed to xConflict */
|
||||||
|
void **ppRebase, int *pnRebase,
|
||||||
|
int flags
|
||||||
|
){
|
||||||
|
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
||||||
|
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
|
||||||
|
int rc = sessionChangesetStart(
|
||||||
|
&pIter, xInput, pIn, nChangeset, pChangeset, bInverse, 1
|
||||||
|
);
|
||||||
|
if( rc==SQLITE_OK ){
|
||||||
|
rc = sessionChangesetApply(db, pIter,
|
||||||
|
xFilter, xFilterIter, xConflict, pCtx, ppRebase, pnRebase, flags
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Apply the changeset passed via pChangeset/nChangeset to the main
|
** Apply the changeset passed via pChangeset/nChangeset to the main
|
||||||
** database attached to handle "db".
|
** database attached to handle "db".
|
||||||
@ -5410,17 +5498,39 @@ int sqlite3changeset_apply_v2(
|
|||||||
void **ppRebase, int *pnRebase,
|
void **ppRebase, int *pnRebase,
|
||||||
int flags
|
int flags
|
||||||
){
|
){
|
||||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
return sessionChangesetApplyV23(db,
|
||||||
int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
|
nChangeset, pChangeset, 0, 0,
|
||||||
int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1);
|
xFilter, 0, xConflict, pCtx,
|
||||||
|
ppRebase, pnRebase, flags
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
/*
|
||||||
rc = sessionChangesetApply(
|
** Apply the changeset passed via pChangeset/nChangeset to the main
|
||||||
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
|
** database attached to handle "db".
|
||||||
);
|
*/
|
||||||
}
|
int sqlite3changeset_apply_v3(
|
||||||
|
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||||
return rc;
|
int nChangeset, /* Size of changeset in bytes */
|
||||||
|
void *pChangeset, /* Changeset blob */
|
||||||
|
int(*xFilter)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing current change */
|
||||||
|
),
|
||||||
|
int(*xConflict)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||||
|
),
|
||||||
|
void *pCtx, /* First argument passed to xConflict */
|
||||||
|
void **ppRebase, int *pnRebase,
|
||||||
|
int flags
|
||||||
|
){
|
||||||
|
return sessionChangesetApplyV23(db,
|
||||||
|
nChangeset, pChangeset, 0, 0,
|
||||||
|
0, xFilter, xConflict, pCtx,
|
||||||
|
ppRebase, pnRebase, flags
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -5443,8 +5553,10 @@ int sqlite3changeset_apply(
|
|||||||
),
|
),
|
||||||
void *pCtx /* First argument passed to xConflict */
|
void *pCtx /* First argument passed to xConflict */
|
||||||
){
|
){
|
||||||
return sqlite3changeset_apply_v2(
|
return sessionChangesetApplyV23(db,
|
||||||
db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0
|
nChangeset, pChangeset, 0, 0,
|
||||||
|
xFilter, 0, xConflict, pCtx,
|
||||||
|
0, 0, 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5453,6 +5565,29 @@ int sqlite3changeset_apply(
|
|||||||
** attached to handle "db". Invoke the supplied conflict handler callback
|
** attached to handle "db". Invoke the supplied conflict handler callback
|
||||||
** to resolve any conflicts encountered while applying the change.
|
** to resolve any conflicts encountered while applying the change.
|
||||||
*/
|
*/
|
||||||
|
int sqlite3changeset_apply_v3_strm(
|
||||||
|
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||||
|
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
||||||
|
void *pIn, /* First arg for xInput */
|
||||||
|
int(*xFilter)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
sqlite3_changeset_iter *p
|
||||||
|
),
|
||||||
|
int(*xConflict)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||||
|
),
|
||||||
|
void *pCtx, /* First argument passed to xConflict */
|
||||||
|
void **ppRebase, int *pnRebase,
|
||||||
|
int flags
|
||||||
|
){
|
||||||
|
return sessionChangesetApplyV23(db,
|
||||||
|
0, 0, xInput, pIn,
|
||||||
|
0, xFilter, xConflict, pCtx,
|
||||||
|
ppRebase, pnRebase, flags
|
||||||
|
);
|
||||||
|
}
|
||||||
int sqlite3changeset_apply_v2_strm(
|
int sqlite3changeset_apply_v2_strm(
|
||||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||||
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
||||||
@ -5470,15 +5605,11 @@ int sqlite3changeset_apply_v2_strm(
|
|||||||
void **ppRebase, int *pnRebase,
|
void **ppRebase, int *pnRebase,
|
||||||
int flags
|
int flags
|
||||||
){
|
){
|
||||||
sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */
|
return sessionChangesetApplyV23(db,
|
||||||
int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT);
|
0, 0, xInput, pIn,
|
||||||
int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1);
|
xFilter, 0, xConflict, pCtx,
|
||||||
if( rc==SQLITE_OK ){
|
ppRebase, pnRebase, flags
|
||||||
rc = sessionChangesetApply(
|
);
|
||||||
db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
int sqlite3changeset_apply_strm(
|
int sqlite3changeset_apply_strm(
|
||||||
sqlite3 *db, /* Apply change to "main" db of this handle */
|
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||||
@ -5495,8 +5626,10 @@ int sqlite3changeset_apply_strm(
|
|||||||
),
|
),
|
||||||
void *pCtx /* First argument passed to xConflict */
|
void *pCtx /* First argument passed to xConflict */
|
||||||
){
|
){
|
||||||
return sqlite3changeset_apply_v2_strm(
|
return sessionChangesetApplyV23(db,
|
||||||
db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0
|
0, 0, xInput, pIn,
|
||||||
|
xFilter, 0, xConflict, pCtx,
|
||||||
|
0, 0, 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,13 +1115,22 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
|||||||
** the changeset passed via the second and third arguments.
|
** the changeset passed via the second and third arguments.
|
||||||
**
|
**
|
||||||
** The fourth argument (xFilter) passed to these functions is the "filter
|
** The fourth argument (xFilter) passed to these functions is the "filter
|
||||||
** callback". If it is not NULL, then for each table affected by at least one
|
** callback". This may be passed NULL, in which case all changes in the
|
||||||
** change in the changeset, the filter callback is invoked with
|
** changeset are applied to the database. For sqlite3changeset_apply() and
|
||||||
** the table name as the second argument, and a copy of the context pointer
|
** sqlite3_changeset_apply_v2(), if it is not NULL, then it is invoked once
|
||||||
** passed as the sixth argument as the first. If the "filter callback"
|
** for each table affected by at least one change in the changeset. In this
|
||||||
** returns zero, then no attempt is made to apply any changes to the table.
|
** case the table name is passed as the second argument, and a copy of
|
||||||
** Otherwise, if the return value is non-zero or the xFilter argument to
|
** the context pointer passed as the sixth argument to apply() or apply_v2()
|
||||||
** is NULL, all changes related to the table are attempted.
|
** as the first. If the "filter callback" returns zero, then no attempt is
|
||||||
|
** made to apply any changes to the table. Otherwise, if the return value is
|
||||||
|
** non-zero, all changes related to the table are attempted.
|
||||||
|
**
|
||||||
|
** For sqlite3_changeset_apply_v3(), the xFilter callback is invoked once
|
||||||
|
** per change. The second argument in this case is an sqlite3_changeset_iter
|
||||||
|
** that may be queried using the usual APIs for the details of the current
|
||||||
|
** change. If the "filter callback" returns zero in this case, then no attempt
|
||||||
|
** is made to apply the current change. If it returns non-zero, the change
|
||||||
|
** is applied.
|
||||||
**
|
**
|
||||||
** For each table that is not excluded by the filter callback, this function
|
** For each table that is not excluded by the filter callback, this function
|
||||||
** tests that the target database contains a compatible table. A table is
|
** tests that the target database contains a compatible table. A table is
|
||||||
@ -1142,11 +1151,11 @@ void sqlite3changegroup_delete(sqlite3_changegroup*);
|
|||||||
** one such warning is issued for each table in the changeset.
|
** one such warning is issued for each table in the changeset.
|
||||||
**
|
**
|
||||||
** For each change for which there is a compatible table, an attempt is made
|
** For each change for which there is a compatible table, an attempt is made
|
||||||
** to modify the table contents according to the UPDATE, INSERT or DELETE
|
** to modify the table contents according to each UPDATE, INSERT or DELETE
|
||||||
** change. If a change cannot be applied cleanly, the conflict handler
|
** change that is not excluded by a filter callback. If a change cannot be
|
||||||
** function passed as the fifth argument to sqlite3changeset_apply() may be
|
** applied cleanly, the conflict handler function passed as the fifth argument
|
||||||
** invoked. A description of exactly when the conflict handler is invoked for
|
** to sqlite3changeset_apply() may be invoked. A description of exactly when
|
||||||
** each type of change is below.
|
** the conflict handler is invoked for each type of change is below.
|
||||||
**
|
**
|
||||||
** Unlike the xFilter argument, xConflict may not be passed NULL. The results
|
** Unlike the xFilter argument, xConflict may not be passed NULL. The results
|
||||||
** of passing anything other than a valid function pointer as the xConflict
|
** of passing anything other than a valid function pointer as the xConflict
|
||||||
@ -1297,6 +1306,23 @@ int sqlite3changeset_apply_v2(
|
|||||||
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
|
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
|
||||||
int flags /* SESSION_CHANGESETAPPLY_* flags */
|
int flags /* SESSION_CHANGESETAPPLY_* flags */
|
||||||
);
|
);
|
||||||
|
int sqlite3changeset_apply_v3(
|
||||||
|
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||||
|
int nChangeset, /* Size of changeset in bytes */
|
||||||
|
void *pChangeset, /* Changeset blob */
|
||||||
|
int(*xFilter)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing change */
|
||||||
|
),
|
||||||
|
int(*xConflict)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||||
|
),
|
||||||
|
void *pCtx, /* First argument passed to xConflict */
|
||||||
|
void **ppRebase, int *pnRebase, /* OUT: Rebase data */
|
||||||
|
int flags /* SESSION_CHANGESETAPPLY_* flags */
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Flags for sqlite3changeset_apply_v2
|
** CAPI3REF: Flags for sqlite3changeset_apply_v2
|
||||||
@ -1716,6 +1742,23 @@ int sqlite3changeset_apply_v2_strm(
|
|||||||
void **ppRebase, int *pnRebase,
|
void **ppRebase, int *pnRebase,
|
||||||
int flags
|
int flags
|
||||||
);
|
);
|
||||||
|
int sqlite3changeset_apply_v3_strm(
|
||||||
|
sqlite3 *db, /* Apply change to "main" db of this handle */
|
||||||
|
int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
|
||||||
|
void *pIn, /* First arg for xInput */
|
||||||
|
int(*xFilter)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
sqlite3_changeset_iter *p
|
||||||
|
),
|
||||||
|
int(*xConflict)(
|
||||||
|
void *pCtx, /* Copy of sixth arg to _apply() */
|
||||||
|
int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||||
|
sqlite3_changeset_iter *p /* Handle describing change and conflict */
|
||||||
|
),
|
||||||
|
void *pCtx, /* First argument passed to xConflict */
|
||||||
|
void **ppRebase, int *pnRebase,
|
||||||
|
int flags
|
||||||
|
);
|
||||||
int sqlite3changeset_concat_strm(
|
int sqlite3changeset_concat_strm(
|
||||||
int (*xInputA)(void *pIn, void *pData, int *pnData),
|
int (*xInputA)(void *pIn, void *pData, int *pnData),
|
||||||
void *pInA,
|
void *pInA,
|
||||||
|
@ -520,6 +520,65 @@ static int test_obj_eq_string(Tcl_Obj *p, const char *z){
|
|||||||
return (nObj==n && (n==0 || 0==memcmp(zObj, z, n)));
|
return (nObj==n && (n==0 || 0==memcmp(zObj, z, n)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Tcl_Obj *testIterData(sqlite3_changeset_iter *pIter){
|
||||||
|
Tcl_Obj *pVar = 0;
|
||||||
|
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 *pOld; /* Vector of old.* values */
|
||||||
|
Tcl_Obj *pNew; /* Vector of new.* values */
|
||||||
|
int bIndirect;
|
||||||
|
|
||||||
|
char *zPK;
|
||||||
|
unsigned char *abPK;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect);
|
||||||
|
pVar = Tcl_NewObj();
|
||||||
|
|
||||||
|
Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(
|
||||||
|
op==SQLITE_INSERT ? "INSERT" :
|
||||||
|
op==SQLITE_UPDATE ? "UPDATE" :
|
||||||
|
"DELETE", -1
|
||||||
|
));
|
||||||
|
|
||||||
|
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();
|
||||||
|
if( op!=SQLITE_INSERT ){
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
sqlite3_value *pVal;
|
||||||
|
sqlite3changeset_old(pIter, i, &pVal);
|
||||||
|
test_append_value(pOld, pVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pNew = Tcl_NewObj();
|
||||||
|
if( op!=SQLITE_DELETE ){
|
||||||
|
for(i=0; i<nCol; i++){
|
||||||
|
sqlite3_value *pVal;
|
||||||
|
sqlite3changeset_new(pIter, i, &pVal);
|
||||||
|
test_append_value(pNew, pVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Tcl_ListObjAppendElement(0, pVar, pOld);
|
||||||
|
Tcl_ListObjAppendElement(0, pVar, pNew);
|
||||||
|
|
||||||
|
return pVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int test_filter_handler(
|
static int test_filter_handler(
|
||||||
void *pCtx, /* Pointer to TestConflictHandler structure */
|
void *pCtx, /* Pointer to TestConflictHandler structure */
|
||||||
const char *zTab /* Table name */
|
const char *zTab /* Table name */
|
||||||
@ -543,6 +602,29 @@ static int test_filter_handler(
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_filter_v3_handler(
|
||||||
|
void *pCtx, /* Pointer to TestConflictHandler structure */
|
||||||
|
sqlite3_changeset_iter *pIter
|
||||||
|
){
|
||||||
|
TestConflictHandler *p = (TestConflictHandler *)pCtx;
|
||||||
|
int res = 1;
|
||||||
|
Tcl_Obj *pEval = 0;
|
||||||
|
Tcl_Interp *interp = p->interp;
|
||||||
|
|
||||||
|
pEval = Tcl_DuplicateObj(p->pFilterScript);
|
||||||
|
Tcl_IncrRefCount(pEval);
|
||||||
|
Tcl_ListObjAppendElement(0, pEval, testIterData(pIter));
|
||||||
|
|
||||||
|
if( TCL_OK!=Tcl_EvalObjEx(interp, pEval, TCL_EVAL_GLOBAL)
|
||||||
|
|| TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &res)
|
||||||
|
){
|
||||||
|
Tcl_BackgroundError(interp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcl_DecrRefCount(pEval);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int test_conflict_handler(
|
static int test_conflict_handler(
|
||||||
void *pCtx, /* Pointer to TestConflictHandler structure */
|
void *pCtx, /* Pointer to TestConflictHandler structure */
|
||||||
int eConf, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
int eConf, /* DATA, MISSING, CONFLICT, CONSTRAINT */
|
||||||
@ -776,7 +858,7 @@ static int testStreamInput(
|
|||||||
|
|
||||||
|
|
||||||
static int SQLITE_TCLAPI testSqlite3changesetApply(
|
static int SQLITE_TCLAPI testSqlite3changesetApply(
|
||||||
int bV2,
|
int iVersion,
|
||||||
void * clientData,
|
void * clientData,
|
||||||
Tcl_Interp *interp,
|
Tcl_Interp *interp,
|
||||||
int objc,
|
int objc,
|
||||||
@ -793,11 +875,13 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
|
|||||||
int nRebase = 0;
|
int nRebase = 0;
|
||||||
int flags = 0; /* Flags for apply_v2() */
|
int flags = 0; /* Flags for apply_v2() */
|
||||||
|
|
||||||
|
assert( iVersion==1 || iVersion==2 || iVersion==3 );
|
||||||
|
|
||||||
memset(&sStr, 0, sizeof(sStr));
|
memset(&sStr, 0, sizeof(sStr));
|
||||||
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
|
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
|
||||||
|
|
||||||
/* Check for the -nosavepoint, -invert or -ignorenoop switches */
|
/* Check for the -nosavepoint, -invert or -ignorenoop switches */
|
||||||
if( bV2 ){
|
if( iVersion==2 || iVersion==3 ){
|
||||||
while( objc>1 ){
|
while( objc>1 ){
|
||||||
const char *z1 = Tcl_GetString(objv[1]);
|
const char *z1 = Tcl_GetString(objv[1]);
|
||||||
int n = (int)strlen(z1);
|
int n = (int)strlen(z1);
|
||||||
@ -822,7 +906,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
|
|||||||
|
|
||||||
if( objc!=4 && objc!=5 ){
|
if( objc!=4 && objc!=5 ){
|
||||||
const char *zMsg;
|
const char *zMsg;
|
||||||
if( bV2 ){
|
if( iVersion==2 || iVersion==3 ){
|
||||||
zMsg = "?-nosavepoint? ?-inverse? ?-ignorenoop? "
|
zMsg = "?-nosavepoint? ?-inverse? ?-ignorenoop? "
|
||||||
"DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
|
"DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
|
||||||
}else{
|
}else{
|
||||||
@ -842,30 +926,49 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
|
|||||||
ctx.interp = interp;
|
ctx.interp = interp;
|
||||||
|
|
||||||
if( sStr.nStream==0 ){
|
if( sStr.nStream==0 ){
|
||||||
if( bV2==0 ){
|
switch( iVersion ){
|
||||||
rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset,
|
case 1:
|
||||||
(objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx
|
rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset,
|
||||||
);
|
(objc==5)?test_filter_handler:0, test_conflict_handler, (void*)&ctx
|
||||||
}else{
|
);
|
||||||
rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset,
|
break;
|
||||||
(objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx,
|
case 2:
|
||||||
&pRebase, &nRebase, flags
|
rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset,
|
||||||
);
|
(objc==5)?test_filter_handler:0, test_conflict_handler, (void*)&ctx,
|
||||||
|
&pRebase, &nRebase, flags
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rc = sqlite3changeset_apply_v3(db, (int)nChangeset, pChangeset,
|
||||||
|
(objc==5)?test_filter_v3_handler:0, test_conflict_handler,
|
||||||
|
(void*)&ctx, &pRebase, &nRebase, flags
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
sStr.aData = (unsigned char*)pChangeset;
|
sStr.aData = (unsigned char*)pChangeset;
|
||||||
sStr.nData = (int)nChangeset;
|
sStr.nData = (int)nChangeset;
|
||||||
if( bV2==0 ){
|
switch( iVersion ){
|
||||||
rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr,
|
case 1:
|
||||||
(objc==5) ? test_filter_handler : 0,
|
rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr,
|
||||||
test_conflict_handler, (void *)&ctx
|
(objc==5) ? test_filter_handler : 0,
|
||||||
);
|
test_conflict_handler, (void *)&ctx
|
||||||
}else{
|
);
|
||||||
rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr,
|
break;
|
||||||
(objc==5) ? test_filter_handler : 0,
|
case 2:
|
||||||
test_conflict_handler, (void *)&ctx,
|
rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr,
|
||||||
&pRebase, &nRebase, flags
|
(objc==5) ? test_filter_handler : 0,
|
||||||
);
|
test_conflict_handler, (void *)&ctx,
|
||||||
|
&pRebase, &nRebase, flags
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rc = sqlite3changeset_apply_v3_strm(db, testStreamInput, (void*)&sStr,
|
||||||
|
(objc==5) ? test_filter_v3_handler : 0,
|
||||||
|
test_conflict_handler, (void *)&ctx,
|
||||||
|
&pRebase, &nRebase, flags
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -873,7 +976,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
|
|||||||
return test_session_error(interp, rc, 0);
|
return test_session_error(interp, rc, 0);
|
||||||
}else{
|
}else{
|
||||||
Tcl_ResetResult(interp);
|
Tcl_ResetResult(interp);
|
||||||
if( bV2 && pRebase ){
|
if( (iVersion==2 || iVersion==3) && pRebase ){
|
||||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pRebase, nRebase));
|
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pRebase, nRebase));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -890,7 +993,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply(
|
|||||||
int objc,
|
int objc,
|
||||||
Tcl_Obj *CONST objv[]
|
Tcl_Obj *CONST objv[]
|
||||||
){
|
){
|
||||||
return testSqlite3changesetApply(0, clientData, interp, objc, objv);
|
return testSqlite3changesetApply(1, clientData, interp, objc, objv);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
** sqlite3changeset_apply_v2 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
|
** sqlite3changeset_apply_v2 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
|
||||||
@ -901,7 +1004,18 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply_v2(
|
|||||||
int objc,
|
int objc,
|
||||||
Tcl_Obj *CONST objv[]
|
Tcl_Obj *CONST objv[]
|
||||||
){
|
){
|
||||||
return testSqlite3changesetApply(1, clientData, interp, objc, objv);
|
return testSqlite3changesetApply(2, clientData, interp, objc, objv);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
** sqlite3changeset_apply_v3 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
|
||||||
|
*/
|
||||||
|
static int SQLITE_TCLAPI test_sqlite3changeset_apply_v3(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
return testSqlite3changesetApply(3, clientData, interp, objc, objv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1034,64 +1148,6 @@ static int SQLITE_TCLAPI test_sqlite3changeset_concat(
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Tcl_Obj *testIterData(sqlite3_changeset_iter *pIter){
|
|
||||||
Tcl_Obj *pVar = 0;
|
|
||||||
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 *pOld; /* Vector of old.* values */
|
|
||||||
Tcl_Obj *pNew; /* Vector of new.* values */
|
|
||||||
int bIndirect;
|
|
||||||
|
|
||||||
char *zPK;
|
|
||||||
unsigned char *abPK;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect);
|
|
||||||
pVar = Tcl_NewObj();
|
|
||||||
|
|
||||||
Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(
|
|
||||||
op==SQLITE_INSERT ? "INSERT" :
|
|
||||||
op==SQLITE_UPDATE ? "UPDATE" :
|
|
||||||
"DELETE", -1
|
|
||||||
));
|
|
||||||
|
|
||||||
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();
|
|
||||||
if( op!=SQLITE_INSERT ){
|
|
||||||
for(i=0; i<nCol; i++){
|
|
||||||
sqlite3_value *pVal;
|
|
||||||
sqlite3changeset_old(pIter, i, &pVal);
|
|
||||||
test_append_value(pOld, pVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pNew = Tcl_NewObj();
|
|
||||||
if( op!=SQLITE_DELETE ){
|
|
||||||
for(i=0; i<nCol; i++){
|
|
||||||
sqlite3_value *pVal;
|
|
||||||
sqlite3changeset_new(pIter, i, &pVal);
|
|
||||||
test_append_value(pNew, pVal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Tcl_ListObjAppendElement(0, pVar, pOld);
|
|
||||||
Tcl_ListObjAppendElement(0, pVar, pNew);
|
|
||||||
|
|
||||||
return pVar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** sqlite3session_foreach VARNAME CHANGESET SCRIPT
|
** sqlite3session_foreach VARNAME CHANGESET SCRIPT
|
||||||
*/
|
*/
|
||||||
@ -1751,6 +1807,7 @@ int TestSession_Init(Tcl_Interp *interp){
|
|||||||
{ "sqlite3changeset_concat", test_sqlite3changeset_concat },
|
{ "sqlite3changeset_concat", test_sqlite3changeset_concat },
|
||||||
{ "sqlite3changeset_apply", test_sqlite3changeset_apply },
|
{ "sqlite3changeset_apply", test_sqlite3changeset_apply },
|
||||||
{ "sqlite3changeset_apply_v2", test_sqlite3changeset_apply_v2 },
|
{ "sqlite3changeset_apply_v2", test_sqlite3changeset_apply_v2 },
|
||||||
|
{ "sqlite3changeset_apply_v3", test_sqlite3changeset_apply_v3 },
|
||||||
{ "sqlite3changeset_apply_replace_all",
|
{ "sqlite3changeset_apply_replace_all",
|
||||||
test_sqlite3changeset_apply_replace_all },
|
test_sqlite3changeset_apply_replace_all },
|
||||||
{ "sql_exec_changeset", test_sql_exec_changeset },
|
{ "sql_exec_changeset", test_sql_exec_changeset },
|
||||||
|
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
|||||||
C Fix\sharmless\scompiler\swarnings\sin\sbuilds\sthat\suse\sSQLITE_OMIT_DATETIME_FUNCS.
|
C Add\snew\ssessions\sfunction\ssqlite3changeset_apply_v3()\sand\sits\sstreaming\sequivalent.\sThis\sallows\schangesets\sto\sbe\sfiltered\son\sa\sper-change\sbasis,\snot\sjust\sper-table.
|
||||||
D 2025-07-14T09:41:59.400
|
D 2025-07-14T14:51:43.802
|
||||||
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
@ -594,6 +594,7 @@ F ext/session/sessionE.test b2010949c9d7415306f64e3c2072ddabc4b8250c98478d3c0c4d
|
|||||||
F ext/session/sessionF.test d37ed800881e742c208df443537bf29aa49fd56eac520d0f0c6df3e6320f3401
|
F ext/session/sessionF.test d37ed800881e742c208df443537bf29aa49fd56eac520d0f0c6df3e6320f3401
|
||||||
F ext/session/sessionG.test 3efe388282d641b65485b5462e67851002cd91a282dc95b685d085eb8efdad0a
|
F ext/session/sessionG.test 3efe388282d641b65485b5462e67851002cd91a282dc95b685d085eb8efdad0a
|
||||||
F ext/session/sessionH.test 71bbff6b1abb2c4ac62b84dee53273c37e0b21e5fde3aed80929403e091ef859
|
F ext/session/sessionH.test 71bbff6b1abb2c4ac62b84dee53273c37e0b21e5fde3aed80929403e091ef859
|
||||||
|
F ext/session/sessionI.test 11e7b6729fc942982a5104a40132f70a2e964d64d60dc5809b8206465af74822
|
||||||
F ext/session/session_common.tcl a31f537a929a695a852d241c9434f2847cadf329856401921139fbb03a5a7697
|
F ext/session/session_common.tcl a31f537a929a695a852d241c9434f2847cadf329856401921139fbb03a5a7697
|
||||||
F ext/session/session_gen.test 942a0002df10da53c45b40b581cc3ed25e7ff42bda1e7ba497273dc2887aa8e6
|
F ext/session/session_gen.test 942a0002df10da53c45b40b581cc3ed25e7ff42bda1e7ba497273dc2887aa8e6
|
||||||
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
|
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
|
||||||
@ -617,9 +618,9 @@ F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a
|
|||||||
F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
|
F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
|
||||||
F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec
|
F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec
|
||||||
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
||||||
F ext/session/sqlite3session.c 6b0877fe1ab832aa4b85eaca72606dfd1630a1363a1be7af10ee1042a5ec719e
|
F ext/session/sqlite3session.c 19e14bcca2fbc63a8022ffd708ea6e6986c4003a1e9bbca9b2989fd230362e15
|
||||||
F ext/session/sqlite3session.h 9bb1a6687b467764b35178dc29bbd2c57ab8cd3acdc8a62f088c34ad17e4fe2b
|
F ext/session/sqlite3session.h b81e8536ce4b83babafd700f4ff67017804b6c1d71df963b30d3972958e7f4a7
|
||||||
F ext/session/test_session.c 2ddff73ea368d827028c32851b291416e1008845832feb27b751d15e57e13cc3
|
F ext/session/test_session.c 8766b5973a6323934cb51248f621c3dc87ad2a98f023c3cc280d79e7d78d36fb
|
||||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||||
F ext/wasm/GNUmakefile d62af1b0914eb2e03fa6e4e75e93acadc8f4faeb2d56335da25d61b9ea144c53
|
F ext/wasm/GNUmakefile d62af1b0914eb2e03fa6e4e75e93acadc8f4faeb2d56335da25d61b9ea144c53
|
||||||
F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a
|
F ext/wasm/README-dist.txt f01081a850ce38a56706af6b481e3a7878e24e42b314cfcd4b129f0f8427066a
|
||||||
@ -2212,8 +2213,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
|
|||||||
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
|
||||||
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
|
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P e5d079549594ca44852773b8919894866394e47ad725dadc7f65242413a219d3
|
P e11fbf9fd630a7de2e0b0e4b67dded05b905b2a0ba04aa7e915ca9df2d9ebe21
|
||||||
R 07c15e107127475edb35cdd6de618874
|
R 082d403ad4bd97cbce0234772b2da39f
|
||||||
U drh
|
U dan
|
||||||
Z cde724828852556a37035896eff32ef8
|
Z 455b5bdcd48088e3f2c57d9eeedfc2e8
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
e11fbf9fd630a7de2e0b0e4b67dded05b905b2a0ba04aa7e915ca9df2d9ebe21
|
10ebd7a119ef1985755ef143a941fbaed1b5ca1c8a71e011c8bbc70e383fd337
|
||||||
|
Reference in New Issue
Block a user