2021-02-05 15:35:30 +01:00
|
|
|
const { expect } = require('chai');
|
|
|
|
const {
|
|
|
|
Db,
|
|
|
|
getAllDbs,
|
|
|
|
getKnexForDb,
|
|
|
|
} = require('../util/knex-instance-provider');
|
|
|
|
|
|
|
|
const QUERY_TABLE_ONE_INDICES =
|
|
|
|
'SELECT type, name, tbl_name, sql FROM sqlite_master WHERE type="index" AND tbl_name="index_table_one"';
|
|
|
|
const QUERY_TABLE_TWO_INDICES =
|
|
|
|
'SELECT type, name, tbl_name, sql FROM sqlite_master WHERE type="index" AND tbl_name="index_table_two"';
|
|
|
|
|
|
|
|
describe('Schema', () => {
|
|
|
|
describe('Index', () => {
|
|
|
|
getAllDbs()
|
|
|
|
.filter((db) => db === Db.SQLite)
|
|
|
|
.forEach((db) => {
|
|
|
|
describe(db, () => {
|
|
|
|
let knex;
|
|
|
|
before(() => {
|
|
|
|
knex = getKnexForDb(db);
|
|
|
|
});
|
|
|
|
|
|
|
|
after(() => {
|
|
|
|
return knex.destroy();
|
|
|
|
});
|
|
|
|
|
|
|
|
beforeEach(async () => {
|
|
|
|
await knex.schema
|
|
|
|
.createTable('index_table_one', (table) => {
|
|
|
|
table.string('id').primary();
|
|
|
|
table
|
|
|
|
.integer('id_three')
|
|
|
|
.unsigned()
|
|
|
|
.notNullable()
|
|
|
|
.references('id')
|
|
|
|
.inTable('index_table_three');
|
|
|
|
|
|
|
|
table.integer('column_one');
|
|
|
|
table.integer('column_two');
|
|
|
|
table.integer('column_three');
|
|
|
|
table.integer('column_four');
|
|
|
|
|
|
|
|
table.index('column_one');
|
|
|
|
table.index('column_two');
|
|
|
|
table.index(['column_two', 'column_three']);
|
|
|
|
})
|
|
|
|
.createTable('index_table_two', (table) => {
|
|
|
|
table.string('no_id');
|
|
|
|
table.integer('no_id_three').unsigned().notNullable();
|
|
|
|
|
|
|
|
table.integer('column_one');
|
|
|
|
table.integer('column_two');
|
|
|
|
table.integer('column_three');
|
|
|
|
table.integer('column_four');
|
|
|
|
|
|
|
|
table.unique('column_one');
|
|
|
|
table.unique('column_two');
|
|
|
|
table.unique(['column_two', 'column_three']);
|
|
|
|
})
|
|
|
|
.createTable('index_table_three', (table) => {
|
|
|
|
table.increments().primary();
|
|
|
|
});
|
|
|
|
|
|
|
|
await knex('index_table_three').insert({});
|
|
|
|
await knex('index_table_one').insert([
|
|
|
|
{
|
|
|
|
id: 'one',
|
|
|
|
id_three: 1,
|
|
|
|
column_one: 1,
|
|
|
|
column_two: 1,
|
|
|
|
column_three: 1,
|
|
|
|
column_four: 3,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 'two',
|
|
|
|
id_three: 1,
|
|
|
|
column_one: 1,
|
|
|
|
column_two: 1,
|
|
|
|
column_three: 1,
|
|
|
|
column_four: 4,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
await knex('index_table_two').insert([
|
|
|
|
{
|
|
|
|
no_id: 'one',
|
|
|
|
no_id_three: 1,
|
|
|
|
column_one: 1,
|
|
|
|
column_two: 1,
|
|
|
|
column_three: 1,
|
|
|
|
column_four: 3,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
no_id: 'two',
|
|
|
|
no_id_three: 1,
|
|
|
|
column_one: 2,
|
|
|
|
column_two: 2,
|
|
|
|
column_three: 2,
|
|
|
|
column_four: 4,
|
|
|
|
},
|
|
|
|
]);
|
|
|
|
});
|
|
|
|
|
|
|
|
afterEach(async () => {
|
|
|
|
await knex.schema
|
|
|
|
.dropTable('index_table_one')
|
|
|
|
.dropTable('index_table_two')
|
|
|
|
.dropTable('index_table_three');
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('dropColumn', () => {
|
|
|
|
it('recreates indices after dropping a column without an index', async () => {
|
|
|
|
const indicesOneBefore = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
const indicesTwoBefore = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_one', (table) => {
|
|
|
|
table.dropColumn('column_four');
|
|
|
|
});
|
|
|
|
await knex.schema.alterTable('index_table_two', (table) => {
|
|
|
|
table.dropColumn('column_four');
|
|
|
|
});
|
|
|
|
|
|
|
|
const indicesOneAfter = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
const indicesTwoAfter = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
|
|
|
|
expect(indicesOneAfter).to.deep.have.same.members(
|
|
|
|
indicesOneBefore
|
|
|
|
);
|
|
|
|
expect(indicesTwoAfter).to.deep.have.same.members(
|
|
|
|
indicesTwoBefore
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('drops indices when the corresponding column is dropped', async () => {
|
|
|
|
const indicesOneBefore = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
const indicesTwoBefore = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
const indicesOneBeforeWithoutIndex = indicesOneBefore.filter(
|
|
|
|
(index) => index.name !== 'index_table_one_column_one_index'
|
|
|
|
);
|
|
|
|
const indicesTwoBeforeWithoutIndex = indicesTwoBefore.filter(
|
|
|
|
(index) => index.name !== 'index_table_two_column_one_unique'
|
|
|
|
);
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_one', (table) => {
|
|
|
|
table.dropColumn('column_one');
|
|
|
|
});
|
|
|
|
await knex.schema.alterTable('index_table_two', (table) => {
|
|
|
|
table.dropColumn('column_one');
|
|
|
|
});
|
|
|
|
|
|
|
|
const indicesOneAfter = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
const indicesTwoAfter = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
|
|
|
|
expect(indicesOneAfter).to.deep.have.same.members(
|
|
|
|
indicesOneBeforeWithoutIndex
|
|
|
|
);
|
|
|
|
expect(indicesTwoAfter).to.deep.have.same.members(
|
|
|
|
indicesTwoBeforeWithoutIndex
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('alters composite indices when one of the corresponding columns is dropped', async () => {
|
|
|
|
const indicesOneBeforeWithoutIndex = [
|
|
|
|
{
|
|
|
|
type: 'index',
|
|
|
|
name: 'sqlite_autoindex_index_table_one_1',
|
|
|
|
tbl_name: 'index_table_one',
|
|
|
|
sql: null,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'index',
|
|
|
|
name: 'index_table_one_column_one_index',
|
|
|
|
tbl_name: 'index_table_one',
|
2021-08-25 16:30:44 +02:00
|
|
|
sql: 'CREATE INDEX `index_table_one_column_one_index` on `index_table_one` (`column_one`)',
|
2021-02-05 15:35:30 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'index',
|
|
|
|
name: 'index_table_one_column_two_column_three_index',
|
|
|
|
tbl_name: 'index_table_one',
|
2021-08-25 16:30:44 +02:00
|
|
|
sql: 'CREATE INDEX `index_table_one_column_two_column_three_index` on `index_table_one` (`column_three`)',
|
2021-02-05 15:35:30 +01:00
|
|
|
},
|
|
|
|
];
|
|
|
|
const indicesTwoBeforeWithoutIndex = [
|
|
|
|
{
|
|
|
|
type: 'index',
|
|
|
|
name: 'index_table_two_column_one_unique',
|
|
|
|
tbl_name: 'index_table_two',
|
2021-08-25 16:30:44 +02:00
|
|
|
sql: 'CREATE UNIQUE INDEX `index_table_two_column_one_unique` on `index_table_two` (`column_one`)',
|
2021-02-05 15:35:30 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'index',
|
|
|
|
name: 'index_table_two_column_two_column_three_unique',
|
|
|
|
tbl_name: 'index_table_two',
|
2021-08-25 16:30:44 +02:00
|
|
|
sql: 'CREATE UNIQUE INDEX `index_table_two_column_two_column_three_unique` on `index_table_two` (`column_three`)',
|
2021-02-05 15:35:30 +01:00
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_one', (table) => {
|
|
|
|
table.dropColumn('column_two');
|
|
|
|
});
|
|
|
|
await knex.schema.alterTable('index_table_two', (table) => {
|
|
|
|
table.dropColumn('column_two');
|
|
|
|
});
|
|
|
|
|
|
|
|
const indicesOneAfter = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
const indicesTwoAfter = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
|
|
|
|
expect(indicesOneAfter).to.deep.have.same.members(
|
|
|
|
indicesOneBeforeWithoutIndex
|
|
|
|
);
|
|
|
|
expect(indicesTwoAfter).to.deep.have.same.members(
|
|
|
|
indicesTwoBeforeWithoutIndex
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-02-26 21:36:46 +01:00
|
|
|
describe('alterColumns', () => {
|
|
|
|
it('recreates indices after altering a column', async () => {
|
|
|
|
const indicesBefore = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_one', (table) => {
|
|
|
|
table.string('column_one').alter();
|
|
|
|
});
|
|
|
|
|
|
|
|
const indicesAfter = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
|
|
|
|
expect(indicesAfter).to.deep.have.same.members(indicesBefore);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2021-02-05 15:35:30 +01:00
|
|
|
describe('dropForeign', () => {
|
|
|
|
it('recreates indices after dropping a foreign key', async () => {
|
|
|
|
const indicesBefore = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_one', (table) => {
|
|
|
|
table.dropForeign('id_three');
|
|
|
|
});
|
|
|
|
|
|
|
|
const indicesAfter = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
|
|
|
|
expect(indicesAfter).to.deep.have.same.members(indicesBefore);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('dropPrimary', () => {
|
|
|
|
it('recreates indices after dropping a primary key', async () => {
|
|
|
|
const indicesBefore = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
const indicesBeforeWithoutPrimary = indicesBefore.filter(
|
|
|
|
(index) => index.sql !== null
|
|
|
|
);
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_one', (table) => {
|
2021-08-25 16:30:44 +02:00
|
|
|
table.dropPrimary();
|
2021-02-05 15:35:30 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
const indicesAfter = await knex.raw(QUERY_TABLE_ONE_INDICES);
|
|
|
|
|
|
|
|
expect(indicesAfter).to.deep.have.same.members(
|
|
|
|
indicesBeforeWithoutPrimary
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('foreign', () => {
|
|
|
|
it('recreates indices after adding a foreign key', async () => {
|
|
|
|
const indicesBefore = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_two', (table) => {
|
|
|
|
table
|
|
|
|
.foreign('no_id_three')
|
|
|
|
.references('id')
|
|
|
|
.inTable('index_table_three');
|
|
|
|
});
|
|
|
|
|
|
|
|
const indicesAfter = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
|
|
|
|
expect(indicesAfter).to.deep.have.same.members(indicesBefore);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('primary', () => {
|
|
|
|
it('recreates indices after adding a primary key', async () => {
|
|
|
|
const indicesBefore = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
|
|
|
|
await knex.schema.alterTable('index_table_two', (table) => {
|
|
|
|
table.primary('no_id');
|
|
|
|
});
|
|
|
|
|
|
|
|
const indicesAfter = await knex.raw(QUERY_TABLE_TWO_INDICES);
|
|
|
|
const indicesAfterWithoutPrimary = indicesAfter.filter(
|
|
|
|
(index) => index.sql !== null
|
|
|
|
);
|
|
|
|
|
|
|
|
expect(indicesAfterWithoutPrimary).to.deep.have.same.members(
|
|
|
|
indicesBefore
|
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|