Merge branch 'master' into mark-calculation-views
This commit is contained in:
commit
1ede966863
|
@ -641,6 +641,109 @@ describe.each([
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("cannot create a calculation view with duplicate calculations", async () => {
|
||||||
|
await config.api.viewV2.create(
|
||||||
|
{
|
||||||
|
tableId: table._id!,
|
||||||
|
name: generator.guid(),
|
||||||
|
schema: {
|
||||||
|
sum: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.SUM,
|
||||||
|
field: "Price",
|
||||||
|
},
|
||||||
|
sum2: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.SUM,
|
||||||
|
field: "Price",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
body: {
|
||||||
|
message:
|
||||||
|
'Duplicate calculation on field "Price", calculation type "sum"',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("finds duplicate counts", async () => {
|
||||||
|
await config.api.viewV2.create(
|
||||||
|
{
|
||||||
|
tableId: table._id!,
|
||||||
|
name: generator.guid(),
|
||||||
|
schema: {
|
||||||
|
count: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.COUNT,
|
||||||
|
},
|
||||||
|
count2: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.COUNT,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
body: {
|
||||||
|
message:
|
||||||
|
'Duplicate calculation on field "*", calculation type "count"',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("finds duplicate count distincts", async () => {
|
||||||
|
await config.api.viewV2.create(
|
||||||
|
{
|
||||||
|
tableId: table._id!,
|
||||||
|
name: generator.guid(),
|
||||||
|
schema: {
|
||||||
|
count: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.COUNT,
|
||||||
|
distinct: true,
|
||||||
|
field: "Price",
|
||||||
|
},
|
||||||
|
count2: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.COUNT,
|
||||||
|
distinct: true,
|
||||||
|
field: "Price",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
body: {
|
||||||
|
message:
|
||||||
|
'Duplicate calculation on field "Price", calculation type "count"',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("does not confuse counts and count distincts in the duplicate check", async () => {
|
||||||
|
await config.api.viewV2.create({
|
||||||
|
tableId: table._id!,
|
||||||
|
name: generator.guid(),
|
||||||
|
schema: {
|
||||||
|
count: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.COUNT,
|
||||||
|
},
|
||||||
|
count2: {
|
||||||
|
visible: true,
|
||||||
|
calculationType: CalculationType.COUNT,
|
||||||
|
distinct: true,
|
||||||
|
field: "Price",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("update", () => {
|
describe("update", () => {
|
||||||
|
|
|
@ -72,11 +72,23 @@ async function guardCalculationViewSchema(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const calculationFieldName of Object.keys(calculationFields)) {
|
const seen: Record<string, Record<CalculationType, boolean>> = {}
|
||||||
const schema = calculationFields[calculationFieldName]
|
|
||||||
|
for (const name of Object.keys(calculationFields)) {
|
||||||
|
const schema = calculationFields[name]
|
||||||
const isCount = schema.calculationType === CalculationType.COUNT
|
const isCount = schema.calculationType === CalculationType.COUNT
|
||||||
const isDistinct = isCount && "distinct" in schema && schema.distinct
|
const isDistinct = isCount && "distinct" in schema && schema.distinct
|
||||||
|
|
||||||
|
const field = isCount && !isDistinct ? "*" : schema.field
|
||||||
|
if (seen[field]?.[schema.calculationType]) {
|
||||||
|
throw new HTTPError(
|
||||||
|
`Duplicate calculation on field "${field}", calculation type "${schema.calculationType}"`,
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
seen[field] ??= {} as Record<CalculationType, boolean>
|
||||||
|
seen[field][schema.calculationType] = true
|
||||||
|
|
||||||
// Count fields that aren't distinct don't need to reference another field,
|
// Count fields that aren't distinct don't need to reference another field,
|
||||||
// so we don't validate it.
|
// so we don't validate it.
|
||||||
if (isCount && !isDistinct) {
|
if (isCount && !isDistinct) {
|
||||||
|
@ -86,14 +98,14 @@ async function guardCalculationViewSchema(
|
||||||
const targetSchema = table.schema[schema.field]
|
const targetSchema = table.schema[schema.field]
|
||||||
if (!targetSchema) {
|
if (!targetSchema) {
|
||||||
throw new HTTPError(
|
throw new HTTPError(
|
||||||
`Calculation field "${calculationFieldName}" references field "${schema.field}" which does not exist in the table schema`,
|
`Calculation field "${name}" references field "${schema.field}" which does not exist in the table schema`,
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCount && !helpers.schema.isNumeric(targetSchema)) {
|
if (!isCount && !helpers.schema.isNumeric(targetSchema)) {
|
||||||
throw new HTTPError(
|
throw new HTTPError(
|
||||||
`Calculation field "${calculationFieldName}" references field "${schema.field}" which is not a numeric field`,
|
`Calculation field "${name}" references field "${schema.field}" which is not a numeric field`,
|
||||||
400
|
400
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue