Skip to content

Commit a2637f8

Browse files
committed
feat: added support for listing scopes and collections
1 parent 766c5ce commit a2637f8

File tree

13 files changed

+209
-31
lines changed

13 files changed

+209
-31
lines changed

expo-example/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ allprojects {
3939
maven { url 'https://www.jitpack.io' }
4040
}
4141
}
42-
apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"
42+
apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"apply from: "../../android/build.gradle"
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import React, { useContext, useState } from 'react';
2+
import { View } from 'react-native';
3+
import { useNavigation } from '@react-navigation/native';
4+
import { useStyleScheme } from '@/components/Themed';
5+
import DatabaseNameForm from '@/components/DatabaseNameForm';
6+
import ResultListView from '@/components/ResultsListView';
7+
import DatabaseContext from '@/providers/DatabaseContext';
8+
import useNavigationBarTitleResetOption from '@/hooks/useNavigationBarTitleResetOption';
9+
import HeaderRunActionView from '@/components/HeaderRunActionView';
10+
import { StyledTextInput } from '@/components/StyledTextInput';
11+
import listCollections from '@/service/collection/list';
12+
13+
export default function CollectionListScreen() {
14+
const { databases } = useContext(DatabaseContext)!;
15+
const [databaseName, setDatabaseName] = useState<string>('');
16+
const [scopeName, setScopeName] = useState<string>('');
17+
const [resultMessage, setResultsMessage] = useState<string[]>([]);
18+
const navigation = useNavigation();
19+
const styles = useStyleScheme();
20+
useNavigationBarTitleResetOption('List Collections', navigation, reset);
21+
22+
function reset() {
23+
setDatabaseName('');
24+
setScopeName('');
25+
setResultsMessage([]);
26+
}
27+
28+
const update = async () => {
29+
if (databaseName === '') {
30+
setResultsMessage((prev) => [
31+
...prev,
32+
'Error: Database name is required',
33+
]);
34+
} else {
35+
try {
36+
const collections = await listCollections(
37+
databases,
38+
databaseName,
39+
scopeName
40+
);
41+
if (collections.length > 0) {
42+
collections.forEach((collection) => {
43+
setResultsMessage((prev) => [
44+
...prev,
45+
`Found Collection: <${collection.fullName()}>`,
46+
]);
47+
});
48+
} else {
49+
setResultsMessage((prev) => [
50+
...prev,
51+
'Error: No collections found. Collections should have at least 1 collection defined in a given scope.',
52+
]);
53+
}
54+
} catch (error) {
55+
// @ts-ignore
56+
setResultsMessage((prev) => [...prev, error.message]);
57+
}
58+
}
59+
};
60+
61+
return (
62+
<View style={styles.container}>
63+
<DatabaseNameForm
64+
setDatabaseName={setDatabaseName}
65+
databaseName={databaseName}
66+
/>
67+
<HeaderRunActionView
68+
name="Scope"
69+
iconName="file-cabinet"
70+
handleUpdatePressed={update}
71+
/>
72+
<StyledTextInput
73+
autoCapitalize="none"
74+
placeholder="Scope Name"
75+
onChangeText={(scopeText) => setScopeName(scopeText)}
76+
defaultValue={scopeName}
77+
/>
78+
<ResultListView messages={resultMessage} />
79+
</View>
80+
);
81+
}

