forked from mozilla-b2g/gaia
/
account.js
185 lines (148 loc) · 4.52 KB
/
account.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
(function(window) {
function Account() {
Calendar.Store.Abstract.apply(this, arguments);
}
Account.prototype = {
__proto__: Calendar.Store.Abstract.prototype,
_store: 'accounts',
verifyAndPersist: function(model, callback) {
var self = this;
var provider = Calendar.App.provider(
model.providerType
);
provider.getAccount(model.toJSON(), function(err, data) {
if (err) {
callback(err);
return;
}
// if this works we always will get a calendar home.
// This is used to find calendars.
model.calendarHome = data.calendarHome;
// entrypoint is used to re-authenticate.
if ('entrypoint' in data) {
model.entrypoint = data.entrypoint;
}
if ('domain' in data) {
model.domain = data.domain;
}
self.persist(model, callback);
});
},
/**
* Because this is a top-level store
* when we remove an account all records
* related to it must be removed.
*/
_dependentStores: [
'accounts', 'calendars', 'events',
'busytimes', 'alarms', 'icalComponents'
],
_removeDependents: function(id, trans) {
var store = this.db.getStore('Calendar');
var related = store.remotesByAccount(id);
var key;
for (key in related) {
store.remove(related[key]._id, trans);
}
},
/**
* Syncs all calendars for account.
*
* @param {Calendar.Models.Account} account sync target.
* @param {Function} callback node style.
*/
sync: function(account, callback) {
//TODO: We need to block removal when syncing
//OR after removal ensure everything created here
//is purged.
var self = this;
var provider = Calendar.App.provider(account.providerType);
var store = this.db.getStore('Calendar');
var persist = [];
// remotesByAccount return an object indexed by remote ids
var calendars = store.remotesByAccount(account._id);
// these are remote ids not local ones
var originalIds = Object.keys(calendars);
provider.findCalendars(account.toJSON(), function(err, remoteCals) {
var key;
if (err) {
callback(err);
return;
}
for (key in remoteCals) {
if (remoteCals.hasOwnProperty(key)) {
var cal = remoteCals[key];
var idx = originalIds.indexOf(key);
if (idx !== -1) {
// update an existing calendar
originalIds.splice(idx, 1);
var original = calendars[key];
original.remote = cal;
persist.push(original);
} else {
// create a new calendar
persist.push(
store._createModel({
remote: new Object(cal),
accountId: account._id
})
);
}
}
}
// at this point whatever is left in originalIds
// is considered a removed calendar.
// update / remove
if (persist.length || originalIds.length) {
var trans = self.db.transaction(
self._dependentStores,
'readwrite'
);
originalIds.forEach(function(id) {
store.remove(calendars[id]._id, trans);
});
persist.forEach(function(object) {
store.persist(object, trans);
});
// event listeners must come at the end
// because persist/remove also listen to
// transaction complete events.
trans.addEventListener('error', function(err) {
callback(err);
});
trans.addEventListener('complete', function() {
callback(null);
});
} else {
// invoke callback nothing to sync
callback(null);
}
});
},
_createModel: function(obj, id) {
if (!(obj instanceof Calendar.Models.Account)) {
obj = new Calendar.Models.Account(obj);
}
if (typeof(id) !== 'undefined') {
obj._id = id;
}
return obj;
},
/**
* Checks if provider type is used
* in any of the cached records.
*
* @param {String} type (like Local).
*/
presetActive: function(type) {
var key;
for (key in this._cached) {
if (this._cached[key].preset === type) {
return true;
}
}
return false;
}
};
Calendar.ns('Store').Account = Account;
}(this));