Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
if(!dojo._hasResource["dojox.grid.tests.databaseModel"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2
dojo._hasResource["dojox.grid.tests.databaseModel"] = true;
3
dojo.provide("dojox.grid.tests.databaseModel");
4
dojo.require("dojox.grid._data.model");
5
 
6
// Provides a sparse array that is also traversable inorder
7
// with basic Array:
8
//   - iterating by index is slow for large sparse arrays
9
//   - for...in iteration is in order of element creation
10
// maintains a secondary index for interating
11
// over sparse elements inorder
12
dojo.declare("dojox.grid.Sparse", null, {
13
	constructor: function() {
14
		this.clear();
15
	},
16
	clear: function() {
17
		this.indices = [];
18
		this.values = [];
19
	},
20
	length: function() {
21
		return this.indices.length;
22
	},
23
	set: function(inIndex, inValue) {
24
		for (var i=0,l=this.indices.length; i<l; i++) {
25
			if (this.indices[i] >= inIndex)
26
				break;
27
		}
28
		if (this.indices[i] != inIndex)
29
			this.indices.splice(i, 0, inIndex);
30
		this.values[inIndex] = inValue;
31
	},
32
	get: function(inIndex) {
33
		return this.values[inIndex];
34
	},
35
	remove: function(inIndex) {
36
		for (var i=0,l=this.indices.length; i<l; i++)
37
			if (this.indices[i] == inIndex) {
38
				this.indices.splice(i, 1);
39
				break;
40
			}
41
		delete this.values[inIndex];
42
	},
43
	inorder: function(inFor) {
44
		for (var i=0,l=this.indices.length, ix; i<l; i++) {
45
			ix = this.indices[i];
46
			if (inFor(this.values[ix], ix) === false)
47
				break;
48
		}
49
	}
50
});
51
 
52
// sample custom model implementation that works with mysql server.
53
dojo.declare("dojox.grid.data.DbTable", dojox.grid.data.Dynamic, {
54
	delayedInsertCommit: true,
55
	constructor: function(inFields, inData, inServer, inDatabase, inTable) {
56
		this.server = inServer;
57
		this.database = inDatabase;
58
		this.table = inTable;
59
		this.stateNames = ['inflight', 'inserting', 'removing', 'error'];
60
		this.clearStates();
61
		this.clearSort();
62
	},
63
	clearData: function() {
64
		this.cache = [ ];
65
		this.clearStates();
66
		this.inherited(arguments);
67
	},
68
	clearStates: function() {
69
		this.states = {};
70
		for (var i=0, s; (s=this.stateNames[i]); i++) {
71
			delete this.states[s];
72
			this.states[s] = new dojox.grid.Sparse();
73
		}
74
	},
75
	// row state information
76
	getState: function(inRowIndex) {
77
		for (var i=0, r={}, s; (s=this.stateNames[i]); i++)
78
			r[s] = this.states[s].get(inRowIndex);
79
		return r;
80
	},
81
	setState: function(inRowIndex, inState, inValue) {
82
		this.states[inState].set(inRowIndex, inValue||true);
83
	},
84
	clearState: function(inRowIndex, inState) {
85
		if (arguments.length == 1) {
86
			for (var i=0, s; (s=this.stateNames[i]); i++)
87
				this.states[s].remove(inRowIndex);
88
		}	else {
89
			for (var i=1, l=arguments.length, arg; (i<l) &&((arg=arguments[i])!=undefined); i++)
90
				this.states[arg].remove(inRowIndex);
91
		}
92
	},
93
	setStateForIndexes: function(inRowIndexes, inState, inValue) {
94
		for (var i=inRowIndexes.length-1, k; (i>=0) && ((k=inRowIndexes[i])!=undefined); i--)
95
			this.setState(k, inState, inValue);
96
	},
97
	clearStateForIndexes: function(inRowIndexes, inState) {
98
		for (var i=inRowIndexes.length-1, k; (i>=0) && ((k=inRowIndexes[i])!=undefined); i--)
99
			this.clearState(k, inState);
100
	},
101
	//$ Return boolean stating whether or not an operation is in progress that may change row indexing.
102
	isAddRemoving: function() {
103
		return Boolean(this.states['inserting'].length() || this.states['removing'].length());
104
	},
105
	isInflight: function() {
106
		return Boolean(this.states['inflight'].length());
107
	},
108
	//$ Return boolean stating if the model is currently undergoing any type of edit.
109
	isEditing: function() {
110
		for (var i=0, r={}, s; (s=this.stateNames[i]); i++)
111
			if (this.states[s].length())
112
				return true;
113
	},
114
	//$ Return true if ok to modify the given row. Override as needed, using model editing state information.
115
	canModify: function(inRowIndex) {
116
		return !this.getState(inRowIndex).inflight && !(this.isInflight() && this.isAddRemoving());
117
	},
118
	// server send / receive
119
	getSendParams: function(inParams) {
120
		var p = {
121
			database: this.database || '',
122
			table: this.table || ''
123
		}
124
		return dojo.mixin(p, inParams || {});
125
	},
126
	send: function(inAsync, inParams, inCallbacks) {
127
		//console.log('send', inParams.command);
128
		var p = this.getSendParams(inParams);
129
		var d = dojo.xhrPost({
130
			url: this.server,
131
			content: p,
132
			handleAs: 'json-comment-filtered',
133
			contentType: "application/x-www-form-urlencoded; charset=utf-8",
134
			sync: !inAsync
135
		});
136
		d.addCallbacks(dojo.hitch(this, "receive", inCallbacks), dojo.hitch(this, "receiveError", inCallbacks));
137
		return d;
138
	},
139
	_callback: function(cb, eb, data) {
140
		try{ cb && cb(data); }
141
		catch(e){ eb && eb(data, e); }
142
	},
143
	receive: function(inCallbacks, inData) {
144
		inCallbacks && this._callback(inCallbacks.callback, inCallbacks.errback, inData);
145
	},
146
	receiveError: function(inCallbacks, inErr) {
147
		this._callback(inCallbacks.errback, null, inErr)
148
	},
149
	encodeRow: function(inParams, inRow, inPrefix) {
150
		for (var i=0, l=inRow.length; i < l; i++)
151
			inParams['_' + (inPrefix ? inPrefix : '') + i] = (inRow[i] ? inRow[i] : '');
152
	},
153
	measure: function() {
154
		this.send(true, { command: 'info' }, { callback: dojo.hitch(this, this.callbacks.info) });
155
	},
156
	fetchRowCount: function(inCallbacks) {
157
		this.send(true, { command: 'count' }, inCallbacks);
158
	},
159
	// server commits
160
	commitEdit: function(inOldData, inNewData, inRowIndex, inCallbacks) {
161
		this.setState(inRowIndex, "inflight", true);
162
		var params = {command: 'update'};
163
		this.encodeRow(params, inOldData, 'o');
164
		this.encodeRow(params, inNewData);
165
		this.send(true, params, inCallbacks);
166
	},
167
	commitInsert: function(inRowIndex, inNewData, inCallbacks) {
168
		this.setState(inRowIndex, "inflight", true);
169
		var params = {command: 'insert'};
170
		this.encodeRow(params, inNewData);
171
		this.send(true, params, inCallbacks);
172
	},
173
	// NOTE: supported only in tables with pk
174
	commitDelete: function(inRows, inCallbacks) {
175
		var params = {
176
			command: 'delete',
177
			count: inRows.length
178
		}
179
		var pk = this.getPkIndex();
180
		if (pk < 0)
181
			return;
182
		for (var i=0; i < inRows.length; i++)	{
183
			params['_' + i] = inRows[i][pk];
184
		}
185
		this.send(true, params, inCallbacks);
186
	},
187
	getUpdateCallbacks: function(inRowIndex) {
188
		return {
189
			callback: dojo.hitch(this, this.callbacks.update, inRowIndex),
190
			errback: dojo.hitch(this, this.callbacks.updateError, inRowIndex)
191
		};
192
	},
193
	// primary key from fields
194
	getPkIndex: function() {
195
		for (var i=0, l=this.fields.count(), f; (i<l) && (f=this.fields.get(i)); i++)
196
			if (f.Key = 'PRI')
197
				return i;
198
		return -1;
199
	},
200
	// model implementations
201
	update: function(inOldData, inNewData, inRowIndex) {
202
		var cbs = this.getUpdateCallbacks(inRowIndex);
203
		if (this.getState(inRowIndex).inserting)
204
			this.commitInsert(inRowIndex, inNewData, cbs);
205
		else
206
			this.commitEdit(this.cache[inRowIndex] || inOldData, inNewData, inRowIndex, cbs);
207
		// set push data immediately to model	so reflectd while committing
208
		this.setRow(inNewData, inRowIndex);
209
	},
210
	insert: function(inData, inRowIndex) {
211
		this.setState(inRowIndex, 'inserting', true);
212
		if (!this.delayedInsertCommit)
213
			this.commitInsert(inRowIndex, inData, this.getUpdateCallbacks(inRowIndex));
214
		return this.inherited(arguments);
215
	},
216
	remove: function(inRowIndexes) {
217
		var rows = [];
218
		for (var i=0, r=0, indexes=[]; (r=inRowIndexes[i]) !== undefined; i++)
219
			if (!this.getState(r).inserting) {
220
				rows.push(this.getRow(r));
221
				indexes.push(r);
222
				this.setState(r, 'removing');
223
			}
224
		var cbs = {
225
			callback: dojo.hitch(this, this.callbacks.remove, indexes),
226
			errback: dojo.hitch(this, this.callbacks.removeError, indexes)
227
		};
228
		this.commitDelete(rows, cbs);
229
		dojox.grid.data.Dynamic.prototype.remove.apply(this, arguments);
230
	},
231
	cancelModifyRow: function(inRowIndex) {
232
		if (this.isDelayedInsert(inRowIndex)) {
233
			this.removeInsert(inRowIndex);
234
		} else
235
			this.finishUpdate(inRowIndex);
236
	},
237
	finishUpdate: function(inRowIndex, inData) {
238
		this.clearState(inRowIndex);
239
		var d = (inData&&inData[0]) || this.cache[inRowIndex];
240
		if (d)
241
			this.setRow(d, inRowIndex);
242
		delete this.cache[inRowIndex];
243
	},
244
	isDelayedInsert: function(inRowIndex) {
245
		return (this.delayedInsertCommit && this.getState(inRowIndex).inserting);
246
	},
247
	removeInsert: function(inRowIndex) {
248
		this.clearState(inRowIndex);
249
		dojox.grid.data.Dynamic.prototype.remove.call(this, [inRowIndex]);
250
	},
251
	// request data
252
	requestRows: function(inRowIndex, inCount)	{
253
		var params = {
254
			command: 'select',
255
			orderby: this.sortField,
256
			desc: (this.sortDesc ? "true" : ''),
257
			offset: inRowIndex,
258
			limit: inCount
259
		}
260
		this.send(true, params, {callback: dojo.hitch(this, this.callbacks.rows, inRowIndex)});
261
	},
262
	// sorting
263
	canSort: function () {
264
		return true;
265
	},
266
	setSort: function(inSortIndex) {
267
		this.sortField = this.fields.get(Math.abs(inSortIndex) - 1).name || inSortIndex;
268
		this.sortDesc = (inSortIndex < 0);
269
	},
270
	sort: function(inSortIndex) {
271
		this.setSort(inSortIndex);
272
		this.clearData();
273
	},
274
	clearSort: function(){
275
		this.sortField = '';
276
		this.sortDesc = false;
277
	},
278
	endModifyRow: function(inRowIndex){
279
		var cache = this.cache[inRowIndex];
280
		var m = false;
281
		if(cache){
282
			var data = this.getRow(inRowIndex);
283
			if(!dojox.grid.arrayCompare(cache, data)){
284
				m = true;
285
				this.update(cache, data, inRowIndex);
286
			}
287
		}
288
		if (!m)
289
			this.cancelModifyRow(inRowIndex);
290
	},
291
	// server callbacks (called with this == model)
292
	callbacks: {
293
		update: function(inRowIndex, inData) {
294
			console.log('received update', arguments);
295
			if (inData.error)
296
				this.updateError(inData)
297
			else
298
				this.finishUpdate(inRowIndex, inData);
299
		},
300
		updateError: function(inRowIndex) {
301
			this.clearState(inRowIndex, 'inflight');
302
			this.setState(inRowIndex, "error", "update failed: " + inRowIndex);
303
			this.rowChange(this.getRow(inRowIndex), inRowIndex);
304
		},
305
		remove: function(inRowIndexes) {
306
			this.clearStateForIndexes(inRowIndexes);
307
		},
308
		removeError: function(inRowIndexes) {
309
			this.clearStateForIndexes(inRowIndexes);
310
			alert('Removal error. Please refresh.');
311
		},
312
		rows: function(inRowIndex, inData) {
313
			//this.beginUpdate();
314
			for (var i=0, l=inData.length; i<l; i++)
315
				this.setRow(inData[i], inRowIndex + i);
316
			//this.endUpdate();
317
			//this.allChange();
318
		},
319
		count: function(inRowCount) {
320
			this.count = Number(inRowCount);
321
			this.clearData();
322
		},
323
		info: function(inInfo) {
324
			this.fields.clear();
325
			for (var i=0, c; (c=inInfo.columns[i]); i++) {
326
				c.name = c.Field;
327
				this.fields.set(i, c);
328
			}
329
			this.table = inInfo.table;
330
			this.database = inInfo.database;
331
			this.notify("MetaData", arguments);
332
			this.callbacks.count.call(this, inInfo.count);
333
		}
334
	}
335
});
336
 
337
}