metrics for view joins and grouped filters
This commit is contained in:
parent
9ef6cbd566
commit
3332f2fa22
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
ViewFilterDeletedEvent,
|
||||
ViewFilterUpdatedEvent,
|
||||
ViewUpdatedEvent,
|
||||
View,
|
||||
ViewV2,
|
||||
ViewCalculation,
|
||||
Table,
|
||||
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 = !!(
|
||||
|
@ -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)
|
||||
|
|
|
@ -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 = {
|
||||
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
@ -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> {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ??= {}
|
||||
|
@ -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> {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { BaseEvent, TableExportFormat } from "./event"
|
||||
import { AIOperationEnum } from "../ai"
|
||||
|
||||
export interface TableCreatedEvent extends BaseEvent {
|
||||
tableId: string
|
||||
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue