Adding stats, code, timings and size of request.

This commit is contained in:
mike12345567 2021-12-06 18:23:18 +00:00
parent 5936fe0f5f
commit 99e2cd52e8
5 changed files with 75 additions and 63 deletions

View File

@ -109,7 +109,7 @@ exports.preview = async function (ctx) {
const enrichedQuery = await enrichQueryFields(fields, parameters)
try {
const { rows, keys } = await Runner.run({
const { rows, keys, info } = await Runner.run({
datasource,
queryVerb,
query: enrichedQuery,
@ -119,6 +119,7 @@ exports.preview = async function (ctx) {
ctx.body = {
rows,
schemaFields: [...new Set(keys)],
info,
}
} catch (err) {
ctx.throw(400, err)

View File

@ -1,6 +1,6 @@
export interface IntegrationBase {
create?(query: any): Promise<any[]>
read?(query: any): Promise<any[]>
update?(query: any): Promise<any[]>
delete?(query: any): Promise<any[]>
create?(query: any): Promise<any[]|any>
read?(query: any): Promise<any[]|any>
update?(query: any): Promise<any[]|any>
delete?(query: any): Promise<any[]|any>
}

View File

@ -38,6 +38,8 @@ const coreFields = {
module RestModule {
const fetch = require("node-fetch")
const { formatBytes } = require("../utilities")
const { performance } = require("perf_hooks")
interface RestConfig {
url: string
@ -46,6 +48,13 @@ module RestModule {
}
}
interface Request {
path: string
queryString?: string
headers?: string
json?: any
}
const SCHEMA: Integration = {
docs: "https://github.com/node-fetch/node-fetch",
description:
@ -102,17 +111,29 @@ module RestModule {
private headers: {
[key: string]: string
} = {}
private startTimeMs: number = performance.now()
constructor(config: RestConfig) {
this.config = config
}
async parseResponse(response: any) {
let data
const contentType = response.headers.get("content-type")
if (contentType && contentType.indexOf("application/json") !== -1) {
return await response.json()
data = await response.json()
} else {
return await response.text()
data = await response.text()
}
const size = formatBytes(response.headers.get("content-length") || 0)
const time = `${Math.round(performance.now() - this.startTimeMs)}ms`
return {
data,
info: {
code: response.status,
size,
time,
},
}
}
@ -125,76 +146,40 @@ module RestModule {
}
}
async create({ path = "", queryString = "", headers = {}, json = {} }) {
async _req({ path = "", queryString = "", headers = {}, json = {}, method = "GET" }) {
this.headers = {
...this.config.defaultHeaders,
...headers,
}
const response = await fetch(this.getUrl(path, queryString), {
method: "POST",
headers: this.headers,
body: JSON.stringify(json),
})
const input: any = { method, headers: this.headers }
if (json && typeof json === "object" && Object.keys(json).length > 0) {
input.body = JSON.stringify(json)
}
this.startTimeMs = performance.now()
const response = await fetch(this.getUrl(path, queryString), input)
return await this.parseResponse(response)
}
async read({ path = "", queryString = "", headers = {} }) {
this.headers = {
...this.config.defaultHeaders,
...headers,
async create(opts: Request) {
return this._req({ ...opts, method: "POST" })
}
const response = await fetch(this.getUrl(path, queryString), {
headers: this.headers,
})
return await this.parseResponse(response)
async read(opts: Request) {
return this._req({ ...opts, method: "GET" })
}
async update({ path = "", queryString = "", headers = {}, json = {} }) {
this.headers = {
...this.config.defaultHeaders,
...headers,
async update(opts: Request) {
return this._req({ ...opts, method: "PUT" })
}
const response = await fetch(this.getUrl(path, queryString), {
method: "PUT",
headers: this.headers,
body: JSON.stringify(json),
})
return await this.parseResponse(response)
async patch(opts: Request) {
return this._req({ ...opts, method: "PATCH" })
}
async patch({ path = "", queryString = "", headers = {}, json = {} }) {
this.headers = {
...this.config.defaultHeaders,
...headers,
}
const response = await fetch(this.getUrl(path, queryString), {
method: "PATCH",
headers: this.headers,
body: JSON.stringify(json),
})
return await this.parseResponse(response)
}
async delete({ path = "", queryString = "", headers = {} }) {
this.headers = {
...this.config.defaultHeaders,
...headers,
}
const response = await fetch(this.getUrl(path, queryString), {
method: "DELETE",
headers: this.headers,
})
return await this.parseResponse(response)
async delete(opts: Request) {
return this._req({ ...opts, method: "DELETE" })
}
}

View File

@ -15,6 +15,15 @@ function formatResponse(resp) {
return resp
}
function hasExtraData(response) {
return (
typeof response === "object" &&
!Array.isArray(response) &&
response.data &&
response.info
)
}
async function runAndTransform(datasource, queryVerb, query, transformer) {
const Integration = integrations[datasource.source]
if (!Integration) {
@ -22,7 +31,13 @@ async function runAndTransform(datasource, queryVerb, query, transformer) {
}
const integration = new Integration(datasource.config)
let rows = formatResponse(await integration[queryVerb](query))
let output = formatResponse(await integration[queryVerb](query))
let rows = output,
info = undefined
if (hasExtraData(output)) {
rows = output.data
info = output.info
}
// transform as required
if (transformer) {
@ -47,7 +62,7 @@ async function runAndTransform(datasource, queryVerb, query, transformer) {
integration.end()
}
return { rows, keys }
return { rows, keys, info }
}
module.exports = (input, callback) => {

View File

@ -150,3 +150,14 @@ exports.doesDatabaseExist = async dbName => {
return false
}
}
exports.formatBytes = bytes => {
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
const byteIncrements = 1024
let unit = 0
let size = parseInt(bytes, 10) || 0
while (size >= byteIncrements && ++unit) {
size /= byteIncrements
}
return `${size.toFixed(size < 10 && unit > 0 ? 1 : 0)}${units[unit]}`
}