Skip to content

Instantly share code, notes, and snippets.

@defrex
Created January 21, 2020 22:14
Show Gist options
  • Save defrex/38666637c323c6665ce8f29227ef77f7 to your computer and use it in GitHub Desktop.
Save defrex/38666637c323c6665ce8f29227ef77f7 to your computer and use it in GitHub Desktop.
TypeORM Repitition Model: encodes an arbitrary repeating period
import { subDays, subWeeks } from 'date-fns'
import { Repitition } from './Repitition'
describe('Repitition', () => {
test('findByDate', async () => {
const base = new Date()
const twoWeeksAgo = subWeeks(base, 2)
const twoWeeksOneDayAgo = subDays(twoWeeksAgo, 1)
const weeklyStartingTwoWeeksAgo = await Repitition.create({
startsAt: twoWeeksAgo,
intervalType: 'day',
interval: 7,
}).save()
const weeklyStartingTwoWeeksOneDayAgo = await Repitition.create({
startsAt: twoWeeksOneDayAgo,
intervalType: 'day',
interval: 7,
}).save()
const dailyStartingTwoWeeksAgo = await Repitition.create({
startsAt: twoWeeksAgo,
intervalType: 'day',
interval: 1,
}).save()
const sixDailyStartingTwoWeeksAgo = await Repitition.create({
startsAt: twoWeeksAgo,
intervalType: 'day',
interval: 6,
}).save()
const result = await Repitition.findByDate(base)
const resultIds = result.map(({ id }) => id)
expect(resultIds).toContain(weeklyStartingTwoWeeksAgo.id)
expect(resultIds).toContain(dailyStartingTwoWeeksAgo.id)
expect(resultIds).not.toContain(weeklyStartingTwoWeeksOneDayAgo.id)
expect(resultIds).not.toContain(sixDailyStartingTwoWeeksAgo.id)
})
})
import { Field, ID, ObjectType } from 'type-graphql'
import {
BaseEntity,
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm'
@ObjectType()
@Entity()
export class Repitition extends BaseEntity {
@Field(() => ID)
@PrimaryGeneratedColumn()
readonly id: number
@Field()
@CreateDateColumn()
readonly createdAt: Date
@UpdateDateColumn()
readonly updatedAt: Date
@Field()
@Column()
startsAt: Date
@Field()
@Column('integer')
interval: number
@Field()
@Column('varchar')
intervalType: 'day' | 'week' | 'month'
static async findByDate(when: Date): Promise<Repitition[]> {
return Repitition.createQueryBuilder('repitition')
.where(
`
DATE_PART(
"repitition"."intervalType",
:when::timestamp - "repitition"."startsAt"
)::integer
% "repitition"."interval"
= 0
`,
{ when },
)
.getMany()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment