Skip to content

Commit

Permalink
tidy some db stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
dholms committed Dec 21, 2023
1 parent c880002 commit 8ff0b5b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 182 deletions.
12 changes: 0 additions & 12 deletions packages/ozone/src/api/com/atproto/moderation/createReport.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { AuthRequiredError } from '@atproto/xrpc-server'
import { Server } from '../../../../lexicon'
import AppContext from '../../../../context'
import { getReasonType } from './util'
import { softDeleted } from '../../../../db/util'
import { subjectFromInput } from '../../../../services/moderation/subject'

export default function (server: Server, ctx: AppContext) {
Expand All @@ -13,18 +11,8 @@ export default function (server: Server, ctx: AppContext) {
const requester = auth.credentials.did
const { reasonType, reason } = input.body
const subject = subjectFromInput(input.body.subject)

const db = ctx.db

// @TODO
// if (requester) {
// // Don't accept reports from users that are fully taken-down
// const actor = await ctx.services.actor(db).getActor(requester, true)
// if (actor && softDeleted(actor)) {
// throw new AuthRequiredError()
// }
// }

const report = await db.transaction(async (dbTxn) => {
const moderationTxn = ctx.services.moderation(dbTxn)
return moderationTxn.report({
Expand Down
86 changes: 75 additions & 11 deletions packages/ozone/src/db/pagination.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { sql } from 'kysely'
import { sql, DynamicModule } from 'kysely'
import { InvalidRequestError } from '@atproto/xrpc-server'
import { AnyQb, DbRef } from './util'
import { AnyQb, DbRef } from './types'

export type Cursor = { primary: string; secondary: string }
export type LabeledResult = {
Expand Down Expand Up @@ -78,17 +78,81 @@ export abstract class GenericKeyset<R, LR extends LabeledResult> {
}
}

type SortAtCidResult = { sortAt: string; cid: string }
type TimeCidLabeledResult = Cursor
type StatusKeysetParam = {
lastReviewedAt: string | null
lastReportedAt: string | null
id: number
}

export class StatusKeyset extends GenericKeyset<StatusKeysetParam, Cursor> {
labelResult(result: StatusKeysetParam): Cursor
labelResult(result: StatusKeysetParam) {
const primaryField = (
this.primary as ReturnType<DynamicModule['ref']>
).dynamicReference.includes('lastReviewedAt')
? 'lastReviewedAt'
: 'lastReportedAt'

return {
primary: result[primaryField]
? new Date(`${result[primaryField]}`).getTime().toString()
: '',
secondary: result.id.toString(),
}
}
labeledResultToCursor(labeled: Cursor) {
return {
primary: labeled.primary,
secondary: labeled.secondary,
}
}
cursorToLabeledResult(cursor: Cursor) {
return {
primary: cursor.primary
? new Date(parseInt(cursor.primary, 10)).toISOString()
: '',
secondary: cursor.secondary,
}
}
unpackCursor(cursorStr?: string): Cursor | undefined {
if (!cursorStr) return
const result = cursorStr.split('::')
const [primary, secondary, ...others] = result
if (!secondary || others.length > 0) {
throw new InvalidRequestError('Malformed cursor')
}
return {
primary,
secondary,
}
}
// This is specifically built to handle nullable columns as primary sorting column
getSql(labeled?: Cursor, direction?: 'asc' | 'desc') {
if (labeled === undefined) return
if (direction === 'asc') {
return !labeled.primary
? sql`(${this.primary} IS NULL AND ${this.secondary} > ${labeled.secondary})`
: sql`((${this.primary}, ${this.secondary}) > (${labeled.primary}, ${labeled.secondary}) OR (${this.primary} is null))`
} else {
return !labeled.primary
? sql`(${this.primary} IS NULL AND ${this.secondary} < ${labeled.secondary})`
: sql`((${this.primary}, ${this.secondary}) < (${labeled.primary}, ${labeled.secondary}) OR (${this.primary} is null))`
}
}
}

type TimeIdKeysetParam = {
id: number
createdAt: string
}
type TimeIdResult = TimeIdKeysetParam

export class TimeCidKeyset<
TimeCidResult = SortAtCidResult,
> extends GenericKeyset<TimeCidResult, TimeCidLabeledResult> {
labelResult(result: TimeCidResult): TimeCidLabeledResult
labelResult<TimeCidResult extends SortAtCidResult>(result: TimeCidResult) {
return { primary: result.sortAt, secondary: result.cid }
export class TimeIdKeyset extends GenericKeyset<TimeIdKeysetParam, Cursor> {
labelResult(result: TimeIdResult): Cursor
labelResult(result: TimeIdResult) {
return { primary: result.createdAt, secondary: result.id.toString() }
}
labeledResultToCursor(labeled: TimeCidLabeledResult) {
labeledResultToCursor(labeled: Cursor) {
return {
primary: new Date(labeled.primary).getTime().toString(),
secondary: labeled.secondary,
Expand Down
5 changes: 5 additions & 0 deletions packages/ozone/src/db/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { Pool as PgPool } from 'pg'
import { DynamicModule, RawBuilder, SelectQueryBuilder } from 'kysely'

export type DbRef = RawBuilder | ReturnType<DynamicModule['ref']>

export type AnyQb = SelectQueryBuilder<any, any, any>

export type PgOptions = {
url: string
Expand Down
61 changes: 0 additions & 61 deletions packages/ozone/src/db/util.ts

This file was deleted.

3 changes: 1 addition & 2 deletions packages/ozone/src/services/moderation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ import {
ReversibleModerationEvent,
} from './types'
import { ModerationEvent } from '../../db/schema/moderation_event'
import { paginate } from '../../db/pagination'
import { StatusKeyset, TimeIdKeyset } from './pagination'
import { StatusKeyset, TimeIdKeyset, paginate } from '../../db/pagination'
import AtpAgent from '@atproto/api'
import { Label } from '../../lexicon/types/com/atproto/label/defs'
import { sql } from 'kysely'
Expand Down
96 changes: 0 additions & 96 deletions packages/ozone/src/services/moderation/pagination.ts

This file was deleted.

0 comments on commit 8ff0b5b

Please sign in to comment.