From 756a2089e98e2ad779d9d482c6b26890374d77a8 Mon Sep 17 00:00:00 2001 From: Brandon Presley Date: Tue, 30 Aug 2022 23:21:25 +1200 Subject: [PATCH] Prevent race condition with database migrations --- App.tsx | 41 +++-------------------------------------- BestList.tsx | 2 +- DrawerMenu.tsx | 3 ++- EditPlan.tsx | 2 +- EditSet.tsx | 3 ++- EditWorkout.tsx | 2 +- PlanItem.tsx | 2 +- PlanList.tsx | 2 +- Routes.tsx | 45 ++++++++++++++++++++++++++++++++++++++++++--- SetForm.tsx | 2 +- SetItem.tsx | 2 +- SetList.tsx | 2 +- SettingsPage.tsx | 3 ++- ViewBest.tsx | 3 ++- WorkoutItem.tsx | 2 +- WorkoutList.tsx | 2 +- 16 files changed, 63 insertions(+), 55 deletions(-) diff --git a/App.tsx b/App.tsx index cf4abc7..89e93b8 100644 --- a/App.tsx +++ b/App.tsx @@ -4,7 +4,7 @@ import { DefaultTheme as NavigationDefaultTheme, NavigationContainer, } from '@react-navigation/native'; -import React, {useEffect, useState} from 'react'; +import React, {useState} from 'react'; import {useColorScheme} from 'react-native'; import { DarkTheme as PaperDarkTheme, @@ -12,19 +12,7 @@ import { Provider, Snackbar, } from 'react-native-paper'; -import {SQLiteDatabase} from 'react-native-sqlite-storage'; import Ionicon from 'react-native-vector-icons/Ionicons'; -import { - addHidden, - addImage, - addNotify, - addSound, - createPlans, - createSets, - createSettings, - createWorkouts, - getDb, -} from './db'; import Routes from './Routes'; export const Drawer = createDrawerNavigator(); @@ -34,9 +22,9 @@ export type DrawerParamList = { Best: {}; Plans: {}; Workouts: {}; + Loading: {}; }; -export const DatabaseContext = React.createContext({} as any); export const SnackbarContext = React.createContext<{ toast: (value: string, timeout: number) => void; }>({toast: () => null}); @@ -61,32 +49,9 @@ export const CombinedDarkTheme = { }; const App = () => { - const [db, setDb] = useState(null); const [snackbar, setSnackbar] = useState(''); const dark = useColorScheme() === 'dark'; - useEffect(() => { - const init = async () => { - const _db = await getDb(); - setDb(_db); - await _db.executeSql(createPlans); - await _db.executeSql(createSets); - await _db.executeSql(createSettings); - await _db.executeSql(addSound).catch(() => null); - await _db.executeSql(createWorkouts); - await _db.executeSql(addHidden).catch(() => null); - await _db.executeSql(addNotify).catch(() => null); - await _db.executeSql(addImage).catch(() => null); - const [result] = await _db.executeSql(`SELECT * FROM settings LIMIT 1`); - if (result.rows.length === 0) - return _db.executeSql(` - INSERT INTO settings(minutes,seconds,alarm,vibrate,predict,sets) - VALUES(3,30,false,true,true,3); - `); - }; - init(); - }, []); - const toast = (value: string, timeout: number) => { setSnackbar(value); setTimeout(() => setSnackbar(''), timeout); @@ -99,7 +64,7 @@ const App = () => { - + (null as any); + +export default function Routes() { + const [db, setDb] = useState(null); const dark = useColorScheme() === 'dark'; + useEffect(() => { + const init = async () => { + const _db = await getDb(); + try { + await _db.executeSql(createPlans); + await _db.executeSql(createSets); + await _db.executeSql(createSettings); + await _db.executeSql(createWorkouts); + await _db.executeSql(addSound).catch(() => null); + await _db.executeSql(addHidden).catch(() => null); + await _db.executeSql(addNotify).catch(() => null); + await _db.executeSql(addImage).catch(() => null); + const [result] = await _db.executeSql(`SELECT * FROM settings LIMIT 1`); + if (result.rows.length === 0) + return _db.executeSql(` + INSERT INTO settings(minutes,seconds,alarm,vibrate,predict,sets) + VALUES(3,30,false,true,true,3); + `); + } finally { + setDb(_db); + } + }; + init(); + }, []); + if (!db) return null; const routes: Route[] = [ diff --git a/SetForm.tsx b/SetForm.tsx index 556d31a..eafa274 100644 --- a/SetForm.tsx +++ b/SetForm.tsx @@ -1,7 +1,7 @@ import React, {useContext, useEffect, useRef, useState} from 'react'; import {ScrollView, Text} from 'react-native'; import {Button} from 'react-native-paper'; -import {DatabaseContext} from './App'; +import {DatabaseContext} from './Routes'; import MassiveInput from './MassiveInput'; import Set from './set'; diff --git a/SetItem.tsx b/SetItem.tsx index 4048577..e97fcd1 100644 --- a/SetItem.tsx +++ b/SetItem.tsx @@ -2,7 +2,7 @@ import {NavigationProp, useNavigation} from '@react-navigation/native'; import React, {useCallback, useContext, useState} from 'react'; import {GestureResponderEvent, Image, Text} from 'react-native'; import {Divider, List, Menu} from 'react-native-paper'; -import {DatabaseContext} from './App'; +import {DatabaseContext} from './Routes'; import {HomePageParams} from './HomePage'; import Set from './set'; diff --git a/SetList.tsx b/SetList.tsx index df6f91f..43807c8 100644 --- a/SetList.tsx +++ b/SetList.tsx @@ -6,7 +6,7 @@ import { import React, {useCallback, useContext, useEffect, useState} from 'react'; import {FlatList, StyleSheet, View} from 'react-native'; import {List, Searchbar} from 'react-native-paper'; -import {DatabaseContext} from './App'; +import {DatabaseContext} from './Routes'; import DrawerMenu from './DrawerMenu'; import {HomePageParams} from './HomePage'; import MassiveFab from './MassiveFab'; diff --git a/SettingsPage.tsx b/SettingsPage.tsx index 3bbc03e..186c5bd 100644 --- a/SettingsPage.tsx +++ b/SettingsPage.tsx @@ -8,10 +8,11 @@ import React, { import {NativeModules, ScrollView, StyleSheet, Text, View} from 'react-native'; import DocumentPicker from 'react-native-document-picker'; import {Button, Searchbar} from 'react-native-paper'; -import {DatabaseContext, SnackbarContext} from './App'; +import {SnackbarContext} from './App'; import ConfirmDialog from './ConfirmDialog'; import MassiveInput from './MassiveInput'; import MassiveSwitch from './MassiveSwitch'; +import {DatabaseContext} from './Routes'; import Settings from './settings'; export default function SettingsPage() { diff --git a/ViewBest.tsx b/ViewBest.tsx index b50dfe1..a8e9320 100644 --- a/ViewBest.tsx +++ b/ViewBest.tsx @@ -18,8 +18,9 @@ import {IconButton} from 'react-native-paper'; import Share from 'react-native-share'; import {Grid, LineChart, XAxis, YAxis} from 'react-native-svg-charts'; import ViewShot from 'react-native-view-shot'; -import {CombinedDarkTheme, CombinedDefaultTheme, DatabaseContext} from './App'; +import {CombinedDarkTheme, CombinedDefaultTheme} from './App'; import {BestPageParams} from './BestPage'; +import {DatabaseContext} from './Routes'; import Set from './set'; import {formatMonth} from './time'; diff --git a/WorkoutItem.tsx b/WorkoutItem.tsx index 97c6335..ba4747e 100644 --- a/WorkoutItem.tsx +++ b/WorkoutItem.tsx @@ -2,7 +2,7 @@ import {NavigationProp, useNavigation} from '@react-navigation/native'; import React, {useCallback, useContext, useEffect, useState} from 'react'; import {GestureResponderEvent, Image, Text} from 'react-native'; import {List, Menu} from 'react-native-paper'; -import {DatabaseContext} from './App'; +import {DatabaseContext} from './Routes'; import ConfirmDialog from './ConfirmDialog'; import Workout from './workout'; import {WorkoutsPageParams} from './WorkoutsPage'; diff --git a/WorkoutList.tsx b/WorkoutList.tsx index 0d6891f..1bec5e6 100644 --- a/WorkoutList.tsx +++ b/WorkoutList.tsx @@ -6,7 +6,7 @@ import { import React, {useCallback, useContext, useEffect, useState} from 'react'; import {FlatList, StyleSheet, View} from 'react-native'; import {List, Searchbar} from 'react-native-paper'; -import {DatabaseContext} from './App'; +import {DatabaseContext} from './Routes'; import MassiveFab from './MassiveFab'; import SetList from './SetList'; import Workout from './workout';