|
|
|
@ -79,34 +79,9 @@ module MSSQLModule { |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
async function internalQuery( |
|
|
|
client: any, |
|
|
|
query: SqlQuery, |
|
|
|
operation: string | undefined = undefined |
|
|
|
) { |
|
|
|
const request = client.request() |
|
|
|
try { |
|
|
|
if (Array.isArray(query.bindings)) { |
|
|
|
let count = 0 |
|
|
|
for (let binding of query.bindings) { |
|
|
|
request.input(`p${count++}`, binding) |
|
|
|
} |
|
|
|
} |
|
|
|
// this is a hack to get the inserted ID back,
|
|
|
|
// no way to do this with Knex nicely
|
|
|
|
const sql = |
|
|
|
operation === Operation.CREATE |
|
|
|
? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;` |
|
|
|
: query.sql |
|
|
|
return await request.query(sql) |
|
|
|
} catch (err) { |
|
|
|
// @ts-ignore
|
|
|
|
throw new Error(err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
class SqlServerIntegration extends Sql implements DatasourcePlus { |
|
|
|
private readonly config: MSSQLConfig |
|
|
|
private index: number = 0 |
|
|
|
static pool: any |
|
|
|
public tables: Record<string, Table> = {} |
|
|
|
public schemaErrors: Record<string, string> = {} |
|
|
|
@ -121,6 +96,33 @@ module MSSQLModule { |
|
|
|
TABLES_SQL = |
|
|
|
"SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'" |
|
|
|
|
|
|
|
async internalQuery( |
|
|
|
query: SqlQuery, |
|
|
|
operation: string | undefined = undefined |
|
|
|
) { |
|
|
|
const client = this.client |
|
|
|
const request = client.request() |
|
|
|
this.index = 0 |
|
|
|
try { |
|
|
|
if (Array.isArray(query.bindings)) { |
|
|
|
let count = 0 |
|
|
|
for (let binding of query.bindings) { |
|
|
|
request.input(`p${count++}`, binding) |
|
|
|
} |
|
|
|
} |
|
|
|
// this is a hack to get the inserted ID back,
|
|
|
|
// no way to do this with Knex nicely
|
|
|
|
const sql = |
|
|
|
operation === Operation.CREATE |
|
|
|
? `${query.sql}; SELECT SCOPE_IDENTITY() AS id;` |
|
|
|
: query.sql |
|
|
|
return await request.query(sql) |
|
|
|
} catch (err) { |
|
|
|
// @ts-ignore
|
|
|
|
throw new Error(err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
getDefinitionSQL(tableName: string) { |
|
|
|
return `select *
|
|
|
|
from INFORMATION_SCHEMA.COLUMNS |
|
|
|
@ -165,6 +167,10 @@ module MSSQLModule { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
getBindingIdentifier(): string { |
|
|
|
return `(@p${this.index++})` |
|
|
|
} |
|
|
|
|
|
|
|
async connect() { |
|
|
|
try { |
|
|
|
this.client = await this.pool.connect() |
|
|
|
@ -175,7 +181,7 @@ module MSSQLModule { |
|
|
|
} |
|
|
|
|
|
|
|
async runSQL(sql: string) { |
|
|
|
return (await internalQuery(this.client, getSqlQuery(sql))).recordset |
|
|
|
return (await this.internalQuery(getSqlQuery(sql))).recordset |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
@ -238,33 +244,32 @@ module MSSQLModule { |
|
|
|
|
|
|
|
async read(query: SqlQuery | string) { |
|
|
|
await this.connect() |
|
|
|
const response = await internalQuery(this.client, getSqlQuery(query)) |
|
|
|
const response = await this.internalQuery(getSqlQuery(query)) |
|
|
|
return response.recordset |
|
|
|
} |
|
|
|
|
|
|
|
async create(query: SqlQuery | string) { |
|
|
|
await this.connect() |
|
|
|
const response = await internalQuery(this.client, getSqlQuery(query)) |
|
|
|
const response = await this.internalQuery(getSqlQuery(query)) |
|
|
|
return response.recordset || [{ created: true }] |
|
|
|
} |
|
|
|
|
|
|
|
async update(query: SqlQuery | string) { |
|
|
|
await this.connect() |
|
|
|
const response = await internalQuery(this.client, getSqlQuery(query)) |
|
|
|
const response = await this.internalQuery(getSqlQuery(query)) |
|
|
|
return response.recordset || [{ updated: true }] |
|
|
|
} |
|
|
|
|
|
|
|
async delete(query: SqlQuery | string) { |
|
|
|
await this.connect() |
|
|
|
const response = await internalQuery(this.client, getSqlQuery(query)) |
|
|
|
const response = await this.internalQuery(getSqlQuery(query)) |
|
|
|
return response.recordset || [{ deleted: true }] |
|
|
|
} |
|
|
|
|
|
|
|
async query(json: QueryJson) { |
|
|
|
await this.connect() |
|
|
|
const operation = this._operation(json) |
|
|
|
const queryFn = (query: any, op: string) => |
|
|
|
internalQuery(this.client, query, op) |
|
|
|
const queryFn = (query: any, op: string) => this.internalQuery(query, op) |
|
|
|
const processFn = (result: any) => |
|
|
|
result.recordset ? result.recordset : [{ [operation]: true }] |
|
|
|
return this.queryWithReturning(json, queryFn, processFn) |
|
|
|
|