Skip to content

Instantly share code, notes, and snippets.

@naosim
Created June 12, 2018 21:59
Show Gist options
  • Save naosim/e0c4afc746dfd3ec7030d3e536e068c4 to your computer and use it in GitHub Desktop.
Save naosim/e0c4afc746dfd3ec7030d3e536e068c4 to your computer and use it in GitHub Desktop.
markdownからcreatetableを作るメモ
// node . inputfile outRootDir
if(process.argv.length == 2) {
const msg = 'USAGE\nnode . inputMarkdownFile outRootDir'
console.log(msg)
throw msg
}
const inputMarkdownFile = process.argv[2]
const outRootDir = process.argv[3]
const fs = require('fs')
function mkdirs(path) {
var current = ''
path.split('/').filter(v => v.trim().length > 0).forEach((p, i) => {
current += `${i == 0 ? '' : '/'}${p}`
try {
fs.mkdirSync(current)
} catch(e) {
// nop
}
})
}
var mdText = fs.readFileSync(inputMarkdownFile, 'utf8')
class DocNode {
constructor(text, parent) {
this.child = []
if(parent) {
text = text.trim();
this.title = text;
this.text = text;
this.parent = parent;
this.nest = parent.nest + 1;
parent.child.push(this);
var pathName = text.split(':')[0].trim();
this.path = parent.isRoot() ? pathName : `${parent.path}.${pathName}`;
} else {
this.nest = 0;
}
this.isRoot = () => parent ? false : true;
this.getParent = (num) => {
var parent = this.parent;
for(var i = 0; i < num; i++) {
parent = parent.parent;
}
return parent;
}
this.getCurrentPath = () => pathName;
this.eachChildNode = (cb) => {
this.child.forEach(c => {
cb(c);
c.eachChildNode(cb);
});
}
this.getBody = () => {
if(this.text.indexOf('\n') != -1) {
return this.text.slice(this.text.indexOf('\n')).trim();
} else {
return '';
}
}
}
}
var root = new DocNode();
function convert(input) {
var root = new DocNode();
var current = root;
input
.split('\n')
.map(v => v.trim())
.filter(v => v.length > 0)
.forEach(line => {
if(line[0] == '#') {
var space = line.indexOf(' ');
var nest = line.slice(0, space).length;
var text = line.slice(space).trim();
var n;
if(nest == current.nest) {
n = new DocNode(text, current.parent);
} else if(nest == current.nest + 1) {
n = new DocNode(text, current);
} else if(nest > current.nest) {
throw '深すぎる'
} else if(nest < current.nest) {
n = new DocNode(text, current.getParent(current.nest - nest));
}
current = n;
} else {// ヘッダー行以外
current.text += '\n' + line;
}
});
root.eachChildNode(node => {
// console.log(node.path);
var body = node.getBody();
if(body.indexOf('-|-') == -1) {//テーブルがない
return;
}
var tableName = node.getCurrentPath();
// テーブルの行を取得する
var rows = body
.split('\n')
.filter(v => v.indexOf('|') != -1 && v.indexOf('-|-') == -1)
.slice(1)
.map(v => v.split('|').map(v => v.trim()))
.map(v => {
const columnName = v[2]
return {
columnName:columnName,
type:v[6],
isNotNull: v[7].length > 0,
other: '',// なし
indexes: v[5] ? [`idx_${tableName}_${columnName}`]: [],
isPk: v[3].length > 0
}
})
;
var maxColumnLength = rows.map(v => v.columnName.length).reduce((memo, v)=> Math.max(memo, v), 0);
// console.log(maxColumnLength);
var formatSpace = (str) => ' '.slice(0, maxColumnLength - str.length)
var columns = rows.map(v => `${v.columnName}${formatSpace(v.columnName)} ${v.type}${v.isPk ? ' PRIMARY KEY' : ''}${v.isNotNull ? ' NOT NULL' : ''}${v.other ? ' ' + v.other:''}`);
var indexes = rows.reduce((memo, v) => {
if(!v.indexes || v.indexes.length == 0) {
return memo;
}
v.indexes.forEach(i => {
if(!memo[i]) {
memo[i] = [];
}
memo[i].push(v.columnName);
});
return memo;
}, {});
Object.keys(indexes).forEach(k => {
const path = `${outRootDir}/createindex/${node.path.split('.').join('/')}`
const f = `${path}/${k}.sql`
const t = `ALTER TABLE ${tableName} ADD INDEX ${k}(${indexes[k].join(', ')});`
console.log(t)
console.log(`=> ${f}`)
console.log(path)
mkdirs(path)
fs.writeFileSync(f, t)
})
const path = `${outRootDir}/createtable/${node.path.split('.').slice(0, -1).join('/')}`
const f = `${path}/${tableName}.sql`
var script = `
|# ${node.path}
|CREATE TABLE ${tableName}(
|${columns.join(',\n')}
|);
|
`.trim().split('\n').map(v => v.trim()).map(v => v[0] == '|' ? v.slice(1) : v).join('\n').trim()
// console.log(script);
console.log(script)
console.log(`=> ${f}`)
mkdirs(path)
fs.writeFileSync(f, script)
})
}
convert(mdText)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment