Skip to content

Commit ab37b2e

Browse files
committed
feat: added scope and collection API support
1 parent 6751538 commit ab37b2e

File tree

5 files changed

+243
-30
lines changed

5 files changed

+243
-30
lines changed

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

Lines changed: 155 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.cblreactnative
22

33
import cbl.js.kotiln.DatabaseManager
4+
import cbl.js.kotiln.CollectionManager
45
import cbl.js.kotiln.FileSystemHelper
56
import cbl.js.kotiln.LoggingManager
67
import com.couchbase.lite.*
@@ -36,13 +37,17 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
3637
}
3738

3839
// Collection Functions
40+
3941
@ReactMethod
4042
fun collection_CreateCollection(
4143
collectionName: String,
4244
name: String,
4345
scopeName: String,
4446
promise: Promise) {
4547
try {
48+
if(!DataValidation.validateCollection(collectionName, scopeName, name, promise)) {
49+
return
50+
}
4651
val col = DatabaseManager.createCollection(collectionName, scopeName, name)
4752
col?.let { collection ->
4853
val colMap = DataAdapter.adaptCollectionToMap(collection, name)
@@ -62,6 +67,9 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
6267
scopeName: String,
6368
promise: Promise) {
6469
try {
70+
if(!DataValidation.validateCollection(collectionName, scopeName, name, promise)) {
71+
return
72+
}
6573
DatabaseManager.deleteCollection(collectionName, scopeName, name)
6674
promise.resolve(null)
6775
} catch (e: Exception) {
@@ -76,6 +84,9 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
7684
scopeName: String,
7785
promise: Promise) {
7886
try {
87+
if(!DataValidation.validateCollection(collectionName, scopeName, name, promise)) {
88+
return
89+
}
7990
val col = DatabaseManager.getCollection(collectionName, scopeName, name)
8091
col?.let { collection ->
8192
val colMap = DataAdapter.adaptCollectionToMap(collection, name)
@@ -88,14 +99,75 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
8899
}
89100
}
90101

102+
@ReactMethod
103+
fun collection_GetCollections(
104+
name: String,
105+
scopeName: String,
106+
promise: Promise) {
107+
try {
108+
if (!DataValidation.validateScope(scopeName, name, promise)) {
109+
return
110+
}
111+
val cols = DatabaseManager.getCollections(scopeName, name)
112+
val colList = Arguments.createArray()
113+
cols?.forEach { collection ->
114+
val colMap = DataAdapter.adaptCollectionToMap(collection, name)
115+
colList.pushMap(colMap)
116+
}
117+
val resultsCollections:WritableMap = Arguments.createMap()
118+
resultsCollections.putArray("collections", colList)
119+
promise.resolve(resultsCollections)
120+
} catch (e: Exception) {
121+
promise.reject("DATABASE_ERROR", e.message)
122+
}
123+
}
124+
125+
@ReactMethod
126+
fun collection_GetCount(
127+
collectionName: String,
128+
name: String,
129+
scopeName: String,
130+
promise: Promise) {
131+
try {
132+
if(!DataValidation.validateCollection(collectionName, scopeName, name, promise)) {
133+
return
134+
}
135+
val count = CollectionManager.documentsCount(collectionName, scopeName, name)
136+
val map = Arguments.createMap()
137+
map.putInt("count", count)
138+
promise.resolve(map)
139+
} catch (e: Exception) {
140+
promise.reject("DATABASE_ERROR", e.message)
141+
}
142+
}
143+
144+
@ReactMethod
145+
fun collection_GetDefault(
146+
name: String,
147+
promise: Promise){
148+
if (!DataValidation.validateDatabaseName(name, promise)) {
149+
return
150+
}
151+
try {
152+
val col = DatabaseManager.defaultCollection(name)
153+
col?.let { collection ->
154+
val colMap = DataAdapter.adaptCollectionToMap(collection, name)
155+
promise.resolve(colMap)
156+
return
157+
}
158+
promise.reject("COLLECTION_ERROR", "Error getting default collection")
159+
} catch (e: Exception) {
160+
promise.reject("DATABASE_ERROR", e.message)
161+
}
162+
}
163+
91164
// Database Functions
92165
@ReactMethod
93166
fun database_ChangeEncryptionKey(
94167
newKey: String,
95168
name: String,
96169
promise: Promise) {
97-
if (name.isEmpty()) {
98-
promise.reject("DATABASE_ERROR", "Database name must be provided")
170+
if (!DataValidation.validateDatabaseName(name, promise)) {
99171
return
100172
}
101173
try {
@@ -110,8 +182,7 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
110182
fun database_Close(
111183
name: String,
112184
promise: Promise) {
113-
if (name.isEmpty()) {
114-
promise.reject("DATABASE_ERROR", "Database name must be provided")
185+
if (!DataValidation.validateDatabaseName(name, promise)) {
115186
return
116187
}
117188
try {
@@ -131,12 +202,10 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
131202
encryptionKey: String?,
132203
promise: Promise) {
133204
try {
134-
if (name.isEmpty()) {
135-
promise.reject("DATABASE_ERROR", "Database name must be provided")
205+
if (!DataValidation.validateDatabaseName(newName, promise)) {
136206
return
137207
}
138-
if (path.isEmpty()) {
139-
promise.reject("DATABASE_ERROR", "Database path must be provided")
208+
if (!DataValidation.validatePath(path, promise)) {
140209
return
141210
}
142211
val databaseConfig = DataAdapter.getDatabaseConfig(directory, encryptionKey)
@@ -151,8 +220,7 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
151220
fun database_Delete(
152221
name: String,
153222
promise: Promise) {
154-
if (name.isEmpty()) {
155-
promise.reject("DATABASE_ERROR", "Database name must be provided")
223+
if (!DataValidation.validateDatabaseName(name, promise)) {
156224
return
157225
}
158226
try {
@@ -168,12 +236,10 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
168236
path: String,
169237
name: String,
170238
promise: Promise) {
171-
if (name.isEmpty()) {
172-
promise.reject("DATABASE_ERROR", "Database name must be provided")
239+
if (!DataValidation.validateDatabaseName(name, promise)) {
173240
return
174241
}
175-
if (path.isEmpty()) {
176-
promise.reject("DATABASE_ERROR", "Database path must be provided")
242+
if (!DataValidation.validatePath(path, promise)) {
177243
return
178244
}
179245
try {
@@ -189,8 +255,10 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
189255
name: String,
190256
directory: String,
191257
promise: Promise) {
192-
if (name.isEmpty()) {
193-
promise.reject("DATABASE_ERROR", "Database name must be provided")
258+
if (!DataValidation.validateDatabaseName(name, promise)) {
259+
return
260+
}
261+
if (!DataValidation.validatePath(directory, promise)) {
194262
return
195263
}
196264
try {
@@ -205,8 +273,7 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
205273
fun database_GetPath(
206274
name: String,
207275
promise: Promise) {
208-
if (name.isEmpty()) {
209-
promise.reject("DATABASE_ERROR", "Database name must be provided")
276+
if (!DataValidation.validateDatabaseName(name, promise)) {
210277
return
211278
}
212279
try {
@@ -223,8 +290,7 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
223290
directory: String? = null,
224291
encryptionKey: String? = null,
225292
promise: Promise) {
226-
if (name.isEmpty()) {
227-
promise.reject("DATABASE_ERROR", "Database name must be provided")
293+
if (!DataValidation.validateDatabaseName(name, promise)) {
228294
return
229295
}
230296
try {
@@ -244,8 +310,7 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
244310
maintenanceType: Double,
245311
databaseName: String,
246312
promise: Promise) {
247-
if (databaseName.isEmpty()) {
248-
promise.reject("DATABASE_ERROR", "Database name must be provided")
313+
if (!DataValidation.validateDatabaseName(name, promise)) {
249314
return
250315
}
251316
try {
@@ -285,6 +350,74 @@ class CblReactnativeModule(reactContext: ReactApplicationContext) :
285350
}
286351
}
287352

353+
// Scope Functions
354+
@ReactMethod
355+
fun scope_GetDefault(
356+
name: String,
357+
promise: Promise ){
358+
try {
359+
if (!DataValidation.validateDatabaseName(name, promise)) {
360+
return
361+
}
362+
val scopeValue = DatabaseManager.defaultScope(name)
363+
scopeValue?.let { scope ->
364+
val scopeMap = DataAdapter.adaptScopeToMap(scope, name)
365+
promise.resolve(scopeMap)
366+
return
367+
}
368+
promise.reject("SCOPE_ERROR", "Error getting default scope")
369+
} catch (e: Exception) {
370+
promise.reject("SCOPE_ERROR", e.message)
371+
}
372+
}
373+
374+
@ReactMethod
375+
fun scope_GetScope(
376+
scopeName: String,
377+
name: String,
378+
promise: Promise) {
379+
try {
380+
if (!DataValidation.validateScope(scopeName, name, promise)) {
381+
return
382+
}
383+
val scopeValue = DatabaseManager.getScope(name, scopeName)
384+
scopeValue?.let { scope ->
385+
val scopeMap = DataAdapter.adaptScopeToMap(scope, name)
386+
promise.resolve(scopeMap)
387+
return
388+
}
389+
promise.reject("SCOPE_ERROR", "Error getting scope")
390+
} catch (e: Exception) {
391+
promise.reject("SCOPE_ERROR", e.message)
392+
} catch(e: Exception) {
393+
promise.reject("SCOPE_ERROR", e.message)
394+
}
395+
}
396+
397+
@ReactMethod
398+
fun scope_GetScopes(
399+
name: String,
400+
promise: Promise){
401+
try {
402+
if (!DataValidation.validateDatabaseName(name, promise)) {
403+
return
404+
}
405+
val scopes = DatabaseManager.scopes(name)
406+
val scopeList = Arguments.createArray()
407+
scopes.forEach { scope ->
408+
val scopeMap = DataAdapter.adaptScopeToMap(scope, name)
409+
scopeList.pushMap(scopeMap)
410+
}
411+
val resultsScopes:WritableMap = Arguments.createMap()
412+
resultsScopes.putArray("scopes", scopeList)
413+
promise.resolve(resultsScopes)
414+
} catch (e: Exception) {
415+
promise.reject("SCOPE_ERROR", e.message)
416+
} catch (e: Exception) {
417+
promise.reject("SCOPE_ERROR", e.message)
418+
}
419+
}
420+
288421
companion object {
289422
const val NAME = "CblReactnative"
290423
}

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,20 @@ object DataAdapter {
2424
fun adaptCollectionToMap(collection: CBLCollection, databaseName: String)
2525
: WritableMap {
2626
val colMap: WritableMap = Arguments.createMap()
27-
val scopeMap: WritableMap = Arguments.createMap()
27+
val scopeMap: WritableMap = adaptScopeToMap(collection.scope, databaseName)
2828
colMap.putString("name", collection.name)
29-
scopeMap.putString("name", collection.scope.name)
30-
scopeMap.putString("databaseName", databaseName)
3129
colMap.putMap("scope", scopeMap)
3230
return colMap
3331
}
34-
32+
33+
fun adaptScopeToMap(scope: Scope,
34+
databaseName: String): WritableMap {
35+
val scopeMap: WritableMap = Arguments.createMap()
36+
scopeMap.putString("name", scope.name)
37+
scopeMap.putString("databaseName", databaseName)
38+
return scopeMap
39+
}
40+
3541
fun getDatabaseConfig(
3642
directory: String?,
3743
encryptionKey: String?): JSONObject {
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.cblreactnative
2+
3+
import com.facebook.react.bridge.Promise
4+
5+
object DataValidation {
6+
7+
fun validateCollection(
8+
collectionName: String,
9+
scopeName: String,
10+
databaseName: String,
11+
promise: Promise): Boolean {
12+
return validateCollectionName(collectionName, promise)
13+
&& validateScopeName(scopeName, promise)
14+
&& validateDatabaseName(databaseName, promise)
15+
}
16+
17+
fun validateScope(
18+
scopeName: String,
19+
databaseName: String,
20+
promise: Promise): Boolean {
21+
return validateScopeName(scopeName, promise)
22+
&& validateDatabaseName(databaseName, promise)
23+
}
24+
25+
fun validateCollectionName(
26+
collectionName: String,
27+
promise: Promise): Boolean {
28+
val isValid = collectionName.isNotEmpty()
29+
if (!isValid) {
30+
promise.reject("COLLECTION_ERROR", "Collection name must be provided")
31+
}
32+
return isValid
33+
}
34+
35+
fun validateScopeName(
36+
scopeName: String,
37+
promise: Promise): Boolean {
38+
val isValid = scopeName.isNotEmpty()
39+
if (!isValid) {
40+
promise.reject("SCOPE_ERROR", "Scope name must be provided")
41+
}
42+
return isValid
43+
}
44+
45+
fun validateDatabaseName(
46+
databaseName: String,
47+
promise: Promise
48+
): Boolean {
49+
val isValid = databaseName.isNotEmpty()
50+
if (!isValid) {
51+
promise.reject("DATABASE_ERROR", "Database name must be provided")
52+
}
53+
return isValid
54+
}
55+
56+
fun validateEncryptionKey(encryptionKey: String): Boolean {
57+
return encryptionKey.isNotEmpty()
58+
}
59+
60+
fun validatePath(
61+
path: String,
62+
promise: Promise): Boolean {
63+
val isValid = path.isNotEmpty()
64+
if (!isValid) {
65+
promise.reject("DATABASE_ERROR", "Database path must be provided")
66+
}
67+
return isValid
68+
}
69+
70+
fun validateNewName(newName: String): Boolean {
71+
return newName.isNotEmpty()
72+
}
73+
}

expo-example/ios/expoexample/Info.plist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
5757
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
5858
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
59+
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
5960
</array>
6061
<key>UILaunchStoryboardName</key>
6162
<string>SplashScreen</string>

0 commit comments

Comments
 (0)