Skip to content

Commit

Permalink
Fix attributeValueToString for invalid Date
Browse files Browse the repository at this point in the history
  • Loading branch information
loicknuchel committed Feb 18, 2025
1 parent aafe9e6 commit 7a6e365
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 43 deletions.
2 changes: 1 addition & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "azimutt",
"description": "Export database schema from relational or document databases. Import it to https://azimutt.app",
"version": "0.1.37",
"version": "0.1.38",
"license": "MIT",
"homepage": "https://azimutt.app",
"keywords": [
Expand Down
2 changes: 1 addition & 1 deletion cli/src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const version = '0.1.37' // FIXME: `process.env.npm_package_version` is not available :/
export const version = '0.1.38' // FIXME: `process.env.npm_package_version` is not available :/
12 changes: 6 additions & 6 deletions gateway/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gateway/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@azimutt/gateway",
"description": "A Gateway to proxy database access for Azimutt frontend",
"version": "0.1.24",
"version": "0.1.25",
"license": "MIT",
"homepage": "https://azimutt.app",
"keywords": [
Expand Down Expand Up @@ -36,7 +36,7 @@
"@azimutt/connector-postgres": "^0.1.11",
"@azimutt/connector-snowflake": "^0.1.2",
"@azimutt/connector-sqlserver": "^0.1.4",
"@azimutt/models": "^0.1.19",
"@azimutt/models": "^0.1.20",
"@azimutt/utils": "^0.1.8",
"@fastify/cors": "9.0.1",
"@sinclair/typebox": "0.29.6",
Expand Down
2 changes: 1 addition & 1 deletion libs/models/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@azimutt/models",
"description": "Define a standard database models for Azimutt.",
"version": "0.1.19",
"version": "0.1.20",
"license": "MIT",
"homepage": "https://azimutt.app",
"keywords": [],
Expand Down
14 changes: 14 additions & 0 deletions libs/models/src/databaseUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
attributesRefSame,
attributesRefToId,
attributeTypeParse,
attributeValueToString,
DatabaseKind,
EntityId,
EntityRef,
Expand Down Expand Up @@ -366,6 +367,19 @@ describe('databaseUtils', () => {
{path: ['details', 'created'], name: 'created', type: 'varchar'},
])
})
test('attributeValueToString', () => {
expect(attributeValueToString('str')).toEqual('str')
expect(attributeValueToString(42)).toEqual('42')
expect(attributeValueToString(BigInt(42))).toEqual('42')
expect(attributeValueToString(NaN)).toEqual('NaN')
expect(attributeValueToString(Infinity)).toEqual('Infinity')
expect(attributeValueToString(true)).toEqual('true')
expect(attributeValueToString(new String('str'))).toEqual('str')
expect(attributeValueToString(new Number(42))).toEqual('42')
expect(attributeValueToString(new Boolean(true))).toEqual('true')
expect(attributeValueToString(new Date(1739896885465))).toEqual('2025-02-18T16:41:25.465Z')
expect(attributeValueToString(new Date('bad'))).toEqual('null')
})
test('parseJsonDatabase', () => {
expect(parseJsonDatabase(`{}`)).toEqual({result: {}})
expect(parseJsonDatabase(`{"entities": [{"name": "users"}, {"name": "posts"}]}`)).toEqual({result: {entities: [{name: 'users'}, {name: 'posts'}]}})
Expand Down
12 changes: 8 additions & 4 deletions libs/models/src/databaseUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,17 @@ function flattenAttribute(attr: Attribute, p: AttributePath = []): (Attribute &
}

export function attributeValueToString(value: AttributeValue): string {
if (value === null) return 'null'
if (value === undefined) return 'null'
if (typeof value === 'string') return value
if (typeof value === 'number') return value.toString()
if (typeof value === 'bigint') return value.toString()
if (typeof value === 'boolean') return value.toString()
if (value instanceof Date) return value.toISOString()
if (value === undefined) return 'null'
if (value === null) return 'null'
return JSON.stringify(value)
if (value instanceof String) return value.toString()
if (value instanceof Number) return value.toString()
if (value instanceof Boolean) return value.toString()
if (value instanceof Date) return isNaN(value.getTime()) ? 'null' : value.toISOString()
return JSON.stringify(value) || 'null'
}

export const indexEntities = (entities: Entity[]): Record<EntityId, Entity> =>
Expand Down
32 changes: 18 additions & 14 deletions libs/models/src/legacy/legacyDatabase.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {z} from "zod";
import {removeEmpty, removeUndefined, stringify, zip} from "@azimutt/utils";
import {errorToString, removeEmpty, removeUndefined, stringify, zip} from "@azimutt/utils";
import {
Attribute,
AttributePath,
Expand All @@ -16,7 +16,7 @@ import {
Relation,
Type
} from "../database";
import {attributeValueToString} from "../databaseUtils";
import {attributePathToId, attributeValueToString, entityToId} from "../databaseUtils";
import {ValueSchema} from "../inferSchema";
import {DateTime} from "../common";

Expand Down Expand Up @@ -227,7 +227,7 @@ function tableToLegacy(e: Entity): LegacyTable {
return removeUndefined({
schema: e.schema || '',
table: e.name,
columns: (e.attrs || []).map(columnToLegacy),
columns: (e.attrs || []).map(a => columnToLegacy(e, a, [])),
view: e.kind === 'view' || e.kind === 'materialized view' || undefined,
definition: e.def,
primaryKey: e.pk ? primaryKeyToLegacy(e.pk) : undefined,
Expand Down Expand Up @@ -288,17 +288,21 @@ function columnFromLegacy(c: LegacyColumn): Attribute {
})
}

function columnToLegacy(a: Attribute): LegacyColumn {
return removeEmpty({
name: a.name,
type: a.type,
nullable: a.null,
default: a.default ? columnValueToLegacy(a.default) : undefined,
comment: a.doc,
values: a.stats?.distinctValues?.map(columnValueToLegacy),
columns: a.attrs?.map(columnToLegacy),
stats: a.stats ? attributeDbStatsToLegacy(a.stats) : undefined,
})
function columnToLegacy(e: Entity, a: Attribute, parents: string[]): LegacyColumn {
try {
return removeEmpty({
name: a.name,
type: a.type,
nullable: a.null,
default: a.default ? columnValueToLegacy(a.default) : undefined,
comment: a.doc,
values: a.stats?.distinctValues?.map(columnValueToLegacy),
columns: a.attrs?.map(aa => columnToLegacy(e, aa, [...parents, a.name])),
stats: a.stats ? attributeDbStatsToLegacy(a.stats) : undefined,
})
} catch (err) {
throw new Error(`Error in columnToLegacy for entity ${entityToId(e)} and attribute ${attributePathToId([...parents, a.name])}: ${errorToString(err)}`)
}
}

export function columnValueFromLegacy(v: LegacyColumnValue): AttributeValue {
Expand Down
28 changes: 14 additions & 14 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7a6e365

Please sign in to comment.