Skip to content

Commit 3e1d367

Browse files
committed
Implemented Collection.delete(DocumentModel)
1 parent ee05c55 commit 3e1d367

3 files changed

Lines changed: 45 additions & 17 deletions

File tree

common/main/kotlin/com/couchbase/lite/CollectionExtensions.kt

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,12 @@ fun <T: DocumentModel> Collection.getDocumentAs(id: String, deserializer: Deseri
5252
modelFromC4Doc(this, id, getC4Document(id), deserializer)
5353

5454

55-
/**
56-
* Saves a [DocumentModel] instance as a document in the collection, with a specified conflict handler.
57-
* If the model's [DocumentModel.documentMeta] property is null, it will be saved as a new document with the
58-
* given [docID], which must not be null.
59-
* Otherwise the [DocumentModel.documentMeta] property determines the document ID and prior revision ID, and the
60-
* [docID] parameter should be null.
61-
* After a successful save, the [DocumentModel.documentMeta] property is updated to the current state. */
55+
/** Saves a [DocumentModel] instance as a document in the collection, with a specified conflict handler.
56+
* If the model's [DocumentModel.documentMeta] property is null, it will be saved as a new document with the
57+
* given [docID], which must not be null.
58+
* Otherwise the [DocumentModel.documentMeta] property determines the document ID and prior revision ID, and the
59+
* [docID] parameter should be null.
60+
* After a successful save, the [DocumentModel.documentMeta] property is updated to the current state. */
6261
@ExperimentalSerializationApi
6362
inline fun <reified T: DocumentModel> Collection.save(model: T,
6463
docID: String? = null,
@@ -80,7 +79,7 @@ fun <T: DocumentModel> Collection.save(model: T,
8079
doc = MutableDocument(docID)
8180
} else {
8281
require(meta.collection == this || meta.collection == null) {"saving document to wrong collection"}
83-
require(docID == null || docID == meta.id) {"docID parameter does not match meta.id"}
82+
require(docID == null || docID == meta.id) {"docID parameter does not match documentMeta.id"}
8483
doc = getDocument(meta.id)?.toMutable() ?: MutableDocument(meta.id)
8584
}
8685

@@ -131,6 +130,31 @@ fun <T: DocumentModel> Collection.save(model: T,
131130
typealias ModelConflictHandler<T> = (T, T?)-> Boolean
132131

133132

133+
/** Deletes a model's document from the collection.
134+
* @throws CouchbaseLiteException if the [DocumentModel.documentMeta] property is null. */
135+
fun Collection.delete(model: DocumentModel, concurrencyControl: ConcurrencyControl = ConcurrencyControl.LAST_WRITE_WINS): Boolean {
136+
val meta = model.documentMeta ?: throw CouchbaseLiteException("DocumentModel has no document ID")
137+
require(meta.collection == this || meta.collection == null) {"deleting document from wrong collection"}
138+
val doc = getDocument(meta.id) ?: return true
139+
if (doc.revisionID != meta.revisionID && concurrencyControl == ConcurrencyControl.FAIL_ON_CONFLICT)
140+
return false
141+
if (!delete(doc, concurrencyControl))
142+
return false
143+
model.documentMeta = null
144+
return true
145+
}
146+
147+
148+
/** Purges a model's document from the collection.
149+
* @throws CouchbaseLiteException if the [DocumentModel.documentMeta] property is null,
150+
* or the document doesn't exist in the collection. */
151+
fun Collection.purge(model: DocumentModel) {
152+
val id = model.documentMeta?.id ?: throw CouchbaseLiteException("DocumentModel has no document ID")
153+
purge(id)
154+
model.documentMeta = null
155+
}
156+
157+
134158
/** Creates a [DocumentModel] instance from a [C4Document]. */
135159
private fun <T:DocumentModel> modelFromC4Doc(collection: Collection,
136160
docID: String,

common/main/kotlin/com/couchbase/lite/QueryExtensions.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,22 @@ import kotlinx.serialization.descriptors.StructureKind
2323
import kotlinx.serialization.serializer
2424

2525

26-
/** Uses Kotlin Serialization to create an object of type [T] from the query row.
27-
* If the [key] parameter is non-null, it uses the row's value for that key as the source,
28-
* instead of the entire row.
26+
/** Uses Kotlin Serialization to create an object of type [T] from a query result.
27+
* If the [key] parameter is non-null, it uses the result's value for that key as the source,
28+
* instead of the entire result.
2929
*
3030
* For example, if your query is `SELECT name, age, shoeSize FROM people` and you have a
31-
* serializable Person class with properties name, age and shoeSize, you can call:
31+
* serializable `Person` class with properties `name`, `age` and `shoeSize`, you can call:
3232
* `val person = result.data<Person>()`
3333
*
34-
* Or you could use the query `SELECT * as person FROM people` and create the Person with
34+
* Or you could use the query `SELECT * as person FROM people` and create the `Person` with
3535
* `val person = result.data<Person>("person")`.
3636
* */
3737
@ExperimentalSerializationApi
3838
inline fun <reified T> Result.data(key: String? = null): T =
3939
data(serializer(), key)
4040

41-
/** Uses Kotlin Serialization to create a [DocumentModel] instance of type [T] from the query row.
41+
/** Uses Kotlin Serialization to create a [DocumentModel] instance of type [T] from the query result.
4242
* This is a specialization of the one-parameter [data] method that adds a [metaKey] parameter.
4343
*
4444
* The [metaKey] parameter is the name of the result property whose value comes from the N1QL
@@ -80,7 +80,7 @@ fun <T> Result.data(deserializer: DeserializationStrategy<T>,
8080
} else {
8181
// Deserializing a single value from the result:
8282
val i = getIndexForKey(key)
83-
if (i < 0) throw CouchbaseLiteError("Query row has no property '$key'")
83+
if (i < 0) throw CouchbaseLiteError("Query result has no property '$key'")
8484
deserializeFromFleece(columns[i], deserializer)
8585
}
8686
if (result is DocumentModel && metaKey != null)
@@ -119,7 +119,7 @@ private class Entry(override val key: String, override val value: FLValue) : Map
119119
// Creates a [DocumentMeta] from the "meta" column of a Result. (Note: It can't set the `collection`.)
120120
private fun Result.getDocumentMeta(key: String): DocumentMeta? {
121121
val i = getIndexForKey(key)
122-
if (i < 0) throw CouchbaseLiteError("Query row has no property '$key'")
122+
if (i < 0) throw CouchbaseLiteError("Query result has no property '$key'")
123123
val col = flValues[i]
124124
if (col.type != FLValue.DICT) return null
125125
val meta = col.asFLDict()

common/test/java/com/couchbase/lite/CollectionTest.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ class CollectionTest : BaseDbTest() {
12171217
}
12181218

12191219
//---------------------------------------------
1220-
// Model-based API
1220+
// Model-based (serialization) API
12211221
//---------------------------------------------
12221222

12231223
@Test
@@ -1249,6 +1249,10 @@ class CollectionTest : BaseDbTest() {
12491249
Assert.assertEquals(2, faves.count())
12501250
Assert.assertEquals("XTC", faves.getString(0))
12511251
Assert.assertEquals("Elvis Costello", faves.getString(1))
1252+
1253+
// Delete the model. `model` is out of date, so it will fail, but `gotModel` is OK:
1254+
Assert.assertFalse(testCollection.delete(model, ConcurrencyControl.FAIL_ON_CONFLICT))
1255+
Assert.assertTrue(testCollection.delete(gotModel, ConcurrencyControl.FAIL_ON_CONFLICT))
12521256
}
12531257
}
12541258

0 commit comments

Comments
 (0)