-
Notifications
You must be signed in to change notification settings - Fork 39
Consider FLEncoder
based approach for setting document properties
#289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@pasin wrote in #286 (comment):
I don't make the conversion from the I could imagine an API similar to this one: FLEncoder* CBLDatabase_DocumentEncoder(CBLDatabase *db);
void CBLDocument_SetPropertiesFromEncoder(CBLDocument *doc, FLEncoder *enc); And this is how it would be used (for brevity I omitted error checks of auto enc = CBLDatabase_DocumentEncoder(db);
FLEncoder_Reset(enc);
FLEncoder_BeginDict(enc, 1);
FLEncoder_WriteKey(enc, FLSTR("A"));
FLEncoder_WriteString(enc, FLSTR("B"));
FLEncoder_EndDict(enc);
auto doc = CBLDocument_Create();
CBLDocument_SetPropertiesFromEncoder(doc, enc); |
From looking at the implementation, the API below seems realistic to me: /** The callback of a \ref CBLDocumentPropertiesEncoder that is invoked when the properties
of the document need to be encoded to Fleece.
The callback must write the document properties to the provided encoder but must not
call \ref FLEncoder_Finish. If for any reason, the callback is unable to encode the
document properties, it must return false.
@note The callback might be invoked from any thread.
@note The encoded root value must be a dictionary.
@note The callback may only use the Fleece API and must not use the CBL API.
@note The callback must not hold onto the \ref encoder.
@note The callback must not use \ref FLEncoder_Free, \ref FLEncoder_GetExtraInfo,
\ref FLEncoder_SetExtraInfo or \ref FLEncoder_SetSharedKeys.
@param context The arbitrary value provided in \ref CBLDocumentPropertiesEncoder.
@param encoder The encoder to use for encoding the document properties to Fleece.
@return Whether the document properties could be fully encoded. */
typedef bool (*CBLDocumentPropertiesEncoderCallback)(void* context, FLEncoder encoder);
/** Encodes an external representation of a document's properties by writing to a \ref FLEncoder.
This provides an alternative to building up a document's properties through mutable Fleece
collections.
If a properties encoder has been set for a document (\ref CBLDocument_SetPropertiesEncoder),
the properties encoder's callback (\ref CBLDocumentPropertiesEncoderCallback) will be invoked
as part of saving the document, to encode the current state of the document's properties.
The callback receives an arbitrary context value that should be used to give the callback access
to the external representation of the document's properties.
While a properties encoder is set for a document, changes to the document's properties
through other APIs will be overridden by the properties encoder when the document is saved.
Directly after a document has been saved it's properties reflect the state of the external
representation of the document's properties.
*/
struct CBLDocumentPropertiesEncoder {
/** Callback that is invoked when the properties of the document need to be encoded to Fleece. */
CBLDocumentPropertiesEncoderCallback callback;
/** Arbitrary value that is passed to the callback. */
void* context;
};
/** Sets a document's \ref CBLDocumentPropertiesEncoder.
@param encoder The properties encoder to use for the document, or NULL to remove the current
one. The provided properties encoder is copied. */
void CBLDocument_SetPropertiesEncoder(CBLDocument*,
CBLDocumentPropertiesEncoder* _cbl_nullable encoder) CBLAPI;
/** Returns a document's current \ref CBLDocumentPropertiesEncoder.
May be NULL, meaning that the document has no properties encoder.
@warning When the document is released or a new properties encoder is set, this reference
becomes invalid. */
CBLDocumentPropertiesEncoder* _cbl_nullable CBLDocument_GetPropertiesEncoder(CBLDocument*) CBLAPI;
/** Writes a \ref CBLBlob to the encoder */
void FLEncoder_WriteBlob(FLEncoder, CBLBlob *blob) CBLAPI;
/** Writes a \ref CBLEncryptable to the encoder */
void FLEncoder_WriteEncryptable(FLEncoder, CBLEncryptable *encryptable) CBLAPI; This API allows users to pass an Especially for large documents, this API would allow for significantly more efficient save operations. @pasin @borrrden I'd be happy to work on this if you think this is a reasonable addition to the API. |
@blaugold First of all , thanks for the suggestion. I have a few comments on this.
|
Thanks for taking a look @pasin.
If someone uses a model (external representation) to access the document properties, I would expect that they usually decode their model from Fleece after loading a document, set a To ensure consistency, if a
The goal of the suggested API is to avoid unnecessary work when encoding model data to Fleece. The fastest way to do this is to pass a
The suggested Ideally, the As a side note, my idea was that |
Actually, there is something else that I have been meaning to bring up relating to document properties and Fleece.
I have basically ported the Fleece integration layer (
MValue
,MCollection
, etc.) to Dart to efficiently read and write document properties from Dart. This means that I don't use of mutable Fleece collections and instead pass aFLEncoder
toMRoot
to serialize the current state of the document properties into Fleece data.The current CBL C API does not support this workflow in an optimal way because there is no way to directly set document properties from Fleece data. I work around this by creating a
FLDoc
from the Fleece data and setting its root value as the new document properties. The downside of this approach is that the document properties are encoded a second time when the document is actually saved.I would be great if a
FLEncoder
based workflow for setting document properties was fully supported.Originally posted by @blaugold in #286 (comment)
The text was updated successfully, but these errors were encountered: