123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- 'use strict';
- const { expect } = require('chai');
- const { createSingleTestSequelizeInstance, sequelize: current } = require('../support');
- const { DataTypes, Op } = require('@sequelize/core');
- const SCHEMA_ONE = 'schema_one';
- const SCHEMA_TWO = 'schema_two';
- let locationId;
- describe('Model', () => {
- if (!current.dialect.supports.schemas) {
- return;
- }
- describe('global schema', () => {
- let schemaTwoSequelize;
- beforeEach('build restaurant tables', async function () {
- schemaTwoSequelize = createSingleTestSequelizeInstance({
- schema: SCHEMA_TWO,
- });
- this.RestaurantOne = schemaTwoSequelize.define(
- 'RestaurantOne',
- {
- foo: DataTypes.STRING,
- bar: DataTypes.STRING,
- },
- { schema: current.dialect.getDefaultSchema(), tableName: 'restaurants' },
- );
- this.LocationOne = schemaTwoSequelize.define(
- 'LocationOne',
- {
- name: DataTypes.STRING,
- },
- { schema: current.dialect.getDefaultSchema(), tableName: 'locations' },
- );
- this.RestaurantOne.belongsTo(this.LocationOne, {
- foreignKey: 'location_id',
- foreignKeyConstraints: false,
- as: 'location',
- });
- this.RestaurantTwo = schemaTwoSequelize.define(
- 'RestaurantTwo',
- {
- foo: DataTypes.STRING,
- bar: DataTypes.STRING,
- },
- { tableName: 'restaurants' },
- );
- this.LocationTwo = schemaTwoSequelize.define(
- 'LocationTwo',
- {
- name: DataTypes.STRING,
- },
- { tableName: 'locations' },
- );
- this.RestaurantTwo.belongsTo(this.LocationTwo, {
- foreignKey: 'location_id',
- foreignKeyConstraints: false,
- as: 'location',
- });
- await schemaTwoSequelize.createSchema(SCHEMA_TWO);
- await schemaTwoSequelize.sync({ force: true });
- });
- describe('Add data via model.create, retrieve via model.findOne', () => {
- it('should be able to sync model without schema option', function () {
- expect(this.RestaurantOne.table.schema).to.eq(current.dialect.getDefaultSchema());
- expect(this.RestaurantTwo.table.schema).to.equal(SCHEMA_TWO);
- });
- it('should be able to insert data into default table using create', async function () {
- await this.RestaurantOne.create({
- foo: 'one',
- });
- const obj0 = await this.RestaurantOne.findOne({
- where: { foo: 'one' },
- });
- expect(obj0).to.not.be.null;
- expect(obj0.foo).to.equal('one');
- const obj = await this.RestaurantTwo.findOne({
- where: { foo: 'one' },
- });
- expect(obj).to.be.null;
- });
- it('should be able to insert data into schema table using create', async function () {
- await this.RestaurantTwo.create({
- foo: 'two',
- });
- const obj0 = await this.RestaurantTwo.findOne({
- where: { foo: 'two' },
- });
- expect(obj0).to.not.be.null;
- expect(obj0.foo).to.equal('two');
- const obj = await this.RestaurantOne.findOne({
- where: { foo: 'two' },
- });
- expect(obj).to.be.null;
- });
- });
- describe('Get associated data in public schema via include', () => {
- beforeEach(async function () {
- await Promise.all([
- this.LocationOne.sync({ force: true }),
- this.LocationTwo.sync({ force: true }),
- ]);
- await this.LocationTwo.create({ name: 'HQ' });
- const obj0 = await this.LocationTwo.findOne({ where: { name: 'HQ' } });
- expect(obj0).to.not.be.null;
- expect(obj0.name).to.equal('HQ');
- locationId = obj0.id;
- const obj = await this.LocationOne.findOne({ where: { name: 'HQ' } });
- expect(obj).to.be.null;
- });
- // TODO: fix https://github.com/sequelize/sequelize/issues/17091
- it.skip('should be able to insert and retrieve associated data into the table in schema_two', async function () {
- await this.RestaurantTwo.create({
- foo: 'two',
- location_id: locationId,
- });
- const obj0 = await this.RestaurantTwo.findOne({
- where: { foo: 'two' },
- include: [
- {
- model: this.LocationTwo,
- as: 'location',
- },
- ],
- });
- expect(obj0).to.not.be.null;
- expect(obj0.foo).to.equal('two');
- expect(obj0.location).to.not.be.null;
- expect(obj0.location.name).to.equal('HQ');
- const obj = await this.RestaurantOne.findOne({ where: { foo: 'two' } });
- expect(obj).to.be.null;
- });
- });
- });
- describe('schemas', () => {
- beforeEach('build restaurant tables', async function () {
- this.Restaurant = current.define(
- 'restaurant',
- {
- foo: DataTypes.STRING,
- bar: DataTypes.STRING,
- },
- { tableName: 'restaurants' },
- );
- this.Location = current.define(
- 'location',
- {
- name: DataTypes.STRING,
- },
- { tableName: 'locations' },
- );
- this.Employee = current.define(
- 'employee',
- {
- first_name: DataTypes.STRING,
- last_name: DataTypes.STRING,
- },
- { tableName: 'employees' },
- );
- this.Restaurant.belongsTo(this.Location, {
- foreignKey: 'location_id',
- foreignKeyConstraints: false,
- });
- this.Employee.belongsTo(this.Restaurant, {
- foreignKey: 'restaurant_id',
- foreignKeyConstraints: false,
- });
- this.Restaurant.hasMany(this.Employee, {
- foreignKey: 'restaurant_id',
- foreignKeyConstraints: false,
- });
- this.EmployeeOne = this.Employee.withSchema(SCHEMA_ONE);
- this.EmployeeTwo = this.Employee.withSchema(SCHEMA_TWO);
- this.RestaurantOne = this.Restaurant.withSchema(SCHEMA_ONE);
- this.RestaurantTwo = this.Restaurant.withSchema(SCHEMA_TWO);
- await Promise.all([current.createSchema(SCHEMA_ONE), current.createSchema(SCHEMA_TWO)]);
- await Promise.all([
- this.RestaurantOne.sync({ force: true }),
- this.RestaurantTwo.sync({ force: true }),
- ]);
- });
- describe('Add data via model.create, retrieve via model.findOne', () => {
- it('should be able to insert data into the table in schema_one using create', async function () {
- await this.RestaurantOne.create({
- foo: 'one',
- location_id: locationId,
- });
- const obj0 = await this.RestaurantOne.findOne({
- where: { foo: 'one' },
- });
- expect(obj0).to.not.be.null;
- expect(obj0.foo).to.equal('one');
- const restaurantId = obj0.id;
- const obj = await this.RestaurantOne.findByPk(restaurantId);
- expect(obj).to.not.be.null;
- expect(obj.foo).to.equal('one');
- const RestaurantObj = await this.RestaurantTwo.findOne({ where: { foo: 'one' } });
- expect(RestaurantObj).to.be.null;
- });
- it('should be able to insert data into the table in schema_two using create', async function () {
- await this.RestaurantTwo.create({
- foo: 'two',
- location_id: locationId,
- });
- const obj0 = await this.RestaurantTwo.findOne({
- where: { foo: 'two' },
- });
- expect(obj0).to.not.be.null;
- expect(obj0.foo).to.equal('two');
- const restaurantId = obj0.id;
- const obj = await this.RestaurantTwo.findByPk(restaurantId);
- expect(obj).to.not.be.null;
- expect(obj.foo).to.equal('two');
- const RestaurantObj = await this.RestaurantOne.findOne({ where: { foo: 'two' } });
- expect(RestaurantObj).to.be.null;
- });
- });
- describe('Persist and retrieve data', () => {
- it('should be able to insert data into both schemas using instance.save and retrieve/count it', async function () {
- // building and saving in random order to make sure calling
- // .schema doesn't impact model prototype
- let restaurauntModel = this.RestaurantOne.build({ bar: 'one.1' });
- await restaurauntModel.save();
- restaurauntModel = this.RestaurantTwo.build({ bar: 'two.1' });
- await restaurauntModel.save();
- restaurauntModel = this.RestaurantOne.build({ bar: 'one.2' });
- await restaurauntModel.save();
- restaurauntModel = this.RestaurantTwo.build({ bar: 'two.2' });
- await restaurauntModel.save();
- restaurauntModel = this.RestaurantTwo.build({ bar: 'two.3' });
- await restaurauntModel.save();
- const restaurantsOne1 = await this.RestaurantOne.findAll();
- expect(restaurantsOne1).to.not.be.null;
- expect(restaurantsOne1.length).to.equal(2);
- for (const restaurant of restaurantsOne1) {
- expect(restaurant.bar).to.contain('one');
- }
- const restaurantsOne0 = await this.RestaurantOne.findAndCountAll();
- expect(restaurantsOne0).to.not.be.null;
- expect(restaurantsOne0.rows.length).to.equal(2);
- expect(restaurantsOne0.count).to.equal(2);
- for (const restaurant of restaurantsOne0.rows) {
- expect(restaurant.bar).to.contain('one');
- }
- const restaurantsOne = await this.RestaurantOne.findAll({
- where: { bar: { [Op.like]: '%.1' } },
- });
- expect(restaurantsOne).to.not.be.null;
- expect(restaurantsOne.length).to.equal(1);
- for (const restaurant of restaurantsOne) {
- expect(restaurant.bar).to.contain('one');
- }
- const count0 = await this.RestaurantOne.count();
- expect(count0).to.not.be.null;
- expect(count0).to.equal(2);
- const restaurantsTwo1 = await this.RestaurantTwo.findAll();
- expect(restaurantsTwo1).to.not.be.null;
- expect(restaurantsTwo1.length).to.equal(3);
- for (const restaurant of restaurantsTwo1) {
- expect(restaurant.bar).to.contain('two');
- }
- const restaurantsTwo0 = await this.RestaurantTwo.findAndCountAll();
- expect(restaurantsTwo0).to.not.be.null;
- expect(restaurantsTwo0.rows.length).to.equal(3);
- expect(restaurantsTwo0.count).to.equal(3);
- for (const restaurant of restaurantsTwo0.rows) {
- expect(restaurant.bar).to.contain('two');
- }
- const restaurantsTwo = await this.RestaurantTwo.findAll({
- where: { bar: { [Op.like]: '%.3' } },
- });
- expect(restaurantsTwo).to.not.be.null;
- expect(restaurantsTwo.length).to.equal(1);
- for (const restaurant of restaurantsTwo) {
- expect(restaurant.bar).to.contain('two');
- }
- const count = await this.RestaurantTwo.count();
- expect(count).to.not.be.null;
- expect(count).to.equal(3);
- });
- });
- describe('Get associated data in public schema via include', () => {
- beforeEach(async function () {
- const Location = this.Location;
- await Location.sync({ force: true });
- await Location.create({ name: 'HQ' });
- const obj = await Location.findOne({ where: { name: 'HQ' } });
- expect(obj).to.not.be.null;
- expect(obj.name).to.equal('HQ');
- locationId = obj.id;
- });
- it('should be able to insert and retrieve associated data into the table in schema_one', async function () {
- await this.RestaurantOne.create({
- foo: 'one',
- location_id: locationId,
- });
- const obj = await this.RestaurantOne.findOne({
- where: { foo: 'one' },
- include: [
- {
- model: this.Location,
- as: 'location',
- },
- ],
- });
- expect(obj).to.not.be.null;
- expect(obj.foo).to.equal('one');
- expect(obj.location).to.not.be.null;
- expect(obj.location.name).to.equal('HQ');
- });
- });
- describe('Get schema specific associated data via include', () => {
- beforeEach(async function () {
- await this.EmployeeOne.sync({ force: true });
- await this.EmployeeTwo.sync({ force: true });
- });
- it('should be able to insert and retrieve associated data into the table in schema_one', async function () {
- await this.RestaurantOne.create({
- foo: 'one',
- });
- const obj1 = await this.RestaurantOne.findOne({
- where: { foo: 'one' },
- });
- expect(obj1).to.not.be.null;
- expect(obj1.foo).to.equal('one');
- const restaurantId = obj1.id;
- await this.EmployeeOne.create({
- first_name: 'Restaurant',
- last_name: 'one',
- restaurant_id: restaurantId,
- });
- const obj0 = await this.RestaurantOne.findOne({
- where: { foo: 'one' },
- include: [
- {
- model: this.EmployeeOne,
- as: 'employees',
- },
- ],
- });
- expect(obj0).to.not.be.null;
- expect(obj0.employees).to.not.be.null;
- expect(obj0.employees.length).to.equal(1);
- expect(obj0.employees[0].last_name).to.equal('one');
- const employees = await obj0.getEmployees({ schema: SCHEMA_ONE });
- expect(employees.length).to.equal(1);
- expect(employees[0].last_name).to.equal('one');
- const obj = await this.EmployeeOne.findOne({
- where: { last_name: 'one' },
- include: [
- {
- model: this.RestaurantOne,
- as: 'restaurant',
- },
- ],
- });
- expect(obj).to.not.be.null;
- expect(obj.restaurant).to.not.be.null;
- expect(obj.restaurant.foo).to.equal('one');
- const restaurant = await obj.getRestaurant({ schema: SCHEMA_ONE });
- expect(restaurant).to.not.be.null;
- expect(restaurant.foo).to.equal('one');
- });
- it('should be able to insert and retrieve associated data into the table in schema_two', async function () {
- await this.RestaurantTwo.create({
- foo: 'two',
- });
- const obj1 = await this.RestaurantTwo.findOne({
- where: { foo: 'two' },
- });
- expect(obj1).to.not.be.null;
- expect(obj1.foo).to.equal('two');
- const restaurantId = obj1.id;
- await this.EmployeeTwo.create({
- first_name: 'Restaurant',
- last_name: 'two',
- restaurant_id: restaurantId,
- });
- const obj0 = await this.RestaurantTwo.findOne({
- where: { foo: 'two' },
- include: [
- {
- model: this.EmployeeTwo,
- as: 'employees',
- },
- ],
- });
- expect(obj0).to.not.be.null;
- expect(obj0.employees).to.not.be.null;
- expect(obj0.employees.length).to.equal(1);
- expect(obj0.employees[0].last_name).to.equal('two');
- const employees = await obj0.getEmployees({ schema: SCHEMA_TWO });
- expect(employees.length).to.equal(1);
- expect(employees[0].last_name).to.equal('two');
- const obj = await this.Employee.withSchema(SCHEMA_TWO).findOne({
- where: { last_name: 'two' },
- include: [
- {
- model: this.RestaurantTwo,
- as: 'restaurant',
- },
- ],
- });
- expect(obj).to.not.be.null;
- expect(obj.restaurant).to.not.be.null;
- expect(obj.restaurant.foo).to.equal('two');
- const restaurant = await obj.getRestaurant({ schema: SCHEMA_TWO });
- expect(restaurant).to.not.be.null;
- expect(restaurant.foo).to.equal('two');
- });
- });
- describe('concurency tests', () => {
- it('should build and persist instances to 2 schemas concurrently in any order', async function () {
- const Restaurant = this.Restaurant;
- let restaurauntModelSchema1 = Restaurant.withSchema(SCHEMA_ONE).build({ bar: 'one.1' });
- const restaurauntModelSchema2 = Restaurant.withSchema(SCHEMA_TWO).build({ bar: 'two.1' });
- await restaurauntModelSchema1.save();
- restaurauntModelSchema1 = Restaurant.withSchema(SCHEMA_ONE).build({ bar: 'one.2' });
- await restaurauntModelSchema2.save();
- await restaurauntModelSchema1.save();
- const restaurantsOne = await Restaurant.withSchema(SCHEMA_ONE).findAll();
- expect(restaurantsOne).to.not.be.null;
- expect(restaurantsOne.length).to.equal(2);
- for (const restaurant of restaurantsOne) {
- expect(restaurant.bar).to.contain('one');
- }
- const restaurantsTwo = await Restaurant.withSchema(SCHEMA_TWO).findAll();
- expect(restaurantsTwo).to.not.be.null;
- expect(restaurantsTwo.length).to.equal(1);
- for (const restaurant of restaurantsTwo) {
- expect(restaurant.bar).to.contain('two');
- }
- });
- });
- });
- });
|