diff --git a/.gitignore b/.gitignore index f9ad7fac..00a1f6b3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,11 @@ +.nyc_output +coverage +dist +logs node_modules tmp -coverage -.nyc_output + +*.log docs/Gemfile.lock package-lock.json .DS_Store @@ -9,11 +13,8 @@ test/types/*.js test/types/*.map test/integration/suite/sharding.test.js* test/models/photo.js* +src/browser.js* src/decorators.js* src/data_types.js* +src/drivers/sqljs/*.js* src/raw.js* - -# Logs -logs -*.log -dist/ \ No newline at end of file diff --git a/src/spell.js b/src/spell.js index 2a79fe2a..5731ad21 100644 --- a/src/spell.js +++ b/src/spell.js @@ -170,7 +170,7 @@ function joinOnConditions(spell, BaseModel, baseName, refName, { where, associat return { type: 'op', name: 'and', args: [ result, condition ] }; }); walkExpr(whereConditions, node => { - if (node.type == 'id') node.qualifiers = [refName]; + if (node.type == 'id' && !node.qualifiers) node.qualifiers = [refName]; }); return { type: 'op', name: 'and', args: [ onConditions, whereConditions ] }; } else { @@ -386,8 +386,18 @@ class Spell { } #emptySpell() { + const whereConditions = []; + const { shardingKey } = this.Model; + if (shardingKey) { + for (const condition of this.whereConditions) { + const [arg] = condition.args; + if (arg.type === 'id' && arg.value === shardingKey) { + whereConditions.push(deepClone(condition)); + } + } + } Object.assign(this, { - whereConditions: [], + whereConditions, groups: [], orders: deepClone(this.orders), havingConditions: [], diff --git a/test/dumpfile.sql b/test/dumpfile.sql index 66cc43e6..3eb0d344 100644 --- a/test/dumpfile.sql +++ b/test/dumpfile.sql @@ -74,7 +74,8 @@ CREATE TABLE `likes` ( `id` bigint(20) AUTO_INCREMENT PRIMARY KEY, `gmt_create` timestamp(3) NULL, `gmt_modified` timestamp DEFAULT CURRENT_TIMESTAMP, - `article_id` bigint(20) NOT NULL, + `target_id` bigint(20) NOT NULL, + `target_type` bigint(20) NOT NULL, `user_id` bigint(20) NOT NULL, `gmt_deleted` timestamp(3) NULL ); diff --git a/test/integration/suite/associations.test.js b/test/integration/suite/associations.test.js index 80ddf792..dbae658c 100644 --- a/test/integration/suite/associations.test.js +++ b/test/integration/suite/associations.test.js @@ -6,6 +6,7 @@ const sinon = require('sinon'); const Attachment = require('../../models/attachment'); const Comment = require('../../models/comment'); +const Like = require('../../models/like'); const Post = require('../../models/post'); const Tag = require('../../models/tag'); const TagMap = require('../../models/tagMap'); @@ -76,7 +77,8 @@ describe('=> Associations', function() { Attachment.remove({}, true), Comment.remove({}, true), TagMap.remove({}, true), - Tag.remove({}, true) + Tag.remove({}, true), + Like.remove({ userId: 1 }, true), ]); }); @@ -96,6 +98,14 @@ describe('=> Associations', function() { expect(attachment.post).to.be.a(Post); }); + it('Bone.belongsTo({ where })', async function() { + await Like.create({ targetId: 1, targetType: 0, userId: 1 }); + await assert.doesNotReject(async function() { + const like = await Like.findOne({ userId: 1 }).with('post'); + assert.ok('post' in like); + }); + }); + it('Bone.hasMany', async function() { let post = await Post.first.with('comments'); expect(post.comments.length).to.be.above(0); diff --git a/test/integration/suite/querying.test.js b/test/integration/suite/querying.test.js index 69fa4262..d7cc0b85 100644 --- a/test/integration/suite/querying.test.js +++ b/test/integration/suite/querying.test.js @@ -768,13 +768,13 @@ describe('=> Sharding', function() { it('should throw if sharding key is defined but not set when INSERT', async function() { await assert.rejects(async () => { - await new Like({ articleId: 1, userId: null }).create({ validate: false }); + await new Like({ targetId: 1, targetType: 0, userId: null }).create({ validate: false }); }, /sharding key/i); }); it('should not throw if sharding key is defined and set when INSERT', async function() { await assert.doesNotReject(async () => { - await new Like({ userId: 1, articleId: 1 }).create(); + await new Like({ userId: 1, targetId: 1, targetType: 0 }).create(); }, /sharding key/i); }); @@ -803,7 +803,7 @@ describe('=> Sharding', function() { }); it('should append sharding key to DELETE condition', async function() { - const like = await Like.create({ articleId: 1, userId: 1 }); + const like = await Like.create({ targetId: 1, targetType: 0, userId: 1 }); await assert.doesNotReject(async () => { await like.remove(); await like.remove(true); @@ -811,15 +811,15 @@ describe('=> Sharding', function() { }); it('should append sharding key to UPDATE condition', async function() { - const like = await Like.create({ articleId: 1, userId: 1}); - like.articleId = 2; + const like = await Like.create({ targetId: 1, targetType: 0, userId: 1}); + like.targetId = 2; await assert.doesNotReject(async () => { await like.update(); }, /sharding key/i); }); it('should append sharking key to SELECT condition', async function() { - const like = await Like.create({ articleId: 1, userId: 1}); + const like = await Like.create({ targetId: 1, targetType: 0, userId: 1}); await assert.doesNotReject(async () => { await like.reload(); }, /sharding key/); diff --git a/test/models/like.js b/test/models/like.js index 3d71f8e4..a70119be 100644 --- a/test/models/like.js +++ b/test/models/like.js @@ -2,6 +2,11 @@ const { Bone } =require('../..'); +const TARGET_TYPE = { + post: 0, + comment: 1, +}; + class Like extends Bone { static get table() { return 'likes'; @@ -14,6 +19,13 @@ class Like extends Bone { static get shardingKey() { return 'userId'; } + + static initialize() { + this.belongsTo('post', { + foreignKey: 'targetId', + where: { 'likes.targetType': TARGET_TYPE.post }, + }); + } } module.exports = Like;