Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

db can now be switched dynamically on the adapter #89

Merged
merged 9 commits into from
Jan 16, 2016
93 changes: 53 additions & 40 deletions addon/adapters/pouch.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,19 @@ export default DS.RESTAdapter.extend({
shouldReloadRecord: function () { return false; },
shouldBackgroundReloadRecord: function () { return false; },

_startChangesToStoreListener: on('init', function () {
this.changes = this.get('db').changes({
since: 'now',
live: true,
returnDocs: false
}).on('change', bind(this, 'onChange'));
_hookObservers : on('init', function() {
this.addObserver('db', this, this._startChangesToStoreListener);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The way this is implemented, the change listener on the old database is never cleared. That means that changes that happen in it will result in attempted updates to the store, even after you've switched databases.

It also means that one database could get the listener applied to it several times (if you switch from database A to B and back to A), which seems like it could cause performance problems if nothing else.

And it means that the change listeners for any database other than the last one set are not torn down when the application is torn down. This will likely cause problems with integration tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will fix it

}),
_startChangesToStoreListener: function () {
var db = this.get('db');
if (db) {
this.changes = db.changes({
since: 'now',
live: true,
returnDocs: false
}).on('change', bind(this, 'onChange'));
}
},

onChange: function (change) {
// If relational_pouch isn't initialized yet, there can't be any records
Expand Down Expand Up @@ -81,7 +87,8 @@ export default DS.RESTAdapter.extend({
_init: function (store, type) {
var self = this,
recordTypeName = this.getRecordTypeName(type);
if (!this.get('db') || typeof this.get('db') !== 'object') {
var db = this.get('db');
if (!db || typeof db !== 'object') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ makes sense

throw new Error('Please set the `db` property on the adapter.');
}

Expand All @@ -97,49 +104,55 @@ export default DS.RESTAdapter.extend({
var plural = pluralize(recordTypeName);

// check that we haven't already registered this model
var isSchemaNew = true;
for (var i = 0, len = this._schema.length; i < len; i++) {
var currentSchemaDef = this._schema[i];
if (currentSchemaDef.singular === singular) {
return;
isSchemaNew = false;
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^ this code doesn't look equivalent to me. can you explain it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the main problem is that the model name is the same, ( for me 'project' ) which means that the schema does not need to be recreated BUT needs to be applied to the new DB instance ( or else 'rel' is not defined ). That the goal of this code and the code below.

}
}

var schemaDef = {
singular: singular,
plural: plural
};

if (type.documentType) {
schemaDef['documentType'] = type.documentType;
}

// else it's new, so update
this._schema.push(schemaDef);

// check all the subtypes
// We check the type of `rel.type`because with ember-data beta 19
// `rel.type` switched from DS.Model to string
type.eachRelationship(function (_, rel) {
if (rel.kind !== 'belongsTo' && rel.kind !== 'hasMany') {
// TODO: support inverse as well
return; // skip
if (isSchemaNew) {
var schemaDef = {
singular: singular,
plural: plural
};

if (type.documentType) {
schemaDef['documentType'] = type.documentType;
}
var relDef = {},
relModel = (typeof rel.type === 'string' ? store.modelFor(rel.type) : rel.type);
if (relModel) {
relDef[rel.kind] = {
type: self.getRecordTypeName(relModel),
options: rel.options
};
if (!schemaDef.relations) {
schemaDef.relations = {};

this._schema.push(schemaDef);
// check all the subtypes
// We check the type of `rel.type`because with ember-data beta 19
// `rel.type` switched from DS.Model to string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change seems unrelated to the intent of the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See note above :)

type.eachRelationship(function (_, rel) {
if (rel.kind !== 'belongsTo' && rel.kind !== 'hasMany') {
// TODO: support inverse as well
return; // skip
}
schemaDef.relations[rel.key] = relDef;
self._init(store, relModel);
}
});
var relDef = {},
relModel = (typeof rel.type === 'string' ? store.modelFor(rel.type) : rel.type);
if (relModel) {
relDef[rel.kind] = {
type: self.getRecordTypeName(relModel),
options: rel.options
};
if (!schemaDef.relations) {
schemaDef.relations = {};
}
schemaDef.relations[rel.key] = relDef;
self._init(store, relModel);
}
});
}

if (!db.rel) {
db.setSchema(this._schema);
}

this.get('db').setSchema(this._schema);
},

_recordToData: function (store, type, record) {
Expand Down