Remove workouts table in favor of storing steps on sets

This commit is contained in:
Brandon Presley 2022-09-23 13:52:33 +12:00
parent f4f29df172
commit 14d71fec8b
8 changed files with 126 additions and 200 deletions

View File

@ -12,15 +12,7 @@ import ConfirmDialog from './ConfirmDialog';
import {MARGIN, PADDING} from './constants'; import {MARGIN, PADDING} from './constants';
import MassiveInput from './MassiveInput'; import MassiveInput from './MassiveInput';
import {updatePlanWorkouts} from './plan.service'; import {updatePlanWorkouts} from './plan.service';
import Set from './set';
import {addSet, getSets, updateManySet, updateSetImage} from './set.service'; import {addSet, getSets, updateManySet, updateSetImage} from './set.service';
import Workout from './workout';
import {
addWorkout,
getWorkout,
updateName,
updateSteps,
} from './workout.service';
import {WorkoutsPageParams} from './WorkoutsPage'; import {WorkoutsPageParams} from './WorkoutsPage';
export default function EditWorkout() { export default function EditWorkout() {
@ -52,31 +44,23 @@ export default function EditWorkout() {
setMinutes(set.minutes?.toString() ?? '3'); setMinutes(set.minutes?.toString() ?? '3');
setSeconds(set.seconds?.toString() ?? '30'); setSeconds(set.seconds?.toString() ?? '30');
setSets(set.sets?.toString() ?? '3'); setSets(set.sets?.toString() ?? '3');
setSteps(set.steps ?? '');
}, },
); );
console.log(`${EditWorkout.name}.focus`, {params});
getWorkout(params.value.name).then(workout => setSteps(workout.steps));
}, [navigation, params]), }, [navigation, params]),
); );
const update = async () => { const update = async () => {
console.log(`${EditWorkout.name}.update`, {
params: params.value.name,
name,
uri,
steps,
});
await updateManySet({ await updateManySet({
oldName: params.value.name, oldName: params.value.name,
newName: name || params.value.name, newName: name || params.value.name,
sets, sets,
seconds, seconds,
minutes, minutes,
steps,
}); });
await updatePlanWorkouts(params.value.name, name || params.value.name); await updatePlanWorkouts(params.value.name, name || params.value.name);
await updateName(params.value.name, name);
if (uri || removeImage) await updateSetImage(params.value.name, uri || ''); if (uri || removeImage) await updateSetImage(params.value.name, uri || '');
if (steps) await updateSteps(params.value.name, steps);
navigation.goBack(); navigation.goBack();
}; };
@ -90,8 +74,8 @@ export default function EditWorkout() {
minutes: +minutes, minutes: +minutes,
seconds: +seconds, seconds: +seconds,
sets: +sets, sets: +sets,
} as Set); steps,
addWorkout({name, steps} as Workout); });
navigation.goBack(); navigation.goBack();
}; };

View File

