Skip to content

Commit

Permalink
fix: perfer using model than attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
lohart13 committed Feb 7, 2024
1 parent b1feda2 commit a2c0e18
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 84 deletions.
22 changes: 12 additions & 10 deletions packages/core/src/dialects/abstract/query-generator-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,17 +806,18 @@ export class AbstractQueryGeneratorTypeScript {
throw new Error('Invalid values: []. Expected at least one element.');
}

const model = isModelStatic(tableName) ? tableName : options?.model;
const allColumns = new Set<string>();
const valueHashes = removeNullishValuesFromArray(values, this.options.omitNull ?? false);
const attributeMap = new Map<string, AttributeOptions>();
const bulkInsertOptions = { model: isModelStatic(tableName) ? tableName : undefined, ...options };
const bulkInsertOptions = { ...options, model };

if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (bulkInsertOptions.model) {
for (const [column, attribute] of Object.entries(bulkInsertOptions.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down Expand Up @@ -922,21 +923,22 @@ export class AbstractQueryGeneratorTypeScript {
}

const bind = Object.create(null);
const model = isModelStatic(tableName) ? tableName : options?.model;
const valueMap = new Map<string, string>();
const valueHash = removeNullishValuesFromHash(value, this.options.omitNull ?? false);
const attributeMap = new Map<string, AttributeOptions>();
const insertOptions: InsertQueryOptions = {
model: isModelStatic(tableName) ? tableName : undefined,
...options,
model,
bindParam: options?.bindParam === undefined ? this.bindParam(bind) : options.bindParam,
};

if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (insertOptions.model) {
for (const [column, attribute] of Object.entries(insertOptions.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/dialects/abstract/query-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,6 @@ export class AbstractQueryInterface extends AbstractQueryInterfaceTypeScript {
tableName,
values,
options,
modelDefinition && getObjectFromMap(modelDefinition.attributes),
);

options.type = QueryTypes.INSERT;
Expand Down
26 changes: 10 additions & 16 deletions packages/core/src/dialects/db2/query-generator-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,17 +237,14 @@ export class Db2QueryGeneratorTypeScript extends AbstractQueryGenerator {
const query = super.bulkInsertQuery(tableName, values, { ...options, returning: false }, attributeHash);

if (options?.returning) {
const model = isModelStatic(tableName) ? tableName : options?.model;
const attributeMap = new Map<string, AttributeOptions>();
if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (isModelStatic(tableName)) {
for (const [column, attribute] of Object.entries(tableName.getAttributes())) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (options.model) {
for (const [column, attribute] of Object.entries(options.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand All @@ -273,17 +270,14 @@ export class Db2QueryGeneratorTypeScript extends AbstractQueryGenerator {
const { query, bind } = super.insertQuery(tableName, value, { ...options, returning: false }, attributeHash);

if (options?.returning) {
const model = isModelStatic(tableName) ? tableName : options?.model;
const attributeMap = new Map<string, AttributeOptions>();
if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (isModelStatic(tableName)) {
for (const [column, attribute] of Object.entries(tableName.getAttributes())) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (options.model) {
for (const [column, attribute] of Object.entries(options.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down
26 changes: 10 additions & 16 deletions packages/core/src/dialects/ibmi/query-generator-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,14 @@ export class IBMiQueryGeneratorTypeScript extends AbstractQueryGenerator {
const query = super.bulkInsertQuery(tableName, values, { ...options, returning: false }, attributeHash);

if (options?.returning) {
const model = isModelStatic(tableName) ? tableName : options?.model;
const attributeMap = new Map<string, AttributeOptions>();
if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (isModelStatic(tableName)) {
for (const [column, attribute] of Object.entries(tableName.getAttributes())) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (options.model) {
for (const [column, attribute] of Object.entries(options.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand All @@ -243,17 +240,14 @@ export class IBMiQueryGeneratorTypeScript extends AbstractQueryGenerator {
const { query, bind } = super.insertQuery(tableName, value, { ...options, returning: false }, attributeHash);

if (options?.returning) {
const model = isModelStatic(tableName) ? tableName : options?.model;
const attributeMap = new Map<string, AttributeOptions>();
if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (isModelStatic(tableName)) {
for (const [column, attribute] of Object.entries(tableName.getAttributes())) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (options.model) {
for (const [column, attribute] of Object.entries(options.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down
22 changes: 12 additions & 10 deletions packages/core/src/dialects/mssql/query-generator-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,17 +401,18 @@ export class MsSqlQueryGeneratorTypeScript extends AbstractQueryGenerator {
throw new Error('Invalid values: []. Expected at least one element.');
}

const model = isModelStatic(tableName) ? tableName : options?.model;
const allColumns = new Set<string>();
const valueHashes = removeNullishValuesFromArray(values, this.options.omitNull ?? false);
const attributeMap = new Map<string, AttributeOptions>();
const bulkInsertOptions = { model: isModelStatic(tableName) ? tableName : undefined, ...options };
const bulkInsertOptions = { ...options, model };

if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (bulkInsertOptions.model) {
for (const [column, attribute] of Object.entries(bulkInsertOptions.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down Expand Up @@ -557,21 +558,22 @@ export class MsSqlQueryGeneratorTypeScript extends AbstractQueryGenerator {
}

const bind = Object.create(null);
const model = isModelStatic(tableName) ? tableName : options?.model;
const valueMap = new Map<string, string>();
const valueHash = removeNullishValuesFromHash(value, this.options.omitNull ?? false);
const attributeMap = new Map<string, AttributeOptions>();
const insertOptions: InsertQueryOptions = {
model: isModelStatic(tableName) ? tableName : undefined,
...options,
model,
bindParam: options?.bindParam === undefined ? this.bindParam(bind) : options.bindParam,
};

if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (insertOptions.model) {
for (const [column, attribute] of Object.entries(insertOptions.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,13 @@ export class PostgresQueryGeneratorTypeScript extends AbstractQueryGenerator {
}

const bind = Object.create(null);
const model = isModelStatic(tableName) ? tableName : options?.model;
const valueMap = new Map<string, string>();
const valueHash = removeNullishValuesFromHash(value, this.options.omitNull ?? false);
const attributeMap = new Map<string, AttributeOptions>();
const insertOptions: InsertQueryOptions = {
model: isModelStatic(tableName) ? tableName : undefined,
...options,
model,
bindParam: options?.bindParam === undefined ? this.bindParam(bind) : options.bindParam,
};

Expand All @@ -272,12 +273,12 @@ export class PostgresQueryGeneratorTypeScript extends AbstractQueryGenerator {
insertOptions.bindParam = undefined;
}

if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (insertOptions.model) {
for (const [column, attribute] of Object.entries(insertOptions.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down
22 changes: 12 additions & 10 deletions packages/core/src/dialects/sqlite/query-generator-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,17 +215,18 @@ export class SqliteQueryGeneratorTypeScript extends AbstractQueryGenerator {
throw new Error('Invalid values: []. Expected at least one element.');
}

const model = isModelStatic(tableName) ? tableName : options?.model;
const allColumns = new Set<string>();
const valueHashes = removeNullishValuesFromArray(values, this.options.omitNull ?? false);
const attributeMap = new Map<string, AttributeOptions>();
const bulkInsertOptions = { model: isModelStatic(tableName) ? tableName : undefined, ...options };
const bulkInsertOptions = { ...options, model };

if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (bulkInsertOptions.model) {
for (const [column, attribute] of Object.entries(bulkInsertOptions.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down Expand Up @@ -301,21 +302,22 @@ export class SqliteQueryGeneratorTypeScript extends AbstractQueryGenerator {
}

const bind = Object.create(null);
const model = isModelStatic(tableName) ? tableName : options?.model;
const valueMap = new Map<string, string>();
const valueHash = removeNullishValuesFromHash(value, this.options.omitNull ?? false);
const attributeMap = new Map<string, AttributeOptions>();
const insertOptions: InsertQueryOptions = {
model: isModelStatic(tableName) ? tableName : undefined,
...options,
model,
bindParam: options?.bindParam === undefined ? this.bindParam(bind) : options.bindParam,
};

if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
if (model) {
for (const [column, attribute] of model.modelDefinition.physicalAttributes.entries()) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
} else if (insertOptions.model) {
for (const [column, attribute] of Object.entries(insertOptions.model.getAttributes())) {
} else if (attributeHash) {
for (const [column, attribute] of Object.entries(attributeHash)) {
attributeMap.set(attribute?.columnName ?? column, attribute);
}
}
Expand Down
11 changes: 2 additions & 9 deletions packages/core/src/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -2261,13 +2261,6 @@ ${associationOwner._getAssociationDebugList()}`);
return out;
});

// Map attributes to fields for serial identification
const fieldMappedAttributes = Object.create(null);
for (const attrName in model.tableAttributes) {
const attribute = modelDefinition.attributes.get(attrName);
fieldMappedAttributes[attribute.columnName] = attribute;
}

// Map updateOnDuplicate attributes to fields
if (options.updateOnDuplicate) {
options.updateOnDuplicate = options.updateOnDuplicate.map(attrName => {
Expand Down Expand Up @@ -2298,7 +2291,7 @@ ${associationOwner._getAssociationDebugList()}`);
options.returning = options.returning.map(attr => modelDefinition.getColumnNameLoose(attr));
}

const results = await model.queryInterface.bulkInsert(model.getTableName(options), records, options, fieldMappedAttributes);
const results = await model.queryInterface.bulkInsert(model, records, options);
if (Array.isArray(results)) {
for (const [i, result] of results.entries()) {
const instance = instances[i];
Expand Down Expand Up @@ -3755,7 +3748,7 @@ Instead of specifying a Model, either:

if (this.isNewRecord) {
query = 'insert';
args = [this, this.constructor.getTableName(options), values, options];
args = [this, this.constructor, values, options];
}

const [result, rowsUpdated] = await this.constructor.queryInterface[query](...args);
Expand Down
6 changes: 3 additions & 3 deletions packages/core/test/unit/query-interface/bulk-insert.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('QueryInterface#bulkInsert', () => {
const stub = sinon.stub(sequelize, 'queryRaw').resolves([[], 0]);

const users = range(1000).map(i => ({ firstName: `user${i}` }));
await sequelize.queryInterface.bulkInsert(User.table, users);
await sequelize.queryInterface.bulkInsert(User, users);

expect(stub.callCount).to.eq(1);
const firstCall = stub.getCall(0).args[0];
Expand All @@ -33,7 +33,7 @@ describe('QueryInterface#bulkInsert', () => {
const transaction = new Transaction(sequelize, {});

const users = range(2000).map(i => ({ firstName: `user${i}` }));
await sequelize.queryInterface.bulkInsert(User.table, users, { transaction });
await sequelize.queryInterface.bulkInsert(User, users, { transaction });

expect(stub.callCount).to.eq(1);
const firstCall = stub.getCall(0).args[0];
Expand All @@ -48,7 +48,7 @@ describe('QueryInterface#bulkInsert', () => {
it('does not parse replacements outside of raw sql', async () => {
const stub = sinon.stub(sequelize, 'queryRaw').resolves([[], 0]);

await sequelize.queryInterface.bulkInsert(User.table, [{
await sequelize.queryInterface.bulkInsert(User, [{
firstName: ':injection',
}], {
replacements: {
Expand Down
8 changes: 4 additions & 4 deletions packages/core/test/unit/query-interface/insert.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('QueryInterface#insert', () => {
it('does not parse replacements outside of raw sql', async () => {
const stub = sinon.stub(sequelize, 'queryRaw');

await sequelize.queryInterface.insert(null, User.table, {
await sequelize.queryInterface.insert(null, User, {
firstName: 'Zoe',
}, {
returning: sequelize.dialect.supports.insert.returning ? [':data'] : undefined,
Expand All @@ -42,7 +42,7 @@ describe('QueryInterface#insert', () => {
it('throws if a bind parameter name starts with the reserved "sequelize_" prefix', async () => {
sinon.stub(sequelize, 'queryRaw');

await expect(sequelize.queryInterface.insert(null, User.table, {
await expect(sequelize.queryInterface.insert(null, User, {
firstName: literal('$sequelize_test'),
}, {
bind: {
Expand All @@ -54,7 +54,7 @@ describe('QueryInterface#insert', () => {
it('merges user-provided bind parameters with sequelize-generated bind parameters (object bind)', async () => {
const stub = sinon.stub(sequelize, 'queryRaw');

await sequelize.queryInterface.insert(null, User.table, {
await sequelize.queryInterface.insert(null, User, {
firstName: literal('$firstName'),
lastName: 'Doe',
}, {
Expand All @@ -78,7 +78,7 @@ describe('QueryInterface#insert', () => {
it('merges user-provided bind parameters with sequelize-generated bind parameters (array bind)', async () => {
const stub = sinon.stub(sequelize, 'queryRaw');

await sequelize.queryInterface.insert(null, User.table, {
await sequelize.queryInterface.insert(null, User, {
firstName: literal('$1'),
lastName: 'Doe',
}, {
Expand Down

0 comments on commit a2c0e18

Please sign in to comment.