Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TECH] Migrer la colonne answers.id de INTEGER en BIG INTEGER avec downtime. #3839

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require('dotenv').config();
const { knex } = require('../../db/knex-database-connection');
const logger = require('../../lib/infrastructure/logger');

const changeAnswerIdTypeToBigint = async () => {
await knex.transaction(async (trx) => {
logger.info('Altering knowledge-elements.answerId type to BIGINT - In progress');
await knex.raw(`ALTER TABLE "knowledge-elements" ALTER COLUMN "answerId" TYPE BIGINT`).transacting(trx);
logger.info('Altering knowledge-elements.answerId type to BIGINT - Done');

logger.info('Altering flash-assessment-results.answerId type to BIGINT - In progress');
await knex.raw(`ALTER TABLE "flash-assessment-results" ALTER COLUMN "answerId" TYPE BIGINT`).transacting(trx);
logger.info('Altering flash-assessment-results.answerId type to BIGINT - Done');

logger.info('Altering answers.id type to BIGINT - In progress');
await knex.raw(`ALTER TABLE "answers" ALTER COLUMN "id" TYPE BIGINT`).transacting(trx);
logger.info('Altering answers.id type to BIGINT - Done');

logger.info('Altering answers_id_seq type to BIGINT - In progress');
await knex.raw(`ALTER SEQUENCE "answers_id_seq" AS BIGINT`).transacting(trx);
logger.info('Altering answers_id_seq type to BIGINT - Done');
});
};

const preventOneOffContainerTimeout = () => {
setInterval(() => {
logger.info('alive');
}, 1000);
};

(async () => {
try {
preventOneOffContainerTimeout();
francois2metz marked this conversation as resolved.
Show resolved Hide resolved
await changeAnswerIdTypeToBigint();
process.exit(0);
} catch (error) {
logger.fatal(error);
process.exit(1);
}
})();

module.exports = { changeAnswerIdTypeToBigint };
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
const {
changeAnswerIdTypeToBigint,
} = require('../../../../scripts/bigint/change-answers-id-type-to-bigint-with-downtime');
const { expect, knex } = require('../../../test-helper');
const DatabaseBuilder = require('../../../../db/database-builder/database-builder');
const databaseBuilder = new DatabaseBuilder({ knex });

describe('#changeAnswerIdTypeToBigint', function () {
let answerIdInsertedBeforeSwitch;

it('should insert answer with an id bigger than the maximum integer type value', async function () {
// when
await changeAnswerIdTypeToBigint();
const maxValueBigIntType = '9223372036854775807';
const { id: assessmentId } = databaseBuilder.factory.buildAssessment();
const { id: answerId } = databaseBuilder.factory.buildAnswer({ id: maxValueBigIntType, assessmentId });
databaseBuilder.factory.buildKnowledgeElement({ assessmentId, answerId });
await databaseBuilder.commit();

// then
expect(answerId).to.be.equal(maxValueBigIntType);
});

it('should change type of answer sequence from integer to bigint', async function () {
// when
await changeAnswerIdTypeToBigint();

// then
const { rows: sequenceDataType } = await knex.raw(
`SELECT data_type FROM information_schema.sequences WHERE sequence_name = 'answers_id_seq'`
);
expect(sequenceDataType[0]['data_type']).to.equal('bigint');
});

it('should sequence are correctly reassigned', async function () {
// given
await changeAnswerIdTypeToBigint();

// when
const [{ id: answerIdInsertedAfterSwitch }] = await knex('answers')
.insert({
value: 'Some value for answer',
result: 'Some result for answer',
challengeId: 'rec123ABC',
createdAt: new Date('2020-01-01'),
updatedAt: new Date('2020-01-02'),
resultDetails: 'Some result details for answer.',
timeSpent: 30,
})
.returning('id');

// then
expect(answerIdInsertedAfterSwitch).to.equal(answerIdInsertedBeforeSwitch + 1);
});

afterEach(async function () {
await knex.transaction(async (trx) => {
await knex.raw(`ALTER TABLE "knowledge-elements" ALTER COLUMN "answerId" TYPE INTEGER`).transacting(trx);
await knex.raw(`ALTER TABLE "flash-assessment-results" ALTER COLUMN "answerId" TYPE INTEGER`).transacting(trx);
await knex.raw(`ALTER TABLE "answers" ALTER COLUMN "id" TYPE INTEGER`).transacting(trx);
await knex.raw(`ALTER SEQUENCE "answers_id_seq" AS INTEGER`).transacting(trx);
});
});
});