Skip to content

Instantly share code, notes, and snippets.

@snahor
Created February 12, 2016 01:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snahor/63058490833e61c38780 to your computer and use it in GitHub Desktop.
Save snahor/63058490833e61c38780 to your computer and use it in GitHub Desktop.
const tableFactory = () => {
const columns = [];
const compositeUniqueColumns = [];
const dataTypes = [
'uuid',
'string',
'timestamp',
'float',
'integer',
'boolean',
'datetime',
'text',
'tinyint',
'json',
];
const ignoredColumnAttrs = [
'notNullable',
'primary',
'nullable',
'references',
];
class Column {
constructor(name) {
this.name = name;
this.isUnique = false;
ignoredColumnAttrs.forEach(x => this[x] = () => this);
}
unique() {
this.isUnique = true;
return this;
}
}
return {
uniqueConstraints: () => [].concat(
columns.filter(x => x.isUnique).map(x => x.name),
compositeUniqueColumns
),
unique: (columns) => {
compositeUniqueColumns.push(columns);
},
...dataTypes.reduce((acc, type) => {
acc[type] = (name) => {
const column = new Column(name);
columns.push(column);
return column;
};
return acc;
}, {}),
}
}
function upsert(tenant, tableName, data) {
const table = tableFactory();
const { build } = schemas.tenantSchema.filter(x => x.tableName === tableName)[0];
build(table);
const constraints = table.uniqueConstraints();
const where = constraints.reduce((acc, column) => {
acc[column] = data[column];
return acc;
}, {});
const values = {};
const insert = knex(tableName)
.insert(data)
.toString()
.replace(/\svalues\s(/, ' select ')
.slice(0, -1);
const update = knex(tableName)
.update(values)
.where(where)
.toString();
const query = `
BEGIN;
SET search_path = '${tenant}';
LOCK TABLE ${tableName} IN SHARE ROW EXCLUSIVE MODE;
WITH upsert AS (${updateQuery} RETURNING *)
${insertQuery} WHERE NOT EXISTS (SELECT * FROM upsert);
COMMIT;`;
const now = new Date();
knex.raw();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment