Skip to content

Commit

Permalink
fix: generate data native types (#1412)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexis Rico <[email protected]>
Co-authored-by: Alexis Rico <[email protected]>
  • Loading branch information
2 people authored and Xata committed May 3, 2024
1 parent 9df7ae2 commit cec5b51
Showing 1 changed file with 46 additions and 39 deletions.
85 changes: 46 additions & 39 deletions packages/importer/src/random-data.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { fakerEN as faker } from '@faker-js/faker';
import { Schemas } from '@xata.io/client';
import { z } from 'zod';

// TODO: Remove this once we migrate pgroll branches
type PgRollColumn = Schemas.Column & {
comment?: string;
pgType?: string;
};

export function generateRandomData(table: Schemas.Table, size: number) {
const records: Record<string, unknown>[] = [];
Expand All @@ -11,61 +18,61 @@ export function generateRandomData(table: Schemas.Table, size: number) {
return records;
}

function randomRecord(columns: Schemas.Column[]) {
function randomRecord(columns: PgRollColumn[]) {
const record: Record<string, unknown> = {};
for (const column of columns) {
record[column.name] = randomData(column);
}
return record;
}

function randomData(column: Schemas.Column) {
switch (column.type) {
case 'text':
return faker.lorem.paragraphs(rand(2, 3));
case 'email':
return faker.internet.email({ provider: 'acme.pets' });
function randomData(column: PgRollColumn) {
const columnCommentType = narrowStringType(column.comment);
// Note that this is a best effort and seeding may fail for invalid Xata columns
// that are foreign keys, or have constraints such as length attached to them.
switch (column.pgType) {
case 'boolean':
return rand(0, 1) === 1;
case 'bigint':
case 'int8':
case 'integer':
case 'int':
case 'int4':
case 'smallint':
return rand(1, 100);
case 'float':
case 'double precision':
case 'float8':
case 'real':
return rand(1, 10000) / rand(1, 100);
case 'bool':
return rand(0, 1) === 1;
case 'multiple':
return faker.word.words(rand(1, 3)).split(' ');
case 'string':
return randomString(column.name);
case 'datetime':
case 'text':
case 'varchar':
case 'character varying':
if (columnCommentType === 'email') return faker.internet.email({ provider: 'acme.pets' });
return faker.word.words(3);
case 'timestamptz':
return faker.date.recent({ days: rand(1, 10) });
default:
return undefined;
case 'text[]':
return faker.word.words(rand(1, 3)).split(' ');
}

if (column.pgType?.startsWith('character(') || column.pgType?.startsWith('varchar(')) return faker.word.words(3);
if (column.pgType?.startsWith('numeric(')) return rand(1, 10000) / rand(1, 100);

return undefined;
}

function rand(min: number, max: number) {
return Math.floor(Math.random() * (max - min) + min);
}

const generators: Record<string, () => string> = {
city: () => faker.location.city(),
country: () => faker.location.country(),
county: () => faker.location.county(),
state: () => faker.location.state(),
street: () => faker.location.street(),
timezone: () => faker.location.timeZone(),
tz: () => faker.location.timeZone(),
zipcode: () => faker.location.zipCode(),
zip: () => faker.location.zipCode(),
department: () => faker.commerce.department(),
product: () => faker.commerce.product(),
company: () => faker.company.name(),
firstName: () => faker.person.firstName(),
lastName: () => faker.person.lastName(),
phone: () => faker.phone.number('501-###-###')
};
export const xataStringColumns = ['email', 'text', 'string'] as const;

function randomString(columnName: string) {
const gen = generators[columnName.toLowerCase()];
if (gen) return gen();
return faker.word.words(2);
}
const XataStringColumn = z.object({
['xata.type']: z.enum(xataStringColumns)
});

const narrowStringType = (comment?: string): Schemas.Column['type'] => {
if (!comment) return 'text';
const result = XataStringColumn.safeParse(JSON.parse(comment));
return result.success ? result.data['xata.type'] : 'text';
};

0 comments on commit cec5b51

Please sign in to comment.