Skip to content

Commit 15d0b07

Browse files
committed
Add updated version of multi-save fix
This is adapted from #249, I’m just pushing to see if it fixes the problems in the application I’m updating.
1 parent 0b7ebc6 commit 15d0b07

File tree

3 files changed

+106
-21
lines changed

3 files changed

+106
-21
lines changed

addon/adapters/pouch.js

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { bind } from '@ember/runloop';
77
import { on } from '@ember/object/evented';
88
import { classify, camelize } from '@ember/string';
99
import { pluralize } from 'ember-inflector';
10+
import { v4 } from 'uuid';
1011
//import BelongsToRelationship from 'ember-data/-private/system/relationships/state/belongs-to';
1112

1213
import {
@@ -15,6 +16,22 @@ import {
1516
configFlagDisabled,
1617
} from '../utils';
1718

19+
function getRevFromSaveResult(records) {
20+
let rev = null;
21+
try {
22+
rev = records[Object.keys(records)[0]][0].rev;
23+
if (!rev || Object.keys(records).length > 1) {
24+
// eslint-disable-next-line no-console
25+
console.warn(
26+
`getRevFromSaveResult going to return ${rev}, but that may not be correct`
27+
);
28+
}
29+
} catch (e) {
30+
throw Error(`Could not determine rev`);
31+
}
32+
return rev;
33+
}
34+
1835
//BelongsToRelationship.reopen({
1936
// findRecord() {
2037
// return this._super().catch(() => {
@@ -516,29 +533,60 @@ export default class PouchAdapter extends RESTAdapter.extend({
516533
});
517534
},
518535

536+
generateIdForRecord: function (/* store, type, inputProperties */) {
537+
return v4();
538+
},
539+
519540
createdRecords: null,
520-
createRecord: async function (store, type, record) {
521-
await this._init(store, type);
522-
var data = this._recordToData(store, type, record);
541+
createRecord: async function (store, type, snapshot) {
542+
const record = snapshot.record;
543+
if (record._emberPouchSavePromise) {
544+
console.log('found save promise');
545+
const changes = record.changedAttributes();
546+
record._emberPouchSavePromise = record._emberPouchSavePromise.then(
547+
(records) => {
548+
// If there have been changes since the document was created then we should update the record now
549+
if (Object.keys(changes).length > 0) {
550+
// Include latest rev to indicate that we're aware that data has changed since original request
551+
// (otherwise a document update conflict error would be thrown by the DB)
552+
snapshot._attributes.rev = getRevFromSaveResult(records);
553+
return this.updateRecord(store, type, snapshot);
554+
}
555+
return records;
556+
}
557+
);
558+
return record._emberPouchSavePromise;
559+
}
560+
561+
this._init(store, type);
562+
var data = this._recordToData(store, type, snapshot);
523563
let rel = this.db.rel;
524564

525565
let id = data.id;
526-
if (!id) {
527-
id = data.id = rel.uuid();
528-
}
529566
this.createdRecords[id] = true;
530567

531568
let typeName = this.getRecordTypeName(type);
532-
try {
533-
let saved = await rel.save(typeName, data);
534-
Object.assign(data, saved);
535-
let result = {};
536-
result[pluralize(typeName)] = [data];
537-
return result;
538-
} catch (e) {
539-
delete this.createdRecords[id];
540-
throw e;
541-
}
569+
570+
Object.defineProperty(record, '_emberPouchSavePromise', {
571+
enumerable: false,
572+
writable: true,
573+
value: rel
574+
.save(typeName, data)
575+
.then((saved) => {
576+
Object.assign(data, saved);
577+
let result = {};
578+
result[pluralize(typeName)] = [data];
579+
console.log('saved, result', saved, result);
580+
return result;
581+
})
582+
.catch((e) => {
583+
console.log('catch', e);
584+
delete this.createdRecords[id];
585+
throw e;
586+
}),
587+
});
588+
589+
return record._emberPouchSavePromise;
542590
},
543591

544592
updateRecord: async function (store, type, record) {

package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
},
4141
"dependencies": {
4242
"ember-auto-import": "~2.4.2",
43-
"ember-cli-babel": "^7.26.11"
43+
"ember-cli-babel": "^7.26.11",
44+
"uuid": "^3.4.0"
4445
},
4546
"devDependencies": {
4647
"@ember/optional-features": "^2.0.0",
@@ -79,16 +80,16 @@
7980
"license-checker": "^25.0.1",
8081
"loader.js": "^4.7.0",
8182
"npm-run-all": "^4.1.5",
82-
"pouchdb-core": "^7.3.1",
83-
"pouchdb-adapter-indexeddb": "^7.3.1",
8483
"pouchdb-adapter-http": "^7.3.1",
84+
"pouchdb-adapter-indexeddb": "^7.3.1",
85+
"pouchdb-core": "^7.3.1",
86+
"pouchdb-find": "^7.3.1",
8587
"pouchdb-mapreduce": "^7.3.1",
8688
"pouchdb-replication": "^7.3.1",
87-
"pouchdb-find": "^7.3.1",
88-
"relational-pouch": "^4.0.1",
8989
"prettier": "^2.6.1",
9090
"qunit": "^2.18.0",
9191
"qunit-dom": "^2.0.0",
92+
"relational-pouch": "^4.0.1",
9293
"webpack": "^5.70.0"
9394
},
9495
"engines": {

tests/integration/adapters/pouch-basics-test.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,42 @@ module('Integration | Adapter | Basic CRUD Ops', {}, function (hooks) {
440440
.finally(done);
441441
});
442442

443+
test('update a newly created record before it has finished saving', function (assert) {
444+
assert.expect(2);
445+
446+
var done = assert.async();
447+
Promise.resolve()
448+
.then(() => {
449+
var newSoup = this.store().createRecord('taco-soup', {
450+
id: 'E',
451+
flavor: 'oops-wrong-flavor',
452+
});
453+
console.log('pre first save');
454+
let res = newSoup.save();
455+
console.log('after first save', res);
456+
newSoup.set('flavor', 'balsamic');
457+
console.log('pre second save');
458+
return newSoup.save();
459+
})
460+
.then(() => {
461+
return this.db().get('tacoSoup_2_E');
462+
})
463+
.then((newDoc) => {
464+
assert.strictEqual(
465+
newDoc.data.flavor,
466+
'balsamic',
467+
'should have saved the attribute'
468+
);
469+
470+
var recordInStore = this.store().peekRecord('tacoSoup', 'E');
471+
assert.strictEqual(
472+
newDoc._rev,
473+
recordInStore.get('rev'),
474+
'should have associated the ember-data record with the rev for the new record'
475+
);
476+
})
477+
.finally(done);
478+
});
443479
test('creating an associated record stores a reference to it in the parent', function (assert) {
444480
assert.expect(1);
445481

0 commit comments

Comments
 (0)