mirror of
https://github.com/h-sphere/sql-seal.git
synced 2026-07-22 10:10:28 +00:00
Merge pull request #17 from h-sphere/feat/sqljs
feat: Reworking Database to SQLJS
This commit is contained in:
commit
cb289ff65f
21 changed files with 912 additions and 15130 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
|
@ -22,9 +22,5 @@ data.json
|
|||
.DS_Store
|
||||
docs/.vitepress/dist
|
||||
docs/.vitepress/cache
|
||||
rebuild
|
||||
better_sqlite3.node
|
||||
|
||||
better_sqlite3*.node
|
||||
database.sqlite
|
||||
coverage/
|
||||
coverage/
|
||||
dist/
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
# 0.10.0
|
||||
SQLSeal is not compatible with mobile! Plugin now uses SQL.JS instead of better-sqlite3 which is written in Web Assembly so no longer native binaries are needed. This makes plugin portable.
|
||||
Also reworked implementation of the parser from Antlr4TS into Antlr4.
|
||||
|
||||
# 0.9.2
|
||||
Adding checkbox method to display boolean values as checkboxes
|
||||
Fixing how updates are parsed
|
||||
|
|
|
|||
10
README.md
10
README.md
|
|
@ -3,13 +3,8 @@
|
|||
SQLSeal allows to transform your CSV files located in your vault into fully-fledged SQL database. You can use SQL statements to query this data however you like.
|
||||
|
||||
## Installation
|
||||
Once the library is published in Obsidian Official Community Repository: just head to Community Tab in your Obisidian Settings page and search for "SQLSeal".
|
||||
|
||||
Note: Please note that this plugin is in early phase. Basic functionality should work just fine but I do not take any responsibility for potential data loss and damage to your Vault.
|
||||
|
||||
On the first try plugin will download better_sqlite3.node binary to run database locally. This is due to the Obsidian restrictions to bundle everything in the `main.js`. The whole process of generating it is public and you can check it in the GitHub workflows.
|
||||
|
||||
The plugin creates database file in configuration folder `.obsidian` named `sqlseal.db`.
|
||||
You can install plugin from the Community Plugins directly from Obsidian, just look for SQLSeal in the marketplace.
|
||||
|
||||
### Manual Instalation
|
||||
To manually install the package, open [Releases](https://github.com/h-sphere/sql-seal/releases) and download .zip of the last one. Unzip it in your vault under `.obsidian/Plugins/sqlseal`.
|
||||
|
|
@ -29,6 +24,9 @@ You can define multiple tables in a single snippet. You can also point to the ta
|
|||
|
||||
For more comprehensive documentation head to [hypersphere.blog/sql-seal](https://hypersphere.blog/sql-seal).
|
||||
|
||||
# Disclaimer
|
||||
The plugin authors do not take any resposibility for any potential data loss. Always backup your files before usage. That said, plugin does not modify any files in the Vault so you should be fine :)
|
||||
|
||||
|
||||
# Stay in Touch!
|
||||
If you have any questions about the project, ideas or want to share your use-cases, [join our Discord Channel](https://discord.gg/ZMRnFeAWXb)!
|
||||
|
|
|
|||
|
|
@ -1,23 +1,44 @@
|
|||
import esbuild from "esbuild";
|
||||
import process from "process";
|
||||
import builtins from "builtin-modules";
|
||||
import replacePlugin from "esbuild-plugin-replace-regex";
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
const patchStr = `
|
||||
const os = require("os")
|
||||
const arch = os.arch()
|
||||
const platform = os.platform()
|
||||
const libPath = app.vault.adapter.getFullPath(app.vault.configDir)
|
||||
addon = DEFAULT_ADDON || (DEFAULT_ADDON = require(path.resolve(libPath, \`plugins/sqlseal/better_sqlite3-\${platform}-\${arch}.node\`)));
|
||||
`;
|
||||
|
||||
const banner =
|
||||
`/*
|
||||
const banner = `/*
|
||||
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||||
if you want to view the source, please visit the github repository of this plugin
|
||||
*/
|
||||
`;
|
||||
|
||||
const wasmPlugin = {
|
||||
name: 'wasm',
|
||||
setup(build) {
|
||||
// Handle direct importing of wasm files
|
||||
build.onResolve({ filter: /\.wasm$/ }, args => {
|
||||
if (args.resolveDir === '') return;
|
||||
return {
|
||||
path: join(args.resolveDir, args.path),
|
||||
namespace: 'wasm-binary',
|
||||
};
|
||||
});
|
||||
|
||||
// Load and encode the wasm file
|
||||
build.onLoad({ filter: /\.wasm$/, namespace: 'wasm-binary' }, async (args) => {
|
||||
const contents = readFileSync(args.path);
|
||||
const wasmBase64 = contents.toString('base64');
|
||||
|
||||
return {
|
||||
contents: `
|
||||
const wasmBase64 = "${wasmBase64}";
|
||||
const wasmBinary = Uint8Array.from(atob(wasmBase64), c => c.charCodeAt(0));
|
||||
export default wasmBinary;
|
||||
`,
|
||||
loader: 'js',
|
||||
};
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
const prod = (process.argv[2] === "production");
|
||||
|
||||
const context = await esbuild.context({
|
||||
|
|
@ -40,7 +61,8 @@ const context = await esbuild.context({
|
|||
"@lezer/common",
|
||||
"@lezer/highlight",
|
||||
"@lezer/lr",
|
||||
...builtins],
|
||||
...builtins
|
||||
],
|
||||
format: "cjs",
|
||||
target: "es2018",
|
||||
logLevel: "info",
|
||||
|
|
@ -48,12 +70,7 @@ const context = await esbuild.context({
|
|||
treeShaking: true,
|
||||
outfile: "main.js",
|
||||
plugins: [
|
||||
replacePlugin({
|
||||
filter: /.*/,
|
||||
patterns: [
|
||||
[/addon\s=\sDEFAULT_ADDON\s\|\|\s\(DEFAULT_ADDON\s=\srequire.*;/, patchStr]
|
||||
]
|
||||
})
|
||||
wasmPlugin
|
||||
]
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"id": "sqlseal",
|
||||
"name": "SQLSeal",
|
||||
"version": "0.9.2",
|
||||
"version": "0.10.0",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Use SQL in your notes to query your vault files and CSV content.",
|
||||
"author": "hypersphere",
|
||||
"authorUrl": "https://hypersphere.blog/",
|
||||
"fundingUrl": "ko-fi.com/hypersphere",
|
||||
"isDesktopOnly": true
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
9441
package-lock.json
generated
9441
package-lock.json
generated
File diff suppressed because it is too large
Load diff
17
package.json
17
package.json
|
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"name": "sqlseal",
|
||||
"version": "0.9.2",
|
||||
"version": "0.10.0",
|
||||
"description": "A plugin for Obsidian that allows you to run SQL queries on your notes.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"typecheck": "tsc -noEmit -skipLibCheck",
|
||||
"build": " node esbuild.config.mjs production",
|
||||
"build-grammar": "antlr4ts -o src/grammar -Dlanguage=TypeScript -visitor SqlSealLang.g4",
|
||||
"build-grammar": "npx antlr4-tool -o src/grammar --visitor SqlSealLang.g4",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json",
|
||||
"rebuild": "electron-rebuild -f -w better-sqlite3",
|
||||
"docs:dev": "vitepress dev docs",
|
||||
|
|
@ -20,20 +20,20 @@
|
|||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@jest/globals": "^29.7.0",
|
||||
"@types/better-sqlite3": "^7.6.10",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/lodash": "^4.17.7",
|
||||
"@types/node": "^22.5.0",
|
||||
"@types/papaparse": "^5.3.14",
|
||||
"@types/sql.js": "^1.4.9",
|
||||
"@typescript-eslint/eslint-plugin": "5.29.0",
|
||||
"@typescript-eslint/parser": "5.29.0",
|
||||
"antlr4-tool": "^1.1.1",
|
||||
"antlr4ts-cli": "0.5.0-alpha.4",
|
||||
"builtin-modules": "3.3.0",
|
||||
"electron": "^30.0.0",
|
||||
"electron-rebuild": "^3.2.9",
|
||||
"esbuild": "0.17.3",
|
||||
"esbuild-plugin-replace": "^1.4.0",
|
||||
"esbuild-plugin-replace-regex": "^0.0.2",
|
||||
"jest": "^29.7.0",
|
||||
"obsidian": "latest",
|
||||
"prettier": "3.2.5",
|
||||
|
|
@ -46,11 +46,14 @@
|
|||
"dependencies": {
|
||||
"@ag-grid-community/theming": "^32.3.2",
|
||||
"ag-grid-community": "^32.3.2",
|
||||
"antlr4ts": "0.5.0-alpha.4",
|
||||
"better-sqlite3": "^11.2.1",
|
||||
"antlr4": "^4.13.2",
|
||||
"antlr4ts-browser": "0.5.0-alpha.4",
|
||||
"antlr4ts-browser-cli": "0.5.0-alpha.7",
|
||||
"json5": "^2.2.3",
|
||||
"lodash": "^4.17.21",
|
||||
"node-sql-parser": "^5.0.0",
|
||||
"papaparse": "^5.4.1"
|
||||
"papaparse": "^5.4.1",
|
||||
"sql.js": "^1.12.0",
|
||||
"util": "^0.12.5"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
521
pnpm-lock.yaml
521
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -36,10 +36,7 @@ export class SqlSealCodeblockHandler {
|
|||
const frontmatter = resolveFrontmatter(ctx, this.app)
|
||||
const renderSelect = async () => {
|
||||
try {
|
||||
const stmt = this.db.db.prepare(statement)
|
||||
const columns = stmt.columns().map(column => column.name);
|
||||
const data = stmt.all(frontmatter ?? {})
|
||||
|
||||
const { data, columns } = this.db.select(statement, frontmatter ?? {})
|
||||
api.setGridOption('columnDefs', columns.map(c => ({ field: c })))
|
||||
api.setGridOption('rowData', data)
|
||||
api.setGridOption('loading', false)
|
||||
|
|
|
|||
122
src/database.ts
122
src/database.ts
|
|
@ -1,4 +1,3 @@
|
|||
import Database from "better-sqlite3"
|
||||
import { App } from "obsidian"
|
||||
import path from 'path'
|
||||
import Papa from 'papaparse'
|
||||
|
|
@ -8,6 +7,8 @@ import { dataToCamelCase, fetchBlobData, FieldTypes, predictJson, predictType, t
|
|||
import os from 'os'
|
||||
import fs from 'fs'
|
||||
import { sanitise } from "./utils/sanitiseColumn"
|
||||
import initSqlJs, { BindParams, Database, Statement } from 'sql.js'
|
||||
import wasmBinary from '../node_modules/sql.js/dist/sql-wasm.wasm'
|
||||
|
||||
export interface FieldDefinition {
|
||||
name: string;
|
||||
|
|
@ -43,7 +44,8 @@ const formatData = (data: Record<string, any>) => {
|
|||
|
||||
export class SqlSealDatabase {
|
||||
private savedDatabases: Record<string, any> = {}
|
||||
db: Database.Database
|
||||
db: Database
|
||||
private SQL: initSqlJs.SqlJsStatic
|
||||
private isConnected = false
|
||||
private connectingPromise: Promise<void>;
|
||||
private connectingPromiseResolve: (value: void | PromiseLike<void>) => void
|
||||
|
|
@ -51,7 +53,6 @@ export class SqlSealDatabase {
|
|||
|
||||
}
|
||||
|
||||
|
||||
async connect() {
|
||||
if (this.isConnected) {
|
||||
return Promise.resolve()
|
||||
|
|
@ -64,47 +65,24 @@ export class SqlSealDatabase {
|
|||
this.connectingPromise = new Promise((resolve) => {
|
||||
this.connectingPromiseResolve = resolve
|
||||
})
|
||||
//@ts-ignore
|
||||
// const dbPath = normalizePath(this.app.vault.adapter.basePath + '/' + this.app.vault.configDir + '/sqlseal.db')
|
||||
|
||||
const arch = os.arch()
|
||||
const platform = os.platform()
|
||||
const better_sql_version = 'v11.2.1'
|
||||
|
||||
const dbNodeFilePath = path.resolve(this.app.vault.adapter.basePath, this.app.vault.configDir, `plugins/sqlseal/better_sqlite3-${platform}-${arch}.node`)
|
||||
// check if file "better_sqlite3.node" exists in the plugin folder, if not, download it from better sqlite release.
|
||||
try {
|
||||
if (!fs.existsSync(dbNodeFilePath)) {
|
||||
const url = `https://github.com/h-sphere/bettersql3-builds/releases/download/processed-${better_sql_version}/better-sqlite3-${better_sql_version}-electron-v${process.versions.modules}-${platform}-${arch}.node`
|
||||
|
||||
await fetchBlobData(url, dbNodeFilePath)
|
||||
}
|
||||
|
||||
await sleep(500)
|
||||
|
||||
|
||||
const dbPath = path.resolve(this.app.vault.adapter.basePath, this.app.vault.configDir, `plugins/sqlseal/database.sqlite`)
|
||||
|
||||
this.db = new Database(dbPath, { verbose: this.verbose ? console.log : undefined })
|
||||
this.SQL = await initSqlJs({
|
||||
wasmBinary: wasmBinary
|
||||
})
|
||||
|
||||
this.db = new this.SQL.Database()
|
||||
await this.defineCustomFunctions()
|
||||
|
||||
|
||||
|
||||
this.isConnected = true
|
||||
this.connectingPromiseResolve()
|
||||
|
||||
} catch (e) {
|
||||
console.error(`Error while loading SQLSeal. Please reload Obsiidan. If it repeats, please create new issue on GitHub: https://github.com/h-sphere/sql-seal/issues . Please quote following parameters:
|
||||
Architecture: ${arch}
|
||||
Platform: ${platform}
|
||||
Electron Version: ${process.versions.modules}
|
||||
BetterSQLite Version: ${better_sql_version}
|
||||
Error: ${e}
|
||||
`, e)
|
||||
console.error('Error initializing SQLite database:', e)
|
||||
}
|
||||
}
|
||||
|
||||
private async defineCustomFunctions() {
|
||||
this.db.function('a', (href: string, name: string) => {
|
||||
this.db.create_function('a', (href: string, name: string) => {
|
||||
const linkObject = {
|
||||
type: 'link',
|
||||
href: href,
|
||||
|
|
@ -113,7 +91,7 @@ export class SqlSealDatabase {
|
|||
return `SQLSEALCUSTOM(${JSON.stringify(linkObject)})`;
|
||||
});
|
||||
|
||||
this.db.function('a', (href: string) => {
|
||||
this.db.create_function('a', (href: string) => {
|
||||
const linkObject = {
|
||||
type: 'link',
|
||||
href: href,
|
||||
|
|
@ -122,7 +100,7 @@ export class SqlSealDatabase {
|
|||
return `SQLSEALCUSTOM(${JSON.stringify(linkObject)})`;
|
||||
});
|
||||
|
||||
this.db.function('img', (href: string) => {
|
||||
this.db.create_function('img', (href: string) => {
|
||||
const imgObject = {
|
||||
type: 'img',
|
||||
href: href
|
||||
|
|
@ -130,7 +108,7 @@ export class SqlSealDatabase {
|
|||
return `SQLSEALCUSTOM(${JSON.stringify(imgObject)})`
|
||||
})
|
||||
|
||||
this.db.function('img', (href: string, path: string) => {
|
||||
this.db.create_function('img', (href: string, path: string) => {
|
||||
const imgObject = {
|
||||
type: 'img',
|
||||
path,
|
||||
|
|
@ -139,7 +117,7 @@ export class SqlSealDatabase {
|
|||
return `SQLSEALCUSTOM(${JSON.stringify(imgObject)})`
|
||||
})
|
||||
|
||||
this.db.function('checkbox', (val: string) => {
|
||||
this.db.create_function('checkbox', (val: string) => {
|
||||
const imgObject = {
|
||||
type: 'checkbox',
|
||||
value: val
|
||||
|
|
@ -167,7 +145,7 @@ export class SqlSealDatabase {
|
|||
|
||||
async addNewColumns(name: string, data: Array<Record<string, unknown>>) {
|
||||
const schema = await this.getSchema(data)
|
||||
const currentSchema = this.db.prepare(`PRAGMA table_info(${name})`).all()
|
||||
const currentSchema = this.toObjectsArray(this.db.prepare(`PRAGMA table_info(${name})`))
|
||||
const currentFields = currentSchema.map((f: any) => f.name)
|
||||
const newFields = Object.keys(schema).filter(f => !currentFields.includes(f))
|
||||
|
||||
|
|
@ -180,50 +158,43 @@ export class SqlSealDatabase {
|
|||
alter.run()
|
||||
}
|
||||
|
||||
private toObjectsArray(stmt: Statement) {
|
||||
const ret = []
|
||||
while(stmt.step()) {
|
||||
ret.push(stmt.getAsObject())
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
private recordToBindParams(record: Record<string, unknown>) {
|
||||
const bindParams = Object.fromEntries(Object.entries(record).map(([key, val]) => ([`@${key}`, val]))) as BindParams
|
||||
return bindParams
|
||||
}
|
||||
|
||||
updateData(name: string, data: Array<Record<string, unknown>>) {
|
||||
const fields = Object.keys(data.reduce((acc, obj) => ({ ...acc, ...obj }), {}));
|
||||
const update = this.db.prepare(`UPDATE ${name} SET ${fields.map((key: string) => `${key} = @${key}`).join(', ')} WHERE id = @id`);
|
||||
const updateMany = this.db.transaction((pData: Array<Record<string, any>>) => {
|
||||
pData.forEach(data => {
|
||||
try {
|
||||
update.run(formatData(data))
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
data.forEach((d: Record<string, unknown>) => {
|
||||
const stmt = this.db.prepare(`UPDATE ${name} SET ${fields.map((key: string) => `${key} = @${key}`).join(', ')} WHERE id = @id`)
|
||||
stmt.run(this.recordToBindParams(d))
|
||||
})
|
||||
|
||||
return updateMany(data)
|
||||
}
|
||||
|
||||
deleteData(name: string, data: Array<Record<string, unknown>>, key: string = 'id') {
|
||||
|
||||
const deleteStmt = this.db.prepare(`DELETE FROM ${name} WHERE ${key} = @${key}`);
|
||||
const deleteMany = this.db.transaction((pData: Array<Record<string, any>>) => {
|
||||
pData.forEach(data => {
|
||||
try {
|
||||
deleteStmt.run(data)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
})
|
||||
data.forEach(d => {
|
||||
const stmt = this.db.prepare(`DELETE FROM ${name} WHERE ${key} = @${key}`);
|
||||
stmt.run({
|
||||
[`@${key}`]: d[key]
|
||||
} as BindParams)
|
||||
})
|
||||
|
||||
return deleteMany(data)
|
||||
}
|
||||
|
||||
async insertData(name: string, inData: Array<Record<string, unknown>>) {
|
||||
const insertMany = this.db.transaction((pData: Array<Record<string, any>>) => {
|
||||
// FIXME: should we do this as a transaction or not?
|
||||
pData.forEach(data => {
|
||||
const columns = Object.keys(data)
|
||||
const insert = this.db.prepare(`INSERT INTO ${name} (${columns.join(', ')}) VALUES (${columns.map((key: string) => '@' + key).join(', ')})`);
|
||||
const d = formatData(data)
|
||||
insert.run(d)
|
||||
})
|
||||
inData.forEach(d => {
|
||||
const columns = Object.keys(d)
|
||||
const insertStatement = this.db.prepare(`INSERT INTO ${name} (${columns.join(', ')}) VALUES (${columns.map((key: string) => '@' + key).join(', ')})`);
|
||||
insertStatement.run(this.recordToBindParams(formatData(d)))
|
||||
})
|
||||
|
||||
insertMany(inData)
|
||||
}
|
||||
|
||||
dropTable(name: string) {
|
||||
|
|
@ -292,6 +263,15 @@ export class SqlSealDatabase {
|
|||
return name
|
||||
}
|
||||
|
||||
select(statement: string, frontmatter: Record<string, unknown>) {
|
||||
const stmt = this.db.prepare(statement)
|
||||
stmt.bind(this.recordToBindParams(frontmatter ?? {}))
|
||||
return {
|
||||
data: this.toObjectsArray(stmt) as Record<string, any>[],
|
||||
columns: stmt.getColumnNames()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @param unprefixedName
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -53,4 +53,4 @@ mode names:
|
|||
DEFAULT_MODE
|
||||
|
||||
atn:
|
||||
[3, 51485, 51898, 1421, 44986, 20307, 1543, 60043, 49729, 2, 15, 82, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 11, 3, 11, 7, 11, 66, 10, 11, 12, 11, 14, 11, 69, 11, 11, 3, 12, 6, 12, 72, 10, 12, 13, 12, 14, 12, 73, 3, 13, 6, 13, 77, 10, 13, 13, 13, 14, 13, 78, 3, 14, 3, 14, 2, 2, 2, 15, 3, 2, 3, 5, 2, 4, 7, 2, 5, 9, 2, 6, 11, 2, 7, 13, 2, 8, 15, 2, 9, 17, 2, 10, 19, 2, 11, 21, 2, 12, 23, 2, 13, 25, 2, 14, 27, 2, 15, 3, 2, 6, 5, 2, 67, 92, 97, 97, 99, 124, 6, 2, 50, 59, 67, 92, 97, 97, 99, 124, 7, 2, 47, 59, 67, 92, 94, 94, 97, 97, 99, 124, 5, 2, 11, 12, 15, 15, 34, 34, 2, 84, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 3, 29, 3, 2, 2, 2, 5, 31, 3, 2, 2, 2, 7, 33, 3, 2, 2, 2, 9, 35, 3, 2, 2, 2, 11, 37, 3, 2, 2, 2, 13, 43, 3, 2, 2, 2, 15, 48, 3, 2, 2, 2, 17, 53, 3, 2, 2, 2, 19, 56, 3, 2, 2, 2, 21, 63, 3, 2, 2, 2, 23, 71, 3, 2, 2, 2, 25, 76, 3, 2, 2, 2, 27, 80, 3, 2, 2, 2, 29, 30, 7, 63, 2, 2, 30, 4, 3, 2, 2, 2, 31, 32, 7, 42, 2, 2, 32, 6, 3, 2, 2, 2, 33, 34, 7, 43, 2, 2, 34, 8, 3, 2, 2, 2, 35, 36, 7, 46, 2, 2, 36, 10, 3, 2, 2, 2, 37, 38, 7, 86, 2, 2, 38, 39, 7, 67, 2, 2, 39, 40, 7, 68, 2, 2, 40, 41, 7, 78, 2, 2, 41, 42, 7, 71, 2, 2, 42, 12, 3, 2, 2, 2, 43, 44, 7, 104, 2, 2, 44, 45, 7, 107, 2, 2, 45, 46, 7, 110, 2, 2, 46, 47, 7, 103, 2, 2, 47, 14, 3, 2, 2, 2, 48, 49, 7, 89, 2, 2, 49, 50, 7, 75, 2, 2, 50, 51, 7, 86, 2, 2, 51, 52, 7, 74, 2, 2, 52, 16, 3, 2, 2, 2, 53, 54, 7, 67, 2, 2, 54, 55, 7, 85, 2, 2, 55, 18, 3, 2, 2, 2, 56, 57, 7, 85, 2, 2, 57, 58, 7, 71, 2, 2, 58, 59, 7, 78, 2, 2, 59, 60, 7, 71, 2, 2, 60, 61, 7, 69, 2, 2, 61, 62, 7, 86, 2, 2, 62, 20, 3, 2, 2, 2, 63, 67, 9, 2, 2, 2, 64, 66, 9, 3, 2, 2, 65, 64, 3, 2, 2, 2, 66, 69, 3, 2, 2, 2, 67, 65, 3, 2, 2, 2, 67, 68, 3, 2, 2, 2, 68, 22, 3, 2, 2, 2, 69, 67, 3, 2, 2, 2, 70, 72, 9, 4, 2, 2, 71, 70, 3, 2, 2, 2, 72, 73, 3, 2, 2, 2, 73, 71, 3, 2, 2, 2, 73, 74, 3, 2, 2, 2, 74, 24, 3, 2, 2, 2, 75, 77, 9, 5, 2, 2, 76, 75, 3, 2, 2, 2, 77, 78, 3, 2, 2, 2, 78, 76, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 26, 3, 2, 2, 2, 80, 81, 11, 2, 2, 2, 81, 28, 3, 2, 2, 2, 6, 2, 67, 73, 78, 2]
|
||||
[4, 0, 13, 80, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 5, 9, 64, 8, 9, 10, 9, 12, 9, 67, 9, 9, 1, 10, 4, 10, 70, 8, 10, 11, 10, 12, 10, 71, 1, 11, 4, 11, 75, 8, 11, 11, 11, 12, 11, 76, 1, 12, 1, 12, 0, 0, 13, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 1, 0, 4, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 5, 0, 45, 57, 65, 90, 92, 92, 95, 95, 97, 122, 3, 0, 9, 10, 13, 13, 32, 32, 82, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 1, 27, 1, 0, 0, 0, 3, 29, 1, 0, 0, 0, 5, 31, 1, 0, 0, 0, 7, 33, 1, 0, 0, 0, 9, 35, 1, 0, 0, 0, 11, 41, 1, 0, 0, 0, 13, 46, 1, 0, 0, 0, 15, 51, 1, 0, 0, 0, 17, 54, 1, 0, 0, 0, 19, 61, 1, 0, 0, 0, 21, 69, 1, 0, 0, 0, 23, 74, 1, 0, 0, 0, 25, 78, 1, 0, 0, 0, 27, 28, 5, 61, 0, 0, 28, 2, 1, 0, 0, 0, 29, 30, 5, 40, 0, 0, 30, 4, 1, 0, 0, 0, 31, 32, 5, 41, 0, 0, 32, 6, 1, 0, 0, 0, 33, 34, 5, 44, 0, 0, 34, 8, 1, 0, 0, 0, 35, 36, 5, 84, 0, 0, 36, 37, 5, 65, 0, 0, 37, 38, 5, 66, 0, 0, 38, 39, 5, 76, 0, 0, 39, 40, 5, 69, 0, 0, 40, 10, 1, 0, 0, 0, 41, 42, 5, 102, 0, 0, 42, 43, 5, 105, 0, 0, 43, 44, 5, 108, 0, 0, 44, 45, 5, 101, 0, 0, 45, 12, 1, 0, 0, 0, 46, 47, 5, 87, 0, 0, 47, 48, 5, 73, 0, 0, 48, 49, 5, 84, 0, 0, 49, 50, 5, 72, 0, 0, 50, 14, 1, 0, 0, 0, 51, 52, 5, 65, 0, 0, 52, 53, 5, 83, 0, 0, 53, 16, 1, 0, 0, 0, 54, 55, 5, 83, 0, 0, 55, 56, 5, 69, 0, 0, 56, 57, 5, 76, 0, 0, 57, 58, 5, 69, 0, 0, 58, 59, 5, 67, 0, 0, 59, 60, 5, 84, 0, 0, 60, 18, 1, 0, 0, 0, 61, 65, 7, 0, 0, 0, 62, 64, 7, 1, 0, 0, 63, 62, 1, 0, 0, 0, 64, 67, 1, 0, 0, 0, 65, 63, 1, 0, 0, 0, 65, 66, 1, 0, 0, 0, 66, 20, 1, 0, 0, 0, 67, 65, 1, 0, 0, 0, 68, 70, 7, 2, 0, 0, 69, 68, 1, 0, 0, 0, 70, 71, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 71, 72, 1, 0, 0, 0, 72, 22, 1, 0, 0, 0, 73, 75, 7, 3, 0, 0, 74, 73, 1, 0, 0, 0, 75, 76, 1, 0, 0, 0, 76, 74, 1, 0, 0, 0, 76, 77, 1, 0, 0, 0, 77, 24, 1, 0, 0, 0, 78, 79, 9, 0, 0, 0, 79, 26, 1, 0, 0, 0, 4, 0, 65, 71, 76, 0]
|
||||
|
|
@ -1,21 +1,17 @@
|
|||
// Generated from SqlSealLang.g4 by ANTLR 4.9.0-SNAPSHOT
|
||||
|
||||
|
||||
import { ATN } from "antlr4ts/atn/ATN";
|
||||
import { ATNDeserializer } from "antlr4ts/atn/ATNDeserializer";
|
||||
import { CharStream } from "antlr4ts/CharStream";
|
||||
import { Lexer } from "antlr4ts/Lexer";
|
||||
import { LexerATNSimulator } from "antlr4ts/atn/LexerATNSimulator";
|
||||
import { NotNull } from "antlr4ts/Decorators";
|
||||
import { Override } from "antlr4ts/Decorators";
|
||||
import { RuleContext } from "antlr4ts/RuleContext";
|
||||
import { Vocabulary } from "antlr4ts/Vocabulary";
|
||||
import { VocabularyImpl } from "antlr4ts/VocabularyImpl";
|
||||
|
||||
import * as Utils from "antlr4ts/misc/Utils";
|
||||
|
||||
|
||||
export class SqlSealLangLexer extends Lexer {
|
||||
// Generated from SqlSealLang.g4 by ANTLR 4.13.2
|
||||
// noinspection ES6UnusedImports,JSUnusedGlobalSymbols,JSUnusedLocalSymbols
|
||||
import {
|
||||
ATN,
|
||||
ATNDeserializer,
|
||||
CharStream,
|
||||
DecisionState, DFA,
|
||||
Lexer,
|
||||
LexerATNSimulator,
|
||||
RuleContext,
|
||||
PredictionContextCache,
|
||||
Token
|
||||
} from "antlr4";
|
||||
export default class SqlSealLangLexer extends Lexer {
|
||||
public static readonly T__0 = 1;
|
||||
public static readonly T__1 = 2;
|
||||
public static readonly T__2 = 3;
|
||||
|
|
@ -29,103 +25,81 @@ export class SqlSealLangLexer extends Lexer {
|
|||
public static readonly FILE_URL = 11;
|
||||
public static readonly WS = 12;
|
||||
public static readonly ANY = 13;
|
||||
public static readonly EOF = Token.EOF;
|
||||
|
||||
// tslint:disable:no-trailing-whitespace
|
||||
public static readonly channelNames: string[] = [
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
|
||||
];
|
||||
|
||||
// tslint:disable:no-trailing-whitespace
|
||||
public static readonly modeNames: string[] = [
|
||||
"DEFAULT_MODE",
|
||||
];
|
||||
public static readonly channelNames: string[] = [ "DEFAULT_TOKEN_CHANNEL", "HIDDEN" ];
|
||||
public static readonly literalNames: (string | null)[] = [ null, "'='",
|
||||
"'('", "')'",
|
||||
"','", "'TABLE'",
|
||||
"'file'", "'WITH'",
|
||||
"'AS'", "'SELECT'" ];
|
||||
public static readonly symbolicNames: (string | null)[] = [ null, null,
|
||||
null, null,
|
||||
null, "TABLE",
|
||||
"FILE", "WITH",
|
||||
"AS", "SELECT",
|
||||
"ID", "FILE_URL",
|
||||
"WS", "ANY" ];
|
||||
public static readonly modeNames: string[] = [ "DEFAULT_MODE", ];
|
||||
|
||||
public static readonly ruleNames: string[] = [
|
||||
"T__0", "T__1", "T__2", "T__3", "TABLE", "FILE", "WITH", "AS", "SELECT",
|
||||
"ID", "FILE_URL", "WS", "ANY",
|
||||
];
|
||||
|
||||
private static readonly _LITERAL_NAMES: Array<string | undefined> = [
|
||||
undefined, "'='", "'('", "')'", "','", "'TABLE'", "'file'", "'WITH'",
|
||||
"'AS'", "'SELECT'",
|
||||
];
|
||||
private static readonly _SYMBOLIC_NAMES: Array<string | undefined> = [
|
||||
undefined, undefined, undefined, undefined, undefined, "TABLE", "FILE",
|
||||
"WITH", "AS", "SELECT", "ID", "FILE_URL", "WS", "ANY",
|
||||
];
|
||||
public static readonly VOCABULARY: Vocabulary = new VocabularyImpl(SqlSealLangLexer._LITERAL_NAMES, SqlSealLangLexer._SYMBOLIC_NAMES, []);
|
||||
|
||||
// @Override
|
||||
// @NotNull
|
||||
public get vocabulary(): Vocabulary {
|
||||
return SqlSealLangLexer.VOCABULARY;
|
||||
}
|
||||
// tslint:enable:no-trailing-whitespace
|
||||
|
||||
|
||||
constructor(input: CharStream) {
|
||||
super(input);
|
||||
this._interp = new LexerATNSimulator(SqlSealLangLexer._ATN, this);
|
||||
this._interp = new LexerATNSimulator(this, SqlSealLangLexer._ATN, SqlSealLangLexer.DecisionsToDFA, new PredictionContextCache());
|
||||
}
|
||||
|
||||
// @Override
|
||||
public get grammarFileName(): string { return "SqlSealLang.g4"; }
|
||||
|
||||
// @Override
|
||||
public get literalNames(): (string | null)[] { return SqlSealLangLexer.literalNames; }
|
||||
public get symbolicNames(): (string | null)[] { return SqlSealLangLexer.symbolicNames; }
|
||||
public get ruleNames(): string[] { return SqlSealLangLexer.ruleNames; }
|
||||
|
||||
// @Override
|
||||
public get serializedATN(): string { return SqlSealLangLexer._serializedATN; }
|
||||
public get serializedATN(): number[] { return SqlSealLangLexer._serializedATN; }
|
||||
|
||||
// @Override
|
||||
public get channelNames(): string[] { return SqlSealLangLexer.channelNames; }
|
||||
|
||||
// @Override
|
||||
public get modeNames(): string[] { return SqlSealLangLexer.modeNames; }
|
||||
|
||||
public static readonly _serializedATN: string =
|
||||
"\x03\uC91D\uCABA\u058D\uAFBA\u4F53\u0607\uEA8B\uC241\x02\x0FR\b\x01\x04" +
|
||||
"\x02\t\x02\x04\x03\t\x03\x04\x04\t\x04\x04\x05\t\x05\x04\x06\t\x06\x04" +
|
||||
"\x07\t\x07\x04\b\t\b\x04\t\t\t\x04\n\t\n\x04\v\t\v\x04\f\t\f\x04\r\t\r" +
|
||||
"\x04\x0E\t\x0E\x03\x02\x03\x02\x03\x03\x03\x03\x03\x04\x03\x04\x03\x05" +
|
||||
"\x03\x05\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x06\x03\x07\x03\x07" +
|
||||
"\x03\x07\x03\x07\x03\x07\x03\b\x03\b\x03\b\x03\b\x03\b\x03\t\x03\t\x03" +
|
||||
"\t\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\n\x03\v\x03\v\x07\vB\n\v\f" +
|
||||
"\v\x0E\vE\v\v\x03\f\x06\fH\n\f\r\f\x0E\fI\x03\r\x06\rM\n\r\r\r\x0E\rN" +
|
||||
"\x03\x0E\x03\x0E\x02\x02\x02\x0F\x03\x02\x03\x05\x02\x04\x07\x02\x05\t" +
|
||||
"\x02\x06\v\x02\x07\r\x02\b\x0F\x02\t\x11\x02\n\x13\x02\v\x15\x02\f\x17" +
|
||||
"\x02\r\x19\x02\x0E\x1B\x02\x0F\x03\x02\x06\x05\x02C\\aac|\x06\x022;C\\" +
|
||||
"aac|\x07\x02/;C\\^^aac|\x05\x02\v\f\x0F\x0F\"\"\x02T\x02\x03\x03\x02\x02" +
|
||||
"\x02\x02\x05\x03\x02\x02\x02\x02\x07\x03\x02\x02\x02\x02\t\x03\x02\x02" +
|
||||
"\x02\x02\v\x03\x02\x02\x02\x02\r\x03\x02\x02\x02\x02\x0F\x03\x02\x02\x02" +
|
||||
"\x02\x11\x03\x02\x02\x02\x02\x13\x03\x02\x02\x02\x02\x15\x03\x02\x02\x02" +
|
||||
"\x02\x17\x03\x02\x02\x02\x02\x19\x03\x02\x02\x02\x02\x1B\x03\x02\x02\x02" +
|
||||
"\x03\x1D\x03\x02\x02\x02\x05\x1F\x03\x02\x02\x02\x07!\x03\x02\x02\x02" +
|
||||
"\t#\x03\x02\x02\x02\v%\x03\x02\x02\x02\r+\x03\x02\x02\x02\x0F0\x03\x02" +
|
||||
"\x02\x02\x115\x03\x02\x02\x02\x138\x03\x02\x02\x02\x15?\x03\x02\x02\x02" +
|
||||
"\x17G\x03\x02\x02\x02\x19L\x03\x02\x02\x02\x1BP\x03\x02\x02\x02\x1D\x1E" +
|
||||
"\x07?\x02\x02\x1E\x04\x03\x02\x02\x02\x1F \x07*\x02\x02 \x06\x03\x02\x02" +
|
||||
"\x02!\"\x07+\x02\x02\"\b\x03\x02\x02\x02#$\x07.\x02\x02$\n\x03\x02\x02" +
|
||||
"\x02%&\x07V\x02\x02&\'\x07C\x02\x02\'(\x07D\x02\x02()\x07N\x02\x02)*\x07" +
|
||||
"G\x02\x02*\f\x03\x02\x02\x02+,\x07h\x02\x02,-\x07k\x02\x02-.\x07n\x02" +
|
||||
"\x02./\x07g\x02\x02/\x0E\x03\x02\x02\x0201\x07Y\x02\x0212\x07K\x02\x02" +
|
||||
"23\x07V\x02\x0234\x07J\x02\x024\x10\x03\x02\x02\x0256\x07C\x02\x0267\x07" +
|
||||
"U\x02\x027\x12\x03\x02\x02\x0289\x07U\x02\x029:\x07G\x02\x02:;\x07N\x02" +
|
||||
"\x02;<\x07G\x02\x02<=\x07E\x02\x02=>\x07V\x02\x02>\x14\x03\x02\x02\x02" +
|
||||
"?C\t\x02\x02\x02@B\t\x03\x02\x02A@\x03\x02\x02\x02BE\x03\x02\x02\x02C" +
|
||||
"A\x03\x02\x02\x02CD\x03\x02\x02\x02D\x16\x03\x02\x02\x02EC\x03\x02\x02" +
|
||||
"\x02FH\t\x04\x02\x02GF\x03\x02\x02\x02HI\x03\x02\x02\x02IG\x03\x02\x02" +
|
||||
"\x02IJ\x03\x02\x02\x02J\x18\x03\x02\x02\x02KM\t\x05\x02\x02LK\x03\x02" +
|
||||
"\x02\x02MN\x03\x02\x02\x02NL\x03\x02\x02\x02NO\x03\x02\x02\x02O\x1A\x03" +
|
||||
"\x02\x02\x02PQ\v\x02\x02\x02Q\x1C\x03\x02\x02\x02\x06\x02CIN\x02";
|
||||
public static __ATN: ATN;
|
||||
public static readonly _serializedATN: number[] = [4,0,13,80,6,-1,2,0,7,
|
||||
0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,
|
||||
9,2,10,7,10,2,11,7,11,2,12,7,12,1,0,1,0,1,1,1,1,1,2,1,2,1,3,1,3,1,4,1,4,
|
||||
1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,8,
|
||||
1,8,1,8,1,8,1,8,1,8,1,8,1,9,1,9,5,9,64,8,9,10,9,12,9,67,9,9,1,10,4,10,70,
|
||||
8,10,11,10,12,10,71,1,11,4,11,75,8,11,11,11,12,11,76,1,12,1,12,0,0,13,1,
|
||||
1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,1,0,4,3,0,
|
||||
65,90,95,95,97,122,4,0,48,57,65,90,95,95,97,122,5,0,45,57,65,90,92,92,95,
|
||||
95,97,122,3,0,9,10,13,13,32,32,82,0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,
|
||||
7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,
|
||||
0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,1,27,1,0,0,0,3,29,
|
||||
1,0,0,0,5,31,1,0,0,0,7,33,1,0,0,0,9,35,1,0,0,0,11,41,1,0,0,0,13,46,1,0,
|
||||
0,0,15,51,1,0,0,0,17,54,1,0,0,0,19,61,1,0,0,0,21,69,1,0,0,0,23,74,1,0,0,
|
||||
0,25,78,1,0,0,0,27,28,5,61,0,0,28,2,1,0,0,0,29,30,5,40,0,0,30,4,1,0,0,0,
|
||||
31,32,5,41,0,0,32,6,1,0,0,0,33,34,5,44,0,0,34,8,1,0,0,0,35,36,5,84,0,0,
|
||||
36,37,5,65,0,0,37,38,5,66,0,0,38,39,5,76,0,0,39,40,5,69,0,0,40,10,1,0,0,
|
||||
0,41,42,5,102,0,0,42,43,5,105,0,0,43,44,5,108,0,0,44,45,5,101,0,0,45,12,
|
||||
1,0,0,0,46,47,5,87,0,0,47,48,5,73,0,0,48,49,5,84,0,0,49,50,5,72,0,0,50,
|
||||
14,1,0,0,0,51,52,5,65,0,0,52,53,5,83,0,0,53,16,1,0,0,0,54,55,5,83,0,0,55,
|
||||
56,5,69,0,0,56,57,5,76,0,0,57,58,5,69,0,0,58,59,5,67,0,0,59,60,5,84,0,0,
|
||||
60,18,1,0,0,0,61,65,7,0,0,0,62,64,7,1,0,0,63,62,1,0,0,0,64,67,1,0,0,0,65,
|
||||
63,1,0,0,0,65,66,1,0,0,0,66,20,1,0,0,0,67,65,1,0,0,0,68,70,7,2,0,0,69,68,
|
||||
1,0,0,0,70,71,1,0,0,0,71,69,1,0,0,0,71,72,1,0,0,0,72,22,1,0,0,0,73,75,7,
|
||||
3,0,0,74,73,1,0,0,0,75,76,1,0,0,0,76,74,1,0,0,0,76,77,1,0,0,0,77,24,1,0,
|
||||
0,0,78,79,9,0,0,0,79,26,1,0,0,0,4,0,65,71,76,0];
|
||||
|
||||
private static __ATN: ATN;
|
||||
public static get _ATN(): ATN {
|
||||
if (!SqlSealLangLexer.__ATN) {
|
||||
SqlSealLangLexer.__ATN = new ATNDeserializer().deserialize(Utils.toCharArray(SqlSealLangLexer._serializedATN));
|
||||
SqlSealLangLexer.__ATN = new ATNDeserializer().deserialize(SqlSealLangLexer._serializedATN);
|
||||
}
|
||||
|
||||
return SqlSealLangLexer.__ATN;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static DecisionsToDFA = SqlSealLangLexer._ATN.decisionToState.map( (ds: DecisionState, index: number) => new DFA(ds, index) );
|
||||
}
|
||||
|
|
@ -1,23 +1,23 @@
|
|||
// Generated from SqlSealLang.g4 by ANTLR 4.9.0-SNAPSHOT
|
||||
// Generated from SqlSealLang.g4 by ANTLR 4.13.2
|
||||
|
||||
import {ParseTreeListener} from "antlr4";
|
||||
|
||||
|
||||
import { ParseTreeListener } from "antlr4ts/tree/ParseTreeListener";
|
||||
|
||||
import { ParseContext } from "./SqlSealLangParser";
|
||||
import { StatementContext } from "./SqlSealLangParser";
|
||||
import { TableStatementContext } from "./SqlSealLangParser";
|
||||
import { QueryStatementContext } from "./SqlSealLangParser";
|
||||
import { WithClauseContext } from "./SqlSealLangParser";
|
||||
import { CteDefinitionContext } from "./SqlSealLangParser";
|
||||
import { SelectStatementContext } from "./SqlSealLangParser";
|
||||
import { SelectBodyContext } from "./SqlSealLangParser";
|
||||
import { ParseContext } from "./SqlSealLangParser.js";
|
||||
import { StatementContext } from "./SqlSealLangParser.js";
|
||||
import { TableStatementContext } from "./SqlSealLangParser.js";
|
||||
import { QueryStatementContext } from "./SqlSealLangParser.js";
|
||||
import { WithClauseContext } from "./SqlSealLangParser.js";
|
||||
import { CteDefinitionContext } from "./SqlSealLangParser.js";
|
||||
import { SelectStatementContext } from "./SqlSealLangParser.js";
|
||||
import { SelectBodyContext } from "./SqlSealLangParser.js";
|
||||
|
||||
|
||||
/**
|
||||
* This interface defines a complete listener for a parse tree produced by
|
||||
* `SqlSealLangParser`.
|
||||
*/
|
||||
export interface SqlSealLangListener extends ParseTreeListener {
|
||||
export default class SqlSealLangListener extends ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.parse`.
|
||||
* @param ctx the parse tree
|
||||
|
|
@ -28,7 +28,6 @@ export interface SqlSealLangListener extends ParseTreeListener {
|
|||
* @param ctx the parse tree
|
||||
*/
|
||||
exitParse?: (ctx: ParseContext) => void;
|
||||
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.statement`.
|
||||
* @param ctx the parse tree
|
||||
|
|
@ -39,7 +38,6 @@ export interface SqlSealLangListener extends ParseTreeListener {
|
|||
* @param ctx the parse tree
|
||||
*/
|
||||
exitStatement?: (ctx: StatementContext) => void;
|
||||
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.tableStatement`.
|
||||
* @param ctx the parse tree
|
||||
|
|
@ -50,7 +48,6 @@ export interface SqlSealLangListener extends ParseTreeListener {
|
|||
* @param ctx the parse tree
|
||||
*/
|
||||
exitTableStatement?: (ctx: TableStatementContext) => void;
|
||||
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.queryStatement`.
|
||||
* @param ctx the parse tree
|
||||
|
|
@ -61,7 +58,6 @@ export interface SqlSealLangListener extends ParseTreeListener {
|
|||
* @param ctx the parse tree
|
||||
*/
|
||||
exitQueryStatement?: (ctx: QueryStatementContext) => void;
|
||||
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.withClause`.
|
||||
* @param ctx the parse tree
|
||||
|
|
@ -72,7 +68,6 @@ export interface SqlSealLangListener extends ParseTreeListener {
|
|||
* @param ctx the parse tree
|
||||
*/
|
||||
exitWithClause?: (ctx: WithClauseContext) => void;
|
||||
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.cteDefinition`.
|
||||
* @param ctx the parse tree
|
||||
|
|
@ -83,7 +78,6 @@ export interface SqlSealLangListener extends ParseTreeListener {
|
|||
* @param ctx the parse tree
|
||||
*/
|
||||
exitCteDefinition?: (ctx: CteDefinitionContext) => void;
|
||||
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.selectStatement`.
|
||||
* @param ctx the parse tree
|
||||
|
|
@ -94,7 +88,6 @@ export interface SqlSealLangListener extends ParseTreeListener {
|
|||
* @param ctx the parse tree
|
||||
*/
|
||||
exitSelectStatement?: (ctx: SelectStatementContext) => void;
|
||||
|
||||
/**
|
||||
* Enter a parse tree produced by `SqlSealLangParser.selectBody`.
|
||||
* @param ctx the parse tree
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +1,16 @@
|
|||
// Generated from SqlSealLang.g4 by ANTLR 4.9.0-SNAPSHOT
|
||||
// Generated from SqlSealLang.g4 by ANTLR 4.13.2
|
||||
|
||||
import {ParseTreeVisitor} from 'antlr4';
|
||||
|
||||
|
||||
import { ParseTreeVisitor } from "antlr4ts/tree/ParseTreeVisitor";
|
||||
|
||||
import { ParseContext } from "./SqlSealLangParser";
|
||||
import { StatementContext } from "./SqlSealLangParser";
|
||||
import { TableStatementContext } from "./SqlSealLangParser";
|
||||
import { QueryStatementContext } from "./SqlSealLangParser";
|
||||
import { WithClauseContext } from "./SqlSealLangParser";
|
||||
import { CteDefinitionContext } from "./SqlSealLangParser";
|
||||
import { SelectStatementContext } from "./SqlSealLangParser";
|
||||
import { SelectBodyContext } from "./SqlSealLangParser";
|
||||
import { ParseContext } from "./SqlSealLangParser.js";
|
||||
import { StatementContext } from "./SqlSealLangParser.js";
|
||||
import { TableStatementContext } from "./SqlSealLangParser.js";
|
||||
import { QueryStatementContext } from "./SqlSealLangParser.js";
|
||||
import { WithClauseContext } from "./SqlSealLangParser.js";
|
||||
import { CteDefinitionContext } from "./SqlSealLangParser.js";
|
||||
import { SelectStatementContext } from "./SqlSealLangParser.js";
|
||||
import { SelectBodyContext } from "./SqlSealLangParser.js";
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -20,56 +20,49 @@ import { SelectBodyContext } from "./SqlSealLangParser";
|
|||
* @param <Result> The return type of the visit operation. Use `void` for
|
||||
* operations with no return type.
|
||||
*/
|
||||
export interface SqlSealLangVisitor<Result> extends ParseTreeVisitor<Result> {
|
||||
export default class SqlSealLangVisitor<Result> extends ParseTreeVisitor<Result> {
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.parse`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitParse?: (ctx: ParseContext) => Result;
|
||||
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.statement`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitStatement?: (ctx: StatementContext) => Result;
|
||||
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.tableStatement`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitTableStatement?: (ctx: TableStatementContext) => Result;
|
||||
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.queryStatement`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitQueryStatement?: (ctx: QueryStatementContext) => Result;
|
||||
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.withClause`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitWithClause?: (ctx: WithClauseContext) => Result;
|
||||
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.cteDefinition`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitCteDefinition?: (ctx: CteDefinitionContext) => Result;
|
||||
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.selectStatement`.
|
||||
* @param ctx the parse tree
|
||||
* @return the visitor result
|
||||
*/
|
||||
visitSelectStatement?: (ctx: SelectStatementContext) => Result;
|
||||
|
||||
/**
|
||||
* Visit a parse tree produced by `SqlSealLangParser.selectBody`.
|
||||
* @param ctx the parse tree
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import { ANTLRErrorListener, CharStreams, CommonTokenStream, RecognitionException, Recognizer } from 'antlr4ts';
|
||||
import { SqlSealLangLexer } from './SqlSealLangLexer';
|
||||
import { QueryStatementContext, TableStatementContext, SqlSealLangParser, ParseContext, StatementContext, WithClauseContext, SelectStatementContext } from './SqlSealLangParser';
|
||||
import { SqlSealLangVisitor } from './SqlSealLangVisitor';
|
||||
import { AbstractParseTreeVisitor } from 'antlr4ts/tree/AbstractParseTreeVisitor';
|
||||
import { CommonTokenStream, ErrorListener, ParseTreeVisitor, RecognitionException } from 'antlr4';
|
||||
import SqlSealLangLexer from './SqlSealLangLexer';
|
||||
import { QueryStatementContext, TableStatementContext, ParseContext, StatementContext, WithClauseContext, SelectStatementContext } from './SqlSealLangParser';
|
||||
import SqlSealLangParser from './SqlSealLangParser';
|
||||
import SqlSealLangVisitor from './SqlSealLangVisitor';
|
||||
import { CharStream, TokenStream } from 'antlr4';
|
||||
|
||||
export interface TableStatement {
|
||||
name: string;
|
||||
|
|
@ -17,10 +18,10 @@ export interface ParsedLanguage {
|
|||
}
|
||||
|
||||
|
||||
class ErrorListener implements ANTLRErrorListener<any> {
|
||||
class SQLSealErrorListener extends ErrorListener<any> {
|
||||
private errors: string[] = [];
|
||||
|
||||
syntaxError(recognizer: Recognizer<any, any>, offendingSymbol: any, line: number, charPositionInLine: number, msg: string, e: RecognitionException | undefined): void {
|
||||
syntaxError(recognizer: any, offendingSymbol: any, line: number, charPositionInLine: number, msg: string, e: RecognitionException | undefined): void {
|
||||
this.errors.push(`Line ${line}:${charPositionInLine} ${msg}`);
|
||||
}
|
||||
|
||||
|
|
@ -31,9 +32,13 @@ class ErrorListener implements ANTLRErrorListener<any> {
|
|||
getErrors(): string {
|
||||
return this.errors.join('\n');
|
||||
}
|
||||
|
||||
reportAttemtpingFullContext() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class SqlSealLangVisitorImpl extends AbstractParseTreeVisitor<ParsedLanguage> implements SqlSealLangVisitor<ParsedLanguage> {
|
||||
export class SqlSealLangVisitorImpl extends ParseTreeVisitor<ParsedLanguage> implements SqlSealLangVisitor<ParsedLanguage> {
|
||||
private tables: TableStatement[] = [];
|
||||
private queryPart: string | null = null;
|
||||
|
||||
|
|
@ -42,7 +47,7 @@ export class SqlSealLangVisitorImpl extends AbstractParseTreeVisitor<ParsedLangu
|
|||
}
|
||||
|
||||
visitParse(ctx: ParseContext): ParsedLanguage {
|
||||
ctx.statement().forEach(stmt => this.visit(stmt));
|
||||
ctx.statement_list().forEach(stmt => this.visit(stmt));
|
||||
return this.defaultResult();
|
||||
}
|
||||
|
||||
|
|
@ -56,11 +61,11 @@ export class SqlSealLangVisitorImpl extends AbstractParseTreeVisitor<ParsedLangu
|
|||
}
|
||||
|
||||
visitTableStatement(ctx: TableStatementContext): ParsedLanguage {
|
||||
const tableName = ctx.ID().text;
|
||||
const fileUrl = ctx.FILE_URL().text;
|
||||
const tableName = ctx.ID().getText();
|
||||
const fileUrl = ctx.FILE_URL().getText();
|
||||
|
||||
// Reconstruct the original table statement with whitespace
|
||||
const tableStmt = ctx.children!.map(child => child.text).join('');
|
||||
const tableStmt = ctx.children!.map(child => child.getText()).join('');
|
||||
|
||||
this.tables.push({
|
||||
name: tableName,
|
||||
|
|
@ -73,7 +78,7 @@ export class SqlSealLangVisitorImpl extends AbstractParseTreeVisitor<ParsedLangu
|
|||
|
||||
visitQueryStatement(ctx: QueryStatementContext): ParsedLanguage {
|
||||
// Reconstruct the original query statement with whitespace and all characters
|
||||
this.queryPart = ctx.children!.map(child => child.text).join('');
|
||||
this.queryPart = ctx.children!.map(child => child.getText()).join('');
|
||||
return this.defaultResult();
|
||||
}
|
||||
|
||||
|
|
@ -89,12 +94,16 @@ export class SqlSealLangVisitorImpl extends AbstractParseTreeVisitor<ParsedLangu
|
|||
}
|
||||
|
||||
export function parseLanguage(input: string): ParsedLanguage {
|
||||
const chars = CharStreams.fromString(input);
|
||||
const lexer = new SqlSealLangLexer(chars);
|
||||
const chars = new CharStream(input); // replace this with a FileStream as required
|
||||
// const lexer = new MyGrammarLexer(chars);
|
||||
// const tokens = new CommonTokenStream(lexer);
|
||||
// const parser = new MyGrammarParser(tokens);
|
||||
|
||||
const lexer = new SqlSealLangLexer(new CharStream(input));
|
||||
const tokens = new CommonTokenStream(lexer);
|
||||
const parser = new SqlSealLangParser(tokens);
|
||||
|
||||
const errorListener = new ErrorListener();
|
||||
const errorListener = new SQLSealErrorListener();
|
||||
parser.removeErrorListeners();
|
||||
parser.addErrorListener(errorListener);
|
||||
|
||||
|
|
|
|||
|
|
@ -38,15 +38,14 @@ export class SyncModel {
|
|||
}
|
||||
|
||||
getSync(filename: string, tableName: string) {
|
||||
const data = this.db.db.prepare(`
|
||||
SELECT *
|
||||
const { data } = this.db.select(`SELECT *
|
||||
FROM sqlseal_sync
|
||||
WHERE filename = @filename
|
||||
AND name = @name
|
||||
`).all({
|
||||
filename: filename,
|
||||
name: tableName,
|
||||
})
|
||||
AND name = @name`,
|
||||
{
|
||||
name: tableName,
|
||||
filename: filename
|
||||
})
|
||||
|
||||
if (data) {
|
||||
return data[0] as SyncEntry
|
||||
|
|
@ -55,6 +54,7 @@ export class SyncModel {
|
|||
}
|
||||
|
||||
removeSync(filename: string, tableName: string) {
|
||||
// FIXME: do not use exposed db, instead implement "exec" method inside the file.
|
||||
this.db.db.prepare('DELETE FROM sqlseal_sync WHERE filename = :filename AND name = :name').run({
|
||||
filename: filename,
|
||||
name: tableName
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
"allowJs": true,
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"importHelpers": false,
|
||||
"isolatedModules": true,
|
||||
"skipLibCheck": true,
|
||||
"types": [],
|
||||
|
|
|
|||
|
|
@ -10,5 +10,6 @@
|
|||
"0.8.0": "0.15.0",
|
||||
"0.9.0": "0.15.0",
|
||||
"0.9.1": "0.15.0",
|
||||
"0.9.2": "0.15.0"
|
||||
"0.9.2": "0.15.0",
|
||||
"0.10.0": "0.15.0"
|
||||
}
|
||||
Loading…
Reference in a new issue