1 var dbGlobals = new Object(); 2 dbGlobals.db = null; 3 dbGlobals.description = "This database is used to store files locally."; 4 dbGlobals.name = "localFileStorage"; 5 dbGlobals.version = 1; 6 dbGlobals.storeName = "fileObjects"; 7 dbGlobals.message = ""; 8 dbGlobals.empty = true; 9 10 // --------------------------------------------------- 11 12 function requiredFeaturesSupported() { 13 switch(window.location.protocol) { 14 case "http:": 15 break; 16 case "https:": 17 break; 18 case "ms-wwa-web": 19 break; 20 case "ms-wwa": 21 break; 22 default: 23 document.getElementById("bodyElement").innerHTML = "<h3>IndexedDB pages must be served via the http:// or https:// protocol - resolve this issue and try again.</h3>"; 24 return false; 25 } // switch 26 27 if(!document.getElementById("fileSelector").files) { 28 document.getElementById("bodyElement").innerHTML = "<h3>File API is not fully supported - upgrade your browser to the latest version.</h3>"; 29 return false; 30 } 31 32 if(!window.indexedDB) { 33 if(window.mozIndexedDB) { 34 window.indexedDB = widnow.mozIndexedDB; 35 } 36 else if(window.webkitIndexedDB) { 37 window.indexedDB = window.webkitIndexedDB; 38 IDBCursor = window.webkitIDBCursor; 39 IDBDatabaseException = window.webkitIDBDatabaseException; 40 IDBRequest = window.webkitIDBRequest; 41 IDBKeyRange = window.webkitIDBKeyRange; 42 IDBTransaction = window.webkitIDBTransaction; 43 } 44 else { 45 document.getElementById("bodyElement").innerHTML = "<h3>IndexedDB is not supported - upgrade your browser to the latest version.</h3>"; 46 return false; 47 } 48 } // if 49 50 if(!window.indexedDB.deleteDatabase) { 51 document.getElementById("bodyElement").innerHTML = "<h3>The required version of IndexedDB is not supported.</h3>"; 52 return false; 53 } 54 return true; 55 } // requiredFeaturesSupported 56 57 // -------------------------------------------------- 58 59 if(requiredFeaturesSupported()) { 60 document.getElementById("openButton").addEventListener("click", openDB, false); 61 document.getElementById("populateButton").addEventListener("click", populateDB, false); 62 document.getElementById("displayButton").addEventListener("click", displayDB, false); 63 document.getElementById("deleteButton").addEventListener("click", deleteDB, false); 64 65 document.getElementById("fileSelector").addEventListener("change", handleFileSelection, false); 66 } // if 67 68 // ----------------------------------------- 69 70 function openDB() { 71 console.log("------------------------openDB_onupgradeneeded()-----------------------"); 72 displayMessage("<p>The database will be created/opened here...</p>"); 73 74 if(!window.indexedDB.open) { 75 console.log("window.indexedDB.open is null in openDB()"); 76 return; 77 } // if 78 79 try { 80 var openRequest = window.indexedDB.open(dbGlobals.name, dbGlobals.version); // 81 82 openRequest.onerror = function(evt) {console.log("openRequest.onerror fired in openDB() - error: " + (evt.target.error ? evt.target.error : evt.target.errorCode));}; 83 openRequest.onblocked = openDB_onblocked; 84 openRequest.onupgradeneeded = openDB_onupgradeneeded; 85 openRequest.onsuccess = openDB_onsuccess; 86 }catch(ex) { 87 console.log("window.indexedDB.open exception in openDB() - " + ex.message); 88 } 89 } // openDB 90 91 // -------------------------------------------------------------- 92 93 function openDB_onblocked(evt) { 94 console.log("openDB_onblocked()"); 95 96 var message = "<p>The database is blocked - error code: " + (evt.target.error ? evt.target.error : evt.target.errorCode) + "</p>"; 97 message += "<p>If this page is open in other browser windows, close these windows.</p>"; 98 99 displayMessage(message); 100 } // openDB_onblocked 101 102 // -------------------------------------------- 103 104 function openDB_onupgradeneeded(evt) { 105 console.log("openDB_onupgradeneeded()"); 106 displayMessage("<p>Your request has been queued.</p>"); 107 108 var db = dbGlobals.db = evt.currentTarget.result; // A successfully opened database results in a database object, which we place in our global IndexedDB variable. 109 110 if(!db) { 111 console.log("db (i.e., evt.target.result) is null in openDB_onupgradeneeded()"); 112 return; 113 } // if 114 115 try { 116 db.createObjectStore(dbGlobals.storeName, {keyPath: "name"}); 117 console.log("openDB_onupgradedneeded() success"); 118 } 119 catch(ex) { 120 console.log("Exception is openDB_onupgradeneeded() - " + ex.message); 121 return; 122 } 123 124 dbGlobals.message = "<p>The database has been created.</p>"; // A means of communicating this information to the openDB_onsuccess handler. 125 } // openDB_onupgradeneeded 126 127 // ------------------------------------------------- 128 129 function openDB_onsuccess(evt) { 130 console.log("openDB_onsuccess()"); 131 displayMessage("<p>Your request has been queued.</p>"); 132 133 var db = dbGlobals.db = evt.target.result; 134 135 if(!db) { 136 console.log("db (i.e., evt.target.result) is null in openDB_onsuccess()"); 137 return; 138 } // if 139 140 dbGlobals.message += "<p>The database has been opened.</p>"; 141 displayMessage(dbGlobals.message); 142 dbGlobals.message = ""; 143 } // openDB_onsuccess 144 145 // ---------------------------------------------- 146 147 function populateDB() { 148 console.log("------------------------populateDB()--------------------------"); 149 150 if(!dbGlobals.db) { 151 displayMessage("<p>The database hasn't been opened/created yet.</p>"); 152 console.log("db (i.e., dbGlobals.db) is null in populateDB()"); 153 return; 154 } 155 156 document.getElementById("fileSelector").style.display = "block"; // Now that we have a valid database, allow the user to put file(s) in it. 157 158 var message = "<p>Using the below <strong>Browse</strong> button, select one or more files to store in the database.</p>"; 159 message += "<p>Then, click the <strong>Display DB<strong> button to display what's currently in the database.</p>"; 160 displayMessage(message); 161 } // populateDB 162 163 // ------------------------------------------------- 164 165 function displayDB() { 166 console.log("------------------------displayDB()----------------------------"); 167 168 var db = dbGlobals.db; 169 170 if(!db) { 171 displayMessage("<p>There's no database to display.</p>"); 172 console.log("db (i.e, dbGlobals.db) is null in displayDB()"); 173 return; 174 } // if 175 176 try{ 177 var transaction = db.transaction(dbGlobals.storeName, (IDBTransaction.READ_ONLY ? IDBTransaction.READ_ONLY : "readonly")); 178 } // try 179 catch(ex) { 180 console.log("db.transaction() exception in displayDB() - " + ex.messsage); 181 return; 182 } // catch 183 184 try{ 185 var objectStore = transaction.objectStore(dbGlobals.storeName); 186 187 try { 188 var cursorRequest = objectStore.openCursor(); 189 190 cursorRequest.onerror = function(evt) { 191 console.log("cursorRequest.onerror fired in displayDB() - error code: " + (evt.target.error ? evt.target.error : evt.target.errorCode)); 192 } 193 194 var fileListHTML = "<p><strong>File(s) in database: </strong></p><ul style='margin: -0.5em 0 1em -1em;'>"; // Be aware that if the database is empty, this variable never gets used. 195 196 cursorRequest.onsuccess = function(evt) { 197 console.log("cursorRequest.onsuccess fired in displayDB()"); 198 199 var cursor = evt.target.result; 200 201 if(cursor) { 202 dbGlobals.empty = false; 203 fileListHTML += "<li>" + cursor.value.name; 204 fileListHTML += "<p style='margin: 0 0 0 0.75em;'>" + cursor.value.name + "</p>"; 205 fileListHTML += "<p style='margin: 0 0 0 0.75em;'>" + cursor.value.size + " bytes</p>"; 206 cursor.continue(); 207 } 208 else { 209 fileListHTML += "</ul>"; 210 displayMessage(fileListHTML); 211 } 212 213 if(dbGlobals.empty) { 214 displayMessage("<p>The database is empty – there's nothing to display.</p>"); 215 } 216 } 217 } // inner try 218 catch(innerException) { 219 console.log("Inner try exception in displayDB() - " + innerException.message); 220 } // inner catch 221 } // outer try 222 catch(outerException) { 223 console.log("Outer try exception in displayDB() - " + outerException.message); 224 } // outer catch 225 } // displayDB 226 227 // ------------------------------------------------- 228 229 function deleteDB() { 230 console.log("------------------------deleteDB()-----------------------------"); 231 displayMessage("<p>The database will be deleted here...</p>"); 232 233 try{ 234 if(dbGlobals.db) { 235 dbGlobals.db.close(); // If the database is open, you must first close the database connection before deleting it. Otherwise, the delete request waits (possibly forever) for the required close request to occur. 236 } 237 238 var deleteRequest = window.indexedDB.deleteDatabase(dbGlobals.name); // Note that we already checked for the availability of the deleteDatabase() method in the above feature detection code. 239 deleteRequest.onsuccess = function() { 240 dbGlobals.db = null; 241 dbGlobals.empty = true; 242 dbGlobals.message = ""; 243 displayMessage("<p>The database has been deleted.</p>"); 244 console.log("delete success"); 245 }; // deleteRequest.onsuccess 246 } // try 247 catch(ex) { 248 console.log("Exception in deleteDB() - " + ex.message); 249 } // catch 250 } // deleteDB 251 252 // ------------------------------------------------- 253 254 function handleFileSelection(evt) { 255 console.log("------------------------handleFileSelection()------------------------"); 256 257 var files = evt.target.files; // The files selected by the uer (as a FileList object). 258 console.log(files); 259 if(!files) { 260 displayMessage("<p>At least one selected file is invalid - do not select any folders.</p><p>Please reselect and try again.</p>"); 261 return; 262 } 263 264 var db = dbGlobals.db; 265 if(!db) { 266 console.log("db (i.e., dbGlobals.db) is null in handleFileSelection()"); 267 return; 268 } // if 269 270 try{ 271 var transaction = db.transaction(dbGlobals.storeName, (IDBTransaction.READ_WRITE ? IDBTransaction.READ_WRITE : "readwrite")); 272 } // try 273 catch(ex) { 274 console.log("db.transaction exception in handleFileTransaction() - " + ex.message); 275 return; 276 } // catch 277 278 transaction.onerror = function(evt) { 279 console.log("transaction.onerror fired in handleFileSelection() - error code: " + (evt.target.error ? evt.target.error : evt.target.errorCode)); 280 }; 281 transaction.onabort = function() { 282 console.log("transaction.onabort fired in handleFileSelection()"); 283 }; 284 transaction.oncomplete = function() { 285 console.log("transaction.oncomplete fired in handleFileSelection()"); 286 }; 287 288 files = [ 289 { 290 name: "sina.jpg", 291 size: 2813, 292 type: "text/html" 293 }, 294 { 295 name: "indexedDB.html", 296 size: 808, 297 type: "text/html" 298 }, 299 { 300 name: "m.html", 301 size: 0, 302 type: "text/html" 303 } 304 ]; 305 306 try { 307 var objectStore = transaction.objectStore(dbGlobals.storeName); 308 309 for(var i = 0, file; file = files[i]; i++) { 310 var putRequest = objectStore.put(file); 311 putRequest.onsuccess = function() {dbGlobals.empty = false;}; 312 putRequest.onerror = function(evt) {console.log("putRequest.onerror fired in handleFileSelection() - error code: " + (evt.target.error ? evt.target.error : evt.target.errorCode));}; 313 } // for 314 } // try 315 catch(ex) { 316 console.log("Transaction and/or put() exception in handleFileSelection() - " + ex.message); 317 return; 318 } // catch 319 320 document.getElementById("fileSelector").style.display = "none"; // The file(s) have already been selected so remove the "file picker" dialog box. 321 } // handleFileSelection 322 323 // -------------------------------------------------- 324 325 function displayMessage(message) { 326 document.getElementById("messages").innerHTML = message; 327 } // displayMessage 328 329 // ------------------------------------------------------