Skip to content

Commit

Permalink
metrics for view joins and grouped filters
Browse files Browse the repository at this point in the history
  • Loading branch information
shogunpurple committed Dec 5, 2024
1 parent 9ef6cbd commit 3332f2f
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ const EXCLUDED_EVENTS: Event[] = [
Event.ROLE_UPDATED,
Event.DATASOURCE_UPDATED,
Event.QUERY_UPDATED,
Event.TABLE_UPDATED,
Event.VIEW_UPDATED,
// Event.TABLE_UPDATED,
// Event.VIEW_UPDATED,
Event.VIEW_FILTER_UPDATED,
Event.VIEW_CALCULATION_UPDATED,
Event.AUTOMATION_TRIGGER_UPDATED,
Expand Down
33 changes: 27 additions & 6 deletions packages/backend-core/src/events/publishers/table.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { publishEvent } from "../events"
import {
Event,
TableExportFormat,
FieldType,
Table,
TableCreatedEvent,
TableUpdatedEvent,
TableDeletedEvent,
TableExportedEvent,
TableExportFormat,
TableImportedEvent,
TableUpdatedEvent,
} from "@budibase/types"

async function created(table: Table, timestamp?: string | number) {
Expand All @@ -20,14 +21,34 @@ async function created(table: Table, timestamp?: string | number) {
await publishEvent(Event.TABLE_CREATED, properties, timestamp)
}

async function updated(table: Table) {
async function updated(oldTable: Table, newTable: Table) {
// only publish the event if it has fields we are interested in
let defaultValues, aiColumn

// check that new fields have been added
for (const key in newTable.schema) {
if (!oldTable.schema[key]) {
const newColumn = newTable.schema[key]
if ("default" in newColumn) {
defaultValues = true
}
if (newColumn.type === FieldType.AI) {
aiColumn = newColumn.operation
}
}
}

const properties: TableUpdatedEvent = {
tableId: table._id as string,
tableId: newTable._id as string,
defaultValues,
aiColumn,
audited: {
name: table.name,
name: newTable.name,
},
}
await publishEvent(Event.TABLE_UPDATED, properties)
if (defaultValues || aiColumn) {
await publishEvent(Event.TABLE_UPDATED, properties)
}
}

async function deleted(table: Table) {
Expand Down
17 changes: 14 additions & 3 deletions packages/backend-core/src/events/publishers/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
ViewFilterDeletedEvent,
ViewFilterUpdatedEvent,
ViewUpdatedEvent,
View,
ViewV2,
ViewCalculation,
Table,
Expand All @@ -19,17 +20,27 @@ import {

/* eslint-disable */

async function created(view: Partial<ViewV2>, timestamp?: string | number) {
async function created(view: ViewV2, timestamp?: string | number) {
const properties: ViewCreatedEvent = {
name: view.name,
type: view.type,
tableId: view.tableId,
}
await publishEvent(Event.VIEW_CREATED, properties, timestamp)
}

async function updated(view: View) {
async function updated(newView: ViewV2) {
// // check whether any of the fields are different
let viewJoins = 0
for (const key in newView.schema) {
if (newView.schema[key]?.columns) {
viewJoins += Object.keys(newView.schema[key]?.columns).length
}
}
const properties: ViewUpdatedEvent = {
tableId: view.tableId,
tableId: newView.tableId,
groupedFilters: newView.queryUI?.groups?.length || 0,
viewJoins,
}
await publishEvent(Event.VIEW_UPDATED, properties)
}
Expand Down
4 changes: 2 additions & 2 deletions packages/server/src/api/controllers/table/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ export async function updateTable(
inputs.created = true
}
try {
const { datasource, table } = await sdk.tables.external.save(
const { datasource, oldTable, table } = await sdk.tables.external.save(
datasourceId!,
inputs,
{ tableId, renaming }
)
builderSocket?.emitDatasourceUpdate(ctx, datasource)
return table
return { table, oldTable }
} catch (err: any) {
if (err instanceof Error) {
ctx.throw(400, err.message)
Expand Down
11 changes: 9 additions & 2 deletions packages/server/src/api/controllers/table/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,15 @@ export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
await events.table.created(savedTable)
} else {
const api = pickApi({ table })
savedTable = await api.updateTable(ctx, renaming)
await events.table.updated(savedTable)
const { table: updatedTable, oldTable } = await api.updateTable(
ctx,
renaming
)
savedTable = updatedTable

if (oldTable) {
await events.table.updated(oldTable, savedTable)
}
}
if (renaming) {
await sdk.views.renameLinkedViews(savedTable, renaming)
Expand Down
4 changes: 2 additions & 2 deletions packages/server/src/api/controllers/table/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ export async function updateTable(
}

try {
const { table } = await sdk.tables.internal.save(tableToSave, {
const { table, oldTable } = await sdk.tables.internal.save(tableToSave, {
userId: ctx.user._id,
rowsToImport: rows,
tableId: ctx.request.body._id,
renaming,
})

return table
return { table, oldTable }
} catch (err: any) {
if (err instanceof Error) {
ctx.throw(400, err.message)
Expand Down
54 changes: 20 additions & 34 deletions packages/server/src/api/controllers/view/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,35 +60,31 @@ export async function save(ctx: Ctx) {
existingTable.views[viewName] = existingTable.views[originalName]
}
await db.put(table)
await handleViewEvents(
existingTable.views[viewName] as View,
table.views[viewName]
)

ctx.body = table.views[viewName]
builderSocket?.emitTableUpdate(ctx, table)
}

export async function calculationEvents(existingView: View, newView: View) {
const existingCalculation = existingView && existingView.calculation
const newCalculation = newView && newView.calculation

if (existingCalculation && !newCalculation) {
await events.view.calculationDeleted(existingView)
}

if (!existingCalculation && newCalculation) {
await events.view.calculationCreated(newView)
}

if (
existingCalculation &&
newCalculation &&
existingCalculation !== newCalculation
) {
await events.view.calculationUpdated(newView)
}
}
// export async function calculationEvents(existingView: View, newView: View) {
// const existingCalculation = existingView && existingView.calculation
// const newCalculation = newView && newView.calculation
//
// if (existingCalculation && !newCalculation) {
// await events.view.calculationDeleted(existingView)
// }
//
// if (!existingCalculation && newCalculation) {
// await events.view.calculationCreated(newView)
// }
//
// if (
// existingCalculation &&
// newCalculation &&
// existingCalculation !== newCalculation
// ) {
// await events.view.calculationUpdated(newView)
// }
// }

export async function filterEvents(existingView: View, newView: View) {
const hasExistingFilters = !!(
Expand All @@ -115,16 +111,6 @@ export async function filterEvents(existingView: View, newView: View) {
}
}

async function handleViewEvents(existingView: View, newView: View) {
if (!existingView) {
await events.view.created(newView)
} else {
await events.view.updated(newView)
}
await calculationEvents(existingView, newView)
await filterEvents(existingView, newView)
}

export async function destroy(ctx: Ctx) {
const db = context.getAppDB()
const viewName = decodeURIComponent(ctx.params.viewName)
Expand Down
11 changes: 6 additions & 5 deletions packages/server/src/api/controllers/view/viewsV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export async function create(ctx: Ctx<CreateViewRequest, ViewResponse>) {
}
const result = await sdk.views.create(tableId, parsedView)

await events.view.created(view)
await events.view.created(result)

ctx.status = 201
ctx.body = {
Expand Down Expand Up @@ -190,10 +190,11 @@ export async function update(ctx: Ctx<UpdateViewRequest, ViewResponse>) {
primaryDisplay: view.primaryDisplay,
}

const result = await sdk.views.update(tableId, parsedView)
ctx.body = {
data: result,
}
const { view: result } = await sdk.views.update(tableId, parsedView)

await events.view.updated(result)

ctx.body = { data: result }

const table = await sdk.tables.getTable(tableId)
builderSocket?.emitTableUpdate(ctx, table)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const backfill = async (appDb: Database, timestamp: string | number) => {
continue
}

await events.view.created(view, timestamp)
// await events.view.created(view, timestamp)

if (view.calculation) {
await events.view.calculationCreated(view, timestamp)
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/sdk/app/tables/external/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ export async function save(
tableToSave.sql = true
}

return { datasource: updatedDatasource, table: tableToSave }
return { datasource: updatedDatasource, table: tableToSave, oldTable }
}

export async function destroy(datasourceId: string, table: Table) {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/sdk/app/tables/internal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export async function save(
}
// has to run after, make sure it has _id
await runStaticFormulaChecks(table, { oldTable, deletion: false })
return { table }
return { table, oldTable }
}

export async function destroy(table: Table) {
Expand Down
4 changes: 2 additions & 2 deletions packages/server/src/sdk/app/views/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function create(
export async function update(
tableId: string,
view: Readonly<ViewV2>
): Promise<ViewV2> {
): Promise<{ view: ViewV2; existingView: ViewV2 }> {
const db = context.getAppDB()

const { datasourceId, tableName } = breakExternalTableId(tableId)
Expand All @@ -87,7 +87,7 @@ export async function update(
delete views[existingView.name]
views[view.name] = view
await db.put(ds)
return view
return { view, existingView }
}

export async function remove(viewId: string): Promise<ViewV2> {
Expand Down
5 changes: 4 additions & 1 deletion packages/server/src/sdk/app/views/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,10 @@ export async function create(
return view
}

export async function update(tableId: string, view: ViewV2): Promise<ViewV2> {
export async function update(
tableId: string,
view: ViewV2
): Promise<{ view: ViewV2; existingView: ViewV2 }> {
await guardViewSchema(tableId, view)

return pickApi(tableId).update(tableId, view)
Expand Down
4 changes: 2 additions & 2 deletions packages/server/src/sdk/app/views/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export async function create(
export async function update(
tableId: string,
view: Readonly<ViewV2>
): Promise<ViewV2> {
): Promise<{ view: ViewV2; existingView: ViewV2 }> {
const db = context.getAppDB()
const table = await sdk.tables.getTable(tableId)
table.views ??= {}
Expand All @@ -76,7 +76,7 @@ export async function update(
delete table.views[existingView.name]
table.views[view.name] = view
await db.put(table)
return view
return { view, existingView }
}

export async function remove(viewId: string): Promise<ViewV2> {
Expand Down
3 changes: 3 additions & 0 deletions packages/types/src/sdk/events/table.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseEvent, TableExportFormat } from "./event"
import { AIOperationEnum } from "../ai"

export interface TableCreatedEvent extends BaseEvent {
tableId: string
Expand All @@ -9,6 +10,8 @@ export interface TableCreatedEvent extends BaseEvent {

export interface TableUpdatedEvent extends BaseEvent {
tableId: string
defaultValues: boolean | undefined
aiColumn: AIOperationEnum | undefined
audited: {
name: string
}
Expand Down
7 changes: 4 additions & 3 deletions packages/types/src/sdk/events/view.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { ViewCalculation, ViewV2Schema, ViewV2Type } from "../../documents"
import { ViewCalculation, ViewV2Type } from "../../documents"
import { BaseEvent, TableExportFormat } from "./event"
import { LegacyFilter, SortOrder, SortType, UISearchFilter } from "../../api"
import { SearchFilters } from "../search"

export interface ViewCreatedEvent extends BaseEvent {
name: string
type?: ViewV2Type
tableId: string
}

export interface ViewUpdatedEvent extends BaseEvent {
tableId: string
groupedFilters: number
viewJoins: number
}

export interface ViewDeletedEvent extends BaseEvent {
Expand Down

0 comments on commit 3332f2f

Please sign in to comment.