Skip to content

Commit 42a291c

Browse files
Merge pull request #56 from DominikZajac/get-document-metadata
fix: collection_getDocument returns only metadata
2 parents 69bf551 + a6324c6 commit 42a291c

File tree

7 files changed

+115
-68
lines changed

7 files changed

+115
-68
lines changed

android/src/main/java/com/cblreactnative/CblReactnativeModule.kt

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import kotlinx.coroutines.DelicateCoroutinesApi
2020
import kotlinx.coroutines.Dispatchers
2121
import kotlinx.coroutines.GlobalScope
2222
import kotlinx.coroutines.launch
23-
23+
import org.json.JSONObject
2424

2525
@OptIn(DelicateCoroutinesApi::class)
2626
@Suppress("FunctionName")
@@ -370,26 +370,55 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
370370
scopeName: String,
371371
collectionName: String,
372372
promise: Promise
373-
){
373+
) {
374374
GlobalScope.launch(Dispatchers.IO) {
375-
try {
376-
if (!DataValidation.validateCollection(collectionName, scopeName, name, promise) ||
377-
!DataValidation.validateDocumentId(docId, promise)
378-
) {
379-
return@launch
380-
}
381-
val doc = CollectionManager.getDocument(docId, collectionName, scopeName, name)
382-
val docMap = DataAdapter.documentToMap(doc)
383-
context.runOnUiQueueThread {
384-
promise.resolve(docMap)
385-
}
386-
} catch (e: Throwable) {
387-
context.runOnUiQueueThread {
388-
promise.reject("DOCUMENT_ERROR", e.message)
375+
try {
376+
if (!DataValidation.validateCollection(collectionName, scopeName, name, promise) ||
377+
!DataValidation.validateDocumentId(docId, promise)
378+
) {
379+
return@launch
380+
}
381+
382+
val doc = CollectionManager.getDocument(docId, collectionName, scopeName, name)
383+
if (doc == null) {
384+
context.runOnUiQueueThread {
385+
promise.resolve(Arguments.createMap())
386+
}
387+
return@launch
388+
}
389+
390+
val documentJson = doc.toJSON()
391+
if (!documentJson.isNullOrEmpty()) {
392+
try {
393+
val test = JSONObject(documentJson)
394+
val map = DataAdapter.jsonObjectToMap(test)
395+
val documentMap = Arguments.makeNativeMap(map)
396+
val writableMap = Arguments.createMap()
397+
writableMap.putMap("_data", documentMap)
398+
399+
writableMap.putString("_id", doc.id)
400+
writableMap.putDouble("_sequence", doc.sequence.toDouble())
401+
402+
context.runOnUiQueueThread {
403+
promise.resolve(writableMap)
404+
}
405+
} catch (e: Exception) {
406+
context.runOnUiQueueThread {
407+
promise.reject("DOCUMENT_ERROR", "Failed to parse document JSON: ${e.message}")
408+
}
409+
}
410+
} else {
411+
context.runOnUiQueueThread {
412+
promise.resolve(Arguments.createMap())
413+
}
414+
}
415+
} catch (e: Throwable) {
416+
context.runOnUiQueueThread {
417+
promise.reject("DOCUMENT_ERROR", e.message)
418+
}
389419
}
390-
}
391420
}
392-
}
421+
}
393422

