fix issue where schema wasn't updating types when a query was run (#14004)
* fix issue where schema wasn't updating types when a query was run * add tests for schema matching
This commit is contained in:
parent
4ac9b657e5
commit
f3d466f255
|
@ -233,9 +233,9 @@
|
|||
response.info = response.info || { code: 200 }
|
||||
// if existing schema, copy over what it is
|
||||
if (schema) {
|
||||
for (let [name, field] of Object.entries(schema)) {
|
||||
if (response.schema[name]) {
|
||||
response.schema[name] = field
|
||||
for (let [name, field] of Object.entries(response.schema)) {
|
||||
if (!schema[name]) {
|
||||
schema[name] = field
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,8 +311,8 @@ export async function preview(
|
|||
|
||||
// if existing schema, update to include any previous schema keys
|
||||
if (existingSchema) {
|
||||
for (let key of Object.keys(previewSchema)) {
|
||||
if (existingSchema[key]) {
|
||||
for (let key of Object.keys(existingSchema)) {
|
||||
if (!previewSchema[key]) {
|
||||
previewSchema[key] = existingSchema[key]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -250,6 +250,67 @@ describe.each(
|
|||
expect(events.query.previewed).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it("should update schema when column type changes from number to string", async () => {
|
||||
const tableName = "schema_change_test"
|
||||
await client.schema.dropTableIfExists(tableName)
|
||||
|
||||
await client.schema.createTable(tableName, table => {
|
||||
table.increments("id").primary()
|
||||
table.string("name")
|
||||
table.integer("data")
|
||||
})
|
||||
|
||||
await client(tableName).insert({
|
||||
name: "test",
|
||||
data: 123,
|
||||
})
|
||||
|
||||
const firstPreview = await config.api.query.preview({
|
||||
datasourceId: datasource._id!,
|
||||
name: "Test Query",
|
||||
queryVerb: "read",
|
||||
fields: {
|
||||
sql: `SELECT * FROM ${tableName}`,
|
||||
},
|
||||
parameters: [],
|
||||
transformer: "return data",
|
||||
schema: {},
|
||||
readable: true,
|
||||
})
|
||||
|
||||
expect(firstPreview.schema).toEqual(
|
||||
expect.objectContaining({
|
||||
data: { type: "number", name: "data" },
|
||||
})
|
||||
)
|
||||
|
||||
await client.schema.alterTable(tableName, table => {
|
||||
table.string("data").alter()
|
||||
})
|
||||
|
||||
await client(tableName).update({
|
||||
data: "string value",
|
||||
})
|
||||
|
||||
const secondPreview = await config.api.query.preview({
|
||||
datasourceId: datasource._id!,
|
||||
name: "Test Query",
|
||||
queryVerb: "read",
|
||||
fields: {
|
||||
sql: `SELECT * FROM ${tableName}`,
|
||||
},
|
||||
parameters: [],
|
||||
transformer: "return data",
|
||||
schema: firstPreview.schema,
|
||||
readable: true,
|
||||
})
|
||||
|
||||
expect(secondPreview.schema).toEqual(
|
||||
expect.objectContaining({
|
||||
data: { type: "string", name: "data" },
|
||||
})
|
||||
)
|
||||
})
|
||||
it("should work with static variables", async () => {
|
||||
await config.api.datasource.update({
|
||||
...datasource,
|
||||
|
|
|
@ -137,6 +137,67 @@ describe("/queries", () => {
|
|||
})
|
||||
})
|
||||
|
||||
it("should update schema when structure changes from object to array", async () => {
|
||||
const name = generator.guid()
|
||||
|
||||
await withCollection(async collection => {
|
||||
await collection.insertOne({ name, field: { subfield: "value" } })
|
||||
})
|
||||
|
||||
const firstPreview = await config.api.query.preview({
|
||||
name: "Test Query",
|
||||
datasourceId: datasource._id!,
|
||||
fields: {
|
||||
json: { name: { $eq: name } },
|
||||
extra: {
|
||||
collection,
|
||||
actionType: "findOne",
|
||||
},
|
||||
},
|
||||
schema: {},
|
||||
queryVerb: "read",
|
||||
parameters: [],
|
||||
transformer: "return data",
|
||||
readable: true,
|
||||
})
|
||||
|
||||
expect(firstPreview.schema).toEqual(
|
||||
expect.objectContaining({
|
||||
field: { type: "json", name: "field" },
|
||||
})
|
||||
)
|
||||
|
||||
await withCollection(async collection => {
|
||||
await collection.updateOne(
|
||||
{ name },
|
||||
{ $set: { field: ["value1", "value2"] } }
|
||||
)
|
||||
})
|
||||
|
||||
const secondPreview = await config.api.query.preview({
|
||||
name: "Test Query",
|
||||
datasourceId: datasource._id!,
|
||||
fields: {
|
||||
json: { name: { $eq: name } },
|
||||
extra: {
|
||||
collection,
|
||||
actionType: "findOne",
|
||||
},
|
||||
},
|
||||
schema: firstPreview.schema,
|
||||
queryVerb: "read",
|
||||
parameters: [],
|
||||
transformer: "return data",
|
||||
readable: true,
|
||||
})
|
||||
|
||||
expect(secondPreview.schema).toEqual(
|
||||
expect.objectContaining({
|
||||
field: { type: "array", name: "field" },
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should generate a nested schema based on all of the nested items", async () => {
|
||||
const name = generator.guid()
|
||||
const item = {
|
||||
|
|
|
@ -92,6 +92,61 @@ describe("rest", () => {
|
|||
expect(cached.rows[0].name).toEqual("one")
|
||||
})
|
||||
|
||||
it("should update schema when structure changes from JSON to array", async () => {
|
||||
const datasource = await config.api.datasource.create({
|
||||
name: generator.guid(),
|
||||
type: "test",
|
||||
source: SourceName.REST,
|
||||
config: {},
|
||||
})
|
||||
|
||||
nock("http://www.example.com")
|
||||
.get("/")
|
||||
.reply(200, [{ obj: {}, id: "1" }])
|
||||
|
||||
const firstResponse = await config.api.query.preview({
|
||||
datasourceId: datasource._id!,
|
||||
name: "test query",
|
||||
parameters: [],
|
||||
queryVerb: "read",
|
||||
transformer: "",
|
||||
schema: {},
|
||||
readable: true,
|
||||
fields: {
|
||||
path: "www.example.com",
|
||||
},
|
||||
})
|
||||
|
||||
expect(firstResponse.schema).toEqual({
|
||||
obj: { type: "json", name: "obj" },
|
||||
id: { type: "string", name: "id" },
|
||||
})
|
||||
|
||||
nock.cleanAll()
|
||||
|
||||
nock("http://www.example.com")
|
||||
.get("/")
|
||||
.reply(200, [{ obj: [], id: "1" }])
|
||||
|
||||
const secondResponse = await config.api.query.preview({
|
||||
datasourceId: datasource._id!,
|
||||
name: "test query",
|
||||
parameters: [],
|
||||
queryVerb: "read",
|
||||
transformer: "",
|
||||
schema: firstResponse.schema,
|
||||
readable: true,
|
||||
fields: {
|
||||
path: "www.example.com",
|
||||
},
|
||||
})
|
||||
|
||||
expect(secondResponse.schema).toEqual({
|
||||
obj: { type: "array", name: "obj" },
|
||||
id: { type: "string", name: "id" },
|
||||
})
|
||||
})
|
||||
|
||||
it("should parse global and query level header mappings", async () => {
|
||||
const datasource = await config.api.datasource.create({
|
||||
name: generator.guid(),
|
||||
|
|
Loading…
Reference in New Issue