Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Substitution 'node-sql-parser' with a forked version until April 1st (Next Release) #597

Merged
merged 12 commits into from
Mar 20, 2024
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
"graphiql": "3.0.6",
"graphql": "^16.8.1",
"gridjs": "6.0.6",
"kevin-node-sql-parser": "^4.18.1",
"monaco-editor": "^0.45.0",
"near-api-js": "1.1.0",
"near-social-bridge": "^1.4.1",
"next": "^13.5.6",
"node-sql-parser": "^4.10.0",
"prettier": "^2.7.1",
"prettier-plugin-sql": "^0.13.0",
"raw-loader": "^4.0.2",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/Editor/Editor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ const Editor = ({ actionButtonText }) => {
`${primitives}}`,
"file:///node_modules/@near-lake/primitives/index.d.ts"
);

setMonacoMount(true);
}

Expand Down
105 changes: 54 additions & 51 deletions frontend/src/utils/pgSchemaTypeGen.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Parser } from "node-sql-parser";
import { Parser } from "kevin-node-sql-parser";
//todo: remove this import and replace with a with default node-sql-parser on next release

export class PgSchemaTypeGen {
constructor() {
Expand Down Expand Up @@ -52,79 +53,81 @@ export class PgSchemaTypeGen {
}

generateTypes(sqlSchema) {
const schemaSyntaxTree = this.parser.astify(sqlSchema, { database: "Postgresql" });
const dbSchema = {};

const statements = Array.isArray(schemaSyntaxTree) ? schemaSyntaxTree : [schemaSyntaxTree];
// Process each statement in the schema
for (const statement of statements) {
if (statement.type === "create" && statement.keyword === "table") {
// Process CREATE TABLE statements
const tableName = statement.table[0].table;
if (dbSchema.hasOwnProperty(tableName)) {
throw new Error(`Table ${tableName} already exists in schema. Table names must be unique. Quotes are not allowed as a differentiator between table names.`);
}
const schemaSyntaxTree = this.parser.astify(sqlSchema, { database: "Postgresql" });
const dbSchema = {};

const statements = Array.isArray(schemaSyntaxTree) ? schemaSyntaxTree : [schemaSyntaxTree];
// Process each statement in the schema
for (const statement of statements) {
if (statement.type === "create" && statement.keyword === "table") {
// Process CREATE TABLE statements
const tableName = statement.table[0].table;
if (dbSchema.hasOwnProperty(tableName)) {
throw new Error(`Table ${tableName} already exists in schema. Table names must be unique. Quotes are not allowed as a differentiator between table names.`);
}

let columns = {};
for (const columnSpec of statement.create_definitions) {
if (columnSpec.hasOwnProperty("column") && columnSpec.hasOwnProperty("definition")) {
// New Column
this.addColumn(columnSpec, columns);
} else if (columnSpec.hasOwnProperty("constraint") && columnSpec.constraint_type == "primary key") {
// Constraint on existing column
for (const foreignKeyDef of columnSpec.definition) {
columns[foreignKeyDef.column].nullable = false;
}
let columns = {};
for (const columnSpec of statement.create_definitions) {
if (columnSpec.hasOwnProperty("column") && columnSpec.hasOwnProperty("definition")) {
// New Column
this.addColumn(columnSpec, columns);
} else if (columnSpec.hasOwnProperty("constraint") && columnSpec.constraint_type == "primary key") {
// Constraint on existing column
for (const foreignKeyDef of columnSpec.definition) {
columns[foreignKeyDef.column.expr.value].nullable = false;
}
}
dbSchema[tableName] = columns;
} else if (statement.type === "alter") {
// Process ALTER TABLE statements
const tableName = statement.table[0].table;
for (const alterSpec of statement.expr) {
switch (alterSpec.action) {
case "add":
switch (alterSpec.resource) {
case "column": // Add column to table
this.addColumn(alterSpec, dbSchema[tableName]);
break;
case "constraint": // Add constraint to column(s) (Only PRIMARY KEY constraint impacts output types)
const newConstraint = alterSpec.create_definitions;
if (newConstraint.constraint_type == "primary key") {
for (const foreignKeyDef of newConstraint.definition) {
dbSchema[tableName][foreignKeyDef.column].nullable = false;
}
}
dbSchema[tableName] = columns;
} else if (statement.type === "alter") {
// Process ALTER TABLE statements
const tableName = statement.table[0].table;
for (const alterSpec of statement.expr) {
switch (alterSpec.action) {
case "add":
switch (alterSpec.resource) {
case "column": // Add column to table
this.addColumn(alterSpec, dbSchema[tableName]);
break;
case "constraint": // Add constraint to column(s) (Only PRIMARY KEY constraint impacts output types)
const newConstraint = alterSpec.create_definitions;
if (newConstraint.constraint_type == "primary key") {
for (const foreignKeyDef of newConstraint.definition) {
dbSchema[tableName][foreignKeyDef.column].nullable = false;
}
break;
}
break;
case "drop": // Can only drop column for now
delete dbSchema[tableName][alterSpec.column.column];
break;
}
}
break;
}
break;
case "drop": // Can only drop column for now
delete dbSchema[tableName][alterSpec.column.column];
break;
}
}
}
}

const tsTypes = this.generateTypeScriptDefinitions(dbSchema);
console.log(`Types successfully generated`);
return tsTypes;
const tsTypes = this.generateTypeScriptDefinitions(dbSchema);
console.log(`Types successfully generated`);
return tsTypes;
}

addColumn(columnDef, columns) {
const columnName = columnDef.column.column;
const columnName = columnDef.column.column.expr.value;
const columnType = this.getTypescriptType(columnDef.definition.dataType);
const nullable = this.getNullableStatus(columnDef);
const required = this.getRequiredStatus(columnDef, nullable);
if (columns.hasOwnProperty(columnName)) {
console.warn(`Column ${columnName} already exists in table. Skipping.`);
return;
}

columns[columnName] = {
type: columnType,
nullable: nullable,
required: required,
};

}

getNullableStatus(columnDef) {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/utils/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export function validateSQLSchema(schema) {
pgSchemaTypeGen.generateTypes(formattedSchema); // Sanity check
return { data: formattedSchema, error: null }
} catch (error) {
console.log(error)
return { data: schema, error: new ValidationError(error.message, TYPE_GENERATION_ERROR_TYPE), location: error.location };
}
}
Expand Down
Loading
Loading