Skip to content

Commit

Permalink
feat: #7707, added sortedSetAddBulk
Browse files Browse the repository at this point in the history
  • Loading branch information
barisusakli committed Jun 24, 2019
1 parent e48c7cd commit 3ecd703
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 35 deletions.
13 changes: 11 additions & 2 deletions src/database/mongo/sorted/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,17 @@ module.exports = function (db, module) {
bulk.find({ _key: keys[i], value: value }).upsert().updateOne({ $set: { score: parseFloat(isArrayOfScores ? scores[i] : scores) } });
}

bulk.execute(function (err) {
callback(err);
bulk.execute(err => callback(err));
};

module.sortedSetAddBulk = function (data, callback) {
if (!Array.isArray(data) || !data.length) {
return setImmediate(callback);
}
var bulk = db.collection('objects').initializeUnorderedBulkOp();
data.forEach(function (item) {
bulk.find({ _key: item[0], value: String(item[2]) }).upsert().updateOne({ $set: { score: parseFloat(item[1]) } });
});
bulk.execute(err => callback(err));
};
};
33 changes: 33 additions & 0 deletions src/database/postgres/sorted/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,37 @@ INSERT INTO "legacy_zset" ("_key", "value", "score")
});
}, callback);
};

module.sortedSetAddBulk = function (data, callback) {
if (!Array.isArray(data) || !data.length) {
return setImmediate(callback);
}
const keys = [];
const values = [];
const scores = [];
data.forEach(function (item) {
keys.push(item[0]);
scores.push(item[1]);
values.push(item[2]);
});
module.transaction(function (tx, done) {
var query = tx.client.query.bind(tx.client);

async.series([
async.apply(helpers.ensureLegacyObjectsType, tx.client, keys, 'zset'),
async.apply(query, {
name: 'sortedSetAddBulk2',
text: `
INSERT INTO "legacy_zset" ("_key", "value", "score")
SELECT k, v, s
FROM UNNEST($1::TEXT[], $2::TEXT[], $3::NUMERIC[]) vs(k, v, s)
ON CONFLICT ("_key", "value")
DO UPDATE SET "score" = EXCLUDED."score"`,
values: [keys, values, scores],
}),
], function (err) {
done(err);
});
}, callback);
};
};
11 changes: 11 additions & 0 deletions src/database/redis/sorted/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,15 @@ module.exports = function (redisClient, module) {
callback(err);
});
};

module.sortedSetAddBulk = function (data, callback) {
if (!Array.isArray(data) || !data.length) {
return setImmediate(callback);
}
var batch = redisClient.batch();
data.forEach(function (item) {
batch.zadd(item[0], item[1], item[2]);
});
batch.exec(err => callback(err));
};
};
56 changes: 23 additions & 33 deletions src/user/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,25 +74,26 @@ module.exports = function (User) {
db.incrObjectField('global', 'userCount', next);
},
function (next) {
db.sortedSetsAdd([
'username:uid', 'user:' + userData.uid + ':usernames',
], [userData.uid, timestamp], userData.username, next);
},
function (next) {
db.sortedSetAdd('username:sorted', 0, userData.username.toLowerCase() + ':' + userData.uid, next);
},
function (next) {
db.sortedSetAdd('userslug:uid', userData.uid, userData.userslug, next);
},
function (next) {
var sets = ['users:joindate', 'users:online'];
const bulk = [
['username:uid', userData.uid, userData.username],
['user:' + userData.uid + ':usernames', timestamp, userData.username],
['username:sorted', 0, userData.username.toLowerCase() + ':' + userData.uid],
['userslug:uid', userData.uid, userData.userslug],
['users:joindate', timestamp, userData.uid],
['users:online', timestamp, userData.uid],
['users:postcount', 0, userData.uid],
['users:reputation', 0, userData.uid],
];

if (parseInt(userData.uid, 10) !== 1) {
sets.push('users:notvalidated');
bulk.push(['users:notvalidated', timestamp, userData.uid]);
}
db.sortedSetsAdd(sets, timestamp, userData.uid, next);
},
function (next) {
db.sortedSetsAdd(['users:postcount', 'users:reputation'], 0, userData.uid, next);
if (userData.email) {
bulk.push(['email:uid', userData.uid, userData.email.toLowerCase()]);
bulk.push(['email:sorted', 0, userData.email.toLowerCase() + ':' + userData.uid]);
bulk.push(['user:' + userData.uid + ':emails', timestamp, userData.email]);
}
db.sortedSetAddBulk(bulk, next);
},
function (next) {
groups.join('registered-users', userData.uid, next);
Expand All @@ -101,23 +102,12 @@ module.exports = function (User) {
User.notifications.sendWelcomeNotification(userData.uid, next);
},
function (next) {
if (userData.email) {
async.parallel([
async.apply(db.sortedSetAdd, 'email:uid', userData.uid, userData.email.toLowerCase()),
async.apply(db.sortedSetAdd, 'email:sorted', 0, userData.email.toLowerCase() + ':' + userData.uid),
async.apply(db.sortedSetAdd, 'user:' + userData.uid + ':emails', timestamp, userData.email),
], next);

if (userData.uid > 1 && meta.config.requireEmailConfirmation) {
User.email.sendValidationEmail(userData.uid, {
email: userData.email,
});
}
} else {
next();
if (userData.email && userData.uid > 1 && meta.config.requireEmailConfirmation) {
User.email.sendValidationEmail(userData.uid, {
email: userData.email,
});
}
},
function (next) {

if (!data.password) {
return next();
}
Expand Down
28 changes: 28 additions & 0 deletions test/database/sorted.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,34 @@ describe('Sorted Set methods', function () {
});
});

describe('sortedSetAddMulti()', function () {
it('should add elements into multiple sorted sets with different scores', function (done) {
db.sortedSetAddBulk([
['bulk1', 1, 'item1'],
['bulk2', 2, 'item1'],
['bulk2', 3, 'item2'],
['bulk3', 4, 'item3'],
], function (err) {
assert.ifError(err);
assert.equal(arguments.length, 1);
db.getSortedSetRevRangeWithScores(['bulk1', 'bulk2', 'bulk3'], 0, -1, function (err, data) {
assert.ifError(err);
assert.deepStrictEqual(data, [{ value: 'item3', score: 4 },
{ value: 'item2', score: 3 },
{ value: 'item1', score: 2 },
{ value: 'item1', score: 1 }]);
done();
});
});
});
it('should not error if data is undefined', function (done) {
db.sortedSetAddBulk(undefined, function (err) {
assert.ifError(err);
done();
});
});
});

describe('getSortedSetRange()', function () {
it('should return the lowest scored element', function (done) {
db.getSortedSetRange('sortedSetTest1', 0, 0, function (err, value) {
Expand Down

0 comments on commit 3ecd703

Please sign in to comment.