Closed richard457 closed 3 years ago
document.properties
uses the Fleece API(FLValue, FLDict, FLArray) of couchbase lite C, use document.jsonProperties
to get/set properties as Dart maps.
Edit: doc.getMutableDocument already returns a mutable document, so Document mutdoc = doc.mutableCopy;
is not needed,
Thanks, I updated the documentation and Sent a PR here https://github.com/Rudiksz/couchbase_lite_dart/pull/7
Another issue found while testing is that doc.jsonProperties = {'name': 'Meem','table':'users'} ;
need exact same properties as original document in order to updated! my first gues was if the document was like {'name':richie','table':'users','email':'b@gmail.com'}
I would only update one field without necessarily explicitly pass all the properties like doc.jsonProperties = {'name': 'Murag'}
just to update only name.
Couchbase lite itself doesn't support subdocument operations, to modify single properties in-place you can use the fleece API Fleece is quite powerful and blazing fast, but it doesn't play well with Flutter and reactive models (I use mobx).
What I do is to have plain Dart data classes and parse the couchbase document like it was a json value (using the Fleece API), and when I'm ready to save it I just turn it into a Couchbase Document which then I save. Here's an example.
Unless you save really large documents and your write operations are substantially more than your read operations, performance is a non issue. Eventually the choice is yours depending on your needs.
class Character {
final String id;
final String name;
final String description;
final Map<CharacterStat, List<int>> stats;
final List<Skill> skills;
final bool remote;
const Character({
this.id,
this.name,
this.description,
this.stats,
this.skills,
this.remote = false,
});
factory Character.fromDocument(Document doc) =>
Character.fromFLValue(doc.properties.value);
factory Character.fromFLValue(FLValue doc) {
return Character(
id: doc['id'].asString,
name: doc['name'].asString,
description: doc['description'].asString,
stats: {
CharacterStat.health: [
doc['stats.health[0]'].asInt,
doc['stats.health[1]'].asInt
],
CharacterStat.strength: [
doc['stats.strength[0]'].asInt,
doc['stats.strength[1]'].asInt
],
CharacterStat.defence: [
doc['stats.defence[0]'].asInt,
doc['stats.defence[1]'].asInt
],
},
skills: doc['skills'].asList.map((e) => Skill.fromFLValue(e)).toList(),
);
}
Document get document {
final data = <String, dynamic>{
'dt': 'character',
'id': id,
'name': name,
'description': description,
'stats': {
CharacterStat.health.asString(): stats[CharacterStat.health],
CharacterStat.strength.asString(): stats[CharacterStat.strength],
CharacterStat.defence.asString(): stats[CharacterStat.defence],
CharacterStat.speed.asString(): stats[CharacterStat.speed],
CharacterStat.luck.asString(): stats[CharacterStat.luck],
},
'skills': skills?.map((e) => e.document.jsonProperties)?.toList() ?? '',
};
data.removeEmptyValues();
return Document(id, data: data);
}
to modify single properties in-place you can use the fleece API
By this I mean that you can do:
Document doc = db.getMutableDocument( '1');
doc.properties['name] = 'another' ;
db.saveDocument(doc);
But the document is still saved as a whole, but without the extra parsing. This is stupidly fast, but the Fleece API needs more testing.
Take a look at the Flutter app in the example folder to see what you can do with the Fleece API. https://www.youtube.com/watch?v=TLsQw7ZW9rI
Thank you a lot, Let me deep test it out.
tried this code
and this:
And they give the following error before I save the document A Value of type 'Map<String,String>' can't be assigned to a variable of type FLDict