*/
static int sessionChangeEqual(
SessionTable *pTab, /* Table used for PK definition */
- int bLeftPkOnly,
+ int bLeftPkOnly, /* True if aLeft[] contains PK fields only */
u8 *aLeft, /* Change record */
- int bRightPkOnly,
+ int bRightPkOnly, /* True if aRight[] contains PK fields only */
u8 *aRight /* Change record */
){
u8 *a1 = aLeft; /* Cursor to iterate through aLeft */
static int sessionMergeUpdate(
u8 **paOut, /* IN/OUT: Pointer to output buffer */
SessionTable *pTab, /* Table change pertains to */
- int bPatchset,
+ int bPatchset, /* True if records are patchset records */
u8 *aOldRecord1, /* old.* record for first change */
u8 *aOldRecord2, /* old.* record for second change */
u8 *aNewRecord1, /* new.* record for first change */
return rc;
}
+/*
+** Append a DELETE change to the buffer passed as the first argument. Use
+** the changeset format if argument bPatchset is zero, or the patchset
+** format otherwise.
+*/
static int sessionAppendDelete(
SessionBuffer *pBuf, /* Buffer to append to */
int bPatchset, /* True for "patchset", 0 for "changeset" */
- sqlite3_stmt *pStmt, /* Statement handle pointing at new row */
SessionChange *p, /* Object containing old values */
+ int nCol, /* Number of columns in table */
u8 *abPK /* Boolean array - true for PK columns */
){
int rc = SQLITE_OK;
if( bPatchset==0 ){
sessionAppendBlob(pBuf, p->aRecord, p->nRecord, &rc);
}else{
- int nCol = sqlite3_column_count(pStmt);
int i;
u8 *a = p->aRecord;
for(i=0; i<nCol; i++){
** SQLite error code before returning.
*/
static void sessionAppendTableHdr(
- SessionBuffer *pBuf,
- int bPatchset,
- SessionTable *pTab,
- int *pRc
+ SessionBuffer *pBuf, /* Append header to this buffer */
+ int bPatchset, /* Use the patchset format if true */
+ SessionTable *pTab, /* Table object to append header for */
+ int *pRc /* IN/OUT: Error code */
){
/* Write a table header */
sessionAppendByte(pBuf, (bPatchset ? 'P' : 'T'), pRc);
sessionAppendBlob(pBuf, (u8 *)pTab->zName, (int)strlen(pTab->zName)+1, pRc);
}
+/*
+** Generate either a changeset (if argument bPatchset is zero) or a patchset
+** (if it is non-zero) based on the current contents of the session object
+** passed as the first argument.
+**
+** If no error occurs, SQLITE_OK is returned and the new changeset/patchset
+** stored in output variables *pnChangeset and *ppChangeset. Or, if an error
+** occurs, an SQLite error code is returned and both output variables set
+** to 0.
+*/
int sessionGenerateChangeset(
sqlite3_session *pSession, /* Session object */
int bPatchset, /* True for patchset, false for changeset */
rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
}
}else if( p->op!=SQLITE_INSERT ){
- rc = sessionAppendDelete(&buf, bPatchset, pSel, p, abPK);
+ rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
}
if( rc==SQLITE_OK ){
rc = sqlite3_reset(pSel);
** When this function is called, *paChange points to the start of the record
** to deserialize. Assuming no error occurs, *paChange is set to point to
** one byte after the end of the same record before this function returns.
+** If the argument abPK is NULL, then the record contains nCol values. Or,
+** if abPK is other than NULL, then the record contains only the PK fields
+** (in other words, it is a patchset DELETE record).
**
** If successful, each element of the apOut[] array (allocated by the caller)
** is set to point to an sqlite3_value object containing the value read
/*
** CAPI3REF: Generate A Patchset From A Session Object
+**
+** The differences between a patchset and a changeset are that:
+**
+** <ul>
+** <li> DELETE records consist of the primary key fields only. The
+** original values of other fields are omitted.
+** <li> The original values of any modified fields are omitted from
+** UPDATE records.
+** </ul>
+**
+** A patchset blob may be used with up to date versions of all
+** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(),
+** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly,
+** attempting to use a patchset blob with old versions of the
+** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error.
+**
+** Because the non-primary key "old.*" fields are omitted, no
+** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset
+** is passed to the sqlite3changeset_apply() API. Other conflict types work
+** in the same way as for changesets.
*/
int sqlite3session_patchset(
sqlite3_session *pSession, /* Session object */
-C Fixes\sfor\sthe\ssqlite3changeset_concat()\sAPI\sregarding\spatchsets.
-D 2014-08-16T16:47:55.133
+C Fix\ssome\smissing\sand\sout-of-date\scomments\sin\sthe\ssessions\smodule.
+D 2014-08-16T19:01:00.672
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 639859a6f81bd15921ccd56ddbd6dfd335278377
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F ext/session/sessionB.test 51c70394bc04ac72d72f54bd0879614b9c34240c
F ext/session/session_common.tcl 1539d8973b2aea0025c133eb0cc4c89fcef541a5
F ext/session/sessionfault.test 496291b287ba3c0b14ca2e074425e29cc92a64a6
-F ext/session/sqlite3session.c eed0f0510859e564f9f8c886d22a299579b5c6c1
-F ext/session/sqlite3session.h c99445ea9918343d3e62acafdf82bc5502cfba29
+F ext/session/sqlite3session.c f2385ab5ebac94d8e54cc3aa8dc9ca77f8cdf0d9
+F ext/session/sqlite3session.h ef0dbcd599ab8b83e3f3f2e9912e1734519a3ef4
F ext/session/test_session.c 920ccb6d6e1df263cd9099563328094c230b2925
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 60a4565a8c44762a002cd02979317df5ca47e899
-R 1bd074b437e8898f047cce1541823103
+P dccb34859508eac8146ae5b19c447673d04be3b0
+R 7605cd9723f946167ef7a988888841f4
U dan
-Z 66bd65019d7460afe376babf330097ba
+Z 7c34f49d718669db325837ce5da84317