Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
/apps/studio/components/interfaces/Organization/Documents/ @supabase/security
/apps/studio/pages/new/index.tsx @supabase/security

/apps/studio/data/sql/queries/ @supabase/postgres @avallete
/apps/studio/data/**/*.sql.ts @supabase/postgres @avallete

/packages/shared-data/compute-disk-limits.ts @supabase/infra
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getScheduleDeleteCronJobRunDetailsSql } from 'data/sql/queries/delete-cron-job-run-details'
import { getScheduleDeleteCronJobRunDetailsSql } from 'data/database-cron-jobs/database-cron-jobs.sql'
import { CheckCircle2, XCircle } from 'lucide-react'
import {
Button,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useExecuteSqlMutation } from 'data/sql/execute-sql-mutation'
import {
CTID_BATCH_PAGE_SIZE,
getDeleteOldCronJobRunDetailsByCtidKey,
getDeleteOldCronJobRunDetailsByCtidSql,
getJobRunDetailsPageCountKey,
getJobRunDetailsPageCountSql,
} from 'data/sql/queries/delete-cron-job-run-details'
} from 'data/database-cron-jobs/database-cron-jobs.sql'
import { useExecuteSqlMutation } from 'data/sql/execute-sql-mutation'
import { useCallback, useRef, useState } from 'react'
import { toast } from 'sonner'

Expand Down
32 changes: 28 additions & 4 deletions apps/studio/components/interfaces/Realtime/RealtimeSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { useCheckEntitlements } from 'hooks/misc/useCheckEntitlements'
import {
Button,
Card,
Expand Down Expand Up @@ -89,15 +90,38 @@ export const RealtimeSettings = () => {
},
})

const { getEntitlementMax: getEntitledMaxPayloadSize } = useCheckEntitlements(
'realtime.max_payload_size_in_kb'
)
const entitledMaxPayloadSize = getEntitledMaxPayloadSize() ?? 3000

const { getEntitlementMax: getEntitledMaxConcurrentUsers } = useCheckEntitlements(
'realtime.max_concurrent_users'
)
const entitledMaxConcurrentUsers = getEntitledMaxConcurrentUsers() ?? 50000

const { getEntitlementMax: getEntitledMaxEventsPerSecond } = useCheckEntitlements(
'realtime.max_events_per_second'
)
const entitledMaxEventsPerSecond = getEntitledMaxEventsPerSecond() ?? 10000

const { getEntitlementMax: getEntitledMaxPresenceEventsPerSecond } = useCheckEntitlements(
'realtime.max_presence_events_per_second'
)
const entitledMaxPresenceEventsPerSecond = getEntitledMaxPresenceEventsPerSecond() ?? 10000

