Skip to content

Instantly share code, notes, and snippets.

@hayeah
Last active July 28, 2020 10:40
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hayeah/1c8d642df5cfeabc2a5b to your computer and use it in GitHub Desktop.
Save hayeah/1c8d642df5cfeabc2a5b to your computer and use it in GitHub Desktop.
monkey patch knex.js for PostgreSQL 9.5 upsert
const BaseQueryCompiler = require("knex/lib/query/compiler");
/*
db = knex({
client: "pg",
connection: config.postgresURL,
debug: true,
});
upsertMonkeyPatch(db);
*/
export default function upsertMonkeyPatch(db) {
// https://github.com/tgriesser/knex/issues/54#issuecomment-183838939
const QueryBuilder = db.client.QueryBuilder;
const QueryCompiler = db.client.QueryCompiler;
// monkey patch to add onConflict
QueryBuilder.prototype.onConflict = function (columns: string[], updates: any) {
// throw error if method is not insert
this._single["onConflictUpdate"] = {
columns,
updates,
}
return this;
}
const __baseInsert = BaseQueryCompiler.prototype.insert;
QueryCompiler.prototype.insert = function insert() {
let sql /*:string */ = __baseInsert.call(this);
if(this.single.onConflictUpdate) {
const {columns, updates} = this.single.onConflictUpdate;
sql += ` on conflict (${this.formatter.columnize(columns)}) `
const doUpdate = Object.keys(updates).sort().map(key => {
const val = updates[key];
return this.formatter.wrap(key) + ' = ' + this.formatter.parameter(val)
}).join(", ");
sql += ` do update set ${doUpdate}`
}
var returning = this.single.returning;
if(returning) {
sql += ' returning ' + this.formatter.columnize(returning);
}
return {
sql,
returning,
};
}
}
@plurch
Copy link

plurch commented Mar 2, 2016

Thanks @hayeah. As an alternative to monkey-patching, I wrote a relatively simple function which works for my use cases:

upsertItem = function(tableName, conflictTarget, itemData)

https://gist.github.com/plurch/118721c2216f77640232

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment