mirror of
https://github.com/cirosantilli/linux-kernel-module-cheat.git
synced 2026-01-23 02:05:57 +01:00
more sequelize will it ever end
This commit is contained in:
@@ -49,6 +49,8 @@ const post2 = await Post.create({body: 'post2'});
|
|||||||
|
|
||||||
// Make user0 like post0
|
// Make user0 like post0
|
||||||
await user0.addPost(post0)
|
await user0.addPost(post0)
|
||||||
|
// Also works.
|
||||||
|
//await user0.addPost(post0.id)
|
||||||
// Make user0 and user2 like post1
|
// Make user0 and user2 like post1
|
||||||
await post1.addUsers([user0, user2])
|
await post1.addUsers([user0, user2])
|
||||||
|
|
||||||
@@ -68,6 +70,20 @@ const user2Likes = await user2.getPosts({order: [['body', 'ASC']]})
|
|||||||
assert(user2Likes[0].body === 'post1');
|
assert(user2Likes[0].body === 'post1');
|
||||||
assert(user2Likes.length === 1);
|
assert(user2Likes.length === 1);
|
||||||
|
|
||||||
|
// Same as get* but with the user ID instead of the model object.
|
||||||
|
{
|
||||||
|
const user0Likes = await Post.findAll({
|
||||||
|
include: [{
|
||||||
|
model: User,
|
||||||
|
where: {id: user0.id},
|
||||||
|
}],
|
||||||
|
order: [['body', 'ASC']],
|
||||||
|
})
|
||||||
|
assert(user0Likes[0].body === 'post0');
|
||||||
|
assert(user0Likes[1].body === 'post1');
|
||||||
|
assert(user0Likes.length === 2);
|
||||||
|
}
|
||||||
|
|
||||||
// Get users that liked a given likes.
|
// Get users that liked a given likes.
|
||||||
|
|
||||||
const post0Likers = await post0.getUsers({order: [['name', 'ASC']]})
|
const post0Likers = await post0.getUsers({order: [['name', 'ASC']]})
|
||||||
@@ -88,6 +104,7 @@ assert(post1Likers.length === 2);
|
|||||||
|
|
||||||
// Check if user likes post.
|
// Check if user likes post.
|
||||||
assert( await user0.hasPost(post0))
|
assert( await user0.hasPost(post0))
|
||||||
|
assert( await user0.hasPost(post0.id)) // same
|
||||||
assert( await user0.hasPost(post1))
|
assert( await user0.hasPost(post1))
|
||||||
assert(!await user0.hasPost(post2))
|
assert(!await user0.hasPost(post2))
|
||||||
|
|
||||||
@@ -104,7 +121,7 @@ assert(!await user0.hasPosts([post0, post1, post2]))
|
|||||||
assert(await user0.countPosts() === 2)
|
assert(await user0.countPosts() === 2)
|
||||||
assert(await post0.countUsers() === 1)
|
assert(await post0.countUsers() === 1)
|
||||||
|
|
||||||
// Autogenerated remove* method
|
// Autogenerated remove* methods
|
||||||
|
|
||||||
// user0 doesn't like post0 anymore.
|
// user0 doesn't like post0 anymore.
|
||||||
await user0.removePost(post0)
|
await user0.removePost(post0)
|
||||||
|
|||||||
@@ -67,14 +67,40 @@ const post2 = await Post.create({body: 'post2'});
|
|||||||
|
|
||||||
// Autogenerated add* methods
|
// Autogenerated add* methods
|
||||||
|
|
||||||
// Make user0 like post0
|
// Make some useres like some posts.
|
||||||
await user0.addPost(post0, {through: { score: 1 }})
|
await user0.addPost(post0, {through: {score: 1}})
|
||||||
|
await user1.addPost(post1, {through: {score: 2}})
|
||||||
|
await user1.addPost(post2, {through: {score: 3}})
|
||||||
|
|
||||||
|
// Find what user0 likes.
|
||||||
const user0Likes = await user0.getPosts({order: [['body', 'ASC']]})
|
const user0Likes = await user0.getPosts({order: [['body', 'ASC']]})
|
||||||
assert(user0Likes[0].body === 'post0');
|
assert(user0Likes[0].body === 'post0');
|
||||||
assert(user0Likes[0].UserLikesPost.score === 1);
|
assert(user0Likes[0].UserLikesPost.score === 1);
|
||||||
assert(user0Likes.length === 1);
|
assert(user0Likes.length === 1);
|
||||||
|
|
||||||
|
// Find what user1 likes.
|
||||||
|
const user1Likes = await user1.getPosts({order: [['body', 'ASC']]})
|
||||||
|
assert(user1Likes[0].body === 'post1');
|
||||||
|
assert(user1Likes[0].UserLikesPost.score === 2);
|
||||||
|
assert(user1Likes[1].body === 'post2');
|
||||||
|
assert(user1Likes[1].UserLikesPost.score === 3);
|
||||||
|
assert(user1Likes.length === 2);
|
||||||
|
|
||||||
|
// Where on the custom through table column.
|
||||||
|
// https://stackoverflow.com/questions/38857156/how-to-query-many-to-many-relationship-sequelize
|
||||||
|
{
|
||||||
|
const user1LikesWithScore3 = await Post.findAll({
|
||||||
|
include: [{
|
||||||
|
model: User,
|
||||||
|
where: {id: user1.id},
|
||||||
|
through: {where: {score: 3}},
|
||||||
|
}],
|
||||||
|
})
|
||||||
|
assert(user1LikesWithScore3[0].body === 'post2');
|
||||||
|
assert(user1LikesWithScore3[0].UserLikesPost.score === 3);
|
||||||
|
assert(user1LikesWithScore3.length === 1);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: this doesn't work. Possible at all in a single addUsers call?
|
// TODO: this doesn't work. Possible at all in a single addUsers call?
|
||||||
// Make user0 and user2 like post1
|
// Make user0 and user2 like post1
|
||||||
// This method automatically generated.
|
// This method automatically generated.
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const sequelize = new Sequelize({
|
|||||||
const User = sequelize.define('User', {
|
const User = sequelize.define('User', {
|
||||||
name: { type: DataTypes.STRING },
|
name: { type: DataTypes.STRING },
|
||||||
}, {});
|
}, {});
|
||||||
User.belongsToMany(User, {through: 'UserFollowsUser', as: 'Follow'});
|
User.belongsToMany(User, {through: 'UserFollowUser', as: 'Follows'});
|
||||||
await sequelize.sync({force: true});
|
await sequelize.sync({force: true});
|
||||||
|
|
||||||
// Create some users.
|
// Create some users.
|
||||||
@@ -29,12 +29,48 @@ const user2 = await User.create({name: 'user2'})
|
|||||||
const user3 = await User.create({name: 'user3'})
|
const user3 = await User.create({name: 'user3'})
|
||||||
|
|
||||||
// Make user0 follow user1 and user2
|
// Make user0 follow user1 and user2
|
||||||
await user0.addFollow(user1)
|
await user0.addFollows([user1, user2])
|
||||||
await user0.addFollow(user2)
|
// Make user2 and user3 follow user0
|
||||||
const user0Follows = await user0.getFollow({order: [['name', 'ASC']]})
|
await user2.addFollow(user0)
|
||||||
|
await user3.addFollow(user0)
|
||||||
|
|
||||||
|
// Check that the follows worked.
|
||||||
|
const user0Follows = await user0.getFollows({order: [['name', 'ASC']]})
|
||||||
assert(user0Follows[0].name === 'user1');
|
assert(user0Follows[0].name === 'user1');
|
||||||
assert(user0Follows[1].name === 'user2');
|
assert(user0Follows[1].name === 'user2');
|
||||||
assert(user0Follows.length === 2);
|
assert(user0Follows.length === 2);
|
||||||
|
|
||||||
|
const user1Follows = await user1.getFollows({order: [['name', 'ASC']]})
|
||||||
|
assert(user1Follows.length === 0);
|
||||||
|
|
||||||
|
const user2Follows = await user2.getFollows({order: [['name', 'ASC']]})
|
||||||
|
assert(user2Follows[0].name === 'user0');
|
||||||
|
assert(user2Follows.length === 1);
|
||||||
|
|
||||||
|
const user3Follows = await user3.getFollows({order: [['name', 'ASC']]})
|
||||||
|
assert(user3Follows[0].name === 'user0');
|
||||||
|
assert(user3Follows.length === 1);
|
||||||
|
|
||||||
|
// Same but with ID instead of object.
|
||||||
|
{
|
||||||
|
const user0Follows = (await User.findOne({
|
||||||
|
where: {id: user0.id},
|
||||||
|
include: [{model: User, as: 'Follows'}],
|
||||||
|
})).Follows
|
||||||
|
assert(user0Follows[0].name === 'user1');
|
||||||
|
assert(user0Follows[1].name === 'user2');
|
||||||
|
assert(user0Follows.length === 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// has methods
|
||||||
|
assert(!await user0.hasFollow(user0))
|
||||||
|
assert(!await user0.hasFollow(user0.id))
|
||||||
|
assert( await user0.hasFollow(user1))
|
||||||
|
assert( await user0.hasFollow(user2))
|
||||||
|
assert(!await user0.hasFollow(user3))
|
||||||
|
|
||||||
|
// Count method
|
||||||
|
assert(await user0.countFollows() === 2)
|
||||||
|
|
||||||
await sequelize.close();
|
await sequelize.close();
|
||||||
})();
|
})();
|
||||||
|
|||||||
235
rootfs_overlay/lkmc/nodejs/sequelize/association_nested_include.js
Executable file
235
rootfs_overlay/lkmc/nodejs/sequelize/association_nested_include.js
Executable file
@@ -0,0 +1,235 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// Find all posts by users that a given user follows.
|
||||||
|
// https://stackoverflow.com/questions/42632943/sequelize-multiple-where-clause
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const { Sequelize, DataTypes } = require('sequelize');
|
||||||
|
|
||||||
|
const sequelize = new Sequelize({
|
||||||
|
dialect: 'sqlite',
|
||||||
|
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
|
||||||
|
});
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
|
||||||
|
// Create the tables.
|
||||||
|
const User = sequelize.define('User', {
|
||||||
|
name: { type: DataTypes.STRING },
|
||||||
|
}, {});
|
||||||
|
const Post = sequelize.define('Post', {
|
||||||
|
body: { type: DataTypes.STRING },
|
||||||
|
}, {});
|
||||||
|
User.belongsToMany(User, {through: 'UserFollowUser', as: 'Follows'});
|
||||||
|
User.hasMany(Post);
|
||||||
|
Post.belongsTo(User);
|
||||||
|
await sequelize.sync({force: true});
|
||||||
|
|
||||||
|
// Create data.
|
||||||
|
const users = await User.bulkCreate([
|
||||||
|
{name: 'user0'},
|
||||||
|
{name: 'user1'},
|
||||||
|
{name: 'user2'},
|
||||||
|
{name: 'user3'},
|
||||||
|
])
|
||||||
|
|
||||||
|
const posts = await Post.bulkCreate([
|
||||||
|
{body: 'body00', UserId: users[0].id},
|
||||||
|
{body: 'body11', UserId: users[0].id},
|
||||||
|
{body: 'body10', UserId: users[1].id},
|
||||||
|
{body: 'body11', UserId: users[1].id},
|
||||||
|
{body: 'body20', UserId: users[2].id},
|
||||||
|
{body: 'body21', UserId: users[2].id},
|
||||||
|
{body: 'body30', UserId: users[3].id},
|
||||||
|
{body: 'body31', UserId: users[3].id},
|
||||||
|
])
|
||||||
|
|
||||||
|
await users[0].addFollows([users[1], users[2]])
|
||||||
|
|
||||||
|
// Get all posts by authors that user0 follows.
|
||||||
|
// The posts are placed inside their respetive authors under .Posts
|
||||||
|
// so we loop to gather all of them.
|
||||||
|
{
|
||||||
|
const user0Follows = (await User.findByPk(users[0].id, {
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: 'Follows',
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Post,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})).Follows
|
||||||
|
const postsFound = []
|
||||||
|
for (const followedUser of user0Follows) {
|
||||||
|
postsFound.push(...followedUser.Posts)
|
||||||
|
}
|
||||||
|
postsFound.sort((x, y) => { return x.body < y.body ? -1 : x.body > y.body ? 1 : 0 })
|
||||||
|
assert(postsFound[0].body === 'body10')
|
||||||
|
assert(postsFound[1].body === 'body11')
|
||||||
|
assert(postsFound[2].body === 'body20')
|
||||||
|
assert(postsFound[3].body === 'body21')
|
||||||
|
assert(postsFound.length === 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
// With ordering, offset and limit.
|
||||||
|
// The posts are placed inside their respetive authors under .Posts
|
||||||
|
// The only difference is that posts that we didn't select got removed.
|
||||||
|
|
||||||
|
{
|
||||||
|
const user0Follows = (await User.findByPk(users[0].id, {
|
||||||
|
offset: 1,
|
||||||
|
limit: 2,
|
||||||
|
// TODO why is this needed? It does try to make a subquery otherwise, and then it doesn't work.
|
||||||
|
// https://selleo.com/til/posts/ddesmudzmi-offset-pagination-with-subquery-in-sequelize-
|
||||||
|
subQuery: false,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: 'Follows',
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Post,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})).Follows
|
||||||
|
assert(user0Follows[0].name === 'user1')
|
||||||
|
assert(user0Follows[1].name === 'user2')
|
||||||
|
assert(user0Follows.length === 2)
|
||||||
|
const postsFound = []
|
||||||
|
for (const followedUser of user0Follows) {
|
||||||
|
postsFound.push(...followedUser.Posts)
|
||||||
|
}
|
||||||
|
postsFound.sort((x, y) => { return x.body < y.body ? -1 : x.body > y.body ? 1 : 0 })
|
||||||
|
// Note that what happens is that some of the
|
||||||
|
assert(postsFound[0].body === 'body11')
|
||||||
|
assert(postsFound[1].body === 'body20')
|
||||||
|
assert(postsFound.length === 2)
|
||||||
|
|
||||||
|
// Same as above, but now with DESC ordering.
|
||||||
|
{
|
||||||
|
const user0Follows = (await User.findByPk(users[0].id, {
|
||||||
|
order: [[
|
||||||
|
{model: User, as: 'Follows'},
|
||||||
|
Post,
|
||||||
|
'body',
|
||||||
|
'DESC'
|
||||||
|
]],
|
||||||
|
offset: 1,
|
||||||
|
limit: 2,
|
||||||
|
subQuery: false,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: 'Follows',
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Post,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})).Follows
|
||||||
|
// Note how user ordering is also reversed from an ASC.
|
||||||
|
// it likely takes the use that has the first post.
|
||||||
|
assert(user0Follows[0].name === 'user2')
|
||||||
|
assert(user0Follows[1].name === 'user1')
|
||||||
|
assert(user0Follows.length === 2)
|
||||||
|
const postsFound = []
|
||||||
|
for (const followedUser of user0Follows) {
|
||||||
|
postsFound.push(...followedUser.Posts)
|
||||||
|
}
|
||||||
|
// In this very specific data case, this would not be needed.
|
||||||
|
// because user2 has the second post body and user1 has the first
|
||||||
|
// alphabetically.
|
||||||
|
postsFound.sort((x, y) => { return x.body < y.body ? 1 : x.body > y.body ? -1 : 0 })
|
||||||
|
// Note that what happens is that some of the
|
||||||
|
assert(postsFound[0].body === 'body20')
|
||||||
|
assert(postsFound[1].body === 'body11')
|
||||||
|
assert(postsFound.length === 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here user2 would have no post hits due to the limit,
|
||||||
|
// so it is entirely pruned from the user list as desired.
|
||||||
|
// Otherwise we would fetch a lot of unwanted user data
|
||||||
|
// in a large database.
|
||||||
|
const user0FollowsLimit2 = (await User.findByPk(users[0].id, {
|
||||||
|
limit: 2,
|
||||||
|
subQuery: false,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: 'Follows',
|
||||||
|
include: [ { model: Post } ],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})).Follows
|
||||||
|
assert(user0FollowsLimit2[0].name === 'user1')
|
||||||
|
assert(user0FollowsLimit2.length === 1)
|
||||||
|
|
||||||
|
// Case in which our post-sorting is needed.
|
||||||
|
// TODO: possible to get sequelize to do this for us by returning
|
||||||
|
// a flat array directly?
|
||||||
|
// It's not big deal since the LIMITed result should be small,
|
||||||
|
// but feels wasteful.
|
||||||
|
// https://stackoverflow.com/questions/41502699/return-flat-object-from-sequelize-with-association
|
||||||
|
// https://github.com/sequelize/sequelize/issues/4419
|
||||||
|
{
|
||||||
|
await Post.truncate({restartIdentity: true})
|
||||||
|
const posts = await Post.bulkCreate([
|
||||||
|
{body: 'body0', UserId: users[0].id},
|
||||||
|
{body: 'body1', UserId: users[1].id},
|
||||||
|
{body: 'body2', UserId: users[2].id},
|
||||||
|
{body: 'body3', UserId: users[3].id},
|
||||||
|
{body: 'body4', UserId: users[0].id},
|
||||||
|
{body: 'body5', UserId: users[1].id},
|
||||||
|
{body: 'body6', UserId: users[2].id},
|
||||||
|
{body: 'body7', UserId: users[3].id},
|
||||||
|
])
|
||||||
|
const user0Follows = (await User.findByPk(users[0].id, {
|
||||||
|
order: [[
|
||||||
|
{model: User, as: 'Follows'},
|
||||||
|
Post,
|
||||||
|
'body',
|
||||||
|
'DESC'
|
||||||
|
]],
|
||||||
|
subQuery: false,
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: User,
|
||||||
|
as: 'Follows',
|
||||||
|
include: [
|
||||||
|
{
|
||||||
|
model: Post,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})).Follows
|
||||||
|
assert(user0Follows[0].name === 'user2')
|
||||||
|
assert(user0Follows[1].name === 'user1')
|
||||||
|
assert(user0Follows.length === 2)
|
||||||
|
const postsFound = []
|
||||||
|
for (const followedUser of user0Follows) {
|
||||||
|
postsFound.push(...followedUser.Posts)
|
||||||
|
}
|
||||||
|
// We need this here, otherwise we would get all user2 posts first:
|
||||||
|
// body6, body2, body5, body1
|
||||||
|
postsFound.sort((x, y) => { return x.body < y.body ? 1 : x.body > y.body ? -1 : 0 })
|
||||||
|
assert(postsFound[0].body === 'body6')
|
||||||
|
assert(postsFound[1].body === 'body5')
|
||||||
|
assert(postsFound[2].body === 'body2')
|
||||||
|
assert(postsFound[3].body === 'body1')
|
||||||
|
assert(postsFound.length === 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await sequelize.close();
|
||||||
|
})();
|
||||||
@@ -96,7 +96,7 @@ await IntegerNames.create({value: 5, name: 'five'});
|
|||||||
// 3 | 5 | five | 2021-03-19 19:12:08.437+00 | 2021-03-19 19:12:08.437+00
|
// 3 | 5 | five | 2021-03-19 19:12:08.437+00 | 2021-03-19 19:12:08.437+00
|
||||||
// (3 rows)
|
// (3 rows)
|
||||||
|
|
||||||
let integerNames = await IntegerNames.findAll({
|
const integerNames = await IntegerNames.findAll({
|
||||||
where: {
|
where: {
|
||||||
value: 2
|
value: 2
|
||||||
}
|
}
|
||||||
|
|||||||
36
rootfs_overlay/lkmc/nodejs/sequelize/truncate_key.js
Executable file
36
rootfs_overlay/lkmc/nodejs/sequelize/truncate_key.js
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
// https://stackoverflow.com/questions/39765582/in-sequelize-model-destroy-truncate-true-does-not-reset-primary-key
|
||||||
|
|
||||||
|
const assert = require('assert')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
const { Sequelize, DataTypes } = require('sequelize')
|
||||||
|
|
||||||
|
const sequelize = new Sequelize({
|
||||||
|
dialect: 'sqlite',
|
||||||
|
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
|
||||||
|
})
|
||||||
|
|
||||||
|
;(async () => {
|
||||||
|
const IntegerNames = sequelize.define('IntegerNames', {
|
||||||
|
value: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
allowNull: false,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
},
|
||||||
|
}, {})
|
||||||
|
await IntegerNames.sync({force: true})
|
||||||
|
await IntegerNames.create({value: 2, name: 'two'})
|
||||||
|
await IntegerNames.create({value: 3, name: 'three'})
|
||||||
|
console.error((await IntegerNames.findOne({where: {value: 2}})).id)
|
||||||
|
await IntegerNames.truncate({cascade: true})
|
||||||
|
await IntegerNames.create({value: 5, name: 'five'})
|
||||||
|
await IntegerNames.create({value: 7, name: 'seven'})
|
||||||
|
console.error((await IntegerNames.findOne({where: {value: 5}})).id)
|
||||||
|
|
||||||
|
await sequelize.close()
|
||||||
|
})();
|
||||||
Reference in New Issue
Block a user