mirror of
https://github.com/lana-k/sqliteviz.git
synced 2025-12-06 18:18:53 +08:00
move sql parsing to dataBase module
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import sqliteParser from 'sqlite-parser'
|
||||||
const worker = new Worker('js/worker.sql-wasm.js')
|
const worker = new Worker('js/worker.sql-wasm.js')
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -15,9 +16,19 @@ export default {
|
|||||||
|
|
||||||
// on 'action: exec' completed
|
// on 'action: exec' completed
|
||||||
worker.onmessage = event => {
|
worker.onmessage = event => {
|
||||||
|
// Parse DDL statements to get column names and types
|
||||||
|
const parsedSchema = []
|
||||||
|
event.data.results[0].values.forEach(item => {
|
||||||
|
parsedSchema.push({
|
||||||
|
name: item[0],
|
||||||
|
columns: getColumns(item[1])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// Return db name and schema
|
||||||
resolve({
|
resolve({
|
||||||
dbName: file.name,
|
dbName: file.name,
|
||||||
schema: event.data.results[0].values
|
schema: parsedSchema
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
worker.postMessage({ action: 'exec', sql: getSchemaSql })
|
worker.postMessage({ action: 'exec', sql: getSchemaSql })
|
||||||
@@ -45,3 +56,47 @@ export default {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAst (sql) {
|
||||||
|
// There is a bug is sqlite-parser
|
||||||
|
// It throws an error if tokenizer has an arguments:
|
||||||
|
// https://github.com/codeschool/sqlite-parser/issues/59
|
||||||
|
const fixedSql = sql
|
||||||
|
.replace(/(?<=tokenize=.+)"tokenchars=.+"/, '')
|
||||||
|
.replace(/(?<=tokenize=.+)"remove_diacritics=.+"/, '')
|
||||||
|
.replace(/(?<=tokenize=.+)"separators=.+"/, '')
|
||||||
|
.replace(/tokenize=.+(?=(,|\)))/, 'tokenize=unicode61')
|
||||||
|
|
||||||
|
return sqliteParser(fixedSql)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return an array of columns with name and type. E.g.:
|
||||||
|
* [
|
||||||
|
* { name: 'id', type: 'INTEGER' },
|
||||||
|
* { name: 'title', type: 'NVARCHAR(30)' },
|
||||||
|
* ]
|
||||||
|
*/
|
||||||
|
function getColumns (sql) {
|
||||||
|
const columns = []
|
||||||
|
const ast = getAst(sql)
|
||||||
|
|
||||||
|
const columnDefinition = ast.statement[0].format === 'table'
|
||||||
|
? ast.statement[0].definition
|
||||||
|
: ast.statement[0].result.args.expression // virtual table
|
||||||
|
|
||||||
|
columnDefinition.forEach(item => {
|
||||||
|
if (item.variant === 'column' && ['identifier', 'definition'].includes(item.type)) {
|
||||||
|
let type = item.datatype ? item.datatype.variant : 'N/A'
|
||||||
|
if (item.datatype && item.datatype.args) {
|
||||||
|
type = type + '(' + item.datatype.args.expression[0].value
|
||||||
|
if (item.datatype.args.expression.length === 2) {
|
||||||
|
type = type + ', ' + item.datatype.args.expression[1].value
|
||||||
|
}
|
||||||
|
type = type + ')'
|
||||||
|
}
|
||||||
|
columns.push({ name: item.name, type: type })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return columns
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,46 +1,8 @@
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import Vuex from 'vuex'
|
import Vuex from 'vuex'
|
||||||
import sqliteParser from 'sqlite-parser'
|
|
||||||
|
|
||||||
Vue.use(Vuex)
|
Vue.use(Vuex)
|
||||||
|
|
||||||
function getAst (sql) {
|
|
||||||
// There is a bug is sqlite-parser
|
|
||||||
// It throws an error if tokenizer has an arguments:
|
|
||||||
// https://github.com/codeschool/sqlite-parser/issues/59
|
|
||||||
const fixedSql = sql
|
|
||||||
.replace(/(?<=tokenize=.+)"tokenchars=.+"/, '')
|
|
||||||
.replace(/(?<=tokenize=.+)"remove_diacritics=.+"/, '')
|
|
||||||
.replace(/(?<=tokenize=.+)"separators=.+"/, '')
|
|
||||||
.replace(/tokenize=.+(?=(,|\)))/, 'tokenize=unicode61')
|
|
||||||
|
|
||||||
return sqliteParser(fixedSql)
|
|
||||||
}
|
|
||||||
|
|
||||||
function getColumns (sql) {
|
|
||||||
const columns = []
|
|
||||||
const ast = getAst(sql)
|
|
||||||
|
|
||||||
const columnDefinition = ast.statement[0].format === 'table'
|
|
||||||
? ast.statement[0].definition
|
|
||||||
: ast.statement[0].result.args.expression // virtual table
|
|
||||||
|
|
||||||
columnDefinition.forEach(item => {
|
|
||||||
if (item.variant === 'column' && ['identifier', 'definition'].includes(item.type)) {
|
|
||||||
let type = item.datatype ? item.datatype.variant : 'N/A'
|
|
||||||
if (item.datatype && item.datatype.args) {
|
|
||||||
type = type + '(' + item.datatype.args.expression[0].value
|
|
||||||
if (item.datatype.args.expression.length === 2) {
|
|
||||||
type = type + ', ' + item.datatype.args.expression[1].value
|
|
||||||
}
|
|
||||||
type = type + ')'
|
|
||||||
}
|
|
||||||
columns.push({ name: item.name, type: type })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return columns
|
|
||||||
}
|
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
schema: null,
|
schema: null,
|
||||||
@@ -55,14 +17,7 @@ export default new Vuex.Store({
|
|||||||
mutations: {
|
mutations: {
|
||||||
saveSchema (state, { dbName, schema }) {
|
saveSchema (state, { dbName, schema }) {
|
||||||
state.dbName = dbName
|
state.dbName = dbName
|
||||||
const parsedSchema = []
|
state.schema = schema
|
||||||
schema.forEach(item => {
|
|
||||||
parsedSchema.push({
|
|
||||||
name: item[0],
|
|
||||||
columns: getColumns(item[1])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
state.schema = parsedSchema
|
|
||||||
},
|
},
|
||||||
saveDbFile (state, file) {
|
saveDbFile (state, file) {
|
||||||
state.dbFile = file
|
state.dbFile = file
|
||||||
|
|||||||
@@ -30,10 +30,14 @@ describe('dataBase.js', () => {
|
|||||||
const buffer = new Blob([data])
|
const buffer = new Blob([data])
|
||||||
return db.loadDb(buffer)
|
return db.loadDb(buffer)
|
||||||
})
|
})
|
||||||
.then(schema => {
|
.then(({dbName, schema}) => {
|
||||||
|
console.log(schema[0].columns)
|
||||||
expect(schema.length).to.equal(1)
|
expect(schema.length).to.equal(1)
|
||||||
expect(schema[0][0]).to.equal('test')
|
expect(schema[0].name).to.equal('test')
|
||||||
expect(schema[0][1]).to.equal('CREATE TABLE test (col1, col2)')
|
expect(schema[0].columns[0].name).to.equal('col1')
|
||||||
|
expect(schema[0].columns[0].type).to.equal('N/A')
|
||||||
|
expect(schema[0].columns[1].name).to.equal('col2')
|
||||||
|
expect(schema[0].columns[1].type).to.equal('N/A')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
Reference in New Issue
Block a user