Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 23 additions & 2 deletions packages/stores/bun-sql/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,19 @@ export class BunSqlIdempotencyStore {
*/
isMySQL;

/**
* @type {boolean}
*/
isPostgres;

/**
* @param {string} connectionString - Database connection string or path
* @param {BunSqlIdempotencyStoreOptions} [options]
*/
constructor(connectionString, options = {}) {
this.isSqlite = this.isSqliteConnection(connectionString);
this.isMySQL = this.isMySqlConnection(connectionString);
this.isPostgres = this.isPostgresConnection(connectionString);

if (this.isSqlite) {
const sqlitePath = this.normalizeSqlitePath(connectionString);
Expand Down Expand Up @@ -118,6 +124,17 @@ export class BunSqlIdempotencyStore {
return lower.includes("mysql") || lower.includes("mariadb");
}

/**
* Check if connection string is PostgreSQL
* @param {string} [connectionString]
* @returns {boolean}
*/
isPostgresConnection(connectionString) {
if (!connectionString) return false;
const lower = connectionString.toLowerCase();
return lower.includes("postgres") || lower.includes("postgresql");
}

/**
* Initialize database schema with tables and indexes
* @private
Expand Down Expand Up @@ -261,8 +278,12 @@ export class BunSqlIdempotencyStore {
byFingerprint: this.parseRecord(byFingerprintRow)
};
} else {
await this
.db`DELETE FROM idempotency_records WHERE expires_at <= ${Date.now()}`;
// PostgreSQL doesn't support LIMIT in DELETE, use subquery
const deleteSql = this.isPostgres
? "DELETE FROM idempotency_records WHERE key IN (SELECT key FROM idempotency_records WHERE expires_at <= $1 LIMIT 10)"
: "DELETE FROM idempotency_records WHERE expires_at <= ? LIMIT 10";
const deleteParams = this.isPostgres ? [Date.now()] : [Date.now()];
await this.db.unsafe(deleteSql, deleteParams);

const keyColumn = this.isMySQL ? "`key`" : '"key"';
const paramPlaceholder = this.isMySQL ? "?" : "$1";
Expand Down
2 changes: 1 addition & 1 deletion packages/stores/mysql/deno-mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export class MysqlIdempotencyStore {
*/
async lookup(key, fingerprint) {
await this.client.execute(
"DELETE FROM idempotency_records WHERE expires_at <= ?",
"DELETE FROM idempotency_records WHERE expires_at <= ? LIMIT 10",
[Date.now()]
);

Expand Down
2 changes: 1 addition & 1 deletion packages/stores/mysql/node-mysql.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export class MysqlIdempotencyStore {
*/
async lookup(key, fingerprint) {
await this.pool.query(
`DELETE FROM \`${this.tableName}\` WHERE expires_at <= ?`,
`DELETE FROM \`${this.tableName}\` WHERE expires_at <= ? LIMIT 10`,
[Date.now()]
);

Expand Down
3 changes: 2 additions & 1 deletion packages/stores/postgres/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,9 @@ export class PostgresIdempotencyStore {
* @returns {Promise<{byKey: IdempotencyRecord | null, byFingerprint: IdempotencyRecord | null}>}
*/
async lookup(key, fingerprint) {
// Use subquery with LIMIT since PostgreSQL doesn't support LIMIT in DELETE directly
await this.pool.query(
`DELETE FROM ${this.quotedSchemaIdentifier}.idempotency_records WHERE expires_at <= $1`,
`DELETE FROM ${this.quotedSchemaIdentifier}.idempotency_records WHERE key IN (SELECT key FROM ${this.quotedSchemaIdentifier}.idempotency_records WHERE expires_at <= $1 LIMIT 10)`,
[Date.now()]
);

Expand Down
Loading