-
-
Notifications
You must be signed in to change notification settings - Fork 167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(sqlite): add sqlite support #291
base: master
Are you sure you want to change the base?
Conversation
Thank you @animir for bringing the support of SQLite. When is this planned to be released? |
} | ||
|
||
|
||
_upsert(rlKey, points, msDuration, forceExpire = false) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@no-on3 Hello, can you make it atomic upsert?
All limiters from this package do atomic upserts. If there is no way to implement the same with SQLite, please, rename the class to RateLimiterSQLiteNonAtomic
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe SQLite supports atomic upserts. Here's how the code would look. I haven't tested it in depth, but if @no-on3 isn't available, I'd be happy to look into it and add it.
_upsert(rlKey, points, msDuration, forceExpire = false) {
if (!this.tableCreated) {
return Promise.reject(Error("Table is not created yet"));
}
return new Promise((resolve, reject) => {
const dateNow = Date.now();
const newExpire = msDuration > 0 ? dateNow + msDuration : null;
this.client.serialize(() => {
this.client.run("BEGIN TRANSACTION", (err) => {
if (err) return reject(err);
let query, params;
if (forceExpire) {
query = `
INSERT INTO ${this.tableName} (key, points, expire)
VALUES (?, ?, ?)
ON CONFLICT(key) DO UPDATE SET
points = excluded.points,
expire = excluded.expire
`;
params = [rlKey, points, newExpire];
} else {
query = `
INSERT INTO ${this.tableName} (key, points, expire)
VALUES (?, ?, ?)
ON CONFLICT(key) DO UPDATE SET
points = CASE
WHEN (expire > ? OR expire IS NULL) THEN points + excluded.points
ELSE excluded.points
END,
expire = CASE
WHEN (expire > ? OR expire IS NULL) THEN expire
ELSE excluded.expire
END
`;
params = [rlKey, points, newExpire, dateNow, dateNow];
}
this.client.run(query, params, (errUpsert) => {
if (errUpsert) {
this.client.run("ROLLBACK");
return reject(errUpsert);
}
this.client.get(
`SELECT points, expire FROM ${this.tableName} WHERE key = ?`,
[key],
(errSelect, result) => {
if (errSelect) {
this.client.run("ROLLBACK");
return reject(errSelect);
}
this.client.run("COMMIT", (errCommit) => {
if (errCommit) {
this.client.run("ROLLBACK");
return reject(errCommit);
}
resolve(result || { points, expire: newExpire });
});
}
);
});
});
});
});
}
this #287
Tests fixed.