mirror of
https://github.com/knex/knex.git
synced 2025-07-10 18:41:18 +00:00
301 lines
9.6 KiB
JavaScript
301 lines
9.6 KiB
JavaScript
'use strict';
|
|
|
|
const { expect } = require('chai');
|
|
const { TEST_TIMESTAMP } = require('../../util/constants');
|
|
const { isMssql } = require('../../util/db-helpers');
|
|
const {
|
|
dropTables,
|
|
createAccounts,
|
|
createTestTableTwo,
|
|
} = require('../../util/tableCreatorHelper');
|
|
const {
|
|
insertAccounts,
|
|
insertTestTableTwoData,
|
|
} = require('../../util/dataInsertHelper');
|
|
|
|
module.exports = function (knex) {
|
|
describe('Deletes with Triggers', function () {
|
|
// Trigger options
|
|
const triggerOptions = { includeTriggerModifications: true };
|
|
|
|
before(function () {
|
|
if (!isMssql(knex)) {
|
|
this.skip('This test is MSSQL only');
|
|
}
|
|
});
|
|
|
|
before(async () => {
|
|
await dropTables(knex);
|
|
await createAccounts(knex);
|
|
await createTestTableTwo(knex);
|
|
await insertAccounts(knex);
|
|
await insertTestTableTwoData(knex);
|
|
});
|
|
|
|
describe('Trigger Specific Tests', function () {
|
|
// Reused variables
|
|
// Table Names
|
|
const primaryTable = 'test_return_with_trigger_primary';
|
|
const secondaryTable = 'test_return_with_trigger_secondary';
|
|
|
|
// Foreign Key Column Names
|
|
const primaryLink = 'foreign_id';
|
|
const secondaryLink = 'looping_id';
|
|
|
|
// Trigger Name
|
|
const triggerName = 'tr_test_delete_with_trigger';
|
|
|
|
// Create proper environment for tests
|
|
before(async function () {
|
|
if (!isMssql(knex)) {
|
|
this.skip('This test is MSSQL only');
|
|
}
|
|
|
|
await knex.schema.hasTable('users').then(async function (exists) {
|
|
if (exists) {
|
|
await knex.schema.dropTable(primaryTable);
|
|
await knex.schema.dropTable(secondaryTable);
|
|
}
|
|
|
|
// Create tables
|
|
await knex.schema.createTable(primaryTable, function (table) {
|
|
table.increments().primary();
|
|
table.string('data').defaultsTo('');
|
|
table.integer(primaryLink).nullable();
|
|
});
|
|
|
|
await knex.schema.createTable(secondaryTable, function (table) {
|
|
table.increments().primary();
|
|
table.string('data').defaultsTo('');
|
|
table.integer(secondaryLink).nullable();
|
|
});
|
|
|
|
await knex.raw(`
|
|
CREATE TRIGGER [dbo].[${triggerName}] ON [dbo].[${secondaryTable}]
|
|
AFTER DELETE
|
|
AS
|
|
BEGIN
|
|
SET NOCOUNT ON;
|
|
|
|
BEGIN
|
|
delete ${primaryTable}
|
|
from ${primaryTable} as pt
|
|
inner join deleted as d
|
|
on pt.id = d.${secondaryLink}
|
|
END
|
|
END
|
|
`);
|
|
});
|
|
});
|
|
|
|
// Clean-up test specific tables
|
|
after(async function () {
|
|
if (!isMssql(knex)) {
|
|
return;
|
|
}
|
|
|
|
// Drop table (Trigger is removed with table)
|
|
await knex.schema.dropTable(primaryTable);
|
|
await knex.schema.dropTable(secondaryTable);
|
|
});
|
|
|
|
// Reset tables for each test
|
|
beforeEach(async function () {
|
|
// "Truncate" tables instead of recreate for each test for speed gains
|
|
await knex.raw(`
|
|
delete from ${primaryTable} dbcc checkident('${primaryTable}', reseed, 0);
|
|
delete from ${secondaryTable} dbcc checkident('${secondaryTable}', reseed, 0);
|
|
`);
|
|
});
|
|
|
|
it('#4152 Should allow returns with deletes on tables with triggers', async function () {
|
|
let reachedEnd = false;
|
|
|
|
await knex.transaction(async function () {
|
|
let insertedId;
|
|
let deletedId;
|
|
|
|
async function insertWithReturn() {
|
|
const insertPrimary = {
|
|
data: 'Testing Data',
|
|
};
|
|
|
|
const insertSecondary = {
|
|
data: 'Test Linking',
|
|
};
|
|
|
|
// Setup primary table for trigger use case
|
|
const primaryId = await knex(primaryTable).insert(
|
|
[insertPrimary],
|
|
['id'],
|
|
triggerOptions
|
|
);
|
|
insertSecondary[secondaryLink] = primaryId[0];
|
|
|
|
// Insert to table with trigger to test delete
|
|
insertedId = (
|
|
await knex(secondaryTable).insert(
|
|
[insertSecondary],
|
|
['id'],
|
|
triggerOptions
|
|
)
|
|
)[0];
|
|
}
|
|
|
|
async function deleteTriggerTable() {
|
|
// Test returning value from delete statement on a table with a trigger
|
|
deletedId = (
|
|
await knex(secondaryTable)
|
|
.whereRaw(`id = ${insertedId}`)
|
|
.delete(['id'], triggerOptions)
|
|
)[0];
|
|
}
|
|
|
|
await insertWithReturn();
|
|
await deleteTriggerTable();
|
|
|
|
expect(Number.parseInt(deletedId)).to.be.finite;
|
|
|
|
reachedEnd = true;
|
|
});
|
|
|
|
expect(reachedEnd).to.be.true;
|
|
});
|
|
|
|
it('#4152 Should allow returns with deletes on tables with triggers using returning function', async function () {
|
|
let reachedEnd = false;
|
|
|
|
await knex.transaction(async function () {
|
|
let insertedId;
|
|
let deletedId;
|
|
|
|
async function insertWithReturn() {
|
|
const insertPrimary = {
|
|
data: 'Testing Data',
|
|
};
|
|
|
|
const insertSecondary = {
|
|
data: 'Test Linking',
|
|
};
|
|
|
|
// Setup primary table for trigger use case
|
|
const primaryId = await knex(primaryTable).insert(
|
|
[insertPrimary],
|
|
['id'],
|
|
triggerOptions
|
|
);
|
|
insertSecondary[secondaryLink] = primaryId[0];
|
|
|
|
// Insert to table with trigger to test delete
|
|
insertedId = (
|
|
await knex(secondaryTable).insert(
|
|
[insertSecondary],
|
|
['id'],
|
|
triggerOptions
|
|
)
|
|
)[0];
|
|
}
|
|
|
|
async function deleteTriggerTable() {
|
|
// Test returning value from delete statement on a table with a trigger
|
|
deletedId = (
|
|
await knex(secondaryTable)
|
|
.whereRaw(`id = ${insertedId}`)
|
|
.returning(['id'], triggerOptions)
|
|
.delete()
|
|
)[0];
|
|
}
|
|
|
|
await insertWithReturn();
|
|
await deleteTriggerTable();
|
|
|
|
expect(Number.parseInt(deletedId)).to.be.finite;
|
|
|
|
reachedEnd = true;
|
|
});
|
|
|
|
expect(reachedEnd).to.be.true;
|
|
});
|
|
});
|
|
|
|
describe('Re-test all Delete Functions with trigger option and returns', function () {
|
|
before(async function () {
|
|
if (!isMssql(knex)) {
|
|
this.skip('This test is MSSQL only');
|
|
}
|
|
|
|
// Reset all table data to original stats of original tests
|
|
});
|
|
|
|
it('should allow returning for deletes in postgresql and mssql', function () {
|
|
return knex('accounts')
|
|
.where('id', 2)
|
|
.del('*', triggerOptions)
|
|
.testSql(function (tester) {
|
|
tester('mysql', 'delete from `accounts` where `id` = ?', [2], 1);
|
|
tester(
|
|
'pg',
|
|
'delete from "accounts" where "id" = ? returning *',
|
|
[2],
|
|
[
|
|
{
|
|
id: '2',
|
|
first_name: 'Test',
|
|
last_name: 'User',
|
|
email: 'test2@example.com',
|
|
logins: 1,
|
|
balance: 0,
|
|
about: 'Lorem ipsum Dolore labore incididunt enim.',
|
|
created_at: TEST_TIMESTAMP,
|
|
updated_at: TEST_TIMESTAMP,
|
|
phone: null,
|
|
},
|
|
]
|
|
);
|
|
tester(
|
|
'pg-redshift',
|
|
'delete from "accounts" where "id" = ?',
|
|
[2],
|
|
1
|
|
);
|
|
tester('sqlite3', 'delete from `accounts` where `id` = ?', [2], 1);
|
|
tester('oracledb', 'delete from "accounts" where "id" = ?', [2], 1);
|
|
tester(
|
|
'mssql',
|
|
'select top(0) [t].* into #out from [accounts] as t left join [accounts] on 0=1;delete from [accounts] output deleted.* into #out where [id] = ?; select * from #out; drop table #out;',
|
|
[2],
|
|
[
|
|
{
|
|
id: '2',
|
|
first_name: 'Test',
|
|
last_name: 'User',
|
|
email: 'test2@example.com',
|
|
logins: 1,
|
|
balance: 0,
|
|
about: 'Lorem ipsum Dolore labore incididunt enim.',
|
|
created_at: TEST_TIMESTAMP,
|
|
updated_at: TEST_TIMESTAMP,
|
|
phone: null,
|
|
},
|
|
]
|
|
);
|
|
});
|
|
});
|
|
});
|
|
it('should handle delete with join and trigger options', function () {
|
|
return knex('test_table_two')
|
|
.join('accounts', 'accounts.id', 'test_table_two.account_id')
|
|
.where({ 'accounts.email': 'test3@example.com' })
|
|
.del('*', triggerOptions)
|
|
.testSql(function (tester) {
|
|
tester(
|
|
'mssql',
|
|
'select top(0) [t].* into #out from [test_table_two] as t left join [test_table_two] on 0=1;delete [test_table_two] output deleted.* into #out from [test_table_two] inner join [accounts] on [accounts].[id] = [test_table_two].[account_id] where [accounts].[email] = ?; select * from #out; drop table #out;',
|
|
['test3@example.com'],
|
|
[{ id: 3, account_id: 3, details: '', status: 1 }]
|
|
);
|
|
});
|
|
});
|
|
});
|
|
};
|