const FormSchema = z.object({
connection_pool: z.coerce
.number()
.min(1)
.max(maxConn?.maxConnections ?? 100),
max_concurrent_users: z.coerce.number().min(1).max(50000),
max_events_per_second: z.coerce.number().min(1).max(10000),
max_presence_events_per_second: z.coerce.number().min(1).max(10000),
max_payload_size_in_kb: z.coerce.number().min(1).max(3000),
max_concurrent_users: z.coerce.number().min(1).max(entitledMaxConcurrentUsers),
max_events_per_second: z.coerce.number().min(1).max(entitledMaxEventsPerSecond),
max_presence_events_per_second: z.coerce
.number()
.min(1)
.max(entitledMaxPresenceEventsPerSecond),
max_payload_size_in_kb: z.coerce.number().min(1).max(entitledMaxPayloadSize),
suspend: z.boolean(),
// [Joshen] These fields are temporarily hidden from the UI
// max_bytes_per_second: z.coerce.number().min(1).max(10000000),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { InlineLink } from 'components/ui/InlineLink'
import { LARGEST_SIZE_LIMIT_BUCKETS_COUNT } from 'data/storage/storage.sql'
import Link from 'next/link'
import { type FieldError } from 'react-hook-form'

import { InlineLink } from 'components/ui/InlineLink'
import { LARGEST_SIZE_LIMIT_BUCKETS_COUNT } from 'data/sql/queries/get-largest-size-limit-buckets'
import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui'

import {
decodeBucketLimitErrorMessage,
formatBytesForDisplay,
Expand Down
6 changes: 3 additions & 3 deletions apps/studio/data/auth/user-query.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useQuery } from '@tanstack/react-query'

import { UUID_REGEX } from '@/lib/constants'
import { executeSql, type ExecuteSqlError } from 'data/sql/execute-sql-query'
import { getUserSQL } from 'data/sql/queries/get-user'
import { UseCustomQueryOptions } from 'types'

import { getUserSQL } from './auth.sql'
import { authKeys } from './keys'
import { User } from './users-infinite-query'
import { UUID_REGEX } from '@/lib/constants'

type UserVariables = {
projectRef?: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { useQuery } from '@tanstack/react-query'

import type { ConnectionVars } from 'data/common.types'
import { getLiveTupleEstimate, getLiveTupleEstimateKey } from 'data/database/database.sql'
import { executeSql } from 'data/sql/execute-sql-query'
import {
getLiveTupleEstimate,
getLiveTupleEstimateKey,
} from 'data/sql/queries/get-live-tuple-stats'
import type { UseCustomQueryOptions } from 'types'

type DatabaseCronJobsCountEstimateVariables = ConnectionVars
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { InfiniteData, useInfiniteQuery } from '@tanstack/react-query'
import { COST_THRESHOLD_ERROR, executeSql } from 'data/sql/execute-sql-query'
import type { ResponseError, UseCustomInfiniteQueryOptions } from 'types'

import { getCronJobsSql } from '../sql/queries/get-cron-jobs'
import { getCronJobsSql } from './database-cron-jobs.sql'
import { databaseCronJobsKeys } from './keys'

export const CRON_JOBS_PAGE_LIMIT = 20
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { InfiniteData, useInfiniteQuery } from '@tanstack/react-query'
import { executeSql } from 'data/sql/execute-sql-query'
import type { ResponseError, UseCustomInfiniteQueryOptions } from 'types'

import { getCronJobsMinimalSql } from '../sql/queries/get-cron-jobs'
import {
CRON_JOBS_PAGE_LIMIT,
CronJob,
DatabaseCronJobRunsVariables,
} from './database-cron-jobs-infinite-query'
import { getCronJobsMinimalSql } from './database-cron-jobs.sql'
import { databaseCronJobsKeys } from './keys'

export async function getDatabaseCronJobsMinimal({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { literal } from '@supabase/pg-meta/src/pg-format'

import { sqlKeys } from '../keys'
import { sqlKeys } from '../sql/keys'

const CRON_CLEANUP_SCHEDULE_NAME = 'delete-job-run-details'
const CRON_CLEANUP_SCHEDULE_EXPRESSION = '0 12 * * *'
Expand Down Expand Up @@ -89,3 +89,74 @@ export const getScheduleDeleteCronJobRunDetailsKey = (
projectRef: string | undefined,
interval: string
) => sqlKeys.query(projectRef, ['cron-job-run-details', 'schedule', interval])

// [Joshen] Just omits the LEFT JOIN as that's the heavy part
export const getCronJobsMinimalSql = ({
searchTerm,
page,
limit,
}: {
searchTerm?: string
page: number
limit: number
}) =>
`
SELECT
job.jobid,
job.jobname,
job.schedule,
job.command,
job.active
FROM
cron.job job
${!!searchTerm ? `WHERE job.jobname ILIKE ${literal(`%${searchTerm}%`)}` : ''}
ORDER BY job.jobid
LIMIT ${limit}
OFFSET ${page * limit};
`.trim()

export const getCronJobsSql = ({
searchTerm,
page,
limit,
}: {
searchTerm?: string
page: number
limit: number
}) =>
`
WITH latest_runs AS (
SELECT
jobid,
status,
MAX(start_time) AS latest_run
FROM cron.job_run_details
GROUP BY jobid, status
), most_recent_runs AS (
SELECT
jobid,
status,
latest_run
FROM latest_runs lr1
WHERE latest_run = (
SELECT MAX(latest_run)
FROM latest_runs lr2
WHERE lr2.jobid = lr1.jobid
)
)
SELECT
job.jobid,
job.jobname,
job.schedule,
job.command,
job.active,
mr.latest_run,
mr.status
FROM
cron.job job
LEFT JOIN most_recent_runs mr ON job.jobid = mr.jobid
${!!searchTerm ? `WHERE job.jobname ILIKE ${literal(`%${searchTerm}%`)}` : ''}
ORDER BY job.jobid
LIMIT ${limit}
OFFSET ${page * limit};
`.trim()
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { ResponseError, UseCustomMutationOptions } from 'types'
import {
getScheduleDeleteCronJobRunDetailsKey,
getScheduleDeleteCronJobRunDetailsSql,
} from '../sql/queries/delete-cron-job-run-details'
} from './database-cron-jobs.sql'

export type ScheduleCronJobRunDetailsCleanupVariables = {
projectRef: string
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useQuery } from '@tanstack/react-query'
import { UseCustomQueryOptions } from 'types'

import { ExecuteSqlError, executeSql } from '../sql/execute-sql-query'
import { getDatabaseExtensionDefaultSchemaSQL } from '../sql/queries/get-extension-default-schema'
import { executeSql, ExecuteSqlError } from '../sql/execute-sql-query'
import { getDatabaseExtensionDefaultSchemaSQL } from './database-extensions.sql'
import { databaseExtensionsKeys } from './keys'

type DatabaseExtensionDefaultSchemaVariables = {
Expand Down
4 changes: 2 additions & 2 deletions apps/studio/data/database-indexes/indexes-query.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { useQuery } from '@tanstack/react-query'

import { getIndexesSQL } from 'data/sql/queries/get-indexes'
import { UseCustomQueryOptions } from 'types'

import { executeSql, ExecuteSqlError } from '../sql/execute-sql-query'
import { getIndexesSQL } from './database-indexes.sql'
import { databaseIndexesKeys } from './keys'

type GetIndexesArgs = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { literal } from '@supabase/pg-meta/src/pg-format'
import { sqlKeys } from '../keys'

import { sqlKeys } from '../sql/keys'

export const getLiveTupleEstimate = (table: string, schema: string = 'public') => {
const sql = /* SQL */ `
Expand Down
72 changes: 0 additions & 72 deletions apps/studio/data/sql/queries/get-cron-jobs.ts

This file was deleted.

11 changes: 4 additions & 7 deletions apps/studio/data/storage/buckets-max-size-limit-query.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { useQuery, useQueryClient } from '@tanstack/react-query'
import { useCallback } from 'react'

import type { ConnectionVars } from 'data/common.types'
import { getLiveTupleEstimate, getLiveTupleEstimateKey } from 'data/database/database.sql'
import { executeSql } from 'data/sql/execute-sql-query'
import { useCallback } from 'react'

import {
getLargestSizeLimitBucketsKey,
getLargestSizeLimitBucketsSqlUnoptimized,
} from 'data/sql/queries/get-largest-size-limit-buckets'
import {
getLiveTupleEstimate,
getLiveTupleEstimateKey,
} from 'data/sql/queries/get-live-tuple-stats'
} from './storage.sql'

export const THRESHOLD_FOR_AUTO_QUERYING_BUCKET_LIMITS = 10_000

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { sqlKeys } from '../keys'
import { sqlKeys } from '../sql/keys'

export const LARGEST_SIZE_LIMIT_BUCKETS_COUNT = 50

Expand Down
7 changes: 7 additions & 0 deletions apps/studio/hooks/misc/useCheckEntitlements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ function getEntitlementSetValues(entitlement: Entitlement | null): string[] {
: []
}

function getEntitlementMax(entitlement: Entitlement | null): number | undefined {
return isEntitlementUnlimited(entitlement)
? Number.MAX_SAFE_INTEGER
: getEntitlementNumericValue(entitlement)
}

export function useCheckEntitlements(
featureKey: FeatureKey,
organizationSlug?: string,
Expand Down Expand Up @@ -110,5 +116,6 @@ export function useCheckEntitlements(
getEntitlementNumericValue: () => getEntitlementNumericValue(entitlement),
isEntitlementUnlimited: () => isEntitlementUnlimited(entitlement),
getEntitlementSetValues: () => getEntitlementSetValues(entitlement),
getEntitlementMax: () => getEntitlementMax(entitlement),
}
}
Loading
Loading