From c25f16b5b4ac46f0da5d961f425e5a76116988ab Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 12:32:19 +1100 Subject: [PATCH 01/31] converted to es6 using lebab.io --- index.js | 366 +++++++++++++++++++++++++++---------------------------- 1 file changed, 182 insertions(+), 184 deletions(-) diff --git a/index.js b/index.js index 3f7dc57..622ba3a 100644 --- a/index.js +++ b/index.js @@ -1,200 +1,198 @@ -var DB = require('sharedb').DB; -var pg = require('pg'); +import {DB} from 'sharedb'; +import pg from 'pg'; // Postgres-backed ShareDB database -function PostgresDB(options) { - if (!(this instanceof PostgresDB)) return new PostgresDB(options); - DB.call(this, options); +class PostgresDB { + constructor(options) { + DB.call(this, options); - this.closed = false; + this.closed = false; - this.pg_config = options; -}; -module.exports = PostgresDB; + this.pg_config = options; + } -PostgresDB.prototype = Object.create(DB.prototype); - -PostgresDB.prototype.close = function(callback) { - this.closed = true; - if (callback) callback(); -}; + close(callback) { + this.closed = true; + if (callback) callback(); + } -function rollback(client, done) { - client.query('ROLLBACK', function(err) { - return done(err); - }) -} - -// Persists an op and snapshot if it is for the next version. Calls back with -// callback(err, succeeded) -PostgresDB.prototype.commit = function(collection, id, op, snapshot, options, callback) { - /* - * op: CreateOp { - * src: '24545654654646', - * seq: 1, - * v: 0, - * create: { type: 'http://sharejs.org/types/JSONv0', data: { ... } }, - * m: { ts: 12333456456 } } - * } - * snapshot: PostgresSnapshot - */ - pg.connect(this.pg_config, function(err, client, done) { - if (err) { - done(client); - callback(err); - return; - } - function commit() { - client.query('COMMIT', function(err) { - done(err); - if (err) { - callback(err); - } else { - callback(null, true); - } - }) - } - client.query( - 'SELECT max(version) AS max_version FROM ops WHERE collection = $1 AND doc_id = $2', - [collection, id], - function(err, res) { - var max_version = res.rows[0].max_version; - if (max_version == null) - max_version = 0; - if (snapshot.v !== max_version + 1) { - return callback(null, false); - } - client.query('BEGIN', function(err) { - client.query( - 'INSERT INTO ops (collection, doc_id, version, operation) VALUES ($1, $2, $3, $4)', - [collection, id, snapshot.v, op], - function(err, res) { - if (err) { - // TODO: if err is "constraint violation", callback(null, false) instead - rollback(client, done); - callback(err); - return; - } - if (snapshot.v === 1) { - client.query( - 'INSERT INTO snapshots (collection, doc_id, doc_type, version, data) VALUES ($1, $2, $3, $4, $5)', - [collection, id, snapshot.type, snapshot.v, snapshot.data], - function(err, res) { - // TODO: - // if the insert was successful and did insert, callback(null, true) - // if the insert was successful and did not insert, callback(null, false) - // if there was an error, rollback and callback(error) - if (err) { - rollback(client, done); - callback(err); - return; + // Persists an op and snapshot if it is for the next version. Calls back with + // callback(err, succeeded) + commit(collection, id, op, snapshot, options, callback) { + /* + * op: CreateOp { + * src: '24545654654646', + * seq: 1, + * v: 0, + * create: { type: 'http://sharejs.org/types/JSONv0', data: { ... } }, + * m: { ts: 12333456456 } } + * } + * snapshot: PostgresSnapshot + */ + pg.connect(this.pg_config, (err, client, done) => { + if (err) { + done(client); + callback(err); + return; + } + function commit() { + client.query('COMMIT', err => { + done(err); + if (err) { + callback(err); + } else { + callback(null, true); + } + }) + } + client.query( + 'SELECT max(version) AS max_version FROM ops WHERE collection = $1 AND doc_id = $2', + [collection, id], + (err, res) => { + let max_version = res.rows[0].max_version; + if (max_version == null) + max_version = 0; + if (snapshot.v !== max_version + 1) { + return callback(null, false); + } + client.query('BEGIN', err => { + client.query( + 'INSERT INTO ops (collection, doc_id, version, operation) VALUES ($1, $2, $3, $4)', + [collection, id, snapshot.v, op], + (err, res) => { + if (err) { + // TODO: if err is "constraint violation", callback(null, false) instead + rollback(client, done); + callback(err); + return; + } + if (snapshot.v === 1) { + client.query( + 'INSERT INTO snapshots (collection, doc_id, doc_type, version, data) VALUES ($1, $2, $3, $4, $5)', + [collection, id, snapshot.type, snapshot.v, snapshot.data], + (err, res) => { + // TODO: + // if the insert was successful and did insert, callback(null, true) + // if the insert was successful and did not insert, callback(null, false) + // if there was an error, rollback and callback(error) + if (err) { + rollback(client, done); + callback(err); + return; + } + commit(); } - commit(); - } - ) - } else { - client.query( - 'UPDATE snapshots SET doc_type = $3, version = $4, data = $5 WHERE collection = $1 AND doc_id = $2 AND version = ($4 - 1)', - [collection, id, snapshot.type, snapshot.v, snapshot.data], - function(err, res) { - // TODO: - // if any rows were updated, success - // if 0 rows were updated, rollback and not success - // if error, rollback and not success - if (err) { - rollback(client, done); - callback(err); - return; + ) + } else { + client.query( + 'UPDATE snapshots SET doc_type = $3, version = $4, data = $5 WHERE collection = $1 AND doc_id = $2 AND version = ($4 - 1)', + [collection, id, snapshot.type, snapshot.v, snapshot.data], + (err, res) => { + // TODO: + // if any rows were updated, success + // if 0 rows were updated, rollback and not success + // if error, rollback and not success + if (err) { + rollback(client, done); + callback(err); + return; + } + commit(); } - commit(); - } - ) + ) + } } - } - ) - }) - } - ) - }) -}; - -// Get the named document from the database. The callback is called with (err, -// snapshot). A snapshot with a version of zero is returned if the docuemnt -// has never been created in the database. -PostgresDB.prototype.getSnapshot = function(collection, id, fields, options, callback) { - pg.connect(this.pg_config, function(err, client, done) { - if (err) { - done(client); - callback(err); - return; - } - client.query( - 'SELECT version, data, doc_type FROM snapshots WHERE collection = $1 AND doc_id = $2 LIMIT 1', - [collection, id], - function(err, res) { - done(); - if (err) { - callback(err); - return; + ) + }) } - if (res.rows.length) { - var row = res.rows[0] - var snapshot = new PostgresSnapshot( - id, - row.version, - row.doc_type, - row.data, - undefined // TODO: metadata - ) - callback(null, snapshot); - } else { - var snapshot = new PostgresSnapshot( - id, - 0, - null, - undefined, - undefined - ) - callback(null, snapshot); - } - } - ) - }) -}; + ) + }) + } -// Get operations between [from, to) noninclusively. (Ie, the range should -// contain start but not end). -// -// If end is null, this function should return all operations from start onwards. -// -// The operations that getOps returns don't need to have a version: field. -// The version will be inferred from the parameters if it is missing. -// -// Callback should be called as callback(error, [list of ops]); -PostgresDB.prototype.getOps = function(collection, id, from, to, options, callback) { - pg.connect(this.pg_config, function(err, client, done) { - if (err) { - done(client); - callback(err); - return; - } - client.query( - 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version >= $3 AND version < $4', - [collection, id, from, to], - function(err, res) { - done(); - if (err) { - callback(err); - return; + // Get the named document from the database. The callback is called with (err, + // snapshot). A snapshot with a version of zero is returned if the docuemnt + // has never been created in the database. + getSnapshot(collection, id, fields, options, callback) { + pg.connect(this.pg_config, (err, client, done) => { + if (err) { + done(client); + callback(err); + return; + } + client.query( + 'SELECT version, data, doc_type FROM snapshots WHERE collection = $1 AND doc_id = $2 LIMIT 1', + [collection, id], + (err, res) => { + done(); + if (err) { + callback(err); + return; + } + if (res.rows.length) { + const row = res.rows[0]; + var snapshot = new PostgresSnapshot( + id, + row.version, + row.doc_type, + row.data, + undefined // TODO: metadata + ) + callback(null, snapshot); + } else { + var snapshot = new PostgresSnapshot( + id, + 0, + null, + undefined, + undefined + ) + callback(null, snapshot); + } } - callback(null, res.rows.map(function(row) { - return row.operation; - })); + ) + }) + } + + // Get operations between [from, to) noninclusively. (Ie, the range should + // contain start but not end). + // + // If end is null, this function should return all operations from start onwards. + // + // The operations that getOps returns don't need to have a version: field. + // The version will be inferred from the parameters if it is missing. + // + // Callback should be called as callback(error, [list of ops]); + getOps(collection, id, from, to, options, callback) { + pg.connect(this.pg_config, (err, client, done) => { + if (err) { + done(client); + callback(err); + return; } - ) - }) -}; + client.query( + 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version >= $3 AND version < $4', + [collection, id, from, to], + (err, res) => { + done(); + if (err) { + callback(err); + return; + } + callback(null, res.rows.map(row => row.operation)); + } + ) + }) + } +} + +export default PostgresDB; + +PostgresDB.prototype = Object.create(DB.prototype); + +function rollback(client, done) { + client.query('ROLLBACK', err => done(err)) +} function PostgresSnapshot(id, version, type, data, meta) { this.id = id; @@ -202,4 +200,4 @@ function PostgresSnapshot(id, version, type, data, meta) { this.type = type; this.data = data; this.m = meta; -} +} \ No newline at end of file From 9435775bae14f9ceae6d3e3fda7b1a91bf29566e Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 12:33:12 +1100 Subject: [PATCH 02/31] changed structure to jsonb --- structure.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/structure.sql b/structure.sql index 606b5fc..977988d 100644 --- a/structure.sql +++ b/structure.sql @@ -2,7 +2,7 @@ CREATE TABLE ops ( collection character varying(255) not null, doc_id character varying(255) not null, version integer not null, - operation json not null, -- {v:0, create:{...}} or {v:n, op:[...]} + operation jsonb not null, -- {v:0, create:{...}} or {v:n, op:[...]} PRIMARY KEY (collection, doc_id, version) ); @@ -11,6 +11,6 @@ CREATE TABLE snapshots ( doc_id character varying(255) not null, doc_type character varying(255) not null, version integer not null, - data json not null, + data jsonb not null, PRIMARY KEY (collection, doc_id) ); From da16bdad2067d97fa1b75c96723d436352380a73 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 13:08:00 +1100 Subject: [PATCH 03/31] rewrote commit to insert ops and snapshot in one transaction --- index.js | 119 +++++++++++++++++-------------------------------------- 1 file changed, 37 insertions(+), 82 deletions(-) diff --git a/index.js b/index.js index 622ba3a..579cf2d 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ class PostgresDB { this.closed = false; this.pg_config = options; + } close(callback) { @@ -36,77 +37,35 @@ class PostgresDB { callback(err); return; } - function commit() { - client.query('COMMIT', err => { - done(err); - if (err) { - callback(err); - } else { - callback(null, true); - } - }) + /*const*/ query = { + // TODO: investigate if ops should use on conflict + name: 'sdb-commit-op-and-snap', + text: `With snaps as ( + Insert into snapshots (collection,doc_id,doc_type, version,data) + Select n.* From ( select $1 c, $2 d, $4 t, $3 v, $5 daa) + n + where v = (select version+1 v from snapshots where collection = $1 and doc_id = $2 for update) or not exists (select 1 from snapshots where collection = $1 and doc_id = $2 for update) + On conflict(collection, doc_id) do update set version = $3, data = $5 , doc_type = $2 + Returning version + ) + Insert into ops (collection,doc_id, version,operation) + Select n.* From ( select $1 c, $2 t, $3 v, $6 daa) + n + where (v = (select version+1 v from ops where collection = $1 and doc_id = $2 for update) or not exists (select 1 from ops where collection = $1 and doc_id = $2 for update)) and exists (select 1 from snaps) + On conflict(collection, doc_id, version) do update set version = $3, operation = $6 + Returning version`, + values: [collection,id,snapshot.v, snapshot.type, snapshot.data,op] + } + client.query(query, (err, res) => { + if (err) { + console.log(err.stack) + callback(err) + } else { + console.log(res.rows[0]) + callback(null,true) } - client.query( - 'SELECT max(version) AS max_version FROM ops WHERE collection = $1 AND doc_id = $2', - [collection, id], - (err, res) => { - let max_version = res.rows[0].max_version; - if (max_version == null) - max_version = 0; - if (snapshot.v !== max_version + 1) { - return callback(null, false); - } - client.query('BEGIN', err => { - client.query( - 'INSERT INTO ops (collection, doc_id, version, operation) VALUES ($1, $2, $3, $4)', - [collection, id, snapshot.v, op], - (err, res) => { - if (err) { - // TODO: if err is "constraint violation", callback(null, false) instead - rollback(client, done); - callback(err); - return; - } - if (snapshot.v === 1) { - client.query( - 'INSERT INTO snapshots (collection, doc_id, doc_type, version, data) VALUES ($1, $2, $3, $4, $5)', - [collection, id, snapshot.type, snapshot.v, snapshot.data], - (err, res) => { - // TODO: - // if the insert was successful and did insert, callback(null, true) - // if the insert was successful and did not insert, callback(null, false) - // if there was an error, rollback and callback(error) - if (err) { - rollback(client, done); - callback(err); - return; - } - commit(); - } - ) - } else { - client.query( - 'UPDATE snapshots SET doc_type = $3, version = $4, data = $5 WHERE collection = $1 AND doc_id = $2 AND version = ($4 - 1)', - [collection, id, snapshot.type, snapshot.v, snapshot.data], - (err, res) => { - // TODO: - // if any rows were updated, success - // if 0 rows were updated, rollback and not success - // if error, rollback and not success - if (err) { - rollback(client, done); - callback(err); - return; - } - commit(); - } - ) - } - } - ) - }) - } - ) + }) + }) } @@ -188,16 +147,12 @@ class PostgresDB { export default PostgresDB; -PostgresDB.prototype = Object.create(DB.prototype); - -function rollback(client, done) { - client.query('ROLLBACK', err => done(err)) -} - -function PostgresSnapshot(id, version, type, data, meta) { - this.id = id; - this.v = version; - this.type = type; - this.data = data; - this.m = meta; +class PostgresSnapshot { + constructor(id, version, type, data, meta) { + this.id = id; + this.v = version; + this.type = type; + this.data = data; + this.m = meta; + } } \ No newline at end of file From 9c9773ad41cccd62712c6c1ea9b8583277fc9419 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 13:26:17 +1100 Subject: [PATCH 04/31] revert es6 style imports --- index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 579cf2d..c4fb974 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ -import {DB} from 'sharedb'; -import pg from 'pg'; +var DB = require('sharedb').DB; +var pg = require('pg'); // Postgres-backed ShareDB database @@ -38,7 +38,7 @@ class PostgresDB { return; } /*const*/ query = { - // TODO: investigate if ops should use on conflict + // TODO: investigate if ops should use on conflict name: 'sdb-commit-op-and-snap', text: `With snaps as ( Insert into snapshots (collection,doc_id,doc_type, version,data) From b803ca1acf7e560b2e6e898d0134ae797077d022 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 13:37:13 +1100 Subject: [PATCH 05/31] es6 exports fix --- index.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/index.js b/index.js index c4fb974..cd2fdb5 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ -var DB = require('sharedb').DB; -var pg = require('pg'); +import {DB} from 'sharedb'; +import pg from 'pg'; // Postgres-backed ShareDB database -class PostgresDB { +module.exports = class PostgresDB { constructor(options) { DB.call(this, options); @@ -145,8 +145,6 @@ class PostgresDB { } } -export default PostgresDB; - class PostgresSnapshot { constructor(id, version, type, data, meta) { this.id = id; From 5235fa04b054dfcb25489bbec3095c3ea83dc1da Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 13:39:05 +1100 Subject: [PATCH 06/31] revert again --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index cd2fdb5..abea56a 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ -import {DB} from 'sharedb'; -import pg from 'pg'; +var DB = require('sharedb').DB; +var pg = require('pg'); // Postgres-backed ShareDB database From b8a81bac261d28b016e496d4a718c0928a20bd31 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 13:43:06 +1100 Subject: [PATCH 07/31] missed var --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index abea56a..97d8cff 100644 --- a/index.js +++ b/index.js @@ -37,7 +37,7 @@ module.exports = class PostgresDB { callback(err); return; } - /*const*/ query = { + /*const*/ var query = { // TODO: investigate if ops should use on conflict name: 'sdb-commit-op-and-snap', text: `With snaps as ( From 47c3e4531531e4aaf27f02c7f2db6b0c5622b15f Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 13:59:17 +1100 Subject: [PATCH 08/31] removed second on conflict --- index.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/index.js b/index.js index 97d8cff..0d68661 100644 --- a/index.js +++ b/index.js @@ -38,7 +38,6 @@ module.exports = class PostgresDB { return; } /*const*/ var query = { - // TODO: investigate if ops should use on conflict name: 'sdb-commit-op-and-snap', text: `With snaps as ( Insert into snapshots (collection,doc_id,doc_type, version,data) @@ -52,7 +51,6 @@ module.exports = class PostgresDB { Select n.* From ( select $1 c, $2 t, $3 v, $6 daa) n where (v = (select version+1 v from ops where collection = $1 and doc_id = $2 for update) or not exists (select 1 from ops where collection = $1 and doc_id = $2 for update)) and exists (select 1 from snaps) - On conflict(collection, doc_id, version) do update set version = $3, operation = $6 Returning version`, values: [collection,id,snapshot.v, snapshot.type, snapshot.data,op] } From 1c8de9dd6753d12ef097a6a3263147b6a3778103 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 18 Feb 2018 19:22:57 +1100 Subject: [PATCH 09/31] upgraded pg --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b1f446..f8863d3 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "keywords": ["sharedb", "sharejs", "share", "postgres"], "repository": "share/sharedb-postgres", "dependencies": { - "pg": "^4.5.1", + "pg": "^7.4.1", "sharedb": "^1.0.0-beta.7" } } From d6c8a2da84de3002eac6f9d160755369143ed089 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sat, 24 Feb 2018 12:17:34 +1100 Subject: [PATCH 10/31] fixed sql and upgraded to use PG pool. Also iif it doens't commit it will return false --- index.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 0d68661..7932148 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ module.exports = class PostgresDB { this.closed = false; this.pg_config = options; + this.pool = new pg.Pool(this.pg_config) } @@ -31,7 +32,7 @@ module.exports = class PostgresDB { * } * snapshot: PostgresSnapshot */ - pg.connect(this.pg_config, (err, client, done) => { + this.pool.connect((err, client, done) => { if (err) { done(client); callback(err); @@ -41,16 +42,16 @@ module.exports = class PostgresDB { name: 'sdb-commit-op-and-snap', text: `With snaps as ( Insert into snapshots (collection,doc_id,doc_type, version,data) - Select n.* From ( select $1 c, $2 d, $4 t, $3 v, $5 daa) + Select n.* From ( select $1 c, $2 d, $4 t, $3::integer v, $5::jsonb daa) n where v = (select version+1 v from snapshots where collection = $1 and doc_id = $2 for update) or not exists (select 1 from snapshots where collection = $1 and doc_id = $2 for update) - On conflict(collection, doc_id) do update set version = $3, data = $5 , doc_type = $2 + On conflict(collection, doc_id) do update set version = $3, data = $5 , doc_type = $4 Returning version ) Insert into ops (collection,doc_id, version,operation) - Select n.* From ( select $1 c, $2 t, $3 v, $6 daa) + Select n.* From ( select $1 c, $2 t, $3::integer v, $6::jsonb daa) n - where (v = (select version+1 v from ops where collection = $1 and doc_id = $2 for update) or not exists (select 1 from ops where collection = $1 and doc_id = $2 for update)) and exists (select 1 from snaps) + where (v = (select max(version)+1 v from ops where collection = $1 and doc_id = $2) or not exists (select 1 from ops where collection = $1 and doc_id = $2 for update)) and exists (select 1 from snaps) Returning version`, values: [collection,id,snapshot.v, snapshot.type, snapshot.data,op] } @@ -58,7 +59,11 @@ module.exports = class PostgresDB { if (err) { console.log(err.stack) callback(err) - } else { + } else if(result.rows.length === 0) { + console.log("Unable to commit, not the latest version") + callback(null,false) + } + else { console.log(res.rows[0]) callback(null,true) } @@ -71,7 +76,7 @@ module.exports = class PostgresDB { // snapshot). A snapshot with a version of zero is returned if the docuemnt // has never been created in the database. getSnapshot(collection, id, fields, options, callback) { - pg.connect(this.pg_config, (err, client, done) => { + this.pool.connect((err, client, done) => { if (err) { done(client); callback(err); @@ -121,7 +126,7 @@ module.exports = class PostgresDB { // // Callback should be called as callback(error, [list of ops]); getOps(collection, id, from, to, options, callback) { - pg.connect(this.pg_config, (err, client, done) => { + this.pool.connect( (err, client, done) => { if (err) { done(client); callback(err); From c5af377532baabc2e8ddc9c01ffc86032b4f3a76 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sat, 24 Feb 2018 12:33:53 +1100 Subject: [PATCH 11/31] fixed typo --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 7932148..7764319 100644 --- a/index.js +++ b/index.js @@ -59,7 +59,7 @@ module.exports = class PostgresDB { if (err) { console.log(err.stack) callback(err) - } else if(result.rows.length === 0) { + } else if(res.rows.length === 0) { console.log("Unable to commit, not the latest version") callback(null,false) } From 11807289782d1a0e334e367c815b82021c0e2fff Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sat, 24 Feb 2018 12:36:13 +1100 Subject: [PATCH 12/31] updated readme --- README.md | 14 +++++++------- package.json | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index b006df0..c1e41ec 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,23 @@ -# sharedb-postgres +# sharedb-postgres-jsonb -PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This +Enhanced PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This driver can be used both as a snapshot store and oplog. Doesn't support queries (yet?). -Moderately experimental. (This drives [Synaptograph](https://www.synaptograph.com)'s backend, and [@nornagon](https://github.com/nornagon) hasn't noticed any issues so far.) +This a fork of [sharedb-postgres](https://github.com/share/sharedb-postgres) that should fix the [high concurency issues](https://github.com/share/sharedb-postgres/issues/1), rewrote to be in js es6 and now uses JSONB datatype in stead. As a result of this you now need Postgres 9.5+. ## Usage -`sharedb-postgres` wraps native [node-postgres](https://github.com/brianc/node-postgres), and it supports the same configuration options. +`sharedb-postgres-jsonb` wraps native [node-postgres](https://github.com/brianc/node-postgres), and it supports the same configuration options. To instantiate a sharedb-postgres wrapper, invoke the module and pass in your -PostgreSQL configuration as an argument. For example: +PostgreSQL configuration as an argument or use environmental arguments. For example: ```js -var db = require('sharedb-postgres')('postgres://localhost/mydb'); -var backend = require('sharedb')({db: db}) +var db = require('sharedb-postgres-jsonb'); +var backend = require('sharedb')({db: new db()}) ``` ## Error codes diff --git a/package.json b/package.json index f8863d3..37f9ad7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "sharedb-postgres", - "version": "2.0.0", + "name": "sharedb-postgres-jsonb", + "version": "3.0.0", "description": "PostgreSQL adapter for ShareDB", "main": "index.js", "scripts": { From 7becba960fa24e211d5e03caa2273838da95d9fc Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sun, 25 Feb 2018 11:36:34 +1100 Subject: [PATCH 13/31] reverted es6 convertion --- README.md | 5 +- index.js | 214 +++++++++++++++++++++++++++--------------------------- 2 files changed, 111 insertions(+), 108 deletions(-) diff --git a/README.md b/README.md index c1e41ec..85f1475 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,9 @@ Enhanced PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This driver can be used both as a snapshot store and oplog. -Doesn't support queries (yet?). - -This a fork of [sharedb-postgres](https://github.com/share/sharedb-postgres) that should fix the [high concurency issues](https://github.com/share/sharedb-postgres/issues/1), rewrote to be in js es6 and now uses JSONB datatype in stead. As a result of this you now need Postgres 9.5+. +This a fork of [sharedb-postgres](https://github.com/share/sharedb-postgres) that should fix the [high concurency issues](https://github.com/share/sharedb-postgres/issues/1) by updating the snapshot and inserting the operation in the same transcation. In order to better impletment queries in the future, the postgres JSONB datatype is used instead. As a result of this you now need Postgres 9.5+. +Also note, this now uses a pool of database conections instead. ## Usage diff --git a/index.js b/index.js index 7764319..9d8359e 100644 --- a/index.js +++ b/index.js @@ -3,35 +3,38 @@ var pg = require('pg'); // Postgres-backed ShareDB database -module.exports = class PostgresDB { - constructor(options) { - DB.call(this, options); +function PostgresDB(options) { + if (!(this instanceof PostgresDB)) return new PostgresDB(options); + DB.call(this, options); - this.closed = false; + this.closed = false; - this.pg_config = options; + this.pg_config = options; this.pool = new pg.Pool(this.pg_config) +}; +module.exports = PostgresDB; - } +PostgresDB.prototype = Object.create(DB.prototype); - close(callback) { - this.closed = true; - if (callback) callback(); - } +PostgresDB.prototype.close = function(callback) { + this.closed = true; + if (callback) callback(); +}; - // Persists an op and snapshot if it is for the next version. Calls back with - // callback(err, succeeded) - commit(collection, id, op, snapshot, options, callback) { - /* - * op: CreateOp { - * src: '24545654654646', - * seq: 1, - * v: 0, - * create: { type: 'http://sharejs.org/types/JSONv0', data: { ... } }, - * m: { ts: 12333456456 } } - * } - * snapshot: PostgresSnapshot - */ + +// Persists an op and snapshot if it is for the next version. Calls back with +// callback(err, succeeded) +PostgresDB.prototype.commit = function(collection, id, op, snapshot, options, callback) { + /* + * op: CreateOp { + * src: '24545654654646', + * seq: 1, + * v: 0, + * create: { type: 'http://sharejs.org/types/JSONv0', data: { ... } }, + * m: { ts: 12333456456 } } + * } + * snapshot: PostgresSnapshot + */ this.pool.connect((err, client, done) => { if (err) { done(client); @@ -60,100 +63,101 @@ module.exports = class PostgresDB { console.log(err.stack) callback(err) } else if(res.rows.length === 0) { + done(client); console.log("Unable to commit, not the latest version") callback(null,false) } else { + done(client); console.log(res.rows[0]) callback(null,true) } }) }) - } +}; - // Get the named document from the database. The callback is called with (err, - // snapshot). A snapshot with a version of zero is returned if the docuemnt - // has never been created in the database. - getSnapshot(collection, id, fields, options, callback) { - this.pool.connect((err, client, done) => { - if (err) { - done(client); - callback(err); - return; - } - client.query( - 'SELECT version, data, doc_type FROM snapshots WHERE collection = $1 AND doc_id = $2 LIMIT 1', - [collection, id], - (err, res) => { - done(); - if (err) { - callback(err); - return; - } - if (res.rows.length) { - const row = res.rows[0]; - var snapshot = new PostgresSnapshot( - id, - row.version, - row.doc_type, - row.data, - undefined // TODO: metadata - ) - callback(null, snapshot); - } else { - var snapshot = new PostgresSnapshot( - id, - 0, - null, - undefined, - undefined - ) - callback(null, snapshot); - } +// Get the named document from the database. The callback is called with (err, +// snapshot). A snapshot with a version of zero is returned if the docuemnt +// has never been created in the database. +PostgresDB.prototype.getSnapshot = function(collection, id, fields, options, callback) { + this.pool.connect(function(err, client, done) { + if (err) { + done(client); + callback(err); + return; + } + client.query( + 'SELECT version, data, doc_type FROM snapshots WHERE collection = $1 AND doc_id = $2 LIMIT 1', + [collection, id], + function(err, res) { + done(); + if (err) { + callback(err); + return; + } + if (res.rows.length) { + var row = res.rows[0] + var snapshot = new PostgresSnapshot( + id, + row.version, + row.doc_type, + row.data, + undefined // TODO: metadata + ) + callback(null, snapshot); + } else { + var snapshot = new PostgresSnapshot( + id, + 0, + null, + undefined, + undefined + ) + callback(null, snapshot); } - ) - }) - } - - // Get operations between [from, to) noninclusively. (Ie, the range should - // contain start but not end). - // - // If end is null, this function should return all operations from start onwards. - // - // The operations that getOps returns don't need to have a version: field. - // The version will be inferred from the parameters if it is missing. - // - // Callback should be called as callback(error, [list of ops]); - getOps(collection, id, from, to, options, callback) { - this.pool.connect( (err, client, done) => { - if (err) { - done(client); - callback(err); - return; } - client.query( - 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version >= $3 AND version < $4', - [collection, id, from, to], - (err, res) => { - done(); - if (err) { - callback(err); - return; - } - callback(null, res.rows.map(row => row.operation)); + ) + }) +}; + +// Get operations between [from, to) noninclusively. (Ie, the range should +// contain start but not end). +// +// If end is null, this function should return all operations from start onwards. +// +// The operations that getOps returns don't need to have a version: field. +// The version will be inferred from the parameters if it is missing. +// +// Callback should be called as callback(error, [list of ops]); +PostgresDB.prototype.getOps = function(collection, id, from, to, options, callback) { + this.pool.connect(function(err, client, done) { + if (err) { + done(client); + callback(err); + return; + } + client.query( + 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version >= $3 AND version < $4', + [collection, id, from, to], + function(err, res) { + done(); + if (err) { + callback(err); + return; } - ) - }) - } -} + callback(null, res.rows.map(function(row) { + return row.operation; + })); + } + ) + }) +}; -class PostgresSnapshot { - constructor(id, version, type, data, meta) { - this.id = id; - this.v = version; - this.type = type; - this.data = data; - this.m = meta; - } -} \ No newline at end of file +function PostgresSnapshot(id, version, type, data, meta) { + this.id = id; + this.v = version; + this.type = type; + this.data = data; + this.m = meta; +} From 3aa6abca132608b00daae4d5ee52d8a1cd551f87 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sat, 10 Mar 2018 12:12:14 +1100 Subject: [PATCH 14/31] cleanup for release --- README.md | 56 ++++++++++++++++++++++++++++++++++++++++++++------- package.json | 4 ++-- structure.sql | 14 +++++++++++-- 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 85f1475..964854e 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,64 @@ -# sharedb-postgres-jsonb +# sharedb-postgres -Enhanced PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This +PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This driver can be used both as a snapshot store and oplog. -This a fork of [sharedb-postgres](https://github.com/share/sharedb-postgres) that should fix the [high concurency issues](https://github.com/share/sharedb-postgres/issues/1) by updating the snapshot and inserting the operation in the same transcation. In order to better impletment queries in the future, the postgres JSONB datatype is used instead. As a result of this you now need Postgres 9.5+. +Doesn't support queries (yet?). -Also note, this now uses a pool of database conections instead. +Moderately experimental. (This drives [Synaptograph](https://www.synaptograph.com)'s backend, and [@nornagon](https://github.com/nornagon) hasn't noticed any issues so far.) + + +## Requirements + +Due to the fix to resolve [high concurency issues](https://github.com/share/sharedb-postgres/issues/1) Postgres 9.5+ is now required. + +## Migrating older versions + +Older versions of this adaptor used the data type json. You will need to alter the data type prior to using if you are upgrading. + +```PLpgSQL +ALTER TABLE ops + ALTER COLUMN operation + SET DATA TYPE jsonb + USING operation::jsonb; + +ALTER TABLE snapshots + ALTER COLUMN data + SET DATA TYPE jsonb + USING data::jsonb; +`` ## Usage `sharedb-postgres-jsonb` wraps native [node-postgres](https://github.com/brianc/node-postgres), and it supports the same configuration options. To instantiate a sharedb-postgres wrapper, invoke the module and pass in your -PostgreSQL configuration as an argument or use environmental arguments. For example: +PostgreSQL configuration as an argument or use environmental arguments. + +For example using environmental arugments: + +```js +var db = require('sharedb-postgres')(); +var backend = require('sharedb')({db: db}) +``` + +Then executing via the command line + +``` +PGUSER=dbuser PGPASSWORD=secretpassword PGHOST=database.server.com PGDATABASE=mydb PGPORT=5433 npm start +``` + +Example using an object ```js -var db = require('sharedb-postgres-jsonb'); -var backend = require('sharedb')({db: new db()}) +var db = require('sharedb-postgres')({ + user: 'dbuser', + host: 'database.server.com', + database: 'mydb', + password: 'secretpassword', + port: 5433, +}); +var backend = require('sharedb')({db: db}) ``` ## Error codes diff --git a/package.json b/package.json index 37f9ad7..f8863d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "sharedb-postgres-jsonb", - "version": "3.0.0", + "name": "sharedb-postgres", + "version": "2.0.0", "description": "PostgreSQL adapter for ShareDB", "main": "index.js", "scripts": { diff --git a/structure.sql b/structure.sql index 977988d..fa9ec40 100644 --- a/structure.sql +++ b/structure.sql @@ -2,7 +2,7 @@ CREATE TABLE ops ( collection character varying(255) not null, doc_id character varying(255) not null, version integer not null, - operation jsonb not null, -- {v:0, create:{...}} or {v:n, op:[...]} + operation json not null, -- {v:0, create:{...}} or {v:n, op:[...]} PRIMARY KEY (collection, doc_id, version) ); @@ -11,6 +11,16 @@ CREATE TABLE snapshots ( doc_id character varying(255) not null, doc_type character varying(255) not null, version integer not null, - data jsonb not null, + data json not null, PRIMARY KEY (collection, doc_id) ); + +ALTER TABLE ops + ALTER COLUMN operation + SET DATA TYPE jsonb + USING operation::jsonb; + +ALTER TABLE snapshots + ALTER COLUMN data + SET DATA TYPE jsonb + USING data::jsonb; \ No newline at end of file From 3ed40399193595bcc69496d935f94b087a31cb38 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sat, 10 Mar 2018 12:13:58 +1100 Subject: [PATCH 15/31] forgot a backtick --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 964854e..794ed3b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ ALTER TABLE snapshots ALTER COLUMN data SET DATA TYPE jsonb USING data::jsonb; -`` +``` ## Usage From 1ed2925c10710a653a471ba6d41ff8f1554e01a6 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sat, 10 Mar 2018 12:28:19 +1100 Subject: [PATCH 16/31] JSONB, PG library, and check max update --- README.md | 47 +++++++++++++++++-- index.js | 124 +++++++++++++++++--------------------------------- package.json | 2 +- structure.sql | 10 ++++ 4 files changed, 96 insertions(+), 87 deletions(-) diff --git a/README.md b/README.md index b006df0..794ed3b 100644 --- a/README.md +++ b/README.md @@ -8,15 +8,56 @@ Doesn't support queries (yet?). Moderately experimental. (This drives [Synaptograph](https://www.synaptograph.com)'s backend, and [@nornagon](https://github.com/nornagon) hasn't noticed any issues so far.) +## Requirements + +Due to the fix to resolve [high concurency issues](https://github.com/share/sharedb-postgres/issues/1) Postgres 9.5+ is now required. + +## Migrating older versions + +Older versions of this adaptor used the data type json. You will need to alter the data type prior to using if you are upgrading. + +```PLpgSQL +ALTER TABLE ops + ALTER COLUMN operation + SET DATA TYPE jsonb + USING operation::jsonb; + +ALTER TABLE snapshots + ALTER COLUMN data + SET DATA TYPE jsonb + USING data::jsonb; +``` + ## Usage -`sharedb-postgres` wraps native [node-postgres](https://github.com/brianc/node-postgres), and it supports the same configuration options. +`sharedb-postgres-jsonb` wraps native [node-postgres](https://github.com/brianc/node-postgres), and it supports the same configuration options. To instantiate a sharedb-postgres wrapper, invoke the module and pass in your -PostgreSQL configuration as an argument. For example: +PostgreSQL configuration as an argument or use environmental arguments. + +For example using environmental arugments: + +```js +var db = require('sharedb-postgres')(); +var backend = require('sharedb')({db: db}) +``` + +Then executing via the command line + +``` +PGUSER=dbuser PGPASSWORD=secretpassword PGHOST=database.server.com PGDATABASE=mydb PGPORT=5433 npm start +``` + +Example using an object ```js -var db = require('sharedb-postgres')('postgres://localhost/mydb'); +var db = require('sharedb-postgres')({ + user: 'dbuser', + host: 'database.server.com', + database: 'mydb', + password: 'secretpassword', + port: 5433, +}); var backend = require('sharedb')({db: db}) ``` diff --git a/index.js b/index.js index 3f7dc57..9d8359e 100644 --- a/index.js +++ b/index.js @@ -10,6 +10,7 @@ function PostgresDB(options) { this.closed = false; this.pg_config = options; + this.pool = new pg.Pool(this.pg_config) }; module.exports = PostgresDB; @@ -20,11 +21,6 @@ PostgresDB.prototype.close = function(callback) { if (callback) callback(); }; -function rollback(client, done) { - client.query('ROLLBACK', function(err) { - return done(err); - }) -} // Persists an op and snapshot if it is for the next version. Calls back with // callback(err, succeeded) @@ -39,91 +35,53 @@ PostgresDB.prototype.commit = function(collection, id, op, snapshot, options, ca * } * snapshot: PostgresSnapshot */ - pg.connect(this.pg_config, function(err, client, done) { - if (err) { - done(client); - callback(err); - return; - } - function commit() { - client.query('COMMIT', function(err) { - done(err); - if (err) { - callback(err); - } else { - callback(null, true); - } - }) + this.pool.connect((err, client, done) => { + if (err) { + done(client); + callback(err); + return; + } + /*const*/ var query = { + name: 'sdb-commit-op-and-snap', + text: `With snaps as ( + Insert into snapshots (collection,doc_id,doc_type, version,data) + Select n.* From ( select $1 c, $2 d, $4 t, $3::integer v, $5::jsonb daa) + n + where v = (select version+1 v from snapshots where collection = $1 and doc_id = $2 for update) or not exists (select 1 from snapshots where collection = $1 and doc_id = $2 for update) + On conflict(collection, doc_id) do update set version = $3, data = $5 , doc_type = $4 + Returning version + ) + Insert into ops (collection,doc_id, version,operation) + Select n.* From ( select $1 c, $2 t, $3::integer v, $6::jsonb daa) + n + where (v = (select max(version)+1 v from ops where collection = $1 and doc_id = $2) or not exists (select 1 from ops where collection = $1 and doc_id = $2 for update)) and exists (select 1 from snaps) + Returning version`, + values: [collection,id,snapshot.v, snapshot.type, snapshot.data,op] } - client.query( - 'SELECT max(version) AS max_version FROM ops WHERE collection = $1 AND doc_id = $2', - [collection, id], - function(err, res) { - var max_version = res.rows[0].max_version; - if (max_version == null) - max_version = 0; - if (snapshot.v !== max_version + 1) { - return callback(null, false); - } - client.query('BEGIN', function(err) { - client.query( - 'INSERT INTO ops (collection, doc_id, version, operation) VALUES ($1, $2, $3, $4)', - [collection, id, snapshot.v, op], - function(err, res) { - if (err) { - // TODO: if err is "constraint violation", callback(null, false) instead - rollback(client, done); - callback(err); - return; - } - if (snapshot.v === 1) { - client.query( - 'INSERT INTO snapshots (collection, doc_id, doc_type, version, data) VALUES ($1, $2, $3, $4, $5)', - [collection, id, snapshot.type, snapshot.v, snapshot.data], - function(err, res) { - // TODO: - // if the insert was successful and did insert, callback(null, true) - // if the insert was successful and did not insert, callback(null, false) - // if there was an error, rollback and callback(error) - if (err) { - rollback(client, done); - callback(err); - return; - } - commit(); - } - ) - } else { - client.query( - 'UPDATE snapshots SET doc_type = $3, version = $4, data = $5 WHERE collection = $1 AND doc_id = $2 AND version = ($4 - 1)', - [collection, id, snapshot.type, snapshot.v, snapshot.data], - function(err, res) { - // TODO: - // if any rows were updated, success - // if 0 rows were updated, rollback and not success - // if error, rollback and not success - if (err) { - rollback(client, done); - callback(err); - return; - } - commit(); - } - ) - } - } - ) - }) + client.query(query, (err, res) => { + if (err) { + console.log(err.stack) + callback(err) + } else if(res.rows.length === 0) { + done(client); + console.log("Unable to commit, not the latest version") + callback(null,false) + } + else { + done(client); + console.log(res.rows[0]) + callback(null,true) } - ) - }) + }) + + }) }; // Get the named document from the database. The callback is called with (err, // snapshot). A snapshot with a version of zero is returned if the docuemnt // has never been created in the database. PostgresDB.prototype.getSnapshot = function(collection, id, fields, options, callback) { - pg.connect(this.pg_config, function(err, client, done) { + this.pool.connect(function(err, client, done) { if (err) { done(client); callback(err); @@ -173,7 +131,7 @@ PostgresDB.prototype.getSnapshot = function(collection, id, fields, options, cal // // Callback should be called as callback(error, [list of ops]); PostgresDB.prototype.getOps = function(collection, id, from, to, options, callback) { - pg.connect(this.pg_config, function(err, client, done) { + this.pool.connect(function(err, client, done) { if (err) { done(client); callback(err); diff --git a/package.json b/package.json index 3b1f446..f8863d3 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "keywords": ["sharedb", "sharejs", "share", "postgres"], "repository": "share/sharedb-postgres", "dependencies": { - "pg": "^4.5.1", + "pg": "^7.4.1", "sharedb": "^1.0.0-beta.7" } } diff --git a/structure.sql b/structure.sql index 606b5fc..fa9ec40 100644 --- a/structure.sql +++ b/structure.sql @@ -14,3 +14,13 @@ CREATE TABLE snapshots ( data json not null, PRIMARY KEY (collection, doc_id) ); + +ALTER TABLE ops + ALTER COLUMN operation + SET DATA TYPE jsonb + USING operation::jsonb; + +ALTER TABLE snapshots + ALTER COLUMN data + SET DATA TYPE jsonb + USING data::jsonb; \ No newline at end of file From 698bb625fc38dda547289585b57cb42c391baf86 Mon Sep 17 00:00:00 2001 From: William Claydon Date: Sat, 17 Mar 2018 18:06:53 +1100 Subject: [PATCH 17/31] typo --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 0293110..9f2ef25 100644 --- a/index.js +++ b/index.js @@ -50,7 +50,7 @@ PostgresDB.prototype.commit = function(collection, id, op, snapshot, options, ca * (iff the new version is exactly 1 more than the latest table or if * the document id does not exists) * - * It will than Insert into the ops table if it is exactly 1 more than the + * It will then insert into the ops table if it is exactly 1 more than the * latest table or it the first operation and iff the previous insert into * the snapshot table is successful. * From cd5b2efc283ff6ad69aa23ccbc2e7429eaeda363 Mon Sep 17 00:00:00 2001 From: zbryikt Date: Wed, 11 Jul 2018 17:00:01 +0800 Subject: [PATCH 18/31] shift the query range in ops --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 9d8359e..9b429e9 100644 --- a/index.js +++ b/index.js @@ -138,7 +138,7 @@ PostgresDB.prototype.getOps = function(collection, id, from, to, options, callba return; } client.query( - 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version >= $3 AND version < $4', + 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version > $3 AND version <= $4', [collection, id, from, to], function(err, res) { done(); From 351485a3448c06f483c4613df845a4a52ee9b9ac Mon Sep 17 00:00:00 2001 From: zbryikt Date: Wed, 11 Jul 2018 17:02:51 +0800 Subject: [PATCH 19/31] shift getops range --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index da934f8..418461e 100644 --- a/index.js +++ b/index.js @@ -172,7 +172,7 @@ PostgresDB.prototype.getOps = function(collection, id, from, to, options, callba return; } client.query( - 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version >= $3 AND version < $4', + 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version > $3 AND version <= $4', [collection, id, from, to], function(err, res) { done(); From 51f1c5792104f67536bf6d6c20fac49b19b71827 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sun, 24 May 2020 21:26:13 +0800 Subject: [PATCH 20/31] by doc, getOps return ops to the latest version if version is null. additionally, ops have to be sorted for things like fetchSnapshots to work. --- index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 9b429e9..57b49af 100644 --- a/index.js +++ b/index.js @@ -137,9 +137,12 @@ PostgresDB.prototype.getOps = function(collection, id, from, to, options, callba callback(err); return; } - client.query( - 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version > $3 AND version <= $4', - [collection, id, from, to], + + var cmd = 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version > $3 '; + var params = [collection, id, from]; + if(to || to == 0) { cmd += ' AND version <= $4'; params.push(to)} + cmd += ' order by version'; + client.query( cmd, params, function(err, res) { done(); if (err) { From 7d6b8e6abc35c1d08b5b2d83a994dd8894af76e2 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sun, 24 May 2020 21:30:41 +0800 Subject: [PATCH 21/31] add index for ops version. dont create table if existed. --- structure.sql | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/structure.sql b/structure.sql index fa9ec40..504de26 100644 --- a/structure.sql +++ b/structure.sql @@ -1,4 +1,4 @@ -CREATE TABLE ops ( +CREATE TABLE IF NOT EXISTS ops ( collection character varying(255) not null, doc_id character varying(255) not null, version integer not null, @@ -6,7 +6,7 @@ CREATE TABLE ops ( PRIMARY KEY (collection, doc_id, version) ); -CREATE TABLE snapshots ( +CREATE TABLE IF NOT EXISTS snapshots ( collection character varying(255) not null, doc_id character varying(255) not null, doc_type character varying(255) not null, @@ -15,6 +15,8 @@ CREATE TABLE snapshots ( PRIMARY KEY (collection, doc_id) ); +CREATE INDEX IF NOT EXISTS ops_version ON snapshots (collection, doc_id, version); + ALTER TABLE ops ALTER COLUMN operation SET DATA TYPE jsonb @@ -23,4 +25,4 @@ ALTER TABLE ops ALTER TABLE snapshots ALTER COLUMN data SET DATA TYPE jsonb - USING data::jsonb; \ No newline at end of file + USING data::jsonb; From 3b81a11143714c6eaf446345737b01bc2e470dcb Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sun, 24 May 2020 21:45:06 +0800 Subject: [PATCH 22/31] remove log --- index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/index.js b/index.js index 57b49af..1e8818c 100644 --- a/index.js +++ b/index.js @@ -69,7 +69,6 @@ PostgresDB.prototype.commit = function(collection, id, op, snapshot, options, ca } else { done(client); - console.log(res.rows[0]) callback(null,true) } }) From a42f2dc98358f76227361187da24d9e5b64dad99 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sun, 24 May 2020 23:26:27 +0800 Subject: [PATCH 23/31] update index. add .gitignore and sample-cmd --- .gitignore | 1 + package-lock.json | 164 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 7 +- sample-cmd | 16 +++++ structure.sql | 2 +- 5 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 sample-cmd diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1548fec --- /dev/null +++ b/package-lock.json @@ -0,0 +1,164 @@ +{ + "name": "sharedb-postgres", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "arraydiff": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/arraydiff/-/arraydiff-0.1.3.tgz", + "integrity": "sha1-hqVDbXty8b3aX9bXTock5C+Dzk0=" + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=" + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "ot-json0": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ot-json0/-/ot-json0-1.1.0.tgz", + "integrity": "sha512-wf5fci7GGpMYRDnbbdIFQymvhsbFACMHtxjivQo5KgvAHlxekyfJ9aPsRr6YfFQthQkk4bmsl5yESrZwC/oMYQ==" + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "pg": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.18.2.tgz", + "integrity": "sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "0.1.3", + "pg-packet-stream": "^1.1.0", + "pg-pool": "^2.0.10", + "pg-types": "^2.1.0", + "pgpass": "1.x", + "semver": "4.3.2" + } + }, + "pg-connection-string": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", + "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-packet-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz", + "integrity": "sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==" + }, + "pg-pool": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.10.tgz", + "integrity": "sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.5.tgz", + "integrity": "sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + }, + "sharedb": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-1.3.4.tgz", + "integrity": "sha512-tHiqFmd07cdbWavooUtGN7VGZdiQXrIhKPTSC2X5B8xHHpdss9NOO3kVvp3rYktb6PDiQteyRl40r10rDAHwHw==", + "requires": { + "arraydiff": "^0.1.1", + "async": "^2.6.3", + "fast-deep-equal": "^2.0.1", + "hat": "0.0.3", + "ot-json0": "^1.0.1" + } + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/package.json b/package.json index f8863d3..aea2daf 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,12 @@ }, "author": "Jeremy Apthorp ", "license": "MIT", - "keywords": ["sharedb", "sharejs", "share", "postgres"], + "keywords": [ + "sharedb", + "sharejs", + "share", + "postgres" + ], "repository": "share/sharedb-postgres", "dependencies": { "pg": "^7.4.1", diff --git a/sample-cmd b/sample-cmd new file mode 100644 index 0000000..086def8 --- /dev/null +++ b/sample-cmd @@ -0,0 +1,16 @@ +/*var query = { + name: "sdb-commit-op-and-snap", + text: ` + with snaps as ( + insert into snapshots (collection, doc_id, doc_type, version, data) + values ($1, $2, $3, $4, $5) + on conflict (collection, doc_id, version) do update set doc_type = $3, data = $5 + returning version + ) + insert into ops ( collection, doc_id, version, operation ) + values ($1, $2, $4, $6) on conflict (collection, doc_id, version) do update set operation = $6 + returning version + `, + values: [collection, id, snapshot.type, snapshot.v, snapshot.data, op] +}*/ + diff --git a/structure.sql b/structure.sql index 504de26..9b44054 100644 --- a/structure.sql +++ b/structure.sql @@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS snapshots ( PRIMARY KEY (collection, doc_id) ); -CREATE INDEX IF NOT EXISTS ops_version ON snapshots (collection, doc_id, version); +CREATE INDEX IF NOT EXISTS snapshots_version ON snapshots (collection, doc_id); ALTER TABLE ops ALTER COLUMN operation From 202ea6a728bf003859c8783519d8ec85252cc009 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sun, 24 May 2020 21:26:13 +0800 Subject: [PATCH 24/31] by doc, getOps return ops to the latest version if version is null. additionally, ops have to be sorted for things like fetchSnapshots to work. --- index.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/index.js b/index.js index 418461e..25e70e6 100644 --- a/index.js +++ b/index.js @@ -171,9 +171,12 @@ PostgresDB.prototype.getOps = function(collection, id, from, to, options, callba callback(err); return; } - client.query( - 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version > $3 AND version <= $4', - [collection, id, from, to], + + var cmd = 'SELECT version, operation FROM ops WHERE collection = $1 AND doc_id = $2 AND version > $3 '; + var params = [collection, id, from]; + if(to || to == 0) { cmd += ' AND version <= $4'; params.push(to)} + cmd += ' order by version'; + client.query( cmd, params, function(err, res) { done(); if (err) { From 3abe1a04fcade089ecb25d4a134c88549cc24c7b Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sun, 24 May 2020 21:30:41 +0800 Subject: [PATCH 25/31] add index for ops version. dont create table if existed. --- structure.sql | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/structure.sql b/structure.sql index 977988d..bb8b297 100644 --- a/structure.sql +++ b/structure.sql @@ -1,4 +1,4 @@ -CREATE TABLE ops ( +CREATE TABLE IF NOT EXISTS ops ( collection character varying(255) not null, doc_id character varying(255) not null, version integer not null, @@ -6,7 +6,7 @@ CREATE TABLE ops ( PRIMARY KEY (collection, doc_id, version) ); -CREATE TABLE snapshots ( +CREATE TABLE IF NOT EXISTS snapshots ( collection character varying(255) not null, doc_id character varying(255) not null, doc_type character varying(255) not null, @@ -14,3 +14,15 @@ CREATE TABLE snapshots ( data jsonb not null, PRIMARY KEY (collection, doc_id) ); + +CREATE INDEX IF NOT EXISTS ops_version ON snapshots (collection, doc_id, version); + +ALTER TABLE ops + ALTER COLUMN operation + SET DATA TYPE jsonb + USING operation::jsonb; + +ALTER TABLE snapshots + ALTER COLUMN data + SET DATA TYPE jsonb + USING data::jsonb; From 45781a105c7730b48d8fd0b5d1061b8a0ac9c7d3 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sun, 24 May 2020 23:26:27 +0800 Subject: [PATCH 26/31] update index. add .gitignore and sample-cmd --- .gitignore | 1 + package-lock.json | 164 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 7 +- sample-cmd | 16 +++++ structure.sql | 2 +- 5 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 package-lock.json create mode 100644 sample-cmd diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1548fec --- /dev/null +++ b/package-lock.json @@ -0,0 +1,164 @@ +{ + "name": "sharedb-postgres", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "arraydiff": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/arraydiff/-/arraydiff-0.1.3.tgz", + "integrity": "sha1-hqVDbXty8b3aX9bXTock5C+Dzk0=" + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } + }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=" + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + }, + "ot-json0": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ot-json0/-/ot-json0-1.1.0.tgz", + "integrity": "sha512-wf5fci7GGpMYRDnbbdIFQymvhsbFACMHtxjivQo5KgvAHlxekyfJ9aPsRr6YfFQthQkk4bmsl5yESrZwC/oMYQ==" + }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "pg": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.18.2.tgz", + "integrity": "sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "0.1.3", + "pg-packet-stream": "^1.1.0", + "pg-pool": "^2.0.10", + "pg-types": "^2.1.0", + "pgpass": "1.x", + "semver": "4.3.2" + } + }, + "pg-connection-string": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", + "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-packet-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz", + "integrity": "sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==" + }, + "pg-pool": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.10.tgz", + "integrity": "sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "^1.0.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.5.tgz", + "integrity": "sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + }, + "sharedb": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-1.3.4.tgz", + "integrity": "sha512-tHiqFmd07cdbWavooUtGN7VGZdiQXrIhKPTSC2X5B8xHHpdss9NOO3kVvp3rYktb6PDiQteyRl40r10rDAHwHw==", + "requires": { + "arraydiff": "^0.1.1", + "async": "^2.6.3", + "fast-deep-equal": "^2.0.1", + "hat": "0.0.3", + "ot-json0": "^1.0.1" + } + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + } + } +} diff --git a/package.json b/package.json index cbf8147..bf9720d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,12 @@ }, "author": "Jeremy Apthorp ", "license": "MIT", - "keywords": ["sharedb", "sharejs", "share", "postgres"], + "keywords": [ + "sharedb", + "sharejs", + "share", + "postgres" + ], "repository": "share/sharedb-postgres", "dependencies": { "pg": "^7.4.1", diff --git a/sample-cmd b/sample-cmd new file mode 100644 index 0000000..086def8 --- /dev/null +++ b/sample-cmd @@ -0,0 +1,16 @@ +/*var query = { + name: "sdb-commit-op-and-snap", + text: ` + with snaps as ( + insert into snapshots (collection, doc_id, doc_type, version, data) + values ($1, $2, $3, $4, $5) + on conflict (collection, doc_id, version) do update set doc_type = $3, data = $5 + returning version + ) + insert into ops ( collection, doc_id, version, operation ) + values ($1, $2, $4, $6) on conflict (collection, doc_id, version) do update set operation = $6 + returning version + `, + values: [collection, id, snapshot.type, snapshot.v, snapshot.data, op] +}*/ + diff --git a/structure.sql b/structure.sql index bb8b297..c071b4e 100644 --- a/structure.sql +++ b/structure.sql @@ -15,7 +15,7 @@ CREATE TABLE IF NOT EXISTS snapshots ( PRIMARY KEY (collection, doc_id) ); -CREATE INDEX IF NOT EXISTS ops_version ON snapshots (collection, doc_id, version); +CREATE INDEX IF NOT EXISTS snapshots_version ON snapshots (collection, doc_id); ALTER TABLE ops ALTER COLUMN operation From 55a0c76cb965fbcc720efadc91de1534dd8fc307 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Sat, 30 May 2020 15:28:40 +0800 Subject: [PATCH 27/31] add pg-pool, update sharedb --- package-lock.json | 15 +++++++++++---- package.json | 3 ++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1548fec..1870f97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sharedb-postgres", - "version": "2.0.0", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -60,6 +60,13 @@ "pg-types": "^2.1.0", "pgpass": "1.x", "semver": "4.3.2" + }, + "dependencies": { + "pg-pool": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.10.tgz", + "integrity": "sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==" + } } }, "pg-connection-string": { @@ -78,9 +85,9 @@ "integrity": "sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==" }, "pg-pool": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.10.tgz", - "integrity": "sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", + "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" }, "pg-types": { "version": "2.2.0", diff --git a/package.json b/package.json index bf9720d..8631ff5 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "repository": "share/sharedb-postgres", "dependencies": { "pg": "^7.4.1", - "sharedb": "^1.0.0-beta.7" + "pg-pool": "^3.2.1", + "sharedb": "^1.0.0" } } From cb0c7041951c661f4125ef4403a44b43c51a8548 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Tue, 2 Feb 2021 12:43:49 +0800 Subject: [PATCH 28/31] upgrade `pg` from 7.4.1 to 8.5.1 to prevent silent failure for node v14 or later --- CHANGELOG.md | 12 +++++ README.md | 10 +++-- package-lock.json | 110 +++++++++++++++++++++++++++------------------- package.json | 8 ++-- 4 files changed, 89 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66db502..d2f7c64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## 4.0.0 + + - upgrade `pg` from 7.4.1 to 8.5.1 to prevent silent failure for node v14 or later, reported in [this issue](https://github.com/brianc/node-postgres/issues/2317). + - fix submit ops failed due to version mismatched - https://github.com/share/sharedb-postgres/issues/8 + +## Note about re-versioning + +Original `sharedb-postgres` seems to have been not maintained for a long time since 2018. Thus we made a fork and maintain it as `@plotdb/sharedb-postgre`. + + +# Change log in original repo + ## 3.0.0 Thanks to @billwashere, we upgraded to a more modern version of `pg` (4.5.1 -> diff --git a/README.md b/README.md index 644bb7e..b73277b 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,17 @@ -# sharedb-postgres +# @plotdb/sharedb-postgres -PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This -driver can be used both as a snapshot store and oplog. +PostgreSQL database adapter for [sharedb](https://github.com/share/sharedb). This driver can be used both as a snapshot store and oplog. Doesn't support queries (yet?). Moderately experimental. (This drives [Synaptograph](https://www.synaptograph.com)'s backend, and [@nornagon](https://github.com/nornagon) hasn't noticed any issues so far.) +## Note about versioning + +This is a fork from the [original `sharedb-postgres`](https://github.com/share/sharedb-postgres) and its relative forks (see [billwashere](https://github.com/billwashere/sharedb-postgres-jsonb), [zbryikt](https://github.com/zbryikt/sharedb-postgres-jsonb). It seems to have been not maintained for a long time since 2018, Thus we decide to fork it and maintain it as `@plotdb/sharedb-postgre`. + + ## Requirements Due to the fix to resolve [high concurency issues](https://github.com/share/sharedb-postgres/issues/1) Postgres 9.5+ is now required. diff --git a/package-lock.json b/package-lock.json index 1870f97..7232016 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "sharedb-postgres", - "version": "3.0.0", + "name": "@plotdb/sharedb-postgres", + "version": "4.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -32,10 +32,15 @@ "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=" }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "ot-json0": { "version": "1.1.0", @@ -48,47 +53,46 @@ "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, "pg": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/pg/-/pg-7.18.2.tgz", - "integrity": "sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==", + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", + "integrity": "sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw==", "requires": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "0.1.3", - "pg-packet-stream": "^1.1.0", - "pg-pool": "^2.0.10", + "pg-connection-string": "^2.4.0", + "pg-pool": "^3.2.2", + "pg-protocol": "^1.4.0", "pg-types": "^2.1.0", - "pgpass": "1.x", - "semver": "4.3.2" + "pgpass": "1.x" }, "dependencies": { "pg-pool": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.10.tgz", - "integrity": "sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==" + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.2.tgz", + "integrity": "sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==" } } }, "pg-connection-string": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", - "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", + "integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==" }, "pg-int8": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" }, - "pg-packet-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz", - "integrity": "sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==" - }, "pg-pool": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" }, + "pg-protocol": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.4.0.tgz", + "integrity": "sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==" + }, "pg-types": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", @@ -102,11 +106,11 @@ } }, "pgpass": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", - "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", "requires": { - "split": "^1.0.0" + "split2": "^3.1.1" } }, "postgres-array": { @@ -120,9 +124,9 @@ "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" }, "postgres-date": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.5.tgz", - "integrity": "sha512-pdau6GRPERdAYUQwkBnGKxEfPyhVZXG/JiS44iZWiNdSOWE09N2lUgN6yshuq6fVSon4Pm0VMXd1srUUkLe9iA==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" }, "postgres-interval": { "version": "1.2.0", @@ -132,10 +136,20 @@ "xtend": "^4.0.0" } }, - "semver": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", - "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "sharedb": { "version": "1.3.4", @@ -149,18 +163,26 @@ "ot-json0": "^1.0.1" } }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "requires": { - "through": "2" + "readable-stream": "^3.0.0" } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "xtend": { "version": "4.0.2", diff --git a/package.json b/package.json index 8631ff5..3c21f6d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "sharedb-postgres", - "version": "3.0.0", - "description": "PostgreSQL adapter for ShareDB", + "name": "@plotdb/sharedb-postgres", + "version": "4.0.0", + "description": "PostgreSQL adapter for ShareDB. forked from share/sharedb-postgres", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" @@ -16,7 +16,7 @@ ], "repository": "share/sharedb-postgres", "dependencies": { - "pg": "^7.4.1", + "pg": "^8.5.1", "pg-pool": "^3.2.1", "sharedb": "^1.0.0" } From 84ce49e2f18aaf2ae0f80a364068e9a4f58bb662 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Tue, 2 Feb 2021 12:51:33 +0800 Subject: [PATCH 29/31] update repo url --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 3c21f6d..b8d76ed 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,10 @@ "share", "postgres" ], - "repository": "share/sharedb-postgres", + "repository": { + "type": "git", + "url": "https://github.com/plotdb/sharedb-postgres" + }, "dependencies": { "pg": "^8.5.1", "pg-pool": "^3.2.1", From f8890b12b7a43537397793e4afe5e949c3649fd6 Mon Sep 17 00:00:00 2001 From: Kirby Wu Date: Tue, 2 Feb 2021 13:08:08 +0800 Subject: [PATCH 30/31] upgrade sharedb --- CHANGELOG.md | 5 + package-lock.json | 235 +++++++++++++++++++++++++++++++++++++++++++++- package.json | 4 +- 3 files changed, 237 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2f7c64..1adfb00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 4.0.1 + + - upgrade sharedb + + ## 4.0.0 - upgrade `pg` from 7.4.1 to 8.5.1 to prevent silent failure for node v14 or later, reported in [this issue](https://github.com/brianc/node-postgres/issues/2317). diff --git a/package-lock.json b/package-lock.json index 7232016..6f0a273 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,233 @@ { "name": "@plotdb/sharedb-postgres", - "version": "4.0.0", - "lockfileVersion": 1, + "version": "4.0.1", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "@plotdb/sharedb-postgres", + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "pg": "^8.5.1", + "pg-pool": "^3.2.1", + "sharedb": "^1.6.0" + } + }, + "node_modules/arraydiff": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/arraydiff/-/arraydiff-0.1.3.tgz", + "integrity": "sha1-hqVDbXty8b3aX9bXTock5C+Dzk0=" + }, + "node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "node_modules/hat": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/hat/-/hat-0.0.3.tgz", + "integrity": "sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo=" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "node_modules/ot-json0": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ot-json0/-/ot-json0-1.1.0.tgz", + "integrity": "sha512-wf5fci7GGpMYRDnbbdIFQymvhsbFACMHtxjivQo5KgvAHlxekyfJ9aPsRr6YfFQthQkk4bmsl5yESrZwC/oMYQ==" + }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, + "node_modules/pg": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.5.1.tgz", + "integrity": "sha512-9wm3yX9lCfjvA98ybCyw2pADUivyNWT/yIP4ZcDVpMN0og70BUWYEGXPCTAQdGTAqnytfRADb7NERrY1qxhIqw==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.4.0", + "pg-pool": "^3.2.2", + "pg-protocol": "^1.4.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/pg-connection-string": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.4.0.tgz", + "integrity": "sha512-3iBXuv7XKvxeMrIgym7njT+HlZkwZqqGX4Bu9cci8xHZNT+Um1gWKqCsAzcC0d95rcKMU5WBg6YRUcHyV0HZKQ==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.1.tgz", + "integrity": "sha512-BQDPWUeKenVrMMDN9opfns/kZo4lxmSWhIqo+cSAF7+lfi9ZclQbr9vfnlNaPr8wYF3UYjm5X0yPAhbcgqNOdA==" + }, + "node_modules/pg-protocol": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.4.0.tgz", + "integrity": "sha512-El+aXWcwG/8wuFICMQjM5ZSAm6OWiJicFdNYo+VY3QP+8vI4SvLIWVe51PppTzMhikUJR+PsyIFKqfdXPz/yxA==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/pg-pool": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.2.2.tgz", + "integrity": "sha512-ORJoFxAlmmros8igi608iVEbQNNZlp89diFVx6yV5v+ehmpMY9sK6QgpmgoXbmkNaBAx8cOOZh9g80kJv1ooyA==" + }, + "node_modules/pgpass": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz", + "integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==", + "dependencies": { + "split2": "^3.1.1" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "node_modules/sharedb": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-1.6.0.tgz", + "integrity": "sha512-N6jhmh408OrZQA7V9Eb1R1vfnJe4zoBjB932L/Z2U4jBZ1F8VTHneMntgVmDfjqkAIWN16TVpxMbcycuLxcDpQ==", + "dependencies": { + "arraydiff": "^0.1.1", + "async": "^2.6.3", + "fast-deep-equal": "^2.0.1", + "hat": "0.0.3", + "ot-json0": "^1.0.1" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + } + }, "dependencies": { "arraydiff": { "version": "0.1.3", @@ -152,9 +377,9 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "sharedb": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-1.3.4.tgz", - "integrity": "sha512-tHiqFmd07cdbWavooUtGN7VGZdiQXrIhKPTSC2X5B8xHHpdss9NOO3kVvp3rYktb6PDiQteyRl40r10rDAHwHw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/sharedb/-/sharedb-1.6.0.tgz", + "integrity": "sha512-N6jhmh408OrZQA7V9Eb1R1vfnJe4zoBjB932L/Z2U4jBZ1F8VTHneMntgVmDfjqkAIWN16TVpxMbcycuLxcDpQ==", "requires": { "arraydiff": "^0.1.1", "async": "^2.6.3", diff --git a/package.json b/package.json index b8d76ed..051bc07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@plotdb/sharedb-postgres", - "version": "4.0.0", + "version": "4.0.1", "description": "PostgreSQL adapter for ShareDB. forked from share/sharedb-postgres", "main": "index.js", "scripts": { @@ -21,6 +21,6 @@ "dependencies": { "pg": "^8.5.1", "pg-pool": "^3.2.1", - "sharedb": "^1.0.0" + "sharedb": "^1.6.0" } } From 2d9aa160183de0eece25fca3430eb52064265ac9 Mon Sep 17 00:00:00 2001 From: cunzhe <32587201+smalllicheng@users.noreply.github.com> Date: Fri, 2 Jul 2021 10:38:58 +0800 Subject: [PATCH 31/31] update package name fix the outdated example code --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b73277b..9ee49de 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,13 @@ Moderately experimental. (This drives [Synaptograph](https://www.synaptograph.co This is a fork from the [original `sharedb-postgres`](https://github.com/share/sharedb-postgres) and its relative forks (see [billwashere](https://github.com/billwashere/sharedb-postgres-jsonb), [zbryikt](https://github.com/zbryikt/sharedb-postgres-jsonb). It seems to have been not maintained for a long time since 2018, Thus we decide to fork it and maintain it as `@plotdb/sharedb-postgre`. +## Installation + +```cmd +npm i @plotdb/sharedb-postgres +``` + + ## Requirements Due to the fix to resolve [high concurency issues](https://github.com/share/sharedb-postgres/issues/1) Postgres 9.5+ is now required. @@ -42,7 +49,7 @@ PostgreSQL configuration as an argument or use environmental arguments. For example using environmental arugments: ```js -var db = require('sharedb-postgres')(); +var db = require('@plotdb/sharedb-postgres')(); var backend = require('sharedb')({db: db}) ``` @@ -55,7 +62,7 @@ PGUSER=dbuser PGPASSWORD=secretpassword PGHOST=database.server.com PGDATABASE=m Example using an object ```js -var db = require('sharedb-postgres')({host: 'localhost', database: 'mydb'}); +var db = require('@plotdb/sharedb-postgres')({host: 'localhost', database: 'mydb'}); var backend = require('sharedb')({db: db}) ```