Skip to content

Commit 865f1e3

Browse files
Merge pull request #2 from journeyapps/sdk-readme-examples
[Documentation] Added More SDK Examples
2 parents 1e5279c + 186e55d commit 865f1e3

File tree

7 files changed

+176
-25
lines changed

7 files changed

+176
-25
lines changed

.github/workflows/build-packages.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737
name: Publish Production Packages
3838
runs-on: ubuntu-latest
3939
needs: build
40-
if: github.ref == 'refs/heads/master'
40+
if: github.ref == 'refs/heads/main'
4141
steps:
4242
- uses: actions/checkout@v3
4343
with:
@@ -46,7 +46,7 @@ jobs:
4646
- name: Setup NodeJS
4747
uses: actions/setup-node@v2
4848
with:
49-
node-version: 16
49+
node-version: 18
5050

5151
- name: Setup Yarn
5252
run: |

.github/workflows/dev-packages.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Setup NodeJS
1818
uses: actions/setup-node@v2
1919
with:
20-
node-version: 16
20+
node-version: 18
2121

2222
- name: Setup Yarn
2323
run: |

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ yarn build:packages
4040
## Testing Supabase example app
4141

4242
``` bash
43-
cd apps/example
43+
cd apps/supabase-todolist
4444
```
4545

4646
Test on either Android or iOS

lerna.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
{
22
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
3-
"version": "0.0.1-alpha.0",
4-
"packages": [
5-
"packages/*"
6-
],
3+
"version": "independent",
4+
"packages": ["packages/*"],
75
"npmClient": "yarn"
86
}

packages/powersync-sdk-react-native/README.md

