UNPKG

@aws-amplify/graphql-schema-generator

Version:
225 lines 7.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MySQLStringDataSourceAdapter = void 0; const schema_representation_1 = require("../schema-representation"); const string_datasource_adapter_1 = require("./string-datasource-adapter"); const graphql_transformer_common_1 = require("graphql-transformer-common"); const expectedColumns = [ 'TABLE_NAME', 'COLUMN_NAME', 'COLUMN_DEFAULT', 'ORDINAL_POSITION', 'DATA_TYPE', 'COLUMN_TYPE', 'IS_NULLABLE', 'CHARACTER_MAXIMUM_LENGTH', 'INDEX_NAME', 'NON_UNIQUE', 'SEQ_IN_INDEX', 'NULLABLE', ]; class MySQLStringDataSourceAdapter extends string_datasource_adapter_1.StringDataSourceAdapter { constructor() { super(...arguments); this.enums = new Map(); this.PRIMARY_KEY_INDEX_NAME = 'PRIMARY'; } setSchema(schema) { this.setFields(schema); this.setIndexes(schema); this.setTables(schema); } validateSchema(schema) { if (schema.length === 0) { throw new string_datasource_adapter_1.EmptySchemaError(); } const columns = Object.keys(schema[0]); const hasAllExpectedColumns = expectedColumns.every((column) => columns.includes(column)); if (!hasAllExpectedColumns) { throw new string_datasource_adapter_1.InvalidSchemaError(schema, expectedColumns); } return true; } setFields(parsedSchema) { this.fields = parsedSchema.map((item) => ({ tableName: item.TABLE_NAME, columnName: item.COLUMN_NAME, default: item.COLUMN_DEFAULT, sequence: item.ORDINAL_POSITION, datatype: item.DATA_TYPE, columnType: item.COLUMN_TYPE, nullable: item.IS_NULLABLE === 'YES', length: item.CHARACTER_MAXIMUM_LENGTH, })); } setIndexes(parsedSchema) { this.indexes = parsedSchema .filter(({ INDEX_NAME }) => !!INDEX_NAME) .map((item) => ({ tableName: item.TABLE_NAME, indexName: item.INDEX_NAME, nonUnique: item.NON_UNIQUE, columnName: item.COLUMN_NAME, sequence: item.SEQ_IN_INDEX, nullable: item.NULLABLE === 'YES', })); } setTables(parsedSchema) { this.tables = Array.from(new Set(parsedSchema.map(({ TABLE_NAME }) => TABLE_NAME))); } getTablesList() { return this.tables; } getFields(tableName) { const fieldsName = [ ...new Set(this.fields .filter((f) => f.tableName === tableName) .sort((a, b) => a.sequence - b.sequence) .map((f) => f.columnName)), ]; const modelFields = fieldsName.map((columnName) => { const dbField = this.fields.find((field) => field.tableName === tableName && field.columnName === columnName); const field = { name: dbField.columnName, type: this.mapDataType(dbField.datatype, dbField.nullable, tableName, dbField.columnName, dbField.columnType), length: dbField.length, default: dbField.default ? { kind: 'DB_GENERATED', value: dbField.default, } : undefined, }; return field; }); return modelFields; } getPrimaryKey(tableName) { const key = this.indexes .filter((index) => index.tableName === tableName && index.indexName === this.PRIMARY_KEY_INDEX_NAME) .sort((a, b) => a.sequence - b.sequence); if (!key || key.length == 0) { return null; } const index = new schema_representation_1.Index(key[0].indexName); index.setFields(key.map((k) => k.columnName)); return index; } getIndexes(tableName) { const indexNames = [ ...new Set(this.indexes.filter((i) => i.tableName === tableName && i.indexName !== this.PRIMARY_KEY_INDEX_NAME).map((i) => i.indexName)), ]; const tableIndexes = indexNames.map((indexName) => { const key = this.indexes .filter((index) => index.tableName == tableName && index.indexName === indexName) .sort((a, b) => a.sequence - b.sequence); const index = new schema_representation_1.Index(indexName); index.setFields(key.map((k) => k.columnName)); return index; }); return tableIndexes; } mapDataType(datatype, nullable, tableName, fieldName, columntype) { let fieldDatatype = 'String'; let listtype = false; switch (datatype.toUpperCase()) { case 'VARCHAR': case 'CHAR': case 'BINARY': case 'VARBINARY': case 'TINYBLOB': case 'TINYTEXT': case 'TEXT': case 'BLOB': case 'MEDIUMTEXT': case 'MEDIUMBLOB': case 'LONGTEXT': case 'LONGBLOB': fieldDatatype = 'String'; break; case 'SET': fieldDatatype = 'String'; listtype = true; break; case 'BOOLEAN': case 'BOOL': fieldDatatype = 'Boolean'; break; case 'BIT': case 'TINYINT': case 'SMALLINT': case 'MEDIUMINT': case 'INT': case 'INTEGER': case 'BIGINT': case 'YEAR': fieldDatatype = 'Int'; break; case 'FLOAT': case 'DOUBLE': case 'DECIMAL': case 'DEC': case 'NUMERIC': fieldDatatype = 'Float'; break; case 'DATE': fieldDatatype = 'AWSDate'; break; case 'TIMESTAMP': case 'DATETIME': fieldDatatype = 'AWSDateTime'; break; case 'TIME': fieldDatatype = 'AWSTime'; break; case 'JSON': fieldDatatype = 'AWSJSON'; break; case 'ENUM': fieldDatatype = 'ENUM'; break; default: fieldDatatype = 'String'; break; } let result; if (fieldDatatype === 'ENUM') { const enumName = this.generateEnumName(tableName, fieldName); result = { kind: 'Enum', values: this.getEnumValues(columntype), name: this.generateEnumName(tableName, fieldName), }; this.enums.set(enumName, result); } else { result = { kind: 'Scalar', name: fieldDatatype, }; } if (!nullable) { result = { kind: 'NonNull', type: result, }; } return result; } getEnumValues(value) { const regex = /(["'])(?:(?=(\\?))\2.)*?\1/g; return value.match(regex).map((a) => a.slice(1, -1)); } generateEnumName(tableName, fieldName) { const enumNamePrefix = (0, graphql_transformer_common_1.toPascalCase)([tableName, fieldName]); let enumName = enumNamePrefix; let counter = 0; while (this.enums.has(enumName)) { enumName = (0, graphql_transformer_common_1.toPascalCase)([enumNamePrefix, counter.toString()]); counter++; } return enumName; } } exports.MySQLStringDataSourceAdapter = MySQLStringDataSourceAdapter; //# sourceMappingURL=mysql-string-datasource-adapter.js.map