diff --git a/DrawerMenu.tsx b/DrawerMenu.tsx index 5f93d5e..c02d2fb 100644 --- a/DrawerMenu.tsx +++ b/DrawerMenu.tsx @@ -4,7 +4,8 @@ import DocumentPicker from 'react-native-document-picker'; import {FileSystem} from 'react-native-file-access'; import {Divider, IconButton, Menu} from 'react-native-paper'; import ConfirmDialog from './ConfirmDialog'; -import {AppDataSource, planRepo} from './db'; +import {AppDataSource} from './data-source'; +import {planRepo} from './db'; import {DrawerParamList} from './drawer-param-list'; import GymSet from './gym-set'; import {useSnackbar} from './MassiveSnack'; diff --git a/PlanItem.tsx b/PlanItem.tsx index 22c559a..6496e52 100644 --- a/PlanItem.tsx +++ b/PlanItem.tsx @@ -39,12 +39,9 @@ export default function PlanItem({ }, [setShow, item.id, onRemove]); const start = useCallback(async () => { - const workouts = item.workouts.split(','); - const first = workouts[0]; - const set = await getBestSet(first); - console.log(`${PlanItem.name}.start:`, {set}); + console.log(`${PlanItem.name}.start:`, {item}); setShow(false); - navigation.navigate('StartPlan', {plan: item, set}); + navigation.navigate('StartPlan', {plan: item}); }, [item, navigation]); const longPress = useCallback( diff --git a/SetForm.tsx b/SetForm.tsx index 23c9c0d..1fa7f10 100644 --- a/SetForm.tsx +++ b/SetForm.tsx @@ -39,7 +39,7 @@ export default function SetForm({ if (!name) return; let image = newImage; if (!newImage && !removeImage) - image = await setRepo.findOne({where: {name}}).then(s => s.image); + image = await setRepo.findOne({where: {name}}).then(s => s?.image); console.log(`${SetForm.name}.handleSubmit:`, {image}); save({ @@ -52,6 +52,7 @@ export default function SetForm({ minutes: Number(set.minutes ?? 3), seconds: Number(set.seconds ?? 30), sets: set.sets ?? 3, + hidden: false, }); }; diff --git a/SetList.tsx b/SetList.tsx index 92a9927..4460a4e 100644 --- a/SetList.tsx +++ b/SetList.tsx @@ -65,7 +65,7 @@ export default function SetList() { }); if (newSets.length === 0) return setEnd(true); if (!sets) return; - // setSets([...sets, ...newSets]); + setSets([...sets, ...newSets]); if (newSets.length < limit) return setEnd(true); setOffset(newOffset); }, [term, end, offset, sets]); @@ -109,10 +109,6 @@ export default function SetList() { data={sets} style={{flex: 1}} renderItem={renderItem} - getItem={(data: any, index: number) => { - console.log({data, index}); - return data[index]; - }} onEndReached={next} /> )} diff --git a/StartPlan.tsx b/StartPlan.tsx index 68361e5..22091a2 100644 --- a/StartPlan.tsx +++ b/StartPlan.tsx @@ -6,12 +6,12 @@ import {Button} from 'react-native-paper'; import {getBestSet} from './best.service'; import {PADDING} from './constants'; import CountMany from './count-many'; -import {AppDataSource, getNow, setRepo} from './db'; +import {AppDataSource} from './data-source'; +import {getNow, setRepo} from './db'; import GymSet from './gym-set'; import MassiveInput from './MassiveInput'; import {useSnackbar} from './MassiveSnack'; import {PlanPageParams} from './plan-page-params'; -import {countMany} from './set.service'; import SetForm from './SetForm'; import StackHeader from './StackHeader'; import StartPlanItem from './StartPlanItem'; @@ -19,15 +19,14 @@ import {useSettings} from './use-settings'; export default function StartPlan() { const {params} = useRoute>(); - const {set} = params; - const [name, setName] = useState(set.name); - const [reps, setReps] = useState(set.reps.toString()); - const [weight, setWeight] = useState(set.weight.toString()); - const [unit, setUnit] = useState(); + const [name, setName] = useState(''); + const [reps, setReps] = useState(''); + const [weight, setWeight] = useState(''); + const [unit, setUnit] = useState('kg'); const {toast} = useSnackbar(); - const [minutes, setMinutes] = useState(set.minutes); - const [seconds, setSeconds] = useState(set.seconds); - const [best, setBest] = useState(set); + const [minutes, setMinutes] = useState(3); + const [seconds, setSeconds] = useState(30); + const [best, setBest] = useState(); const [selected, setSelected] = useState(0); const {settings} = useSettings(); const [counts, setCounts] = useState(); @@ -38,35 +37,55 @@ export default function StartPlan() { const [selection, setSelection] = useState({ start: 0, - end: set.reps.toString().length, + end: 0, }); const refresh = useCallback(() => { - const questions = workouts.map(_ => '(?)').join(','); - const condition = ` - sets.name = workouts.name + const questions = workouts + .map((workout, index) => `('${workout}',${index})`) + .join(','); + console.log({questions, workouts}); + const select = ` + SELECT workouts.name, COUNT(sets.id) as total + FROM (select 0 as name, 0 as sequence union values ${questions}) as workouts + LEFT JOIN sets ON sets.name = workouts.name AND sets.created LIKE STRFTIME('%Y-%m-%d%%', 'now', 'localtime') AND NOT sets.hidden + GROUP BY workouts.name + ORDER BY workouts.sequence + LIMIT -1 + OFFSET 1 `; - return AppDataSource.manager - .createQueryBuilder() - .select('COUNT(sets.id)', 'total') - .addSelect('workouts') - .from(`(SELECT 0 AS name UNION values ${questions})`, 'workouts') - .leftJoin('sets', condition) - .groupBy('workouts.name') - .limit(-1) - .offset(1) - .getRawMany() - .then(newCounts => { - setCounts(newCounts); - console.log(`${StartPlan.name}.focus:`, {newCounts}); - }); + return AppDataSource.manager.query(select).then(newCounts => { + setCounts(newCounts); + console.log(`${StartPlan.name}.focus:`, {newCounts}); + return newCounts; + }); }, [workouts]); + const select = useCallback( + async (index: number, newCounts?: CountMany[]) => { + setSelected(index); + console.log(`${StartPlan.name}.next:`, {name, index}); + if (!counts && !newCounts) return; + const workout = counts ? counts[index] : newCounts[index]; + console.log(`${StartPlan.name}.next:`, {workout}); + const newBest = await getBestSet(workout.name); + console.log(`${StartPlan.name}.next:`, {newBest}); + setMinutes(newBest.minutes); + setSeconds(newBest.seconds); + setName(newBest.name); + setReps(newBest.reps.toString()); + setWeight(newBest.weight.toString()); + setUnit(newBest.unit); + setBest(newBest); + }, + [name, counts], + ); + useFocusEffect( useCallback(() => { - refresh(); + refresh().then(newCounts => select(0, newCounts)); }, [refresh]), ); @@ -77,12 +96,12 @@ export default function StartPlan() { name, weight: +weight, reps: +reps, - minutes: set.minutes, - seconds: set.seconds, - steps: set.steps, - image: set.image, unit, created: now, + minutes, + seconds, + sets: best.sets, + hidden: false, }); await refresh(); if ( @@ -108,26 +127,6 @@ export default function StartPlan() { [toast], ); - const select = useCallback( - async (index: number) => { - setSelected(index); - console.log(`${StartPlan.name}.next:`, {name, index}); - if (!counts) return; - const workout = counts[index]; - console.log(`${StartPlan.name}.next:`, {workout}); - const newBest = await getBestSet(workout.name); - console.log(`${StartPlan.name}.next:`, {newBest}); - setMinutes(newBest.minutes); - setSeconds(newBest.seconds); - setName(newBest.name); - setReps(newBest.reps.toString()); - setWeight(newBest.weight.toString()); - setUnit(newBest.unit); - setBest(newBest); - }, - [name, counts], - ); - return ( <> diff --git a/ViewBest.tsx b/ViewBest.tsx index ae25a8a..040fcf4 100644 --- a/ViewBest.tsx +++ b/ViewBest.tsx @@ -2,7 +2,6 @@ import {Picker} from '@react-native-picker/picker'; import {RouteProp, useRoute} from '@react-navigation/native'; import {useEffect, useState} from 'react'; import {View} from 'react-native'; -import {getOneRepMax} from './best.service'; import {BestPageParams} from './BestPage'; import Chart from './Chart'; import {PADDING} from './constants'; @@ -56,7 +55,14 @@ export default function ViewBest() { .then(setVolumes); break; default: - getOneRepMax({name: params.best.name, period}).then(setWeights); + // Brzycki formula https://en.wikipedia.org/wiki/One-repetition_maximum#Brzycki + builder + .addSelect('MAX(weight / (1.0278 - 0.0278 * reps))', 'weight') + .getRawMany() + .then(weights => { + console.log({weights}); + setWeights(weights); + }); } }, [params.best.name, metric, period]); diff --git a/babel.config.js b/babel.config.js index 9a82bd1..edd6299 100644 --- a/babel.config.js +++ b/babel.config.js @@ -2,8 +2,8 @@ module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ '@babel/plugin-transform-flow-strip-types', - ['@babel/plugin-proposal-class-properties', { loose: true }], ['@babel/plugin-proposal-decorators', { legacy: true }], + ['@babel/plugin-proposal-class-properties', { loose: true }], 'react-native-reanimated/plugin', 'react-native-paper/babel', ], diff --git a/best.service.ts b/best.service.ts index e4d696f..9dc22a0 100644 --- a/best.service.ts +++ b/best.service.ts @@ -1,31 +1,5 @@ -import {db, setRepo} from './db'; +import {setRepo} from './db'; import GymSet from './gym-set'; -import {Periods} from './periods'; - -export const getOneRepMax = async ({ - name, - period, -}: { - name: string; - period: Periods; -}) => { - // Brzycki formula https://en.wikipedia.org/wiki/One-repetition_maximum#Brzycki - const select = ` - SELECT max(weight / (1.0278 - 0.0278 * reps)) AS weight, - STRFTIME('%Y-%m-%d', created) as created, unit - FROM sets - WHERE name = ? AND NOT hidden - AND DATE(created) >= DATE('now', 'weekday 0', ?) - GROUP BY name, STRFTIME(?, created) - `; - let difference = '-7 days'; - if (period === Periods.Monthly) difference = '-1 months'; - else if (period === Periods.Yearly) difference = '-1 years'; - let group = '%Y-%m-%d'; - if (period === Periods.Yearly) group = '%Y-%m'; - const [result] = await db.executeSql(select, [name, difference, group]); - return result.rows.raw(); -}; export const getBestSet = async (name: string): Promise => { return setRepo diff --git a/data-source.ts b/data-source.ts new file mode 100644 index 0000000..9faa6a7 --- /dev/null +++ b/data-source.ts @@ -0,0 +1,58 @@ +import {DataSource} from 'typeorm'; +import GymSet from './gym-set'; +import {Sets1667185586014} from './migrations/1667185586014-sets'; +import {plans1667186124792} from './migrations/1667186124792-plans'; +import {settings1667186130041} from './migrations/1667186130041-settings'; +import {addSound1667186139844} from './migrations/1667186139844-add-sound'; +import {addHidden1667186159379} from './migrations/1667186159379-add-hidden'; +import {addNotify1667186166140} from './migrations/1667186166140-add-notify'; +import {addImage1667186171548} from './migrations/1667186171548-add-image'; +import {addImages1667186179488} from './migrations/1667186179488-add-images'; +import {insertSettings1667186203827} from './migrations/1667186203827-insert-settings'; +import {addSteps1667186211251} from './migrations/1667186211251-add-steps'; +import {addSets1667186250618} from './migrations/1667186250618-add-sets'; +import {addMinutes1667186255650} from './migrations/1667186255650-add-minutes'; +import {addSeconds1667186259174} from './migrations/1667186259174-add-seconds'; +import {addShowUnit1667186265588} from './migrations/1667186265588-add-show-unit'; +import {addColor1667186320954} from './migrations/1667186320954-add-color'; +import {addSteps1667186348425} from './migrations/1667186348425-add-steps'; +import {addDate1667186431804} from './migrations/1667186431804-add-date'; +import {addShowDate1667186435051} from './migrations/1667186435051-add-show-date'; +import {addTheme1667186439366} from './migrations/1667186439366-add-theme'; +import {addShowSets1667186443614} from './migrations/1667186443614-add-show-sets'; +import {addSetsCreated1667186451005} from './migrations/1667186451005-add-sets-created'; +import {addNoSound1667186456118} from './migrations/1667186456118-add-no-sound'; +import {Plan} from './plan'; +import Settings from './settings'; + +export const AppDataSource = new DataSource({ + type: 'react-native', + database: 'massive.db', + location: 'default', + entities: [GymSet, Plan, Settings], + migrationsTableName: 'typeorm_migrations', + migrations: [ + Sets1667185586014, + plans1667186124792, + settings1667186130041, + addSound1667186139844, + addHidden1667186159379, + addNotify1667186166140, + addImage1667186171548, + addImages1667186179488, + insertSettings1667186203827, + addSteps1667186211251, + addSets1667186250618, + addMinutes1667186255650, + addSeconds1667186259174, + addShowUnit1667186265588, + addColor1667186320954, + addSteps1667186348425, + addDate1667186431804, + addShowDate1667186435051, + addTheme1667186439366, + addShowSets1667186443614, + addSetsCreated1667186451005, + addNoSound1667186456118, + ], +}); diff --git a/db.ts b/db.ts index df7c64c..bde42d1 100644 --- a/db.ts +++ b/db.ts @@ -1,143 +1,13 @@ -import { - enablePromise, - openDatabase, - SQLiteDatabase, -} from 'react-native-sqlite-storage'; -import {DataSource} from 'typeorm'; +import {enablePromise, SQLiteDatabase} from 'react-native-sqlite-storage'; +import {AppDataSource} from './data-source'; import GymSet from './gym-set'; import {Plan} from './plan'; import Settings from './settings'; enablePromise(true); -const migrations = [ - ` - CREATE TABLE IF NOT EXISTS sets ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - reps INTEGER NOT NULL, - weight INTEGER NOT NULL, - created TEXT NOT NULL, - unit TEXT DEFAULT 'kg' - ) -`, - ` - CREATE TABLE IF NOT EXISTS plans ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - days TEXT NOT NULL, - workouts TEXT NOT NULL - ) -`, - ` - CREATE TABLE IF NOT EXISTS settings ( - minutes INTEGER NOT NULL DEFAULT 3, - seconds INTEGER NOT NULL DEFAULT 30, - alarm BOOLEAN NOT NULL DEFAULT 0, - vibrate BOOLEAN NOT NULL DEFAULT 1, - sets INTEGER NOT NULL DEFAULT 3 - ) -`, - `ALTER TABLE settings ADD COLUMN sound TEXT NULL`, - ` - CREATE TABLE IF NOT EXISTS workouts( - name TEXT PRIMARY KEY, - sets INTEGER DEFAULT 3 - ) - `, - ` - ALTER TABLE sets ADD COLUMN hidden DEFAULT false - `, - ` - ALTER TABLE settings ADD COLUMN notify DEFAULT false - `, - ` - ALTER TABLE sets ADD COLUMN image TEXT NULL - `, - ` - ALTER TABLE settings ADD COLUMN images BOOLEAN DEFAULT true - `, - ` - SELECT * FROM settings LIMIT 1 - `, - ` - INSERT INTO settings(minutes) VALUES(3) - `, - ` - ALTER TABLE workouts ADD COLUMN steps TEXT NULL - `, - ` - INSERT OR IGNORE INTO workouts (name) SELECT DISTINCT name FROM sets - `, - ` - ALTER TABLE sets ADD COLUMN sets INTEGER NOT NULL DEFAULT 3 - `, - ` - ALTER TABLE sets ADD COLUMN minutes INTEGER NOT NULL DEFAULT 3 - `, - ` - ALTER TABLE sets ADD COLUMN seconds INTEGER NOT NULL DEFAULT 30 - `, - ` - ALTER TABLE settings ADD COLUMN showUnit BOOLEAN DEFAULT true - `, - ` - ALTER TABLE sets ADD COLUMN steps TEXT NULL - `, - ` - UPDATE sets SET steps = ( - SELECT workouts.steps FROM workouts WHERE workouts.name = sets.name - ) - `, - ` - DROP TABLE workouts - `, - ` - ALTER TABLE settings ADD COLUMN color TEXT NULL - `, - ` - UPDATE settings SET showUnit = 1 - `, - ` - ALTER TABLE settings ADD COLUMN workouts BOOLEAN DEFAULT true - `, - ` - ALTER TABLE settings ADD COLUMN steps BOOLEAN DEFAULT true - `, - ` - ALTER TABLE settings ADD COLUMN nextAlarm TEXT NULL - `, - ` - ALTER TABLE settings ADD COLUMN newSet TEXT NULL - `, - ` - ALTER TABLE settings ADD COLUMN date TEXT NULL - `, - ` - ALTER TABLE settings ADD COLUMN showDate BOOLEAN DEFAULT false - `, - ` - ALTER TABLE settings ADD COLUMN theme TEXT - `, - ` - ALTER TABLE settings ADD COLUMN showSets BOOLEAN DEFAULT true - `, - ` - CREATE INDEX sets_created ON sets(created) - `, - ` - ALTER TABLE settings ADD COLUMN noSound BOOLEAN DEFAULT false - `, -]; - export let db: SQLiteDatabase; -export const AppDataSource = new DataSource({ - type: 'react-native', - database: 'massive.db', - location: 'default', - entities: [GymSet, Plan, Settings], -}); - export const setRepo = AppDataSource.manager.getRepository(GymSet); export const planRepo = AppDataSource.manager.getRepository(Plan); export const settingsRepo = AppDataSource.manager.getRepository(Settings); @@ -149,22 +19,8 @@ export const getNow = (): Promise<{now: string}[]> => { }; export const runMigrations = async () => { + console.log(`${runMigrations.name}:`, 'Initializing...'); await AppDataSource.initialize(); - db = await openDatabase({name: 'massive.db'}); - await db.executeSql(` - CREATE TABLE IF NOT EXISTS migrations( - id INTEGER PRIMARY KEY AUTOINCREMENT, - command TEXT NOT NULL - ) - `); - const [result] = await db.executeSql(`SELECT * FROM migrations`); - const missing = migrations.slice(result.rows.length); - for (const command of missing) { - await db.executeSql(command).catch(console.error); - const insert = ` - INSERT INTO migrations (command) - VALUES (?) - `; - await db.executeSql(insert, [command]); - } + console.log(`${runMigrations.name}:`, 'Running migrations...'); + await AppDataSource.runMigrations(); }; diff --git a/gym-set.ts b/gym-set.ts index ad51509..f0c8a59 100644 --- a/gym-set.ts +++ b/gym-set.ts @@ -27,13 +27,13 @@ export default class GymSet { hidden = false; @Column('text') - created?: string; + created: string; @Column('text') - unit?: string; + unit: string; @Column('text') - image?: string; + image: string; @Column('text') steps?: string; diff --git a/migrations/1667185586014-sets.ts b/migrations/1667185586014-sets.ts new file mode 100644 index 0000000..c99d92e --- /dev/null +++ b/migrations/1667185586014-sets.ts @@ -0,0 +1,20 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class Sets1667185586014 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TABLE IF NOT EXISTS sets ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + reps INTEGER NOT NULL, + weight INTEGER NOT NULL, + created TEXT NOT NULL, + unit TEXT DEFAULT 'kg' + ) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE sets`); + } +} diff --git a/migrations/1667186124792-plans.ts b/migrations/1667186124792-plans.ts new file mode 100644 index 0000000..4bc7315 --- /dev/null +++ b/migrations/1667186124792-plans.ts @@ -0,0 +1,17 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class plans1667186124792 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TABLE IF NOT EXISTS plans ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + days TEXT NOT NULL, + workouts TEXT NOT NULL + ) +`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('plans'); + } +} diff --git a/migrations/1667186130041-settings.ts b/migrations/1667186130041-settings.ts new file mode 100644 index 0000000..6919f5a --- /dev/null +++ b/migrations/1667186130041-settings.ts @@ -0,0 +1,19 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class settings1667186130041 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TABLE IF NOT EXISTS settings ( + minutes INTEGER NOT NULL DEFAULT 3, + seconds INTEGER NOT NULL DEFAULT 30, + alarm BOOLEAN NOT NULL DEFAULT 0, + vibrate BOOLEAN NOT NULL DEFAULT 1, + sets INTEGER NOT NULL DEFAULT 3 + ) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('settings'); + } +} diff --git a/migrations/1667186139844-add-sound.ts b/migrations/1667186139844-add-sound.ts new file mode 100644 index 0000000..05d2e01 --- /dev/null +++ b/migrations/1667186139844-add-sound.ts @@ -0,0 +1,11 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addSound1667186139844 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE settings ADD COLUMN sound TEXT NULL`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'sound'); + } +} diff --git a/migrations/1667186159379-add-hidden.ts b/migrations/1667186159379-add-hidden.ts new file mode 100644 index 0000000..bffc426 --- /dev/null +++ b/migrations/1667186159379-add-hidden.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addHidden1667186159379 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE sets ADD COLUMN hidden DEFAULT false + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('sets', 'hidden'); + } +} diff --git a/migrations/1667186166140-add-notify.ts b/migrations/1667186166140-add-notify.ts new file mode 100644 index 0000000..ee7f860 --- /dev/null +++ b/migrations/1667186166140-add-notify.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addNotify1667186166140 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN notify DEFAULT false + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'notify'); + } +} diff --git a/migrations/1667186171548-add-image.ts b/migrations/1667186171548-add-image.ts new file mode 100644 index 0000000..9562fb7 --- /dev/null +++ b/migrations/1667186171548-add-image.ts @@ -0,0 +1,11 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addImage1667186171548 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('ALTER TABLE sets ADD COLUMN image TEXT NULL'); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('sets', 'image'); + } +} diff --git a/migrations/1667186179488-add-images.ts b/migrations/1667186179488-add-images.ts new file mode 100644 index 0000000..33830ac --- /dev/null +++ b/migrations/1667186179488-add-images.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addImages1667186179488 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN images BOOLEAN DEFAULT true + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'images'); + } +} diff --git a/migrations/1667186203827-insert-settings.ts b/migrations/1667186203827-insert-settings.ts new file mode 100644 index 0000000..5b0b858 --- /dev/null +++ b/migrations/1667186203827-insert-settings.ts @@ -0,0 +1,11 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class insertSettings1667186203827 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query('INSERT INTO settings(minutes) VALUES(3)'); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query('DELETE FROM settings'); + } +} diff --git a/migrations/1667186211251-add-steps.ts b/migrations/1667186211251-add-steps.ts new file mode 100644 index 0000000..d3a00d3 --- /dev/null +++ b/migrations/1667186211251-add-steps.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addSteps1667186211251 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN steps BOOLEAN DEFAULT true + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'steps'); + } +} diff --git a/migrations/1667186250618-add-sets.ts b/migrations/1667186250618-add-sets.ts new file mode 100644 index 0000000..2a973c2 --- /dev/null +++ b/migrations/1667186250618-add-sets.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addSets1667186250618 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE sets ADD COLUMN sets INTEGER NOT NULL DEFAULT 3 + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('sets', 'sets'); + } +} diff --git a/migrations/1667186255650-add-minutes.ts b/migrations/1667186255650-add-minutes.ts new file mode 100644 index 0000000..ba6ada2 --- /dev/null +++ b/migrations/1667186255650-add-minutes.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addMinutes1667186255650 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE sets ADD COLUMN minutes INTEGER NOT NULL DEFAULT 3 + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('sets', 'minutes'); + } +} diff --git a/migrations/1667186259174-add-seconds.ts b/migrations/1667186259174-add-seconds.ts new file mode 100644 index 0000000..9470d17 --- /dev/null +++ b/migrations/1667186259174-add-seconds.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addSeconds1667186259174 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE sets ADD COLUMN seconds INTEGER NOT NULL DEFAULT 30 + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('sets', 'seconds'); + } +} diff --git a/migrations/1667186265588-add-show-unit.ts b/migrations/1667186265588-add-show-unit.ts new file mode 100644 index 0000000..665df9c --- /dev/null +++ b/migrations/1667186265588-add-show-unit.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addShowUnit1667186265588 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN showUnit BOOLEAN DEFAULT true + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'showUnit'); + } +} diff --git a/migrations/1667186320954-add-color.ts b/migrations/1667186320954-add-color.ts new file mode 100644 index 0000000..d973647 --- /dev/null +++ b/migrations/1667186320954-add-color.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addColor1667186320954 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN color TEXT NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'color'); + } +} diff --git a/migrations/1667186348425-add-steps.ts b/migrations/1667186348425-add-steps.ts new file mode 100644 index 0000000..8c7c78d --- /dev/null +++ b/migrations/1667186348425-add-steps.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addSteps1667186348425 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE sets ADD COLUMN steps TEXT NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('sets', 'steps'); + } +} diff --git a/migrations/1667186431804-add-date.ts b/migrations/1667186431804-add-date.ts new file mode 100644 index 0000000..c3ba740 --- /dev/null +++ b/migrations/1667186431804-add-date.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addDate1667186431804 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN date TEXT NULL + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'date'); + } +} diff --git a/migrations/1667186435051-add-show-date.ts b/migrations/1667186435051-add-show-date.ts new file mode 100644 index 0000000..c3d0a2e --- /dev/null +++ b/migrations/1667186435051-add-show-date.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addShowDate1667186435051 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN showDate BOOLEAN DEFAULT false + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'showDate'); + } +} diff --git a/migrations/1667186439366-add-theme.ts b/migrations/1667186439366-add-theme.ts new file mode 100644 index 0000000..3141e48 --- /dev/null +++ b/migrations/1667186439366-add-theme.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addTheme1667186439366 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN theme TEXT + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'theme'); + } +} diff --git a/migrations/1667186443614-add-show-sets.ts b/migrations/1667186443614-add-show-sets.ts new file mode 100644 index 0000000..770af2f --- /dev/null +++ b/migrations/1667186443614-add-show-sets.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addShowSets1667186443614 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN showSets BOOLEAN DEFAULT true + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'showSets'); + } +} diff --git a/migrations/1667186451005-add-sets-created.ts b/migrations/1667186451005-add-sets-created.ts new file mode 100644 index 0000000..a5d59d5 --- /dev/null +++ b/migrations/1667186451005-add-sets-created.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addSetsCreated1667186451005 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE INDEX sets_created ON sets(created) + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropIndex('sets', 'sets_created'); + } +} diff --git a/migrations/1667186456118-add-no-sound.ts b/migrations/1667186456118-add-no-sound.ts new file mode 100644 index 0000000..185c7d4 --- /dev/null +++ b/migrations/1667186456118-add-no-sound.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from 'typeorm'; + +export class addNoSound1667186456118 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + ALTER TABLE settings ADD COLUMN noSound BOOLEAN DEFAULT false + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn('settings', 'noSound'); + } +} diff --git a/plan-page-params.ts b/plan-page-params.ts index 86fbb0e..425a4a4 100644 --- a/plan-page-params.ts +++ b/plan-page-params.ts @@ -1,5 +1,4 @@ import {Plan} from './plan'; -import GymSet from './gym-set'; export type PlanPageParams = { PlanList: {}; @@ -8,6 +7,5 @@ export type PlanPageParams = { }; StartPlan: { plan: Plan; - set: GymSet; }; }; diff --git a/set.service.ts b/set.service.ts deleted file mode 100644 index 8b904c9..0000000 --- a/set.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import CountMany from './count-many'; -import {db} from './db'; - -export const countMany = async (names: string[]): Promise => { - const questions = names.map(_ => '(?)').join(','); - console.log({questions, names}); - const select = ` - SELECT workouts.name, COUNT(sets.id) as total - FROM (select 0 as name union values ${questions}) as workouts - LEFT JOIN sets ON sets.name = workouts.name - AND sets.created LIKE STRFTIME('%Y-%m-%d%%', 'now', 'localtime') - AND NOT sets.hidden - GROUP BY workouts.name - LIMIT -1 - OFFSET 1 - `; - const [result] = await db.executeSql(select, names); - return result.rows.raw(); -};