fix is materialized view (#260)

This commit is contained in:
Guy Ben-Aharon
2024-10-08 10:47:21 +03:00
committed by GitHub
parent 392e3c16c8
commit 13d9d92ad5
6 changed files with 63 additions and 85 deletions

65
package-lock.json generated
View File

@@ -36,7 +36,6 @@
"@xyflow/react": "^12.3.1",
"ahooks": "^3.8.1",
"ai": "^3.3.14",
"buffer": "^6.0.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
@@ -4200,26 +4199,6 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/big-integer": {
"version": "1.6.52",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
@@ -4295,30 +4274,6 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
@@ -6938,26 +6893,6 @@
"@babel/runtime": "^7.23.2"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",

View File

@@ -40,7 +40,6 @@
"@xyflow/react": "^12.3.1",
"ahooks": "^3.8.1",
"ai": "^3.3.14",
"buffer": "^6.0.3",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",

View File

@@ -4,7 +4,7 @@ import {
schemaNameToDomainSchemaName,
schemaNameToSchemaId,
} from './db-schema';
import type { DBTable } from './db-table';
import { decodeViewDefinition, type DBTable } from './db-table';
import { generateId } from '@/lib/utils';
import type { AST } from 'node-sql-parser';
@@ -48,7 +48,6 @@ export const createDependenciesFromMetadata = async ({
databaseType: DatabaseType;
}): Promise<DBDependency[]> => {
const { Parser } = await import('node-sql-parser');
const { Buffer } = await import('buffer/');
const parser = new Parser();
const dependencies = views
@@ -68,20 +67,10 @@ export const createDependenciesFromMetadata = async ({
if (view.view_definition) {
try {
let decodedViewDefinition: string;
// For other database types, decode the base64-encoded view definition
if (databaseType === DatabaseType.SQL_SERVER) {
decodedViewDefinition = Buffer.from(
view.view_definition,
'base64'
).toString('utf16le');
} else {
decodedViewDefinition = Buffer.from(
view.view_definition,
'base64'
).toString('utf-8');
}
const decodedViewDefinition = decodeViewDefinition(
databaseType,
view.view_definition
);
let modifiedViewDefinition = '';
if (

View File

@@ -7,11 +7,17 @@ import { materializedViewColor, viewColor, randomColor } from '@/lib/colors';
import type { DBRelationship } from './db-relationship';
import type { PrimaryKeyInfo } from '../data/import-metadata/metadata-types/primary-key-info';
import type { ViewInfo } from '../data/import-metadata/metadata-types/view-info';
import { deepCopy, generateId } from '../utils';
import {
decodeBase64ToUtf16LE,
decodeBase64ToUtf8,
deepCopy,
generateId,
} from '../utils';
import {
schemaNameToDomainSchemaName,
schemaNameToSchemaId,
} from './db-schema';
import { DatabaseType } from './database-type';
export interface DBTable {
id: string;
@@ -38,18 +44,38 @@ export const shouldShowTablesBySchemaFilter = (
!table.schema ||
filteredSchemas.includes(schemaNameToSchemaId(table.schema));
export const decodeViewDefinition = (
databaseType: DatabaseType,
viewDefinition?: string
): string => {
if (!viewDefinition) {
return '';
}
let decodedViewDefinition: string;
if (databaseType === DatabaseType.SQL_SERVER) {
decodedViewDefinition = decodeBase64ToUtf16LE(viewDefinition);
} else {
decodedViewDefinition = decodeBase64ToUtf8(viewDefinition);
}
return decodedViewDefinition;
};
export const createTablesFromMetadata = ({
tableInfos,
columns,
indexes,
primaryKeys,
views,
databaseType,
}: {
tableInfos: TableInfo[];
columns: ColumnInfo[];
indexes: IndexInfo[];
primaryKeys: PrimaryKeyInfo[];
views: ViewInfo[];
databaseType: DatabaseType;
}): DBTable[] => {
return tableInfos.map((tableInfo: TableInfo) => {
const tableSchema = schemaNameToDomainSchemaName(tableInfo.schema);
@@ -165,8 +191,10 @@ export const createTablesFromMetadata = ({
const isMaterializedView = views.some(
(view) =>
view.view_definition?.includes('MATERIALIZED') &&
view.view_name === tableInfo.table
view.view_name === tableInfo.table &&
decodeViewDefinition(databaseType, view.view_definition)
.toLowerCase()
.includes('materialized')
);
// Initial random positions; these will be adjusted later

View File

@@ -47,6 +47,7 @@ export const loadFromDatabaseMetadata = async ({
indexes,
primaryKeys,
views,
databaseType,
});
// First pass: Create relationships

View File

@@ -59,3 +59,29 @@ export const debounce = <T extends (...args: Parameters<T>) => ReturnType<T>>(
export const removeDups = <T>(array: T[]): T[] => {
return [...new Set(array)];
};
export const decodeBase64ToUtf16LE = (base64: string) => {
const binaryString = atob(base64);
const charCodes = new Uint16Array(binaryString.length / 2);
for (let i = 0; i < charCodes.length; i++) {
charCodes[i] =
binaryString.charCodeAt(i * 2) +
(binaryString.charCodeAt(i * 2 + 1) << 8);
}
return String.fromCharCode(...charCodes);
};
export const decodeBase64ToUtf8 = (base64: string) => {
const binaryString = atob(base64);
const bytes = new Uint8Array(binaryString.length);
for (let i = 0; i < binaryString.length; i++) {
bytes[i] = binaryString.charCodeAt(i);
}
const decoder = new TextDecoder('utf-8');
return decoder.decode(bytes);
};