@supercat1337/mysql-schema-parser
Version:
A library for parsing and working with MySQL database schema metadata.
5 lines (4 loc) • 7.12 kB
JavaScript
function f(r){if(typeof r!="object"||r===null)throw new Error("Input must be a non-null object");let t=["TABLE_CATALOG","TABLE_SCHEMA","TABLE_NAME","COLUMN_NAME","ORDINAL_POSITION","IS_NULLABLE","DATA_TYPE","COLUMN_TYPE","COLUMN_KEY","EXTRA","PRIVILEGES","COLUMN_COMMENT","IS_GENERATED"];for(let e of t)if(!(e in r))throw new Error(`Missing required field: ${e}`);let i={TABLE_CATALOG:e=>typeof e=="string"||`Expected string, got ${typeof e}`,TABLE_SCHEMA:e=>typeof e=="string"||`Expected string, got ${typeof e}`,TABLE_NAME:e=>typeof e=="string"||`Expected string, got ${typeof e}`,COLUMN_NAME:e=>typeof e=="string"||`Expected string, got ${typeof e}`,ORDINAL_POSITION:e=>typeof e=="number"||`Expected number, got ${typeof e}`,COLUMN_DEFAULT:e=>e===null||typeof e=="string"||`Expected string or null, got ${typeof e}`,IS_NULLABLE:e=>e==="YES"||e==="NO"||`Expected 'YES' or 'NO', got ${e}`,DATA_TYPE:e=>typeof e=="string"||`Expected string, got ${typeof e}`,CHARACTER_MAXIMUM_LENGTH:e=>e===null||typeof e=="number"||`Expected number or null, got ${typeof e}`,CHARACTER_OCTET_LENGTH:e=>e===null||typeof e=="number"||`Expected number or null, got ${typeof e}`,NUMERIC_PRECISION:e=>e===null||typeof e=="number"||`Expected number or null, got ${typeof e}`,NUMERIC_SCALE:e=>e===null||typeof e=="number"||`Expected number or null, got ${typeof e}`,DATETIME_PRECISION:e=>e===null||typeof e=="number"||`Expected number or null, got ${typeof e}`,CHARACTER_SET_NAME:e=>e===null||typeof e=="string"||`Expected string or null, got ${typeof e}`,COLLATION_NAME:e=>e===null||typeof e=="string"||`Expected string or null, got ${typeof e}`,COLUMN_TYPE:e=>typeof e=="string"||`Expected string, got ${typeof e}`,COLUMN_KEY:e=>["PRI","UNI","MUL",""].includes(e)||`Expected 'PRI', 'UNI', 'MUL' or empty string, got ${e}`,EXTRA:e=>typeof e=="string"||`Expected string, got ${typeof e}`,PRIVILEGES:e=>typeof e=="string"||`Expected string, got ${typeof e}`,COLUMN_COMMENT:e=>typeof e=="string"||`Expected string, got ${typeof e}`,IS_GENERATED:e=>e==="NEVER"||e==="ALWAYS"||typeof e=="string"||`Expected 'NEVER', 'ALWAYS' or string, got ${e}`,GENERATION_EXPRESSION:e=>e===null||typeof e=="string"||`Expected string or null, got ${typeof e}`};for(let[e,o]of Object.entries(i)){let s=o(r[e]);if(typeof s=="string")throw new Error(`Invalid ${e}: ${s}`)}return!0}var E=class{tableCatalog;tableSchema;tableName;columnName;ordinalPosition;columnDefault;isNullable;dataType;characterMaximumLength;characterOctetLength;numericPrecision;numericScale;datetimePrecision;characterSetName;collationName;columnType;columnKey;extra;privileges;columnComment;isGenerated;generationExpression;constructor(t){t&&(this.tableCatalog=t.tableCatalog,this.tableSchema=t.tableSchema,this.tableName=t.tableName,this.columnName=t.columnName,this.ordinalPosition=t.ordinalPosition,this.columnDefault=t.columnDefault,this.isNullable=t.isNullable,this.dataType=t.dataType,this.characterMaximumLength=t.characterMaximumLength,this.characterOctetLength=t.characterOctetLength,this.numericPrecision=t.numericPrecision,this.numericScale=t.numericScale,this.datetimePrecision=t.datetimePrecision,this.characterSetName=t.characterSetName,this.collationName=t.collationName,this.columnType=t.columnType,this.columnKey=t.columnKey,this.extra=t.extra,this.privileges=t.privileges,this.columnComment=t.columnComment,this.isGenerated=t.isGenerated,this.generationExpression=t.generationExpression)}importFromRawData(t){f(t),this.tableCatalog=t.TABLE_CATALOG,this.tableSchema=t.TABLE_SCHEMA,this.tableName=t.TABLE_NAME,this.columnName=t.COLUMN_NAME,this.ordinalPosition=t.ORDINAL_POSITION,this.columnDefault=t.COLUMN_DEFAULT,this.isNullable=t.IS_NULLABLE,this.dataType=t.DATA_TYPE,this.characterMaximumLength=t.CHARACTER_MAXIMUM_LENGTH,this.characterOctetLength=t.CHARACTER_OCTET_LENGTH,this.numericPrecision=t.NUMERIC_PRECISION,this.numericScale=t.NUMERIC_SCALE,this.datetimePrecision=t.DATETIME_PRECISION,this.characterSetName=t.CHARACTER_SET_NAME,this.collationName=t.COLLATION_NAME,this.columnType=t.COLUMN_TYPE,this.columnKey=t.COLUMN_KEY,this.extra=t.EXTRA,this.privileges=t.PRIVILEGES,this.columnComment=t.COLUMN_COMMENT,this.isGenerated=t.IS_GENERATED,this.generationExpression=t.GENERATION_EXPRESSION}isPrimaryKey(){return this.columnKey==="PRI"}allowsNull(){return this.isNullable==="YES"}isAutoIncrement(){return this.extra.includes("auto_increment")}getColumnDefinition(){return`${this.columnName} ${this.columnType}`+(this.isPrimaryKey()?" PRIMARY KEY":"")+(this.isAutoIncrement()?" AUTO_INCREMENT":"")+(this.allowsNull()?"":" NOT NULL")}toJSON(){return{...this}}},m=class{databaseName;tables=new Map;constructor(t,i=[]){this.databaseName=t;let e=new Set;for(let o=0;o<i.length;o++)e.add(i[o].TABLE_NAME);for(let o of e){let s=i.filter(l=>l.TABLE_NAME===o);if(s.length===0)continue;let c=new N(o,s);this.addTable(c)}}addTable(t){this.tables.set(t.tableName,t)}getTableNames(){return Array.from(this.tables.keys())}},N=class{tableName;columns=new Map;constructor(t,i=[]){this.tableName=t;for(let e=0;e<i.length;e++){let o=new E;i[e].TABLE_NAME===t&&(o.importFromRawData(i[e]),this.columns.set(i[e].COLUMN_NAME,o))}}addColumn(t){this.columns.set(t.columnName,t)}getColumns(){return Array.from(this.columns.values())}getColumn(t){return this.columns.get(t)||null}generateCreateTableQuery(t={}){let i=this.getColumns();if(i.length===0)throw new Error(`Table ${this.tableName} has no columns`);let e=[],o=[],s=[],c=[];for(let n of i){let u=`\`${n.columnName}\` ${n.columnType}`;if(n.allowsNull()||(u+=" NOT NULL"),n.columnDefault!==null){let A=this.#t(n);u+=` DEFAULT ${A}`}n.isAutoIncrement()&&(u+=" AUTO_INCREMENT"),n.columnComment&&(u+=` COMMENT '${this.#e(n.columnComment)}'`),e.push(u),n.isPrimaryKey()?o.push(`\`${n.columnName}\``):n.columnKey==="UNI"?s.push(`\`${n.columnName}\``):n.columnKey==="MUL"&&c.push(`\`${n.columnName}\``)}o.length>0&&e.push(`PRIMARY KEY (${o.join(", ")})`);for(let n of s)e.push(`UNIQUE KEY \`${n.replace(/`/g,"")}_unique\` (${n})`);let l=`CREATE TABLE \`${this.tableName}\` (
`;l+=e.join(`,
`),l+=`
)`,t.engine&&(l+=` ENGINE=${t.engine}`);let h=t.charset||i[0].characterSetName||"utf8mb4",p=t.collation||i[0].collationName||"utf8mb4_unicode_ci";return l+=` DEFAULT CHARSET=${h} COLLATE=${p}`,t.comment&&(l+=` COMMENT='${this.#e(t.comment)}'`),l+";"}#t(t){return t.columnDefault===null?"NULL":["char","varchar","text","enum","set"].includes(t.dataType.toLowerCase())?`'${this.#e(t.columnDefault)}'`:["timestamp","datetime"].includes(t.dataType.toLowerCase())&&t.columnDefault.toUpperCase()==="CURRENT_TIMESTAMP"?"CURRENT_TIMESTAMP":["blob","binary"].includes(t.dataType.toLowerCase())?`x'${t.columnDefault}'`:t.columnDefault}#e(t){return t.replace(/'/g,"''").replace(/\\/g,"\\\\")}getColumnNames(){return Array.from(this.columns.keys())}};function T(r){if(!Array.isArray(r))throw new Error("Schema must be an array");if(r.length===0)throw new Error("Schema must not be empty");let t=r[0].TABLE_SCHEMA;return new m(t,r)}export{m as MySQLDatabase,N as MySQLTable,E as MySQLTableColumn,f as assertColumnMetadataRaw,T as parseMySQLSchema};