@ -3,9 +3,10 @@ import {useColorScheme} from 'react-native';
import {IconButton} from 'react-native-paper'; import {IconButton} from 'react-native-paper';
import {Drawer, DrawerParamList} from './App'; import {Drawer, DrawerParamList} from './App';
import BestPage from './BestPage'; import BestPage from './BestPage';
import {migrations} from './db'; import {runMigrations} from './db';
import HomePage from './HomePage'; import HomePage from './HomePage';
import PlanPage from './PlanPage'; import PlanPage from './PlanPage';
import {getSettings} from './settings.service';
import SettingsPage from './SettingsPage'; import SettingsPage from './SettingsPage';
import WorkoutsPage from './WorkoutsPage'; import WorkoutsPage from './WorkoutsPage';
@ -20,7 +21,9 @@ export default function Routes() {
const dark = useColorScheme() === 'dark'; const dark = useColorScheme() === 'dark';
useEffect(() => { useEffect(() => {
migrations().then(() => setMigrated(true)); runMigrations()
.then(getSettings)
.then(() => setMigrated(true));
}, []); }, []);
if (!migrated) return null; if (!migrated) return null;

View File

@ -5,7 +5,6 @@ import {List, Menu, Text} from 'react-native-paper';
import ConfirmDialog from './ConfirmDialog'; import ConfirmDialog from './ConfirmDialog';
import {deleteSetsBy} from './set.service'; import {deleteSetsBy} from './set.service';
import Workout from './workout'; import Workout from './workout';
import {removeWorkout} from './workout.service';
import {WorkoutsPageParams} from './WorkoutsPage'; import {WorkoutsPageParams} from './WorkoutsPage';
export default function WorkoutItem({ export default function WorkoutItem({
@ -22,7 +21,6 @@ export default function WorkoutItem({
const remove = useCallback(async () => { const remove = useCallback(async () => {
await deleteSetsBy(item.name); await deleteSetsBy(item.name);
await removeWorkout(item.name);
setShowMenu(false); setShowMenu(false);
onRemoved(); onRemoved();
}, [setShowMenu, onRemoved, item.name]); }, [setShowMenu, onRemoved, item.name]);

229
db.ts
View File

@ -3,140 +3,111 @@ import {
openDatabase, openDatabase,
SQLiteDatabase, SQLiteDatabase,
} from 'react-native-sqlite-storage'; } from 'react-native-sqlite-storage';
import {getSettings} from './settings.service';
enablePromise(true); enablePromise(true);
const createSets = ` const migrations = [
CREATE TABLE IF NOT EXISTS sets ( `
id INTEGER PRIMARY KEY AUTOINCREMENT, CREATE TABLE IF NOT EXISTS sets (
name TEXT NOT NULL, id INTEGER PRIMARY KEY AUTOINCREMENT,
reps INTEGER NOT NULL, name TEXT NOT NULL,
weight INTEGER NOT NULL, reps INTEGER NOT NULL,
created TEXT NOT NULL, weight INTEGER NOT NULL,
unit TEXT DEFAULT 'kg' created TEXT NOT NULL,
); unit TEXT DEFAULT 'kg'
`; )
`,
const createPlans = ` `
CREATE TABLE IF NOT EXISTS plans ( CREATE TABLE IF NOT EXISTS plans (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
days TEXT NOT NULL, days TEXT NOT NULL,
workouts TEXT NOT NULL workouts TEXT NOT NULL
); )
`; `,
`
const createSettings = ` CREATE TABLE IF NOT EXISTS settings (
CREATE TABLE IF NOT EXISTS settings ( minutes INTEGER NOT NULL DEFAULT 3,
minutes INTEGER NOT NULL DEFAULT 3, seconds INTEGER NOT NULL DEFAULT 30,
seconds INTEGER NOT NULL DEFAULT 30, alarm BOOLEAN NOT NULL DEFAULT false,
alarm BOOLEAN NOT NULL DEFAULT false, vibrate BOOLEAN NOT NULL DEFAULT true,
vibrate BOOLEAN NOT NULL DEFAULT true, predict BOOLEAN NOT NULL DEFAULT true,
predict BOOLEAN NOT NULL DEFAULT true, sets INTEGER NOT NULL DEFAULT 3
sets INTEGER NOT NULL DEFAULT 3 )
); `,
`; `ALTER TABLE settings ADD COLUMN sound TEXT NULL`,
`
const addSound = ` CREATE TABLE IF NOT EXISTS workouts(
ALTER TABLE settings ADD COLUMN sound TEXT NULL; name TEXT PRIMARY KEY,
`; sets INTEGER DEFAULT 3
)
const createWorkouts = ` `,
CREATE TABLE IF NOT EXISTS workouts( `
name TEXT PRIMARY KEY, ALTER TABLE sets ADD COLUMN hidden DEFAULT false
sets INTEGER DEFAULT 3 `,
); `
`; ALTER TABLE settings ADD COLUMN notify DEFAULT false
`,
const addHidden = ` `
ALTER TABLE sets ADD COLUMN hidden DEFAULT false; ALTER TABLE sets ADD COLUMN image TEXT NULL
`; `,
`
const addNotify = ` ALTER TABLE settings ADD COLUMN images BOOLEAN DEFAULT false
ALTER TABLE settings ADD COLUMN notify DEFAULT false; `,
`; `
SELECT * FROM settings LIMIT 1
const addImage = ` `,
ALTER TABLE sets ADD COLUMN image TEXT NULL; `
`; INSERT INTO settings(minutes) VALUES(3)
`,
const addImages = ` `
ALTER TABLE settings ADD COLUMN images BOOLEAN DEFAULT false; ALTER TABLE workouts ADD COLUMN steps TEXT NULL
`; `,
`
const selectSettings = ` INSERT OR IGNORE INTO workouts (name) SELECT DISTINCT name FROM sets
SELECT * FROM settings LIMIT 1 `,
`; `
ALTER TABLE sets ADD COLUMN sets INTEGER NOT NULL DEFAULT 3
const insertSettings = ` `,
INSERT INTO settings(minutes) VALUES(3); `
`; ALTER TABLE sets ADD COLUMN minutes INTEGER NOT NULL DEFAULT 3
`,
const addSteps = ` `
ALTER TABLE workouts ADD COLUMN steps TEXT NULL; ALTER TABLE sets ADD COLUMN seconds INTEGER NOT NULL DEFAULT 30
`; `,
`
const insertWorkouts = ` ALTER TABLE settings ADD COLUMN showUnit BOOLEAN DEFAULT true
INSERT OR IGNORE INTO workouts (name) SELECT DISTINCT name FROM sets; `,
`; `
ALTER TABLE sets ADD COLUMN steps TEXT NULL
const removeSeconds = ` `,
ALTER TABLE settings DROP COLUMN seconds `
`; UPDATE sets SET steps = (
SELECT workouts.steps FROM workouts WHERE workouts.name = sets.name
const removeMinutes = ` )
ALTER TABLE settings DROP COLUMN minutes `,
`; `
DROP TABLE workouts
const removeSets = ` `,
ALTER TABLE settings DROP COLUMN sets ];
`;
const addSets = `
ALTER TABLE sets ADD COLUMN sets INTEGER NOT NULL DEFAULT 3
`;
const addMinutes = `
ALTER TABLE sets ADD COLUMN minutes INTEGER NOT NULL DEFAULT 3
`;
const addSeconds = `
ALTER TABLE sets ADD COLUMN seconds INTEGER NOT NULL DEFAULT 30
`;
const addShowUnit = `
ALTER TABLE settings ADD COLUMN showUnit BOOLEAN DEFAULT true;
`;
export let db: SQLiteDatabase; export let db: SQLiteDatabase;
export const migrations = async () => { export const runMigrations = async () => {
db = await openDatabase({name: 'massive.db'}); db = await openDatabase({name: 'massive.db'});
await db.executeSql(createPlans); await db.executeSql(`
await db.executeSql(createSets); CREATE TABLE IF NOT EXISTS migrations(
await db.executeSql(createSettings); id INTEGER PRIMARY KEY AUTOINCREMENT,
await db.executeSql(createWorkouts); command TEXT NOT NULL
await db.executeSql(addSound).catch(() => null); )
await db.executeSql(addHidden).catch(() => null); `);
await db.executeSql(addNotify).catch(() => null); const [result] = await db.executeSql(`SELECT * FROM migrations`);
await db.executeSql(addImage).catch(() => null); const missing = migrations.slice(result.rows.length);
await db.executeSql(addImages).catch(() => null); for (const command of missing) {
await db.executeSql(addSteps).catch(() => null); await db.executeSql(command).catch(console.error);
await db.executeSql(insertWorkouts).catch(() => null); const insert = `
await db.executeSql(removeSeconds).catch(() => null); INSERT INTO migrations (command)
await db.executeSql(removeMinutes).catch(() => null); VALUES (?)
await db.executeSql(removeSets).catch(() => null); `;
await db.executeSql(addSets).catch(() => null); await db.executeSql(insert, [command]);
await db.executeSql(addMinutes).catch(() => null); }
await db.executeSql(addSeconds).catch(() => null);
await db.executeSql(addShowUnit).catch(() => null);
const [result] = await db.executeSql(selectSettings);
if (result.rows.length === 0) await db.executeSql(insertSettings);
await getSettings();
}; };
export interface PageParams {
search: string;
limit: number;
offset: number;
}

View File

@ -17,9 +17,10 @@ export const updateSet = async (value: Set) => {
]); ]);
}; };
export const addSets = async (values: string) => { export const addSets = async (columns: string, values: string) => {
console.log({columns, values});
const insert = ` const insert = `
INSERT INTO sets(name,reps,weight,created,unit,hidden) INSERT INTO sets(${columns})
VALUES ${values} VALUES ${values}
`; `;
return db.executeSql(insert); return db.executeSql(insert);
@ -54,7 +55,7 @@ export const getAllSets = async (): Promise<Set[]> => {
return result.rows.raw(); return result.rows.raw();
}; };
export interface PageParams { interface PageParams {
search: string; search: string;
limit: number; limit: number;
offset: number; offset: number;
@ -97,18 +98,27 @@ export const updateManySet = async ({
minutes, minutes,
seconds, seconds,
sets, sets,
steps,
}: { }: {
oldName: string; oldName: string;
newName: string; newName: string;
minutes: string; minutes: string;
seconds: string; seconds: string;
sets: string; sets: string;
steps: string;
}) => { }) => {
const update = ` const update = `
UPDATE sets SET name = ?, minutes = ?, seconds = ?, sets = ? UPDATE sets SET name = ?, minutes = ?, seconds = ?, sets = ?, steps = ?
WHERE name = ? WHERE name = ?
`; `;
return db.executeSql(update, [newName, minutes, seconds, sets, oldName]); return db.executeSql(update, [
newName,
minutes,
seconds,
sets,
steps,
oldName,
]);
}; };
export const updateSetImage = async (name: string, image: string) => { export const updateSetImage = async (name: string, image: string) => {

1
set.ts
View File

@ -10,4 +10,5 @@ export default interface Set {
unit?: string; unit?: string;
hidden?: boolean; hidden?: boolean;
image?: string; image?: string;
steps?: string;
} }

View File

@ -6,6 +6,7 @@ export let settings: Settings;
export const getSettings = async () => { export const getSettings = async () => {
const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`); const [result] = await db.executeSql(`SELECT * FROM settings LIMIT 1`);
settings = result.rows.item(0); settings = result.rows.item(0);
return settings;
}; };
export const updateSettings = async (value: Settings) => { export const updateSettings = async (value: Settings) => {

View File

@ -1,42 +0,0 @@
import {db} from './db';
import Workout from './workout';
export const getWorkout = async (name: string): Promise<Workout> => {
const select = `
SELECT * FROM workouts
WHERE workouts.name = ?
LIMIT 1
`;
const [result] = await db.executeSql(select, [name]);
return result.rows.raw()[0];
};
export const updateName = (oldName: string, newName: string) => {
const update = `
UPDATE workouts SET name = ? WHERE name = ?
`;
return db.executeSql(update, [newName, oldName]);
};
export const updateSteps = (name: string, steps: string): Promise<unknown> => {
const update = `
UPDATE workouts SET steps = ? WHERE name = ?
`;
return db.executeSql(update, [steps, name]);
};
export const addWorkout = (value: Workout) => {
const insert = `
INSERT INTO workouts(name, steps)
VALUES (?, ?)
`;
return db.executeSql(insert, [value.name, value.steps]);
};
export const removeWorkout = (name: string) => {
const remove = `
DELETE FROM workouts
WHERE name = ?
`;
return db.executeSql(remove, [name]);
};