Skip to content

Commit

Permalink
fix: fix #260 UPDATE with LIMIT and ORDER should be formatted(mysql o…
Browse files Browse the repository at this point in the history
…nly) (#261)

Co-authored-by: JimmyDaddy <[email protected]>
  • Loading branch information
JimmyDaddy and JimmyDaddy authored Jan 25, 2022
1 parent 2d135d9 commit e20a035
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/adapters/sequelize.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ module.exports = Bone => {
const { where, paranoid, individualHooks } = options;
if (individualHooks) {
let findSpell = this._find(where, options);
translateOptions(findSpell, options);
if (paranoid === false) findSpell = findSpell.unparanoid;
const instances = await findSpell;
if (instances.length) {
Expand All @@ -482,6 +483,7 @@ module.exports = Bone => {
const { where, paranoid = false, validate } = options;
const whereConditions = where || {};
const spell = super.update(whereConditions, values, { validate, hooks: false, ...options });
translateOptions(spell, options);
if (!paranoid) return spell.unparanoid;
return spell;
}
Expand Down
12 changes: 12 additions & 0 deletions src/drivers/abstract/spellbook.js
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,22 @@ function formatUpdate(spell) {
for (const condition of whereConditions) collectLiteral(spell, condition, values);
chunks.push(`WHERE ${formatConditions(spell, whereConditions)}`);
}

const extraOptions = this.formatUpdateExtraOptions(spell);
if (extraOptions.length) {
chunks.push(...extraOptions);
}

return {
sql: chunks.join(' '),
values,
};
}

function formatUpdateExtraOptions() {
return [];
}

/**
* @param {Spell} spell
* @param {Array} columns columns for value set
Expand Down Expand Up @@ -606,4 +616,6 @@ module.exports = {
formatSelectWithoutJoin,
formatUpdateOnDuplicate,
formatReturning,
formatUpdateExtraOptions,
formatOrders
};
10 changes: 10 additions & 0 deletions src/drivers/mysql/spellbook.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,14 @@ module.exports = {
formatReturning() {
return '';
},

formatUpdateExtraOptions(spell) {
const { rowCount, orders } = spell;

const chunks = [];
if (orders.length > 0) chunks.push(`ORDER BY ${this.formatOrders(spell, orders).join(', ')}`);

if (rowCount > 0) chunks.push(`LIMIT ${rowCount}`);
return chunks;
}
};
15 changes: 15 additions & 0 deletions test/integration/suite/basics.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,21 @@ describe('=> Basic', () => {
expect(posts.length).to.equal(affectedRows);
});

it('Bone.update(where, values) should work with limit/offset and order', async function() {
if (Post.driver.type === 'mysql') {
await Promise.all([
Post.create({ title: 'New Post' }),
Post.create({ title: 'New Post 2'})
]);
let affectedRows = await Post.update({ title: { $like: '%Post%' } }, { title: 'Untitled' }).limit(1);
expect(affectedRows).to.equal(1);
affectedRows = await Post.update({}, { title: 'Untitled1' }).limit(1);
expect(affectedRows).to.equal(1);
affectedRows = await Post.update({}, { title: 'Untitled2' }).order('id ASC').limit(2);
expect(affectedRows).to.equal(2);;
}
});

it('Bone.update(where, values) should support customized type', async () => {
const { id } = await Post.create({ title: 'New Post' });
await Post.update({ id }, {
Expand Down
67 changes: 67 additions & 0 deletions test/unit/adapters/sequelize.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1816,6 +1816,11 @@ describe('Transaction', function() {
});
});

after(async () => {
await User.truncate();
Bone.driver = null;
});

it('should be able to manage transaction', async function() {
await assert.rejects(async function() {
await Spine.transaction(async function(transaction) {
Expand All @@ -1831,3 +1836,65 @@ describe('Transaction', function() {
assert.equal(await User.count(), 0);
});
});

describe('Model.update with order, limit (mysql only)', () => {

const Spine = sequelize(Bone);

class Post extends Spine {
static get table() {
return 'articles';
}
};

before(async function() {
await connect({
Model: Spine,
models: [ Post ],
database: 'leoric',
user: 'root',
port: process.env.MYSQL_PORT,
});
});

after(async () => {
await Post.truncate();
Bone.driver = null;
});

it('should work', async () => {

let i = 0;
while (i <= 5) {
await Post.create({ title: 'Throne' });
i += 1;
}
await Post.update({ title: 'Game' }, {
where: {},
limit: 2,
order: 'id ASC',
silent: true,
});
let allPosts = await Post.findAll({ order: 'id ASC' });
assert.equal(allPosts[0].title, 'Game');
assert.equal(allPosts[1].title, 'Game');
assert.equal(allPosts[2].title, 'Throne');
assert.equal(allPosts[3].title, 'Throne');

await Post.bulkUpdate({ title: 'Pilot' }, {
where: {},
limit: 2,
order: 'id ASC',
silent: true,
});
allPosts = await Post.findAll({ order: 'id ASC' });
assert.equal(allPosts[0].title, 'Pilot');
assert.equal(allPosts[1].title, 'Pilot');
assert.equal(allPosts[2].title, 'Throne');
assert.equal(allPosts[3].title, 'Throne');


});


});
17 changes: 17 additions & 0 deletions test/unit/spell.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,23 @@ describe('=> Spell', function() {
assert(/UPDATE `articles` SET `gmt_deleted` = '[\s\S]*' WHERE `title` LIKE '%Post%' AND `gmt_deleted` = '[\s\S]*'$/.test(sqlString));
});

it('update with order, limit and offset', function () {
assert.equal(
User.update({}, { level: 2 }).limit(5).toString(),
'UPDATE `users` SET `level` = 2 LIMIT 5'
);

assert.equal(
User.update({ title: { $like: '%halo%' } }, { level: 2 }).limit(5).toString(),
'UPDATE `users` SET `level` = 2 WHERE `title` LIKE \'%halo%\' LIMIT 5'
);

assert.equal(
User.update({ title: { $like: '%halo%' } }, { level: 2 }).limit(5).order('id DESC').toString(),
'UPDATE `users` SET `level` = 2 WHERE `title` LIKE \'%halo%\' ORDER BY `id` DESC LIMIT 5'
);
});

it('update with raw sql', function() {
assert.equal(
User.update({ id: 1 }, { level: raw('level + 1') }).toString(),
Expand Down

0 comments on commit e20a035

Please sign in to comment.