Sqlite

Streaming Versions of API functions

流式API函数版本

流式 API 函数版本。

int sqlite3changeset_apply_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() */ const char *zTab /* Table name */ ), 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 */ int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA, int (*xInputB)(void *pIn, void *pData, int *pnData), void *pInB, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut int sqlite3changeset_invert_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut int sqlite3changeset_start_strm( sqlite3_changeset_iter **pp, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn int sqlite3session_changeset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut int sqlite3session_patchset_strm( sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut int sqlite3changegroup_add_strm(sqlite3_changegroup*, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn int sqlite3changegroup_output_strm(sqlite3_changegroup*, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut

这六个流式 API xxx_strm() 函数为相应的非流式 API 函数提供类似的用途:

流函数非流式等式
sqlite3changeset_apply_strmsqlite3changeset_apply
sqlite3changeset_concat_strmsqlite3changeset_concat
sqlite3changeset_invert_strmsqlite3changeset_invert
sqlite3changeset_start_strmsqlite3changeset_start
sqlite3session_changeset_strmsqlite3session_changeset
sqlite3session_patchset_strmsqlite3session_patchset

接受变更集(或补丁集)作为输入的非流功能需要将整个变更集存储在内存中的单个缓冲区中。同样,那些返回变更集或补丁集的人通过返回一个指向使用 sqlite3_malloc() 分配的单个大缓冲区的指针来实现。通常这很方便。但是,如果需要在低内存环境中运行的应用程序处理非常大的变更集,则所需的大型连续内存分配可能变得繁重。

为了避免这个问题,输入通过回调函数传递给流式 API 函数,会话模块调用该函数以根据需要递增地请求输入数据。在所有情况下,一对 API 函数参数如

  int nChangeset,   void *pChangeset,

被替换为:

  int (*xInput)(void *pIn, void *pData, int *pnData),   void *pIn,

每次会话模块调用 xInput 回调函数时,传递的第一个参数都是提供的 pIn 上下文指针的副本。第二个参数 pData 指向一个大小为缓冲区(* pnData)的字节。假设没有发生错误,xInput 方法应该将最多(* pnData)个字节的数据拷贝到缓冲区中,并将(* pnData)设置为在返回 SQLITE_OK 之前复制的实际字节数。如果输入完全耗尽,(* pnData)应该设置为零来表示这一点。或者,如果发生错误,则应返回 SQLite 错误代码。在任何情况下,如果一个 xInput 回调函数返回一个错误,所有的处理都会被放弃,流式 API 函数会将错误代码的一个副本返回给调用者。

在 sqlite3changeset_start_strm() 的情况下,xInput 回调可能会在迭代器的生命周期中的任何点由会话模块调用。如果这样的 xInput 回调函数返回错误,则迭代器将进入错误状态,从而所有对迭代器函数的后续调用将立即失败,并返回由 xInput 返回的错误代码。

同样,返回变更集(或补丁集)的流 API 函数通过回调函数以块的形式返回它们,而不是通过指向单个大缓冲区的指针。在这种情况下,一对参数如:

  int *pnChangeset,   void **ppChangeset,

被替换为:

  int (*xOutput)(void *pOut, const void *pData, int nData),   void *pOut

调用 xOutput 回调零次或多次以将数据返回给应用程序。传递给每个调用的第一个参数是应用程序提供的 pOut 指针的副本。第二个参数 pData 指向一个大小为 nData 的缓冲区,其中包含返回的输出数据块。如果 xOutput 回调成功处理提供的数据,它应该返回 SQLITE_OK 以指示成功。否则,它应该返回一些其他的 SQLite 错误代码。在这种情况下,立即放弃处理,流式 API 函数将 xOutput 错误代码的副本返回给应用程序。

会话模块从未调用 xOutput 回调,并将第三个参数设置为小于或等于零的值。除此之外,不保证返回的数据块的大小。