schemas.test.ts 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import type { CreateSchemaQueryOptions } from '@sequelize/core';
  2. import { DataTypes, QueryTypes, sql } from '@sequelize/core';
  3. import { basicComparator } from '@sequelize/utils';
  4. import { expect } from 'chai';
  5. import { spy } from 'sinon';
  6. import { sequelize } from '../support';
  7. const { dialect } = sequelize;
  8. const testSchema = 'testSchema';
  9. const queryInterface = sequelize.queryInterface;
  10. describe('QueryInterface#{create,drop,list}Schema', () => {
  11. if (!dialect.supports.schemas) {
  12. it('should throw, indicating that the method is not supported', async () => {
  13. await expect(queryInterface.createSchema(testSchema)).to.be.rejectedWith(
  14. `Schemas are not supported in ${dialect.name}.`,
  15. );
  16. await expect(queryInterface.dropSchema(testSchema)).to.be.rejectedWith(
  17. `Schemas are not supported in ${dialect.name}.`,
  18. );
  19. await expect(queryInterface.listSchemas()).to.be.rejectedWith(
  20. `Schemas are not supported in ${dialect.name}.`,
  21. );
  22. });
  23. return;
  24. }
  25. it('creates a schema', async () => {
  26. const preCreationSchemas = await queryInterface.listSchemas();
  27. expect(preCreationSchemas).to.not.include(testSchema, 'testSchema existed before tests ran');
  28. await queryInterface.createSchema(testSchema);
  29. const postCreationSchemas = await queryInterface.listSchemas();
  30. expect(postCreationSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  31. });
  32. if (dialect.supports.createSchema.authorization) {
  33. it('creates a schema with an authorization', async () => {
  34. if (dialect.name === 'mssql') {
  35. await sequelize.query(
  36. `IF SUSER_ID (N'myUser') IS NULL CREATE LOGIN [myUser] WITH PASSWORD = 'Password12!'`,
  37. );
  38. await sequelize.query(
  39. `IF DATABASE_PRINCIPAL_ID (N'myUser') IS NULL CREATE USER [myUser] FOR LOGIN [myUser]`,
  40. );
  41. await queryInterface.createSchema(testSchema, { authorization: 'myUser' });
  42. } else if (dialect.name === 'postgres') {
  43. await sequelize.query(
  44. `DROP ROLE IF EXISTS "myUser"; CREATE ROLE "myUser" WITH LOGIN PASSWORD 'Password12!' CREATEDB`,
  45. );
  46. await queryInterface.createSchema(testSchema, { authorization: 'myUser' });
  47. } else {
  48. await queryInterface.createSchema(testSchema, { authorization: sql`CURRENT_USER` });
  49. }
  50. const postCreationSchemas = await queryInterface.listSchemas();
  51. expect(postCreationSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  52. if (['mssql', 'postgres'].includes(dialect.name)) {
  53. const [result] = await sequelize.query<{ schema_owner: string }>(
  54. `SELECT schema_owner FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${testSchema}'`,
  55. { type: QueryTypes.SELECT },
  56. );
  57. expect(result.schema_owner).to.equal('myUser');
  58. } else if (dialect.name === 'db2') {
  59. const [result] = await sequelize.query<{ OWNER: string }>(
  60. `SELECT OWNER FROM syscat.schemata WHERE SCHEMANAME = '${testSchema}'`,
  61. { type: QueryTypes.SELECT },
  62. );
  63. expect(result.OWNER).to.equal('CURRENT_USER');
  64. }
  65. await queryInterface.dropSchema(testSchema);
  66. if (dialect.name === 'mssql') {
  67. await sequelize.query('DROP USER [myUser]');
  68. await sequelize.query('DROP LOGIN [myUser]');
  69. } else if (dialect.name === 'postgres') {
  70. await sequelize.query('DROP ROLE "myUser"');
  71. }
  72. });
  73. }
  74. if (dialect.supports.createSchema.charset) {
  75. it('creates a schema with a charset', async () => {
  76. await queryInterface.createSchema(testSchema, { charset: 'utf8mb4' });
  77. const postCreationSchemas = await queryInterface.listSchemas();
  78. expect(postCreationSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  79. const [result] = await sequelize.query<{ DEFAULT_CHARACTER_SET_NAME: string }>(
  80. `SELECT DEFAULT_CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${testSchema}'`,
  81. { type: QueryTypes.SELECT },
  82. );
  83. expect(result.DEFAULT_CHARACTER_SET_NAME).to.equal('utf8mb4');
  84. });
  85. }
  86. if (dialect.supports.createSchema.collate) {
  87. it('creates a schema with a collate', async () => {
  88. await queryInterface.createSchema(testSchema, { collate: 'latin2_general_ci' });
  89. const postCreationSchemas = await queryInterface.listSchemas();
  90. expect(postCreationSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  91. const [result] = await sequelize.query<{ DEFAULT_COLLATION_NAME: string }>(
  92. `SELECT DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${testSchema}'`,
  93. { type: QueryTypes.SELECT },
  94. );
  95. expect(result.DEFAULT_COLLATION_NAME).to.equal('latin2_general_ci');
  96. });
  97. }
  98. if (dialect.supports.createSchema.comment) {
  99. it('creates a schema with a comment', async () => {
  100. await queryInterface.createSchema(testSchema, { comment: 'myComment' });
  101. const postCreationSchemas = await queryInterface.listSchemas();
  102. expect(postCreationSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  103. const [result] = await sequelize.query<{ SCHEMA_COMMENT: string }>(
  104. `SELECT SCHEMA_COMMENT FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${testSchema}'`,
  105. { type: QueryTypes.SELECT },
  106. );
  107. expect(result.SCHEMA_COMMENT).to.equal('myComment');
  108. });
  109. }
  110. if (dialect.supports.createSchema.ifNotExists) {
  111. it('does not throw if the schema already exists', async () => {
  112. await queryInterface.createSchema(testSchema);
  113. const postCreationSchemas = await queryInterface.listSchemas();
  114. expect(postCreationSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  115. await queryInterface.createSchema(testSchema, { ifNotExists: true });
  116. const postReplaceSchemas = await queryInterface.listSchemas();
  117. expect(postReplaceSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  118. });
  119. }
  120. if (dialect.supports.createSchema.replace) {
  121. it('replaces a schema if it already exists', async () => {
  122. await queryInterface.createSchema(testSchema);
  123. const postCreationSchemas = await queryInterface.listSchemas();
  124. expect(postCreationSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  125. await queryInterface.createTable(
  126. { tableName: 'testTable', schema: testSchema },
  127. { id: { type: DataTypes.INTEGER, primaryKey: true } },
  128. );
  129. await queryInterface.createSchema(testSchema, { replace: true });
  130. const postReplaceSchemas = await queryInterface.listSchemas();
  131. const postReplaceTables = await queryInterface.listTables({ schema: testSchema });
  132. expect(postReplaceSchemas).to.include(testSchema, 'createSchema did not replace testSchema');
  133. expect(postReplaceTables).to.be.empty;
  134. });
  135. }
  136. it(`passes options through to the queryInterface's queryGenerator`, async () => {
  137. const options: CreateSchemaQueryOptions = {
  138. collate: 'en_US.UTF-8',
  139. charset: 'utf8mb4',
  140. };
  141. const queryGeneratorSpy = spy(sequelize.queryGenerator, 'createSchemaQuery');
  142. try {
  143. await queryInterface.createSchema(testSchema, options);
  144. } catch {
  145. // Dialects which don't support collate/charset will throw
  146. }
  147. expect(queryGeneratorSpy.args[0]).to.include(options);
  148. });
  149. it('drops a schema', async () => {
  150. await queryInterface.createSchema(testSchema);
  151. const preDeletionSchemas = await queryInterface.listSchemas();
  152. expect(preDeletionSchemas).to.include(testSchema, 'createSchema did not create testSchema');
  153. await queryInterface.dropSchema(testSchema);
  154. const postDeletionSchemas = await queryInterface.listSchemas();
  155. expect(postDeletionSchemas).to.not.include(testSchema, 'dropSchema did not drop testSchema');
  156. });
  157. it('shows all schemas', async () => {
  158. await queryInterface.createSchema(testSchema);
  159. const allSchemas = await queryInterface.listSchemas();
  160. const expected = !dialect.supports.multiDatabases
  161. ? [sequelize.dialect.getDefaultSchema(), testSchema]
  162. : [testSchema];
  163. expect(allSchemas.sort()).to.deep.eq(expected.sort(basicComparator()));
  164. });
  165. });