@clickup/pg-microsharding
Version:
Microshards support for PostgreSQL
65 lines (57 loc) • 1.82 kB
text/typescript
import compact from "lodash/compact";
import flatMap from "lodash/flatMap";
import sortBy from "lodash/sortBy";
import uniq from "lodash/uniq";
const SUFFIXES = [
{ suffix: "K", factor: 1000 },
{ suffix: "M", factor: 1000000 },
{ suffix: "G", factor: 1000000000 },
{ suffix: "T", factor: 1000000000000 },
];
/**
* Treats rows as table rows where keys of each row are column names. For each
* column name, checks that all cell values there are numbers (or are empty). If
* so, chooses the maximal suitable factor suffix for those numbers. Also, makes
* sure that all rows have the same number of columns (adding empty cells if
* needed).
*/
export function normalizeCellNumbers(
rows: Array<Record<string, string>>,
): typeof rows {
if (rows.length === 0) {
return [];
}
const columns = uniq(flatMap(rows, (row) => Object.keys(row)));
for (const column of columns) {
const values = rows.map((row) => row[column]);
if (!values.every((v) => v === undefined || v === "" || v.match(/^\d+$/))) {
// For the column to be normalizable, it must only include numeric and
// empty cells.
continue;
}
// Only numbers longer than 1 digit are significant.
const min = Math.min(
...compact(
values.map((v) => (v && v.length > 1 ? parseFloat(v) : undefined)),
),
);
const found = sortBy(SUFFIXES, ({ factor }) => -factor).find(
({ factor }) => min >= factor * 10,
);
if (found) {
for (const row of rows) {
const v = row[column];
if (v && v.length > 1) {
row[column] =
`${Math.round(parseFloat(v) / found.factor)}${found.suffix}`;
}
}
}
for (const row of rows) {
if (!(column in row)) {
row[column] = "";
}
}
}
return rows;
}