UNPKG

@aws-amplify/graphql-schema-generator

Version:
241 lines 8.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PostgresStringDataSourceAdapter = exports.expectedColumns = 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"); exports.expectedColumns = [ 'enum_name', 'enum_values', 'table_name', 'column_name', 'column_default', 'ordinal_position', 'data_type', 'udt_name', 'is_nullable', 'character_maximum_length', 'index_columns', 'indexname', 'constraint_type', ]; class PostgresStringDataSourceAdapter extends string_datasource_adapter_1.StringDataSourceAdapter { constructor() { super(...arguments); this.PRIMARY_KEY_INDEX_NAME = 'PRIMARY'; } setSchema(schema) { this.setEnums(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 = exports.expectedColumns.every((column) => columns.includes(column)); if (!hasAllExpectedColumns) { throw new string_datasource_adapter_1.InvalidSchemaError(schema, exports.expectedColumns); } return true; } 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.find((index) => index.tableName === tableName && index.constraintType === 'PRIMARY KEY'); if (!key || key.columns.length == 0) { return null; } const index = new schema_representation_1.Index(key.indexName); index.setFields(key.columns); return index; } getIndexes(tableName) { const indexNames = [ ...new Set(this.indexes.filter((i) => i.tableName === tableName && i.constraintType !== 'PRIMARY KEY').map((i) => i.indexName)), ]; const tableIndexes = indexNames.map((indexName) => { const key = this.indexes.find((index) => index.tableName == tableName && index.indexName === indexName); const index = new schema_representation_1.Index(indexName); index.setFields(key.columns); return index; }); return tableIndexes; } generateEnumName(tableName, fieldName) { return (0, graphql_transformer_common_1.toPascalCase)([tableName, fieldName]); } setEnums(parsedSchema) { this.enums = new Map(); parsedSchema .filter(({ enum_name }) => !!enum_name) .forEach((row) => { const tableName = row.table_name; const columnName = row.column_name; const enumName = this.generateEnumName(tableName, columnName); const enumValues = row.enum_values.substring(1, row.enum_values.length - 1).split(','); const enumType = { kind: 'Enum', name: enumName, values: enumValues, }; this.enums.set(enumName, enumType); }); } setTables(parsedSchema) { this.tables = Array.from(new Set(parsedSchema.map(({ table_name }) => table_name))); } setFields(fields) { this.fields = fields.map((item) => ({ tableName: item.table_name, columnName: item.column_name, default: item.column_default, sequence: item.ordinal_position, datatype: item.data_type, columnType: item.udt_name, nullable: item.is_nullable === 'YES', length: item.character_maximum_length, })); } setIndexes(indexes) { this.indexes = indexes .filter(({ index_columns }) => !!index_columns) .map((item) => ({ tableName: item.table_name, columns: item.index_columns.split(', '), indexName: item.indexname, columnName: item.column_name, constraintType: item.constraint_type, })); } mapDataType(datatype, nullable, tableName, fieldName, columntype) { let fieldDatatype = 'String'; let listtype = false; if (columntype.startsWith('_')) { listtype = true; columntype = columntype.slice(1); } switch (columntype.toUpperCase()) { case 'VARCHAR': case 'CHAR': case 'TEXT': fieldDatatype = 'String'; break; case 'BOOLEAN': case 'BOOL': fieldDatatype = 'Boolean'; break; case 'BIGINT': case 'INT8': case 'BIGSERIAL': case 'BIT': case 'INT': case 'INT4': case 'INT2': case 'SMALLINT': case 'SMALLSERIAL': case 'SERIAL': case 'SERIAL4': fieldDatatype = 'Int'; break; case 'FLOAT8': case 'MONEY': case 'NUMERIC': case 'DECIMAL': case 'REAL': case 'FLOAT4': fieldDatatype = 'Float'; break; case 'UUID': fieldDatatype = 'ID'; break; case 'DATE': fieldDatatype = 'AWSDate'; break; case 'TIMESTAMP': case 'DATETIME': fieldDatatype = 'AWSDateTime'; break; case 'TIME': fieldDatatype = 'AWSTime'; break; case 'BOX': case 'CIRCLE': case 'JSON': case 'JSONB': case 'LINE': case 'LSEG': case 'PATH': case 'POINT': case 'POLYGON': fieldDatatype = 'AWSJSON'; break; case 'CIDR': case 'INET': fieldDatatype = 'AWSIPAddress'; break; default: if (this.enums.has(this.generateEnumName(tableName, fieldName))) { fieldDatatype = 'ENUM'; } break; } let result; if (fieldDatatype === 'ENUM') { const enumRef = this.enums.get(this.generateEnumName(tableName, fieldName)); result = { kind: 'Enum', values: enumRef.values, name: enumRef.name, }; } else { result = { kind: 'Scalar', name: fieldDatatype, }; } if (!nullable) { result = { kind: 'NonNull', type: result, }; } if (listtype) { result = { kind: 'List', type: result, }; } return result; } } exports.PostgresStringDataSourceAdapter = PostgresStringDataSourceAdapter; //# sourceMappingURL=pg-string-datasource-adapter.js.map