diff --git a/db/index.js b/db/index.js index ce0212a..d060896 100644 --- a/db/index.js +++ b/db/index.js @@ -4,8 +4,11 @@ import nodejs from 'nodejs-mobile-react-native' import fs from 'react-native-fs' import restart from 'react-native-restart' import schemas from './schemas' +import cycleModule from '../lib/cycle' let db +let isMensesStart +let getMensesDaysAfter export async function openDb ({ hash, persistConnection }) { const realmConfig = {} @@ -32,6 +35,9 @@ export async function openDb ({ hash, persistConnection }) { )) if (persistConnection) db = connection + const cycle = cycleModule() + isMensesStart = cycle.isMensesStart + getMensesDaysAfter = cycle.getMensesDaysAfter } @@ -47,16 +53,58 @@ export function getCycleDaysSortedByDate() { export function saveSymptom(symptom, cycleDay, val) { db.write(() => { - cycleDay[symptom] = val + if (symptom === 'bleeding') { + saveBleeding(cycleDay, val) + } else { + cycleDay[symptom] = val + } }) } +export function saveBleeding(cycleDay, bleeding) { + if (!bleeding) { + updateCycleDayAndMaybeSetNewCycleStart(cycleDay, bleeding) + } else { + cycleDay.bleeding = bleeding + cycleDay.isCycleStart = isMensesStart(cycleDay) + maybeClearOldCycleStartsInThisMenses(cycleDay) + } + + function updateCycleDayAndMaybeSetNewCycleStart(oldCycleDay, newValue) { + // if a bleeding value is deleted, we need to check if + // there are any following bleeding days and if the + // next one of them is now a cycle start + + // in order to get the menses days, the cycle day in question still + // has to have a bleeding value, so we get those days first and only + // then update the cycle day + const mensesDaysAfter = getMensesDaysAfter(oldCycleDay) + oldCycleDay.bleeding = newValue + + if (!mensesDaysAfter.length) return + + const nextOne = mensesDaysAfter[mensesDaysAfter.length - 1] + if (isMensesStart(nextOne)) { + nextOne.isCycleStart = true + } + } + + function maybeClearOldCycleStartsInThisMenses(cycleDay) { + // if we have a new bleeding day, we need to clear the + // menses start marker from all following days of this + // menses that may have been marked as start before + const mensesDaysAfter = getMensesDaysAfter(cycleDay) + mensesDaysAfter.forEach(day => day.isCycleStart = false) + } +} + export function getOrCreateCycleDay(localDate) { let result = db.objectForPrimaryKey('CycleDay', localDate) if (!result) { db.write(() => { result = db.create('CycleDay', { - date: localDate + date: localDate, + isCycleStart: false }) }) } diff --git a/db/schemas/2.js b/db/schemas/2.js new file mode 100644 index 0000000..6bf5cfb --- /dev/null +++ b/db/schemas/2.js @@ -0,0 +1,166 @@ +import cycleModule from '../../lib/cycle' + +const TemperatureSchema = { + name: 'Temperature', + properties: { + value: 'double', + exclude: 'bool', + time: { + type: 'string', + optional: true + }, + note: { + type: 'string', + optional: true + } + } +} + +const BleedingSchema = { + name: 'Bleeding', + properties: { + value: 'int', + exclude: 'bool' + } +} + +const MucusSchema = { + name: 'Mucus', + properties: { + feeling: 'int', + texture: 'int', + value: 'int', + exclude: 'bool' + } +} + +const CervixSchema = { + name: 'Cervix', + properties: { + opening: 'int', + firmness: 'int', + position: {type: 'int', optional: true }, + exclude: 'bool' + } +} + +const NoteSchema = { + name: 'Note', + properties: { + value: 'string' + } +} + +const DesireSchema = { + name: 'Desire', + properties: { + value: 'int' + } +} + +const SexSchema = { + name: 'Sex', + properties: { + solo: { type: 'bool', optional: true }, + partner: { type: 'bool', optional: true }, + condom: { type: 'bool', optional: true }, + pill: { type: 'bool', optional: true }, + iud: { type: 'bool', optional: true }, + patch: { type: 'bool', optional: true }, + ring: { type: 'bool', optional: true }, + implant: { type: 'bool', optional: true }, + diaphragm: { type: 'bool', optional: true }, + none: { type: 'bool', optional: true }, + other: { type: 'bool', optional: true }, + note: { type: 'string', optional: true } + } +} + +const PainSchema = { + name: 'Pain', + properties: { + cramps: { type: 'bool', optional: true }, + ovulationPain: { type: 'bool', optional: true }, + headache: { type: 'bool', optional: true }, + backache: { type: 'bool', optional: true }, + nausea: { type: 'bool', optional: true }, + tenderBreasts: { type: 'bool', optional: true }, + migraine: { type: 'bool', optional: true }, + other: { type: 'bool', optional: true }, + note: { type: 'string', optional: true } + } +} + +const CycleDaySchema = { + name: 'CycleDay', + primaryKey: 'date', + properties: { + date: 'string', + temperature: { + type: 'Temperature', + optional: true + }, + isCycleStart: 'bool', + bleeding: { + type: 'Bleeding', + optional: true + }, + mucus: { + type: 'Mucus', + optional: true + }, + cervix: { + type: 'Cervix', + optional: true + }, + note: { + type: 'Note', + optional: true + }, + desire: { + type: 'Desire', + optional: true + }, + sex: { + type: 'Sex', + optional: true + }, + pain: { + type: 'Pain', + optional: true + } + } +} + +export default { + schema: [ + CycleDaySchema, + TemperatureSchema, + BleedingSchema, + MucusSchema, + CervixSchema, + NoteSchema, + DesireSchema, + SexSchema, + PainSchema + ], + schemaVersion: 2, + migration: (oldRealm, newRealm) => { + if (oldRealm.schemaVersion >= 2) return + const oldBleedingDays = oldRealm.objects('CycleDay') + .filtered('bleeding != null') + .sorted('date', true) + + const { isMensesStart } = cycleModule({ + bleedingDaysSortedByDate: oldBleedingDays + }) + + const newBleedingDays = newRealm.objects('CycleDay') + .filtered('bleeding != null') + .sorted('date', true) + + oldBleedingDays.forEach((day, i) => { + newBleedingDays[i].isCycleStart = isMensesStart(day) + }) + } +} diff --git a/db/schemas/index.js b/db/schemas/index.js index eacf7dd..5b80738 100644 --- a/db/schemas/index.js +++ b/db/schemas/index.js @@ -1,4 +1,5 @@ import schema0 from './0.js' import schema1 from './1.js' +import schema2 from './2.js' -export default [schema0, schema1] \ No newline at end of file +export default [schema0, schema1, schema2] \ No newline at end of file diff --git a/lib/cycle.js b/lib/cycle.js index 042cff2..f565ed5 100644 --- a/lib/cycle.js +++ b/lib/cycle.js @@ -150,14 +150,14 @@ export default function config(opts) { } } - function getMensesDaysAfter(bleedingDay) { + function getMensesDaysAfter(cycleDay) { const bleedingDays = bleedingDaysSortedByDate.filter(d => { return !d.bleeding.exclude }) const startIndex = bleedingDays.findIndex(day => { - return day.date === bleedingDay.date + return day.date === cycleDay.date }) - return recurse(bleedingDay, startIndex, []) + return recurse(cycleDay, startIndex, []) function recurse(day, i, mensesDays) { if (i === 0) return mensesDays