394423
@ReactMethod
395424
fun collection_GetDocumentExpiration(

android/src/main/java/com/cblreactnative/DataAdapter.kt

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -55,45 +55,6 @@ object DataAdapter {
5555
return format.format(date)
5656
}
5757

58-
/**
59-
* Converts a `Document` to a `WritableMap`.
60-
*
61-
* This function is used to adapt a Couchbase Lite `Document` to a `WritableMap` that can be
62-
* used in React Native to send to Javascript via the Native Bridge. It iterates through the entries
63-
* of the provided `Document` and converts any nested maps that represent blobs into their properties.
64-
* A developer needing the blob would need to manually call the Collection `getBlobContent` method.
65-
*
66-
* @param document The `Document` to be converted. If the document is `null`, an empty `WritableMap` is returned.
67-
* @return A `WritableMap` representation of the provided `Document`.
68-
* @throws Exception If there is an error during the conversion.
69-
*/
70-
@Throws(Exception::class)
71-
fun documentToMap(document: Document?): WritableMap {
72-
if (document == null) {
73-
return Arguments.createMap()
74-
}
75-
val map = document.toMap()
76-
//fix blob - only return properties, to get the content they will have to call getBlobContent
77-
for (key in map.keys) {
78-
val itemValue = map[key]
79-
if (itemValue is Blob) {
80-
document.getBlob(key)?.let { blob ->
81-
val properties = blob.properties.toMutableMap()
82-
val raw = blob.content?.toTypedArray()
83-
properties["raw"] = raw
84-
map[key] = properties
85-
}
86-
}
87-
}
88-
map.remove("sequence")
89-
val resultsMap = Arguments.createMap()
90-
val documentMap: WritableMap = Arguments.makeNativeMap(map)
91-
resultsMap.putString("_id", document.id)
92-
resultsMap.putDouble("_sequence", document.sequence.toDouble())
93-
resultsMap.putMap("_data", documentMap)
94-
return resultsMap
95-
}
96-
9758
/**
9859
* Converts an integer value to a `MaintenanceType` enum.
9960
*
@@ -584,4 +545,54 @@ object DataAdapter {
584545
}
585546
return null
586547
}
548+
549+
/**
550+
* Converts a `JSONObject` to a `Map<String, Any?>`.
551+
*
552+
* This function recursively converts a `JSONObject` into a Kotlin `Map<String, Any?>`.
553+
* Nested `JSONObject` and `JSONArray` objects are also converted to `Map` and `List`, respectively.
554+
*
555+
* @param jsonObject The `JSONObject` to be converted.
556+
* @return A `Map<String, Any?>` representation of the `JSONObject`.
557+
*/
558+
fun jsonObjectToMap(jsonObject: JSONObject): Map<String, Any?> {
559+
val map = mutableMapOf<String, Any?>()
560+
val keys = jsonObject.keys()
561+
while (keys.hasNext()) {
562+
val key = keys.next()
563+
val value = jsonObject.get(key)
564+
map[key] = when (value) {
565+
is JSONObject -> jsonObjectToMap(value)
566+
is JSONArray -> jsonArrayToList(value)
567+
JSONObject.NULL -> null
568+
else -> value
569+
}
570+
}
571+
return map
572+
}
573+
574+
/**
575+
* Converts a `JSONArray` to a `List<Any?>`.
576+
*
577+
* This function recursively converts a `JSONArray` into a Kotlin `List<Any?>`.
578+
* Nested `JSONObject` and `JSONArray` objects are also converted to `Map` and `List`, respectively.
579+
*
580+
* @param jsonArray The `JSONArray` to be converted.
581+
* @return A `List<Any?>` representation of the `JSONArray`.
582+
*/
583+
fun jsonArrayToList(jsonArray: JSONArray): List<Any?> {
584+
val list = mutableListOf<Any?>()
585+
for (i in 0 until jsonArray.length()) {
586+
val value = jsonArray.get(i)
587+
list.add(
588+
when (value) {
589+
is JSONObject -> jsonObjectToMap(value)
590+
is JSONArray -> jsonArrayToList(value)
591+
JSONObject.NULL -> null
592+
else -> value
593+
}
594+
)
595+
}
596+
return list
597+
}
587598
}

ios/CblReactnative.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ class CblReactnative: RCTEventEmitter {
357357
let (isError, args) = DataAdapter.shared.adaptCollectionArgs(name: name, collectionName: collectionName, scopeName: scopeName, reject: reject)
358358
let (isDocumentError, documentId) = DataAdapter.shared.adaptNonEmptyString(value: docId, propertyName: "docId", reject: reject)
359359
let (isKeyError, keyValue) = DataAdapter.shared.adaptNonEmptyString(value: key, propertyName: "key", reject: reject)
360-
360+
361361
if isError || isDocumentError || isKeyError {
362362
return
363363
}
@@ -521,14 +521,21 @@ class CblReactnative: RCTEventEmitter {
521521
resolve(dict)
522522
return
523523
}
524-
//convert document to map using shared library
525524
var data:[String: Any] = [:]
526-
let documentMap = MapHelper.documentToMap(doc)
527-
data["_data"] = documentMap
525+
let documentJson = doc.toJSON()
526+
if !documentJson.isEmpty {
527+
guard let jsonData = documentJson.data(using: .utf8),
528+
let jsonDict = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] else {
529+
reject("DOCUMENT_ERROR", "Failed to parse document JSON", nil)
530+
return
531+
}
532+
data["_data"] = jsonDict
533+
} else {
534+
data["_data"] = [:]
535+
}
528536
data["_id"] = documentId
529537
data["_sequence"] = doc.sequence
530-
531-
//React Native requires NSDictionary - type cast it and return as NSDictionary instead
538+
532539
let dict:NSDictionary = data as NSDictionary
533540
resolve(dict)
534541
} catch let error as NSError {

ios/cbl-js-swift

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cblite-js

0 commit comments

Comments
 (0)