expo-example/app/collection/scope/get.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { useContext, useState } from 'react';
2-
import { TextInput, View } from 'react-native';
2+
import { View } from 'react-native';
33
import { useNavigation } from '@react-navigation/native';
44
import { useStyleScheme } from '@/components/Themed';
55
import DatabaseNameForm from '@/components/DatabaseNameForm';
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React, { useContext, useState } from 'react';
2+
import { View } from 'react-native';
3+
import { useNavigation } from '@react-navigation/native';
4+
import { useStyleScheme } from '@/components/Themed';
5+
import DatabaseNameActionForm from '@/components/DatabaseNameActionForm';
6+
import ResultListView from '@/components/ResultsListView';
7+
import DatabaseContext from '@/providers/DatabaseContext';
8+
import useNavigationBarTitleResetOption from '@/hooks/useNavigationBarTitleResetOption';
9+
import listScopes from '@/service/scope/list';
10+
11+
export default function ScopeListScreen() {
12+
const { databases } = useContext(DatabaseContext)!;
13+
const [databaseName, setDatabaseName] = useState<string>('');
14+
const [resultMessage, setResultsMessage] = useState<string[]>([]);
15+
const navigation = useNavigation();
16+
const styles = useStyleScheme();
17+
useNavigationBarTitleResetOption('List Scopes', navigation, reset);
18+
19+
function reset() {
20+
setDatabaseName('');
21+
setResultsMessage([]);
22+
}
23+
24+
const update = async () => {
25+
if (databaseName === '') {
26+
setResultsMessage((prev) => [
27+
...prev,
28+
'Error: Database name is required',
29+
]);
30+
} else {
31+
try {
32+
const scopes = await listScopes(databases, databaseName);
33+
if (scopes.length > 0) {
34+
scopes.forEach((scope) => {
35+
setResultsMessage((prev) => [
36+
...prev,
37+
`Found Scope: <${scope.name}>`,
38+
]);
39+
});
40+
} else {
41+
setResultsMessage((prev) => [
42+
...prev,
43+
'Error: No scopes found. Scopes should have at least 1 scope defined.',
44+
]);
45+
}
46+
} catch (error) {
47+
// @ts-ignore
48+
setResultsMessage((prev) => [...prev, error.message]);
49+
}
50+
}
51+
};
52+
53+
return (
54+
<View style={styles.container}>
55+
<DatabaseNameActionForm
56+
setDatabaseName={setDatabaseName}
57+
databaseName={databaseName}
58+
handleUpdatePressed={update}
59+
/>
60+
<ResultListView messages={resultMessage} />
61+
</View>
62+
);
63+
}

expo-example/ios/expoexample/Info.plist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
5555
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
5656
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
57+
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
58+
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
59+
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
60+
<string>$(PRODUCT_BUNDLE_IDENTIFIER).expo.index_route</string>
5761
</array>
5862
<key>UILaunchStoryboardName</key>
5963
<string>SplashScreen</string>

expo-example/package-lock.json

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

expo-example/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "expo-example",
33
"main": "expo-router/entry",
4-
"version": "1.0.0",
4+
"version": "0.1.1",
55
"scripts": {
66
"prebuild": "expo prebuild",
77
"prebuild:clean": "expo prebuild --clean",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Database, Collection } from 'cbl-reactnative';
2+
3+
export default async function listCollections(
4+
databases: Record<string, Database>,
5+
databaseName: string,
6+
scopeName: string
7+
): Promise<Collection[]> {
8+
if (databaseName in databases) {
9+
let database = databases[databaseName];
10+
const scope = await database.scope(scopeName);
11+
if (scope === null || scope === undefined || scope.name !== scopeName) {
12+
throw new Error(`Error: No Scope found for name ${scopeName}.`);
13+
} else {
14+
const collections = await database.collections(scope);
15+
return collections;
16+
}
17+
} else {
18+
throw new Error('Error: Database not in Context, open Database first');
19+
}
20+
}

expo-example/service/scope/list.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Database, Scope } from 'cbl-reactnative';
2+
3+
export default async function listScopes(
4+
databases: Record<string, Database>,
5+
databaseName: string
6+
): Promise<Scope[]> {
7+
if (databaseName in databases) {
8+
let database = databases[databaseName];
9+
const scopes = await database.scopes();
10+
return scopes;
11+
} else {
12+
throw new Error('Error: Database not in Context, open Database first');
13+
}
14+
}

ios/CblReactnative.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ class CblReactnative: NSObject {
109109
return
110110
}
111111
if let collections = try DatabaseManager.shared.collections(args.scopeName, databaseName: args.databaseName){
112-
let dict = DataAdapter.shared.adaptCollectionsToNSDictionaryString(collections, databaseName: name)
112+
let collectionsArray = DataAdapter.shared.adaptCollectionsToNSDictionaryString(collections, databaseName: name)
113113
let results:NSDictionary = [
114-
"collections": dict ]
114+
"collections": collectionsArray ]
115115
DispatchQueue.main.async {
116116
resolve(results)
117117
}
@@ -624,8 +624,8 @@ class CblReactnative: NSObject {
624624
return
625625
}
626626
if let scopes = try DatabaseManager.shared.scopes(databaseName){
627-
let dict = DataAdapter.shared.adaptScopesToNSDictionary(scopes, databaseName: name)
628-
let results:NSDictionary = ["scopes": dict]
627+
let scopesArray = DataAdapter.shared.adaptScopesToNSDictionary(scopes, databaseName: name)
628+
let results:NSDictionary = ["scopes": scopesArray]
629629
DispatchQueue.main.async {
630630
resolve(results)
631631
}

0 commit comments

Comments
 (0)