Skip to content
Snippets Groups Projects
index.js 5.71 KiB
Newer Older
import Realm from 'realm'
import { LocalDate, ChronoUnit } from 'js-joda'
import {
  cycleWithTempAndNoMucusShift,
  cycleWithFhm,
  longAndComplicatedCycle
} from './fixtures'

const TemperatureSchema = {
  name: 'Temperature',
  properties: {
    value: 'double',
    exclude: 'bool',
    time: {
      type: 'string',
      optional: true
    },
const BleedingSchema = {
  name: 'Bleeding',
  properties: {
    value: 'int',
    exclude: 'bool'
  }
}

const MucusSchema = {
  name: 'Mucus',
  properties: {
    feeling: 'int',
    texture: 'int',
Julia Friesel's avatar
Julia Friesel committed
    value: 'int',
    exclude: 'bool'
  }
}

emelko's avatar
emelko committed
const CervixSchema = {
  name: 'Cervix',
  properties: {
    opening: 'int',
    firmness: 'int',
    position: {type: 'int', optional: true },
    exclude: 'bool'
  }
}

Julia Friesel's avatar
Julia Friesel committed
const NoteSchema = {
  name: 'Note',
  properties: {
    value: 'string'
  }
}

const DesireSchema = {
  name: 'Desire',
  properties: {
    value: 'int'
  }
}

Bl00dyMarie's avatar
Bl00dyMarie committed
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 },
    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',
  properties: {
    temperature: {
      type: 'Temperature',
      optional: true
    },
    bleeding: {
      type: 'Bleeding',
      optional: true
    },
    mucus: {
      type: 'Mucus',
      optional: true
emelko's avatar
emelko committed
    },
    cervix: {
      type: 'Cervix',
      optional: true
Julia Friesel's avatar
Julia Friesel committed
    },
    note: {
      type: 'Note',
      optional: true
    },
    desire: {
      type: 'Desire',
      optional: true
Bl00dyMarie's avatar
Bl00dyMarie committed
    },
    sex: {
      type: 'Sex',
      optional: true
    },
    pain: {
      type: 'Pain',
      optional: true
const realmConfig = {
  schema: [
    CycleDaySchema,
    TemperatureSchema,
    BleedingSchema,
emelko's avatar
emelko committed
    MucusSchema,
Julia Friesel's avatar
Julia Friesel committed
    CervixSchema,
Bl00dyMarie's avatar
Bl00dyMarie committed
    DesireSchema,
    SexSchema,
    PainSchema
  ],
  // we only want this in dev mode
  deleteRealmIfMigrationNeeded: true
}

const db = new Realm(realmConfig)

const bleedingDaysSortedByDate = db.objects('CycleDay').filtered('bleeding != null').sorted('date', true)
const temperatureDaysSortedByDate = db.objects('CycleDay').filtered('temperature != null').sorted('date', true)
const cycleDaysSortedByDate = db.objects('CycleDay').sorted('date', true)
function saveSymptom(symptom, cycleDay, val) {
  db.write(() => {
    cycleDay[symptom] = val
function getOrCreateCycleDay(localDate) {
  let result = db.objectForPrimaryKey('CycleDay', localDate)
  if (!result) {
    db.write(() => {
      result = db.create('CycleDay', {
function getCycleDay(localDate) {
  return db.objectForPrimaryKey('CycleDay', localDate)
}

function fillWithDummyData() {
  const dummyCycles = [
    cycleWithFhm,
    longAndComplicatedCycle,
    cycleWithTempAndNoMucusShift
  ]

  db.write(() => {
    db.deleteAll()
    dummyCycles.forEach(cycle => {
      cycle.forEach(day => {
        const existing = getCycleDay(day.date)
        if (existing) {
          Object.keys(day).forEach(key => {
            if (key === 'date') return
            existing[key] = day[key]
          })
        } else {
          db.create('CycleDay', day)
        }
      })
    })
Julia Friesel's avatar
Julia Friesel committed
function deleteAll() {
  db.write(() => {
    db.deleteAll()
  })
}

function getPreviousTemperature(cycleDay) {
  cycleDay.wrappedDate = LocalDate.parse(cycleDay.date)
  const winner = temperatureDaysSortedByDate.find(day => {
    const wrappedDate = LocalDate.parse(day.date)
    return wrappedDate.isBefore(cycleDay.wrappedDate)
  })
  if (!winner) return null
  return winner.temperature.value
}

const schema = db.schema.reduce((acc, curr) => {
  acc[curr.name] = curr.properties
  return acc
}, {})

function tryToCreateCycleDay(day, i) {
  try {
    db.create('CycleDay', day)
  } catch (err) {
    const msg = `Line ${i + 1}(${day.date}): ${err.message}`
    throw new Error(msg)
function getAmountOfCycleDays() {
  const amountOfCycleDays = cycleDaysSortedByDate.length
  if (!amountOfCycleDays) return 0
  const earliest = cycleDaysSortedByDate[amountOfCycleDays - 1]
  const today = LocalDate.now()
  const earliestAsLocalDate = LocalDate.parse(earliest.date)
  return earliestAsLocalDate.until(today, ChronoUnit.DAYS)
}

function tryToImportWithDelete(cycleDays) {
  db.write(() => {
    db.delete(db.objects('CycleDay'))
    cycleDays.forEach(tryToCreateCycleDay)
  })
}

function tryToImportWithoutDelete(cycleDays) {
  db.write(() => {
    cycleDays.forEach((day, i) => {
      const existing = getCycleDay(day.date)
      if (existing) db.delete(existing)
      tryToCreateCycleDay(day, i)
    })
  })
}
  saveSymptom,
  getOrCreateCycleDay,
  bleedingDaysSortedByDate,
  cycleDaysSortedByDate,
  fillWithDummyData,
Julia Friesel's avatar
Julia Friesel committed
  deleteAll,
  getPreviousTemperature,
  getCycleDay,
  getAmountOfCycleDays,
  schema,
  tryToImportWithDelete,
  tryToImportWithoutDelete