Created
June 12, 2018 21:59
-
-
Save naosim/e0c4afc746dfd3ec7030d3e536e068c4 to your computer and use it in GitHub Desktop.
markdownからcreatetableを作るメモ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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