Lines changed: 160 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -254,50 +254,77 @@ export const setupPowerSync = async () => {
254254

255255
Once the PowerSync instance is configured you can start using the SQLite DB functions
256256

257+
### Fetching an Item
258+
259+
```JSX
260+
// TodoItemWidget.jsx
261+
import {Text} from 'react-native';
262+
263+
export const TodoItemWidget = ({id}) => {
264+
const [todoItem, setTodoItem] = React.useState([]);
265+
const [error, setError] = React.useState([]);
266+
267+
React.useEffect(() => {
268+
// .get returns the first item of the result. Throws an exception if no result is found.
269+
PowerSync.get('SELECT * from todos WHERE id = ?', [id])
270+
.then(setTodoItem)
271+
.catch(ex => setError(ex.message))
272+
}, []);
273+
274+
return <Text>{error || todoItem.description}</Text>
275+
}
276+
```
277+
257278
### Querying Items
258279

259280
```JSX
260-
// ListWidget.jsx
261-
export const ListWidget = () => {
281+
// ListsWidget.jsx
282+
import {FlatList, Text} from 'react-native';
283+
284+
export const ListsWidget = () => {
262285
const [lists, setLists] = React.useState([]);
263286

264287
React.useEffect(() => {
265288
PowerSync.getAll('SELECT * from lists').then(setLists)
266289
}, []);
267290

268-
return <ul>
269-
{lists.map(list => <li key={list.id}>{list.name}</li>)}
270-
</ul>
291+
return (<FlatList
292+
data={lists.map(list => ({key: list.id, ...list}))}
293+
renderItem={({item}) => <Text>{item.name}</Text>}
294+
/>)
271295
}
272296
```
273297

274298
### Querying with React Query
275299
The PowerSync instance can be used with [React Query](https://tanstack.com/query/v3/docs/react/quick-start). The example below omits the necessary provider setup (see Quickstart).
276300

277301
```JSX
278-
// ListWidget.jsx
302+
// ListsWidget.jsx
279303
import {useQuery} from 'react-query';
304+
import {FlatList, Text} from 'react-native';
280305

281-
export const ListWidget = () => {
306+
export const ListsWidget = () => {
282307
const {data: lists} = useQuery({
283308
queryKey: 'lists',
284309
queryFn: async () => PowerSync.getAll('SELECT * from lists'),
285310
});
286311

287-
return <ul>
288-
{lists.map(list => <li key={list.id}>{list.name}</li>)}
289-
</ul>
312+
return (<FlatList
313+
data={lists.map(list => ({key: list.id, ...list}))}
314+
renderItem={({item}) => <Text>{item.name}</Text>}
315+
/>)
290316
}
291317
```
292318

293-
294319
### Watching Queries
295320

296321
A watch API allows for queries to be executed whenever a change to a dependant table is made.
297322

298323
```JSX
299-
// ListWidget.jsx
300-
export const ListWidget = () => {
324+
// ListsWidget.jsx
325+
import {FlatList, Text} from 'react-native';
326+
327+
export const ListsWidget = () => {
301328
const [lists, setLists] = React.useState([]);
302329

303330
React.useEffect(() => {
@@ -313,12 +340,129 @@ A watch API allows for queries to be executed whenever a change to a dependant t
313340
}
314341
}, []);
315342

316-
return <ul>
317-
{lists.map(list => <li key={list.id}>{list.name}</li>)}
318-
</ul>
343+
return (<FlatList
344+
data={lists.map(list => ({key: list.id, ...list}))}
345+
renderItem={({item}) => <Text>{item.name}</Text>}
346+
/>)
319347
}
320348
```
321349

350+
### Mutations
351+
352+
The `execute` method can be used for executing single SQLite statements.
353+
354+
```JSX
355+
// ListsWidget.jsx
356+
import {Alert, Button, FlatList, Text, View} from 'react-native';
357+
358+
export const ListsWidget = () => {
359+
// Populate lists with one of methods listed above
360+
const [lists, setLists] = React.useState([]);
361+
362+
return (
363+
<View>
364+
<FlatList
365+
data={lists.map(list => ({key: list.id, ...list}))}
366+
renderItem={({item}) => (<View>
367+
<Text>{item.name}</Text>
368+
<Button
369+
title="Delete"
370+
onPress={async () => {
371+
try {
372+
await PowerSync.execute(`DELETE FROM lists WHERE id = ?`, [item.id])
373+
// Watched queries should automatically reload after mutation
374+
} catch (ex) {
375+
Alert('Error', ex.message)
376+
}
377+
}}
378+
/>
379+
</View>)}
380+
/>
381+
<Button
382+
title="Create List"
383+
color="#841584"
384+
onPress={async () => {
385+
try {
386+
await PowerSync.execute('INSERT INTO lists (id, created_at, name, owner_id) VALUES (uuid(), datetime(), ?, ?) RETURNING *', [
387+
'A list name',
388+
"[The user's uuid]"
389+
])
390+
// Watched queries should automatically reload after mutation
391+
} catch (ex) {
392+
Alert.alert('Error', ex.message)
393+
}
394+
}}
395+
/>
396+
</View>
397+
)
398+
}
399+
```
400+
401+
### Transactions
402+
403+
Read and write transactions present a context where multiple changes can be made then finally committed to the DB or rolled back. This ensures that either all the changes get persisted, or no change is made to the DB (in the case of a rollback or exception).
404+
405+
`PowerSync.writeTransaction(callback)` automatically commits changes after the transaction callback is completed if `tx.rollback()` has not explicitly been called. If an exception is thrown in the callback then changes are automatically rolled back.
406+
407+
`PowerSync.readTransaction(callback)` automatically rolls back any attempted changes made in the transaction callback.
408+
409+
410+
```JSX
411+
// ListsWidget.jsx
412+
import {Alert, Button, FlatList, Text, View} from 'react-native';
413+
414+
export const ListsWidget = () => {
415+
// Populate lists with one of methods listed above
416+
const [lists, setLists] = React.useState([]);
417+
418+
return (
419+
<View>
420+
<FlatList
421+
data={lists.map(list => ({key: list.id, ...list}))}
422+
renderItem={({item}) => (<View>
423+
<Text>{item.name}</Text>
424+
<Button
425+
title="Delete"
426+
onPress={async () => {
427+
try {
428+
await PowerSync.writeTransaction(async (tx) => {
429+
// Delete the main list
430+
await tx.executeAsync(`DELETE FROM lists WHERE id = ?`, [item.id]);
431+
// Delete any children of the list
432+
await tx.executeAsync(`DELETE FROM todos WHERE list_id = ?`, [item.id]);
433+
434+
// Transactions are automatically committed at the end of execution
435+
// Transactions are automatically rolled back if an exception ocurred
436+
})
437+
// Watched queries should automatically reload after mutation
438+
} catch (ex) {
439+
Alert.alert('Error', ex.message)
440+
}
441+
}}
442+
/>
443+
</View>)}
444+
/>
445+
<Button
446+
title="Create List"
447+
color="#841584"
448+
onPress={async () => {
449+
try {
450+
await PowerSync.execute('INSERT INTO lists (id, created_at, name, owner_id) VALUES (uuid(), datetime(), ?, ?) RETURNING *', [
451+
'A list name',
452+
"[The user's uuid]"
453+
])
454+
// Watched queries should automatically reload after mutation
455+
} catch (ex) {
456+
Alert.alert('Error', ex.message)
457+
}
458+
}}
459+
/>
460+
</View>
461+
)
462+
}
463+
```
464+
465+
322466
### Using Hooks
323467

324468
Configure a PowerSync DB connection and add it to a context provider

packages/powersync-sdk-react-native/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@journeyapps/powersync-sdk-react-native",
3-
"version": "0.0.1-alpha.0",
3+
"version": "0.0.1-alpha.1",
44
"publishConfig": {
55
"registry": "https://registry.npmjs.org/",
66
"access": "public"

yarn.lock

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,6 +1959,15 @@
19591959
"@types/yargs" "^17.0.8"
19601960
chalk "^4.0.0"
19611961

1962+
"@journeyapps/powersync-sdk-react-native@0.0.1-alpha.0":
1963+
version "0.0.1-alpha.0"
1964+
resolved "https://registry.npmjs.org/@journeyapps/powersync-sdk-react-native/-/powersync-sdk-react-native-0.0.1-alpha.0.tgz#f5cef94d61c9e910f1a197f8da147f996acdd78f"
1965+
integrity sha512-FcQW+ei899RO2vFXV4qF+tHCxAEdYmGFZCQEePtzXQ66KrMhpH5Pz31+97JAkFCw0TDsrq0l++4SDwvYV7JrQg==
1966+
dependencies:
1967+
"@journeyapps/powersync-react" "^0.0.1-alpha.0"
1968+
"@journeyapps/powersync-sdk-common" "^0.0.1-alpha.0"
1969+
async-lock "^1.4.0"
1970+
19621971
"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
19631972
version "0.3.3"
19641973
resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"

0 commit comments

Comments
 (0)