-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathpostgres.js
79 lines (71 loc) · 4.4 KB
/
postgres.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
var extend = require('extend');
function PostgresAdapter(opts) {
extend(this, opts);
}
PostgresAdapter.prototype.connect = function (cb) {
if (this.knex) return cb();
var connection = {
database: this.dbname || 'template1',
host: this.host || 'localhost',
port: this.port || 5432,
user: this.username || 'postgres',
password: this.password || '',
};
if (this.ssl) {
extend(connection, { ssl: this.ssl })
}
this.knex = require('knex')({
client: 'pg',
connection: connection,
debug: false,
useNullAsDefault: true,
pool: {
min: 1,
max: 8
}
});
this.initialize(cb);
};
// http://stackoverflow.com/questions/1109061/insert-on-duplicate-update-in-postgresql
PostgresAdapter.prototype.initialize = function (cb) {
var sql = ' \n\
CREATE OR REPLACE FUNCTION upsert_' + this.tableName + '(_id TEXT, _lock TEXT, _task TEXT, _priority NUMERIC) RETURNS VOID AS \n\
$$ \n\
BEGIN \n\
LOOP \n\
-- first try to update the key \n\
-- note that "id" must be unique \n\
UPDATE ' + this.tableName + ' SET lock=_lock, task=_task, priority=_priority WHERE id=_id; \n\
IF found THEN \n\
RETURN; \n\
END IF; \n\
-- not there, so try to insert the key \n\
-- if someone else inserts the same key concurrently, \n\
-- we could get a unique-key failure \n\
BEGIN \n\
INSERT INTO ' + this.tableName + ' (id, lock, task, priority) VALUES (_id, _lock, _task, _priority); \n\
RETURN; \n\
EXCEPTION WHEN unique_violation THEN \n\
-- do nothing, and loop to try the UPDATE again \n\
END; \n\
END LOOP; \n\
END; \n\
$$ \n\
LANGUAGE plpgsql; \n\
';
this.knex.raw(sql).then(function (res) {
cb();
}).catch(function (err) {
cb(err);
});
};
PostgresAdapter.prototype.upsert = function (properties, cb) {
var args = [properties.id, properties.lock, properties.task, properties.priority];
this.knex.raw("SELECT upsert_" + this.tableName + "(?, ?, ?, ?)", args)
.then(function () { cb(); })
.catch(cb);
};
PostgresAdapter.prototype.close = function (cb) {
return cb()
};
module.exports = PostgresAdapter;