First version of schema generation for ms-sql, able to retrieve basic tables and rows.
This commit is contained in:
parent
09d83dea39
commit
5e846ac64d
|
@ -6,10 +6,18 @@ import {
|
||||||
SqlQuery,
|
SqlQuery,
|
||||||
} from "../definitions/datasource"
|
} from "../definitions/datasource"
|
||||||
import { getSqlQuery } from "./utils"
|
import { getSqlQuery } from "./utils"
|
||||||
|
import { DatasourcePlus } from "./base/datasourcePlus"
|
||||||
|
import { Table, TableSchema } from "../definitions/common";
|
||||||
|
|
||||||
module MSSQLModule {
|
module MSSQLModule {
|
||||||
const sqlServer = require("mssql")
|
const sqlServer = require("mssql")
|
||||||
const Sql = require("./base/sql")
|
const Sql = require("./base/sql")
|
||||||
|
const { FieldTypes } = require("../constants")
|
||||||
|
const {
|
||||||
|
buildExternalTableId,
|
||||||
|
convertType,
|
||||||
|
finaliseExternalTables,
|
||||||
|
} = require("./utils")
|
||||||
|
|
||||||
interface MSSQLConfig {
|
interface MSSQLConfig {
|
||||||
user: string
|
user: string
|
||||||
|
@ -22,6 +30,7 @@ module MSSQLModule {
|
||||||
|
|
||||||
const SCHEMA: Integration = {
|
const SCHEMA: Integration = {
|
||||||
docs: "https://github.com/tediousjs/node-mssql",
|
docs: "https://github.com/tediousjs/node-mssql",
|
||||||
|
plus: true,
|
||||||
description:
|
description:
|
||||||
"Microsoft SQL Server is a relational database management system developed by Microsoft. ",
|
"Microsoft SQL Server is a relational database management system developed by Microsoft. ",
|
||||||
friendlyName: "MS SQL Server",
|
friendlyName: "MS SQL Server",
|
||||||
|
@ -69,18 +78,66 @@ module MSSQLModule {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: need to update this
|
||||||
|
const TYPE_MAP = {
|
||||||
|
text: FieldTypes.LONGFORM,
|
||||||
|
blob: FieldTypes.LONGFORM,
|
||||||
|
enum: FieldTypes.STRING,
|
||||||
|
varchar: FieldTypes.STRING,
|
||||||
|
float: FieldTypes.NUMBER,
|
||||||
|
int: FieldTypes.NUMBER,
|
||||||
|
numeric: FieldTypes.NUMBER,
|
||||||
|
bigint: FieldTypes.NUMBER,
|
||||||
|
mediumint: FieldTypes.NUMBER,
|
||||||
|
decimal: FieldTypes.NUMBER,
|
||||||
|
dec: FieldTypes.NUMBER,
|
||||||
|
double: FieldTypes.NUMBER,
|
||||||
|
real: FieldTypes.NUMBER,
|
||||||
|
fixed: FieldTypes.NUMBER,
|
||||||
|
smallint: FieldTypes.NUMBER,
|
||||||
|
timestamp: FieldTypes.DATETIME,
|
||||||
|
date: FieldTypes.DATETIME,
|
||||||
|
datetime: FieldTypes.DATETIME,
|
||||||
|
time: FieldTypes.DATETIME,
|
||||||
|
tinyint: FieldTypes.BOOLEAN,
|
||||||
|
json: DatasourceFieldTypes.JSON,
|
||||||
|
}
|
||||||
|
|
||||||
async function internalQuery(client: any, query: SqlQuery) {
|
async function internalQuery(client: any, query: SqlQuery) {
|
||||||
try {
|
try {
|
||||||
return await client.query(query.sql, query.bindings || {})
|
if (Array.isArray(query.bindings)) {
|
||||||
|
let count = 0
|
||||||
|
for (let binding of query.bindings) {
|
||||||
|
client.input(`p${count++}`, binding)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return await client.query(query.sql)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
throw new Error(err)
|
throw new Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SqlServerIntegration extends Sql {
|
class SqlServerIntegration extends Sql implements DatasourcePlus {
|
||||||
private readonly config: MSSQLConfig
|
private readonly config: MSSQLConfig
|
||||||
static pool: any
|
static pool: any
|
||||||
|
public tables: Record<string, Table> = {}
|
||||||
|
public schemaErrors: Record<string, string> = {}
|
||||||
|
|
||||||
|
MASTER_TABLES = [
|
||||||
|
"spt_fallback_db",
|
||||||
|
"spt_fallback_dev",
|
||||||
|
"spt_fallback_usg",
|
||||||
|
"spt_monitor",
|
||||||
|
"MSreplication_options"
|
||||||
|
]
|
||||||
|
TABLES_SQL = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'"
|
||||||
|
|
||||||
|
getDefinitionSQL(tableName: string) {
|
||||||
|
return `select *
|
||||||
|
from INFORMATION_SCHEMA.COLUMNS
|
||||||
|
where TABLE_NAME='${tableName}'`
|
||||||
|
}
|
||||||
|
|
||||||
constructor(config: MSSQLConfig) {
|
constructor(config: MSSQLConfig) {
|
||||||
super("mssql")
|
super("mssql")
|
||||||
|
@ -89,6 +146,7 @@ module MSSQLModule {
|
||||||
...this.config,
|
...this.config,
|
||||||
options: {
|
options: {
|
||||||
encrypt: this.config.encrypt,
|
encrypt: this.config.encrypt,
|
||||||
|
enableArithAbort: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
delete clientCfg.encrypt
|
delete clientCfg.encrypt
|
||||||
|
@ -107,6 +165,46 @@ module MSSQLModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the tables from the sql server database and assigns them to the datasource.
|
||||||
|
* @param {*} datasourceId - datasourceId to fetch
|
||||||
|
* @param entities - the tables that are to be built
|
||||||
|
*/
|
||||||
|
async buildSchema(datasourceId: string, entities: Record<string, Table>) {
|
||||||
|
|
||||||
|
await this.connect()
|
||||||
|
let tableNames = await internalQuery(this.client, getSqlQuery(this.TABLES_SQL))
|
||||||
|
if (tableNames == null || !Array.isArray(tableNames.recordset)) {
|
||||||
|
throw "Unable to get list of tables in database"
|
||||||
|
}
|
||||||
|
tableNames = tableNames.recordset.map((record: any) => record.TABLE_NAME).filter((name: string) => this.MASTER_TABLES.indexOf(name) === -1)
|
||||||
|
const tables: Record<string, Table> = {}
|
||||||
|
for (let tableName of tableNames) {
|
||||||
|
const definition = await internalQuery(this.client, getSqlQuery(this.getDefinitionSQL(tableName)))
|
||||||
|
let schema: TableSchema = {}
|
||||||
|
for (let def of definition.recordset) {
|
||||||
|
const name = def.COLUMN_NAME
|
||||||
|
if (typeof name !== "string") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const type: string = convertType(def.DATA_TYPE, TYPE_MAP)
|
||||||
|
const identity = false
|
||||||
|
schema[name] = {
|
||||||
|
autocolumn: identity,
|
||||||
|
name: name,
|
||||||
|
type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tables[tableName] = {
|
||||||
|
_id: buildExternalTableId(datasourceId, tableName),
|
||||||
|
primary: ["id"],
|
||||||
|
name: tableName,
|
||||||
|
schema,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.tables = tables
|
||||||
|
}
|
||||||
|
|
||||||
async read(query: SqlQuery | string) {
|
async read(query: SqlQuery | string) {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const response = await internalQuery(this.client, getSqlQuery(query))
|
const response = await internalQuery(this.client, getSqlQuery(query))
|
||||||
|
@ -132,6 +230,7 @@ module MSSQLModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
async query(json: QueryJson) {
|
async query(json: QueryJson) {
|
||||||
|
await this.connect()
|
||||||
const operation = this._operation(json).toLowerCase()
|
const operation = this._operation(json).toLowerCase()
|
||||||
const input = this._query(json)
|
const input = this._query(json)
|
||||||
const response = await internalQuery(this.client, input)
|
const response = await internalQuery(this.client, input)
|
||||||
|
|
Loading…
Reference in New Issue