1
0
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:
lana-k
2020-12-27 18:30:43 +01:00
parent 34764a6e33
commit dc3979584c
3 changed files with 64 additions and 50 deletions

View File

@@ -1,3 +1,4 @@
import sqliteParser from 'sqlite-parser'
const worker = new Worker('js/worker.sql-wasm.js')
export default {
@@ -15,9 +16,19 @@ export default {
// on 'action: exec' completed
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({
dbName: file.name,
schema: event.data.results[0].values
schema: parsedSchema
})
}
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
}

View File

@@ -1,46 +1,8 @@
import Vue from 'vue'
import Vuex from 'vuex'
import sqliteParser from 'sqlite-parser'
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({
state: {
schema: null,
@@ -55,14 +17,7 @@ export default new Vuex.Store({
mutations: {
saveSchema (state, { dbName, schema }) {
state.dbName = dbName
const parsedSchema = []
schema.forEach(item => {
parsedSchema.push({
name: item[0],
columns: getColumns(item[1])
})
})
state.schema = parsedSchema
state.schema = schema
},
saveDbFile (state, file) {
state.dbFile = file

View File

@@ -30,10 +30,14 @@ describe('dataBase.js', () => {
const buffer = new Blob([data])
return db.loadDb(buffer)
})
.then(schema => {
.then(({dbName, schema}) => {
console.log(schema[0].columns)
expect(schema.length).to.equal(1)
expect(schema[0][0]).to.equal('test')
expect(schema[0][1]).to.equal('CREATE TABLE test (col1, col2)')
expect(schema[0].name).to.equal('test')
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')
})
})
})