1 // ========================================================================== 2 // Project: Greenhouse 3 // Copyright: ©2010-2010 Mike Ball 4 // ========================================================================== 5 /*globals Greenhouse */ 6 7 /** 8 This DataSource connects to the SproutCore sc-server to retrieve files 9 */ 10 Greenhouse.DataSource = SC.DataSource.extend({ 11 12 /** 13 Fetch a group of records from the data source. 14 */ 15 fetch: function(store, query) { 16 var ret = NO, rt = query.get('recordType'); 17 if(rt === Greenhouse.File || rt === Greenhouse.Dir){ 18 ret = this.listFiles(store, query); 19 } 20 else if(rt === Greenhouse.Target){ 21 ret = this.fetchTargets(store, query); 22 } 23 else if(rt === Greenhouse.ViewConfig){ 24 ret = this.fetchViewConfigs(store,query); 25 } 26 return ret; 27 }, 28 29 // .......................................................... 30 // Get file list 31 // 32 listFiles: function(store, query){ 33 SC.Request.create({type: 'GET', isJSON: YES, address: '/sproutcore/fs/apps%@/?action=list'.fmt(query.get('urlPath'))}) 34 .notify(this,this.listFilesDidComplete, {query: query, store: store}) 35 .send(); 36 }, 37 38 listFilesDidComplete: function(request, options){ 39 var response = request.get('response'), 40 query = options.query, 41 store = options.store, 42 storeKeys, recordTypes; 43 44 if (!SC.$ok(response)) { 45 console.error("Couldn't request files"); 46 } 47 else { 48 recordTypes = response.map(function(item){ 49 return item.type === 'File' ? Greenhouse.File : Greenhouse.Dir; 50 }); 51 storeKeys = store.loadRecords(recordTypes, response); 52 store.loadQueryResults(query, storeKeys); 53 Greenhouse.sendAction('fileListCallDidComplete'); 54 } 55 }, 56 57 // .......................................................... 58 // FETCHING TARGETS 59 // 60 61 /** 62 Fetch the actual targets. Only understands how to handle a remote query. 63 */ 64 fetchTargets: function(store, query) { 65 66 if (!query.get('isRemote')) return NO ; 67 68 SC.Request.getUrl('/sc/targets.json') 69 .set('isJSON', YES) 70 .notify(this, 'fetchTargetsDidComplete', { query: query, store: store }) 71 .send(); 72 return YES ; 73 }, 74 75 fetchTargetsDidComplete: function(request, opts) { 76 var response = request.get('response'), 77 query = opts.query, 78 store = opts.store, 79 storeKeys; 80 81 if (!SC.$ok(response)) { 82 console.error("TODO: Add handler when fetching targets fails"); 83 } else { 84 storeKeys = store.loadRecords(Greenhouse.Target, response); 85 store.loadQueryResults(query, storeKeys); 86 Greenhouse.sendAction('fetchTargetsDidComplete'); 87 } 88 }, 89 90 // .......................................................... 91 // FETCHING VIEW CONFIGS 92 // 93 fetchViewConfigs: function(store, query){ 94 if (!query.get('isRemote')) return NO ; 95 96 SC.Request.getUrl('/sc/greenhouseconf.json?app=%@'.fmt(query.get('app'))) 97 .set('isJSON', YES) 98 .notify(this, 'fetchViewConfigsDidComplete', { query: query, store: store }) 99 .send(); 100 return YES ; 101 }, 102 fetchViewConfigsDidComplete: function(request, opts){ 103 var response = request.get('response'), 104 query = opts.query, 105 store = opts.store, 106 storeKeys; 107 if (!SC.$ok(response)) { 108 console.error("TODO: Add handler when fetching view configs fails"); 109 } else { 110 storeKeys = store.loadRecords(Greenhouse.ViewConfig, response); 111 store.loadQueryResults(query, storeKeys); 112 } 113 }, 114 115 // .......................................................... 116 // Single File Actions 117 // 118 /** 119 updates a single record 120 121 @param {SC.Store} store the requesting store 122 @param {Array} storeKey key to update 123 @param {Hash} params to be passed down to data source. originated 124 from the commitRecords() call on the store 125 @returns {Boolean} YES if handled 126 */ 127 updateRecord: function(store, storeKey, params) { 128 var file = store.materializeRecord(storeKey); 129 var request = SC.Request.create({type: 'POST', address: "/sproutcore/fs/%@?action=overwrite".fmt(file.get('path')), 130 body: file.get('body')}) 131 .notify(this,this.updateRecordDidComplete, {file: file, storeKey: storeKey, store: store}) 132 .send(); 133 return YES ; 134 }, 135 updateRecordDidComplete: function(response, params){ 136 var file = params.file, results = response.get('body'), store = params.store; 137 if(SC.ok(response)){ 138 //HACK: for some reason the records are always 514 ready dirty not refreshing dirty... 139 status = store.readStatus(params.storeKey); 140 store.writeStatus(params.storeKey, SC.Record.BUSY_COMMITTING); 141 //end HACK 142 params.store.dataSourceDidComplete(params.storeKey); 143 } 144 else{ 145 console.error("Couldn't update file!"); 146 } 147 }, 148 149 /** 150 Called from retrieveRecords() to retrieve a single record. 151 152 @param {SC.Store} store the requesting store 153 @param {Array} storeKey key to retrieve 154 @param {String} id the id to retrieve 155 @returns {Boolean} YES if handled 156 */ 157 retrieveRecord: function(store, storeKey, params) { 158 var file = store.materializeRecord(storeKey), request; 159 if(file.kindOf(Greenhouse.File)){ 160 request = SC.Request.create({type: 'GET', address: "/sproutcore/fs%@".fmt(file.get('path'))}) 161 .notify(this, this.retrieveRecordDidComplete, {file: file, storeKey: storeKey, store: store}) 162 .send(); 163 return YES; 164 } 165 return NO; 166 }, 167 retrieveRecordDidComplete: function(response, params){ 168 var file = params.file, store = params.store, attributes, status; 169 if(SC.ok(response)){ 170 attributes = file.get('attributes');//SC.clone(file.get('attributes')); 171 attributes.body = response.get('body'); 172 //HACK: for some reason the records are always 514 ready dirty not refreshing dirty... 173 status = store.readStatus(params.storeKey); 174 store.writeStatus(params.storeKey, SC.Record.BUSY_REFRESH | (status & 0x03)) ; 175 //end HACK 176 store.dataSourceDidComplete(params.storeKey, attributes); 177 } 178 else{ 179 console.error("Couldn't request file"); 180 } 181 }, 182 /** 183 Called from createdRecords() to created a single record. This is the 184 most basic primitive to can implement to support creating a record. 185 186 To support cascading data stores, be sure to return NO if you cannot 187 handle the passed storeKey or YES if you can. 188 189 @param {SC.Store} store the requesting store 190 @param {Array} storeKey key to update 191 @param {Hash} params to be passed down to data source. originated 192 from the commitRecords() call on the store 193 @returns {Boolean} YES if handled 194 */ 195 createRecord: function(store, storeKey, params) { 196 var file = store.materializeRecord(storeKey); 197 var request = SC.Request.create({type: 'POST', address: "/sproutcore/fs/%@?action=touch".fmt(file.get('path')), 198 body: file.get('body')}) 199 .notify(this,this.createRecordDidComplete, {file: file, storeKey: storeKey, store: store}) 200 .send(); 201 return YES ; 202 }, 203 createRecordDidComplete: function(response, params){ 204 var file = params.file, results = response.get('body'), store = params.store; 205 if(SC.ok(response)){ 206 //HACK: for some reason the records are always 514 ready dirty not refreshing dirty... 207 status = store.readStatus(params.storeKey); 208 store.writeStatus(params.storeKey, SC.Record.BUSY_COMMITTING); 209 //end HACK 210 params.store.dataSourceDidComplete(params.storeKey); 211 } 212 else{ 213 console.error("Couldn't create file!"); 214 } 215 }, 216 217 /** 218 Called from destroyRecords() to destroy a single record. This is the 219 most basic primitive to can implement to support destroying a record. 220 221 To support cascading data stores, be sure to return NO if you cannot 222 handle the passed storeKey or YES if you can. 223 224 @param {SC.Store} store the requesting store 225 @param {Array} storeKey key to update 226 @param {Hash} params to be passed down to data source. originated 227 from the commitRecords() call on the store 228 @returns {Boolean} YES if handled 229 */ 230 destroyRecord: function(store, storeKey, params) { 231 var request = SC.Request.create({type: 'POST'}), file = store.materializeRecord(storeKey); 232 233 request.set('address', "/sproutcore/fs/%@?action=remove".fmt(file.get('path'))); 234 235 request.notify(this,this.destroyRecordDidComplete,{file: file, storeKey: storeKey, store: store}).send(); 236 237 return YES; 238 }, 239 240 destroyRecordDidComplete: function(response, params){ 241 var status, store = params.store; 242 //HACK: for some reason the records are always 514 ready dirty not refreshing dirty... 243 status = store.readStatus(params.storeKey); 244 store.writeStatus(params.storeKey, SC.Record.BUSY_DESTROYING); 245 //end HACK 246 params.store.dataSourceDidDestroy(params.storeKey); 247 } 248 249 250 }); 251