Commit ac9f5b7e authored by xiegelin's avatar xiegelin

feat: 兼容PostgreSQL

parent 367da3b6
......@@ -4,9 +4,12 @@
"description": "drawio utils",
"main": "mysql.js",
"scripts": {
"dev": "node mysql.js"
"dev": "node mysql.js",
"mysql": "node mysql.js",
"pgsql": "node postgreSQL.js"
},
"dependencies": {
"mysql2": "^3.6.0"
"mysql2": "^3.6.0",
"pg": "^8.11.3"
}
}
\ No newline at end of file
const { Client } = require('pg');
const readline = require('readline');
const fs = require('fs');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// Function to prompt user for input
function askQuestion(query) {
return new Promise((resolve) => {
rl.question(query, resolve);
});
}
async function main() {
try {
// PostgreSQL connection configuration
const host = '172.16.1.173';
const port = '5432';
const user = 'postgres';
const password = '123456';
const database = 'ai_data_governance';
// Alternative configuration (commented out)
// const host = '10.10.10.132';
// const port = '5432';
// const user = 'postgres';
// const password = 'your_password';
// const database = 'your_database';
let tableNames = await askQuestion(
'Enter table names (separated by commas): '
);
if (!tableNames) {
console.log('表名不得为空!');
return;
}
// Split table names by both Chinese and English commas, and trim whitespace
tableNames = tableNames
.split(/[,,]/)
.map((name) => name.trim())
.filter((name) => name);
// Process each table name
for (const tableName of tableNames) {
// Check if table name contains Chinese characters
if (/[\u4e00-\u9fa5]/.test(tableName)) {
console.error(`Table name "${tableName}" 不能有中文.`);
continue;
}
// Convert camelCase to snake_case
let processedTableName = tableName
.replace(/([A-Z])/g, '_$1')
.toLowerCase();
// Remove leading underscore if present
if (processedTableName[0] === '_') {
processedTableName = processedTableName.slice(1);
}
console.log('Processing table:', processedTableName);
console.log('\nConnecting to database...');
// Create PostgreSQL client
const client = new Client({
host,
port: parseInt(port),
user,
password,
database,
});
await client.connect();
console.log('Connected to database successfully!\n');
// Execute query - PostgreSQL uses different column names in information_schema
// col_description function is used to get column comments in PostgreSQL
const sql = `
SELECT
c.column_name,
pgd.description as column_comment
FROM information_schema.columns c
LEFT JOIN pg_catalog.pg_statio_all_tables st
ON c.table_schema = st.schemaname
AND c.table_name = st.relname
LEFT JOIN pg_catalog.pg_description pgd
ON pgd.objoid = st.relid
AND pgd.objsubid = c.ordinal_position
WHERE c.table_schema = $1
AND c.table_name = $2
ORDER BY c.ordinal_position
`;
console.log('Executing query...\n');
const result = await client.query(sql, ['public', processedTableName]);
const rows = result.rows;
if (rows.length === 0) {
console.error(
`***** No results found for table ${processedTableName}. *****`
);
} else {
generateXMLWithTableColumns(processedTableName, rows);
console.log(
`===== XML file generated successfully for ${processedTableName}! =====`
);
}
// Close connection
await client.end();
console.log('\nConnection closed.');
}
} catch (error) {
console.error('Error:', error.message);
} finally {
rl.close();
}
}
function generateXMLWithTableColumns(tableName, rows) {
// XML template start with the table name in the label
let xmlContent = `<mxGraphModel>
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<object label="${tableName}" id="2">
<mxCell style="swimlane;fontStyle=1;childLayout=stackLayout;horizontal=1;startSize=30;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="340" y="140" width="260" height="${
30 + rows.length * 30
}" as="geometry"/>
</mxCell>
</object>`;
// Generate a cell for each column
rows.forEach((row, index) => {
const cellValue = `${row.column_name} ${row.column_comment || ''}`;
const cellId = index + 3; // Starting from 3
// Check if the column is an audit field
const unimportantColumns = [
'created_at',
'create_time',
'created_code',
'create_code',
'updated_at',
'update_time',
'updated_code',
'update_code',
'deleted_at',
'deleted_code',
'delete_flag',
].includes(row.column_name);
const style = unimportantColumns
? 'text;strokeColor=default;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;fontColor=#B3B3B3;'
: 'text;strokeColor=default;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;';
xmlContent += `
<mxCell id="${cellId}" value="${cellValue}" style="${style}" vertex="1" parent="2">
<mxGeometry y="${
30 + index * 30
}" width="260" height="30" as="geometry"/>
</mxCell>`;
});
// XML template end
xmlContent += `
</root>
</mxGraphModel>`;
// console.log(xmlContent);
fs.writeFileSync(`xml/${tableName}_diagram.xml`, xmlContent);
}
main();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment