| Line 3: |
Line 3: |
| | console.log('Indb loading'); | | console.log('Indb loading'); |
| | | | |
| − | function idxdbContainer( ww ) { | + | function IndexedDBContainer( ww ) { |
| | + | |
| | + | // suppress console.log, switch to true for debug |
| | var Debug_switch = false; | | var Debug_switch = false; |
| | + | |
| | + | // deterministic hash generator for creating user id#s from usernames, should be replaced by something more functional (guaranteed to be transitively different) |
| | hashCode = function(s) { | | hashCode = function(s) { |
| | if ( s == undefined) { | | if ( s == undefined) { |
| Line 15: |
Line 19: |
| | return h; | | return h; |
| | }; | | }; |
| − |
| + | |
| | + | |
| | if ( ww.user != undefined ) { | | if ( ww.user != undefined ) { |
| | + | // if user exists in object passed to constructor, get username |
| | var self = ww.user.getName(); | | var self = ww.user.getName(); |
| − |
| + | // create userid by hashing username |
| | var idgen = hashCode(self); | | var idgen = hashCode(self); |
| | + | debuglog(idgen); |
| | | | |
| − | debuglog(idgen);
| + | // Take username for standard databasename format: |
| − | // Take username for standard databasename format
| + | // Our current convention for personal databasename (separate dbname for each user) |
| | var PersonalDataDataBaseName = "PD.IO" + idgen + "Database"; | | var PersonalDataDataBaseName = "PD.IO" + idgen + "Database"; |
| | // Use username in user to get up to date version of self | | // Use username in user to get up to date version of self |
| | + | // Blank object for personal data Record with id and username included |
| | this.CurrentPerson = {id: idgen, name: {user: self}, age: 0}; | | this.CurrentPerson = {id: idgen, name: {user: self}, age: 0}; |
| − |
| |
| | debuglog(PersonalDataDataBaseName); | | debuglog(PersonalDataDataBaseName); |
| | debuglog(this.CurrentPerson); | | debuglog(this.CurrentPerson); |
| Line 34: |
Line 41: |
| | | | |
| | // EnqueuePDIO a PDIOLocalDatabase:User database access function with modes | | // EnqueuePDIO a PDIOLocalDatabase:User database access function with modes |
| − | // External accessible wrapper for Enquire | + | // Externally accessible wrapper for Enquire with current user / db preloaded |
| − |
| + | |
| | this.EnqueuePDIO = async function( sw, c1, c2, c3 ) { | | this.EnqueuePDIO = async function( sw, c1, c2, c3 ) { |
| | var k = await Enquire( PersonalDataDataBaseName, this.CurrentPerson, sw, c1, c2, c3 ); | | var k = await Enquire( PersonalDataDataBaseName, this.CurrentPerson, sw, c1, c2, c3 ); |
| Line 70: |
Line 77: |
| | var pddb = window.indexedDB.open(pddbname, 3); | | var pddb = window.indexedDB.open(pddbname, 3); |
| | var inp_obj; | | var inp_obj; |
| | + | |
| | + | // indexeddb internal mechanism for version tracking of schema |
| | pddb.onupgradeneeded = function() { | | pddb.onupgradeneeded = function() { |
| | + | console.log('upgrading database'); |
| | var db = pddb.result; | | var db = pddb.result; |
| | var store = db.createObjectStore(pddbname, {keyPath: "id"}); | | var store = db.createObjectStore(pddbname, {keyPath: "id"}); |
| Line 78: |
Line 88: |
| | var index = store.createIndex("NameIndex", ["id"]); | | var index = store.createIndex("NameIndex", ["id"]); |
| | }; | | }; |
| | + | // Database successfully opened function. |
| | pddb.onsuccess = function() { | | pddb.onsuccess = function() { |
| | var db = pddb.result; | | var db = pddb.result; |
| Line 93: |
Line 104: |
| | // Essential recordAdd | | // Essential recordAdd |
| | if ( sqitch === "aggressive push" ) { | | if ( sqitch === "aggressive push" ) { |
| | + | // Mode 'aggressive push': |
| | + | // parameter record is pushed to database, overwriting whatever is there |
| | inp_obj = record; | | inp_obj = record; |
| | store.put( inp_obj ); | | store.put( inp_obj ); |
| | return inp_obj; | | return inp_obj; |
| | } else if ( sqitch === "checkin" ) { | | } else if ( sqitch === "checkin" ) { |
| − |
| + | // Mode 'checkin': |
| | + | // record is retrieved from database, parameter record is pushed if not found |
| | if ( getRecord.result != undefined ) { | | if ( getRecord.result != undefined ) { |
| | debuglog("getting from store"); | | debuglog("getting from store"); |
| Line 108: |
Line 122: |
| | | | |
| | } else { | | } else { |
| | + | // Methods manipulationg the actual record come here |
| | + | // Update & Remove from |
| | + | // If we got the record from store, use that version to be manipulated |
| | if ( getRecord.result != undefined ) { | | if ( getRecord.result != undefined ) { |
| | inp_obj = getRecord.result; | | inp_obj = getRecord.result; |
| | + | |
| | if ( sqitch === "get record" ) { | | if ( sqitch === "get record" ) { |
| − | // if found, let's use that from now on | + | |
| | debuglog("Getting record"); | | debuglog("Getting record"); |
| − | // let's return it so that our addrecord can be used as a getter as well | + | // we will return later |
| − | return inp_obj; | + | |
| | } | | } |
| − | //
| + | |
| | // endof onsuccess | | // endof onsuccess |
| | } else { | | } else { |
| − | debuglog("record not found"); | + | |
| | + | debuglog("Record not found"); |
| | + | |
| | if ( sqitch === "update record" ) { | | if ( sqitch === "update record" ) { |
| | + | // Update record will use supplied copy to update it |
| | inp_obj = record; | | inp_obj = record; |
| | } else { | | } else { |
| | + | // Remove from record will quit as record was not even found |
| | return undefined; | | return undefined; |
| | } | | } |
| | } | | } |
| − | // endof resultdefined
| |
| | } | | } |
| − | // endofELSE
| + | |
| | if ( sqitch === "update record" ) { // Record Update | | if ( sqitch === "update record" ) { // Record Update |
| | if ( control_1 != undefined ) { | | if ( control_1 != undefined ) { |
| | if ( control_2 != undefined ) { | | if ( control_2 != undefined ) { |
| | if ( control_3 != undefined ) { | | if ( control_3 != undefined ) { |
| | + | |
| | + | // Mode 'update record' field1 field2 field3 |
| | + | // retrieve record, make record.field1.field2 = field3, push back |
| | + | |
| | if ( inp_obj[ control_1 ] == undefined ) { inp_obj[ control_1 ] = (isNaN( control_2 )) ? {} : [] }; | | if ( inp_obj[ control_1 ] == undefined ) { inp_obj[ control_1 ] = (isNaN( control_2 )) ? {} : [] }; |
| | inp_obj[ control_1 ][ control_2 ] = control_3; // => "Bob" | | inp_obj[ control_1 ][ control_2 ] = control_3; // => "Bob" |
| | store.put(inp_obj); | | store.put(inp_obj); |
| | } else { | | } else { |
| | + | |
| | + | // Mode 'update record' field1 field2 |
| | + | // retrieve record, make record.field1 = field2, push back |
| | + | |
| | inp_obj[ control_1 ] = inp_obj[ control_1 ] || {}; | | inp_obj[ control_1 ] = inp_obj[ control_1 ] || {}; |
| | if ( Array.isArray( inp_obj[ control_1 ] ) ) { | | if ( Array.isArray( inp_obj[ control_1 ] ) ) { |
| Line 146: |
Line 175: |
| | | | |
| | } | | } |
| − | // +3
| |
| | } else { | | } else { |
| − | store.put(inp_obj); | + | // Only one control defined. We will return that part of the record, and change nothing |
| − | debuglog("mark N");
| |
| − | debuglog(inp_obj);
| |
| − | debuglog(inp_obj[ control_1 ]);
| |
| − | debuglog("mark NN")
| |
| | inp_obj = inp_obj[ control_1 ]; | | inp_obj = inp_obj[ control_1 ]; |
| | } | | } |
| − | // +2
| |
| | } else { | | } else { |
| | | | |
| − | //return inp_obj; | + | // There's not even control_1, we will just return the record itself |
| | | | |
| | } | | } |
| Line 169: |
Line 192: |
| | if ( control_1 != undefined ) { | | if ( control_1 != undefined ) { |
| | if ( control_2 != undefined ) { | | if ( control_2 != undefined ) { |
| | + | |
| | + | // Mode 'remove from record' field1 field2 |
| | + | // retrieve record, splice/delete record.field1.field2, push back |
| | + | |
| | if ( Array.isArray( inp_obj[ control_1 ] ) && !isNaN( control_2 ) ) { | | if ( Array.isArray( inp_obj[ control_1 ] ) && !isNaN( control_2 ) ) { |
| | inp_obj[ control_1 ].splice( control_2, 1 ); | | inp_obj[ control_1 ].splice( control_2, 1 ); |
| Line 174: |
Line 201: |
| | delete inp_obj[ control_1 ][ control_2 ]; | | delete inp_obj[ control_1 ][ control_2 ]; |
| | } | | } |
| | + | |
| | } else { | | } else { |
| | + | |
| | + | // Mode 'remove from record' field1 |
| | + | // retrieve record, splice/delete record.field1, push back |
| | + | |
| | delete inp_obj[ control_1 ]; | | delete inp_obj[ control_1 ]; |
| | } | | } |
| Line 181: |
Line 213: |
| | } | | } |
| | | | |
| − | debuglog("return 2")
| + | // We are past all methodic code, Async return |
| | + | |
| | resolve( inp_obj ); | | resolve( inp_obj ); |
| | | | |
| | }; | | }; |
| − | | + | |
| | + | // Indexeddb internal mechanism, close db |
| | + | |
| | tx.oncomplete = function() { | | tx.oncomplete = function() { |
| | debuglog("return 1") | | debuglog("return 1") |
| Line 193: |
Line 228: |
| | debuglog("return 0") | | debuglog("return 0") |
| | | | |
| | + | // End of promise |
| | + | |
| | }).then( function(result) { | | }).then( function(result) { |
| | debuglog("Mark 3"); | | debuglog("Mark 3"); |