Difference between revisions of "User:Abel/PersonalData.js"

From Wikibase Personal data
Jump to navigation Jump to search
m
 
(8 intermediate revisions by one other user not shown)
Line 3: Line 3:
 
console.log('Indb loading');
 
console.log('Indb loading');
  
function IndexedDBContainer( ww ) {
+
function IndexedDBContainer(ww) {
  
// suppress console.log, switch to true for debug
+
  // suppress console.log, switch to true for debug
var Debug_switch = true;
+
  var Debug_switch = false;
var iOS = !!navigator.platform && /Macintosh|MacIntel|MacPPC|Mac68K|Mac|iPad|iPhone|iPod/.test(navigator.platform);
+
  // seemingly the Safari engine uses a somewhat different implementation of arguments for db.transaction and index.get
 +
  // because no browser on any mac / ios is allowed to use a different engine, rather than user agent, platform can be tested
 +
  var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
 +
  var Safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
 +
  debuglog("iOS:" + iOS + " & Saf:" + Safari);
  
// deterministic hash generator for creating user id#s from usernames, should be replaced by something more functional (guaranteed to be transitively different)
+
  // 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) {
s = '00'
+
      s = '00'
}
+
    }
var h = 0, l = s.length, i = 0;
+
    var h = 0,
if ( l > 0 )
+
      l = s.length,
while (i < l)
+
      i = 0;
h = (h << 5) - h + s.charCodeAt(i++) | 0;
+
    if (l > 0)
return h;
+
      while (i < l)
};
+
        h = (h << 5) - h + s.charCodeAt(i++) | 0;
 +
    return h;
 +
  };
  
 
if ( ww.user != undefined ) {
 
// if user exists in object passed to constructor, get username
 
var self = ww.user.getName();
 
// create userid by hashing username
 
var idgen = hashCode(self);
 
debuglog(idgen);
 
  
// Take username for standard databasename format:
+
  if (ww.user != undefined) {
// Our current convention for personal databasename (separate dbname for each user)
+
    // if user exists in object passed to constructor, get username
var PersonalDataDataBaseName = "PD.IO" + idgen + "Database";
+
    var self = ww.user.getName();
// Use username in user to get up to date version of self
+
    // create userid by hashing username
// Blank object for personal data Record with id and username included
+
    var idgen = hashCode(self);
this.CurrentPerson = {id: idgen, name: {user: self}, age: 0};
+
    debuglog(idgen);
debuglog(PersonalDataDataBaseName);
 
debuglog(this.CurrentPerson);
 
}
 
  
// ADD MORE DOC
+
    // Take username for standard databasename format:
 +
    // Our current convention for personal databasename (separate dbname for each user)
 +
    var PersonalDataDataBaseName = "PD.IO" + idgen + "Database";
 +
    // 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
 +
    };
 +
    debuglog(PersonalDataDataBaseName);
 +
    debuglog(this.CurrentPerson);
 +
  }
  
// EnqueuePDIO a PDIOLocalDatabase:User database access function with modes
+
  // ADD MORE DOC
// Externally accessible wrapper for Enquire with current user / db preloaded
 
  
this.EnqueuePDIO = async function( sw, c1, c2, c3 ) {
+
  // EnqueuePDIO a PDIOLocalDatabase:User database access function with modes
debuglog("enquing pdio db " + PersonalDataDataBaseName + " with user " + JSON.stringify(this.CurrentPerson));
+
  // Externally accessible wrapper for Enquire with current user / db preloaded
var k = await Enquire( PersonalDataDataBaseName, this.CurrentPerson, sw, c1, c2, c3 );
 
return k;
 
}
 
  
// Enquire, a general purpose indexeddb update function with modes
+
  this.EnqueuePDIO = async function(sw, c1, c2, c3) {
 +
    debuglog("enquing pdio db " + PersonalDataDataBaseName + " with user " + JSON.stringify(this.CurrentPerson));
 +
    var k = await Enquire(PersonalDataDataBaseName, this.CurrentPerson, sw, c1, c2, c3);
 +
    return k;
 +
  }
  
// Mode 'aggressive push':
+
  // Enquire, a general purpose indexeddb update function with modes
// parameter record is pushed to database, overwriting whatever is there
 
  
// Mode 'checkin':
+
  // Mode 'aggressive push':
// record is retrieved from database, parameter record is pushed if not found
+
  // parameter record is pushed to database, overwriting whatever is there
  
// Mode 'get record'
+
  // Mode 'checkin':
// updates record given as argument
+
  // record is retrieved from database, parameter record is pushed if not found
  
// Mode 'update record' field1 field2 field3
+
  // Mode 'get record'
// retrieve record, make record.field1.field2 = field3, push back
+
  // updates record given as argument
  
// Mode 'update record' field1 field2
+
  // Mode 'update record' field1 field2 field3
// retrieve record, make record.field1 = field2, push back
+
  // retrieve record, make record.field1.field2 = field3, push back
  
// Mode 'remove from record' field1
+
  // Mode 'update record' field1 field2
// retrieve record, splice/delete record.field1, push back
+
  // retrieve record, make record.field1 = field2, push back
 
// Mode 'remove from record' field1 field2  
 
// retrieve record, splice/delete record.field1.field2, push back
 
  
async function Enquire( pddbname, record, sqitch, control_1, control_2, control_3 ) {
+
  // Mode 'remove from record' field1
return new Promise(
+
  // retrieve record, splice/delete record.field1, push back
function(resolve, reject) {
 
  
var pddb = window.indexedDB.open(pddbname, 3);
+
  // Mode 'remove from record' field1 field2
var inp_obj;
+
  // retrieve record, splice/delete record.field1.field2, push back
  
pddb.onerror = function() { 
+
  // Mode 'import record' field1
    console.log("Warning: Access to IndexedDB for application has been rejected.");
+
  // retrieve record, add all fields from field1, push back
};
 
  
// indexeddb internal mechanism for version tracking of schema
+
  async function Enquire(pddbname, record, sqitch, control_1, control_2, control_3) {
pddb.onupgradeneeded = function() {
+
    return new Promise(
console.log('upgrading database');
+
      function(resolve, reject) {
var db = pddb.result;
 
var store = db.createObjectStore(pddbname, {keyPath: "id"});
 
var index;
 
// shouldn't the index be the wiki.personaldata.io username?
 
if ( iOS ) {
 
index = db.store.createIndex("NameIndex", ["id"]);
 
} else {
 
index = store.createIndex("NameIndex", ["id"]);
 
}
 
 
};
 
// Database successfully opened function.
 
pddb.onsuccess = function() {
 
debuglog(pddb.result);
 
var db = pddb.result;
 
var tx;
 
 
if ( iOS ) {
 
tx = db.transaction([pddbname], "readwrite");
 
} else {
 
tx = db.transaction(pddbname, "readwrite");
 
}
 
 
var store = tx.objectStore(pddbname);
 
var index = store.index("NameIndex");
 
  
// Get the original record from the db...
+
        var pddb = window.indexedDB.open(pddbname, 3);
var getRecord = index.get(record.id);
+
        var inp_obj;
  
getRecord.onsuccess = function() {
+
        pddb.onerror = function() {
debuglog( "Record in database: \n <<");
+
          console.log("Warning: Access to IndexedDB for application has been rejected.");
debuglog( getRecord.result );
+
        };
debuglog( ">>");
 
// Essential recordAdd
 
if ( sqitch === "aggressive push" ) {
 
// Mode 'aggressive push':
 
// parameter record is pushed to database, overwriting whatever is there
 
inp_obj = record;
 
store.put( inp_obj );
 
return inp_obj;
 
} else if ( sqitch === "checkin" ) {
 
// Mode 'checkin':
 
// record is retrieved from database, parameter record is pushed if not found
 
if ( getRecord.result != undefined ) {
 
debuglog("getting from store");
 
inp_obj = getRecord.result;
 
} else {
 
debuglog("overriding whatever in there");
 
inp_obj = record;
 
store.put(inp_obj);
 
}
 
  
} else {
+
        // indexeddb internal mechanism for version tracking of schema
// Methods manipulationg the actual record come here
+
        pddb.onupgradeneeded = function() {
// Update & Remove from
+
          console.log('upgrading database');
// If we got the record from store, use that version to be manipulated
+
          var db = pddb.result;
if ( getRecord.result !== undefined ) {
+
          var store = db.createObjectStore(pddbname, {
inp_obj = getRecord.result;
+
            keyPath: "id"
+
          });
if ( sqitch === "get record" ) {
+
          var index = store.createIndex("NameIndex", ["id"]);
 
debuglog("Getting record");
 
// we will return later
 
 
}
 
  
// endof onsuccess
+
        };
} else {
+
        // Database successfully opened function.
 +
        pddb.onsuccess = function() {
 +
          debuglog(pddb.result);
 +
          var db = pddb.result;
 +
          var tx;
  
debuglog("Record not found");
+
          if (iOS || Safari) {
 +
            tx = db.transaction([pddbname], "readwrite");
 +
          } else {
 +
            tx = db.transaction(pddbname, "readwrite");
 +
          }
  
if ( sqitch === "update record" ) {
+
          var store = tx.objectStore(pddbname);
// Update record will use supplied copy to update it
+
          var index = store.index("NameIndex");
inp_obj = record;
 
} else {
 
if ( sqitch === "get record" ) {
 
inp_obj = undefined;
 
} else if ( sqitch === "remove from record" ) {
 
inp_obj = record;
 
} else {
 
// any other method ...... would quit as record was not even foun
 
return undefined;
 
}
 
}
 
}
 
}
 
  
if ( sqitch === "update record" ) { // Record Update
+
          // Get the original record from the db...
if ( control_1 != undefined ) {
+
          var getRecord;
if ( control_2 != undefined ) {
+
          if (iOS || Safari) {
if ( control_3 != undefined ) {
+
            getRecord = index.get(record.id);
 +
          } else {
 +
            getRecord = index.get([record.id]);
 +
          }
  
// Mode 'update record' field1 field2 field3
+
          getRecord.onsuccess = function() {
// retrieve record, make record.field1.field2 = field3, push back
+
            debuglog("Record in database: \n <<");
 +
            debuglog(getRecord.result);
 +
            debuglog(">>");
 +
            // Essential recordAdd
 +
            if (sqitch === "aggressive push") {
 +
              // Mode 'aggressive push':
 +
              // parameter record is pushed to database, overwriting whatever is there
 +
              inp_obj = record;
 +
              store.put(inp_obj);
 +
              return inp_obj;
 +
            } else if (sqitch === "checkin") {
 +
              // Mode 'checkin':
 +
              // record is retrieved from database, parameter record is pushed if not found
 +
              if (getRecord.result != undefined) {
 +
                debuglog("getting from store");
 +
                inp_obj = getRecord.result;
 +
              } else {
 +
                debuglog("overriding whatever in there");
 +
                inp_obj = record;
 +
                store.put(inp_obj);
 +
              }
  
if ( inp_obj[ control_1 ] == undefined ) { inp_obj[ control_1 ] = (isNaN( control_2 )) ? {} : [] };
+
            } else {
inp_obj[ control_1 ][ control_2 ] = control_3; // => "Bob"
+
              // Methods manipulationg the actual record come here
store.put(inp_obj);
+
              // Update & Remove from
} else {
+
              // If we got the record from store, use that version to be manipulated
 +
              if (getRecord.result !== undefined) {
 +
                inp_obj = getRecord.result;
  
// Mode 'update record' field1 field2
+
                if (sqitch === "get record") {
// retrieve record, make record.field1 = field2, push back
 
  
inp_obj[ control_1 ] = inp_obj[ control_1 ] || {};
+
                  debuglog("Getting record");
if ( Array.isArray( inp_obj[ control_1 ] ) ) {
+
                  // we will return later
inp_obj[ control_1 ].push( control_2 );
 
} else {
 
inp_obj[ control_1 ] = control_2;
 
}
 
store.put(inp_obj);
 
  
}
+
                }
} else {
 
// Only one control defined. We will return that part of the record, and change nothing
 
inp_obj = inp_obj[ control_1 ];
 
}
 
} else {
 
  
// There's not even control_1, we will just return the record itself
+
                // endof onsuccess
 +
              } else {
  
}
+
                debuglog("Record not found");
debuglog("return 3")
 
// return inp_obj;
 
  
};
+
                if (sqitch === "update record") {
 +
                  // Update record will use supplied copy to update it
 +
                  inp_obj = record;
 +
                } else {
 +
                  if (sqitch === "get record") {
 +
                    inp_obj = undefined;
 +
                  } else if (sqitch === "remove from record") {
 +
                    inp_obj = record;
 +
                  } else {
 +
                    // any other method ...... would quit as record was not even foun
 +
                    return undefined;
 +
                  }
 +
                }
 +
              }
 +
            }
  
if ( sqitch === "remove from 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) {
  
// Mode 'remove from record' field1 field2  
+
                    // Mode 'update record' field1 field2 field3
// retrieve record, splice/delete record.field1.field2, push back
+
                    // retrieve record, make record.field1.field2 = field3, push back
 
if ( Array.isArray( inp_obj[ control_1 ] ) && !isNaN( control_2 ) ) {
 
inp_obj[ control_1 ].splice( control_2, 1 );
 
} else {
 
delete inp_obj[ control_1 ][ control_2 ];
 
}
 
  
} else {
+
                    if (inp_obj[control_1] == undefined) {
 +
                      inp_obj[control_1] = (isNaN(control_2)) ? {} : []
 +
                    };
 +
                    inp_obj[control_1][control_2] = control_3; // => "Bob"
 +
                    store.put(inp_obj);
 +
                  } else {
  
// Mode 'remove from record' field1  
+
                    // Mode 'update record' field1 field2
// retrieve record, splice/delete record.field1, push back
+
                    // retrieve record, make record.field1 = field2, push back
  
delete inp_obj[ control_1 ];
+
                    inp_obj[control_1] = inp_obj[control_1] || {};
}
+
                    if (Array.isArray(inp_obj[control_1])) {
}
+
                      inp_obj[control_1].push(control_2);
debuglog("putting object to store:");
+
                    } else {
debuglog(inp_obj);
+
                      inp_obj[control_1] = control_2;
store.put(inp_obj);
+
                    }
}
+
                    store.put(inp_obj);
  
// We are past all methodic code, Async return
+
                  }
+
                } else {
resolve( inp_obj );
+
                  // Only one control defined. We will return that part of the record, and change nothing
 +
                  inp_obj = inp_obj[control_1];
 +
                }
 +
              } else {
  
};
+
                // There's not even control_1, we will just return the record itself
 
// Indexeddb internal mechanism, close db
 
 
tx.oncomplete = function() {
 
debuglog("return 1")
 
db.close();
 
};
 
};
 
debuglog("return 0")
 
  
// End of promise
+
              }
+
              debuglog("return 3")
}).then( function(result) {
+
              // return inp_obj;
debuglog("Mark 3");
 
debuglog(result);
 
return result;
 
});
 
}
 
  
function debuglog( l0g ){
+
            };
if ( Debug_switch ) {
+
 
console.log( l0g );
+
            if (sqitch === "remove from record") { // Record Update
}
+
              if (control_1 != 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)) {
 +
                    inp_obj[control_1].splice(control_2, 1);
 +
                  } else {
 +
                    delete inp_obj[control_1][control_2];
 +
                  }
 +
 
 +
                } else {
 +
 
 +
                  // Mode 'remove from record' field1
 +
                  // retrieve record, splice/delete record.field1, push back
 +
 
 +
                  delete inp_obj[control_1];
 +
                }
 +
              }
 +
              debuglog("putting object to store:");
 +
              debuglog(inp_obj);
 +
              store.put(inp_obj);
 +
            }
 +
 
 +
            if (sqitch === "import record") {
 +
              debuglog("import command");
 +
              if (control_1 != undefined) {
 +
                // Only import if control_1 is a non-empty object
 +
                if ((!Array.isArray(control_1)) && (Object.keys(control_1).length > 0)) {
 +
                  debuglog("command is obj");
 +
                  Object.keys(control_1).forEach(function(importkey) {
 +
                    debuglog("importing " + importkey);
 +
                    if (control_1.hasOwnProperty(importkey)) {
 +
                      inp_obj[importkey] = control_1[importkey]
 +
                    };
 +
                  })
 +
                  store.put(inp_obj);
 +
                }
 +
              }
 +
            }
 +
 
 +
            // We are past all methodic code, Async return
 +
 
 +
            resolve(inp_obj);
 +
 
 +
          };
 +
 
 +
          // Indexeddb internal mechanism, close db
 +
 
 +
          tx.oncomplete = function() {
 +
            debuglog("return 1")
 +
            db.close();
 +
          };
 +
        };
 +
        debuglog("return 0")
 +
 
 +
        // End of promise
 +
 
 +
      }).then(function(result) {
 +
      debuglog("Mark 3");
 +
      debuglog(result);
 +
      return result;
 +
    });
 +
  }
 +
 
 +
  function debuglog(l0g) {
 +
    if (Debug_switch) {
 +
      console.log(l0g);
 +
    }
 +
  }
 
};
 
};

Latest revision as of 11:43, 4 June 2019

// License: GPL
// Indexeddb JavaScript 
console.log('Indb loading');

function IndexedDBContainer(ww) {

  // suppress console.log, switch to true for debug
  var Debug_switch = false;
  // seemingly the Safari engine uses a somewhat different implementation of arguments for db.transaction and index.get
  // because no browser on any mac / ios is allowed to use a different engine, rather than user agent, platform can be tested
  var iOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
  var Safari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
  debuglog("iOS:" + iOS + " & Saf:" + Safari);

  // 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) {
    if (s == undefined) {
      s = '00'
    }
    var h = 0,
      l = s.length,
      i = 0;
    if (l > 0)
      while (i < l)
        h = (h << 5) - h + s.charCodeAt(i++) | 0;
    return h;
  };


  if (ww.user != undefined) {
    // if user exists in object passed to constructor, get username		
    var self = ww.user.getName();
    // create userid by hashing username
    var idgen = hashCode(self);
    debuglog(idgen);

    // Take username for standard databasename format:
    // Our current convention for personal databasename (separate dbname for each user)
    var PersonalDataDataBaseName = "PD.IO" + idgen + "Database";
    // 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
    };
    debuglog(PersonalDataDataBaseName);
    debuglog(this.CurrentPerson);
  }

  // ADD MORE DOC

  // EnqueuePDIO a PDIOLocalDatabase:User database access function with modes
  // Externally accessible wrapper for Enquire with current user / db preloaded

  this.EnqueuePDIO = async function(sw, c1, c2, c3) {
    debuglog("enquing pdio db " + PersonalDataDataBaseName + " with user " + JSON.stringify(this.CurrentPerson));
    var k = await Enquire(PersonalDataDataBaseName, this.CurrentPerson, sw, c1, c2, c3);
    return k;
  }

  // Enquire, a general purpose indexeddb update function with modes

  // Mode 'aggressive push':
  // parameter record is pushed to database, overwriting whatever is there

  // Mode 'checkin':
  // record is retrieved from database, parameter record is pushed if not found

  // Mode 'get record'
  // updates record given as argument

  // Mode 'update record' field1 field2 field3
  // retrieve record, make record.field1.field2 = field3, push back

  // Mode 'update record' field1 field2
  // retrieve record, make record.field1 = field2, push back

  // Mode 'remove from record' field1 
  // retrieve record, splice/delete record.field1, push back

  // Mode 'remove from record' field1 field2 
  // retrieve record, splice/delete record.field1.field2, push back

  // Mode 'import record' field1
  // retrieve record, add all fields from field1, push back

  async function Enquire(pddbname, record, sqitch, control_1, control_2, control_3) {
    return new Promise(
      function(resolve, reject) {

        var pddb = window.indexedDB.open(pddbname, 3);
        var inp_obj;

        pddb.onerror = function() {
          console.log("Warning: Access to IndexedDB for application has been rejected.");
        };

        // indexeddb internal mechanism for version tracking of schema
        pddb.onupgradeneeded = function() {
          console.log('upgrading database');
          var db = pddb.result;
          var store = db.createObjectStore(pddbname, {
            keyPath: "id"
          });
          var index = store.createIndex("NameIndex", ["id"]);

        };
        // Database successfully opened function.
        pddb.onsuccess = function() {
          debuglog(pddb.result);
          var db = pddb.result;
          var tx;

          if (iOS || Safari) {
            tx = db.transaction([pddbname], "readwrite");
          } else {
            tx = db.transaction(pddbname, "readwrite");
          }

          var store = tx.objectStore(pddbname);
          var index = store.index("NameIndex");

          // Get the original record from the db...
          var getRecord;
          if (iOS || Safari) {
            getRecord = index.get(record.id);
          } else {
            getRecord = index.get([record.id]);
          }

          getRecord.onsuccess = function() {
            debuglog("Record in database: \n <<");
            debuglog(getRecord.result);
            debuglog(">>");
            // Essential recordAdd																													
            if (sqitch === "aggressive push") {
              // Mode 'aggressive push':
              // parameter record is pushed to database, overwriting whatever is there
              inp_obj = record;
              store.put(inp_obj);
              return inp_obj;
            } else if (sqitch === "checkin") {
              // Mode 'checkin':
              // record is retrieved from database, parameter record is pushed if not found
              if (getRecord.result != undefined) {
                debuglog("getting from store");
                inp_obj = getRecord.result;
              } else {
                debuglog("overriding whatever in there");
                inp_obj = record;
                store.put(inp_obj);
              }

            } 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) {
                inp_obj = getRecord.result;

                if (sqitch === "get record") {

                  debuglog("Getting record");
                  // we will return later

                }

                // endof onsuccess
              } else {

                debuglog("Record not found");

                if (sqitch === "update record") {
                  // Update record will use supplied copy to update it
                  inp_obj = record;
                } else {
                  if (sqitch === "get record") {
                    inp_obj = undefined;
                  } else if (sqitch === "remove from record") {
                    inp_obj = record;
                  } else {
                    // any other method ...... would quit as record was not even foun
                    return undefined;
                  }
                }
              }
            }

            if (sqitch === "update record") { // Record Update															
              if (control_1 != undefined) {
                if (control_2 != 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)) ? {} : []
                    };
                    inp_obj[control_1][control_2] = control_3; // => "Bob"
                    store.put(inp_obj);
                  } else {

                    // Mode 'update record' field1 field2
                    // retrieve record, make record.field1 = field2, push back

                    inp_obj[control_1] = inp_obj[control_1] || {};
                    if (Array.isArray(inp_obj[control_1])) {
                      inp_obj[control_1].push(control_2);
                    } else {
                      inp_obj[control_1] = control_2;
                    }
                    store.put(inp_obj);

                  }
                } else {
                  // Only one control defined. We will return that part of the record, and change nothing
                  inp_obj = inp_obj[control_1];
                }
              } else {

                // There's not even control_1, we will just return the record itself

              }
              debuglog("return 3")
              // return inp_obj;

            };

            if (sqitch === "remove from record") { // Record Update															
              if (control_1 != 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)) {
                    inp_obj[control_1].splice(control_2, 1);
                  } else {
                    delete inp_obj[control_1][control_2];
                  }

                } else {

                  // Mode 'remove from record' field1 
                  // retrieve record, splice/delete record.field1, push back

                  delete inp_obj[control_1];
                }
              }
              debuglog("putting object to store:");
              debuglog(inp_obj);
              store.put(inp_obj);
            }

            if (sqitch === "import record") {
              debuglog("import command");
              if (control_1 != undefined) {
                // Only import if control_1 is a non-empty object
                if ((!Array.isArray(control_1)) && (Object.keys(control_1).length > 0)) {
                  debuglog("command is obj");
                  Object.keys(control_1).forEach(function(importkey) {
                    debuglog("importing " + importkey);
                    if (control_1.hasOwnProperty(importkey)) {
                      inp_obj[importkey] = control_1[importkey]
                    };
                  })
                  store.put(inp_obj);
                }
              }
            }

            // We are past all methodic code, Async return						

            resolve(inp_obj);

          };

          // Indexeddb internal mechanism, close db

          tx.oncomplete = function() {
            debuglog("return 1")
            db.close();
          };
        };
        debuglog("return 0")

        // End of promise

      }).then(function(result) {
      debuglog("Mark 3");
      debuglog(result);
      return result;
    });
  }

  function debuglog(l0g) {
    if (Debug_switch) {
      console.log(l0g);
    }
  }
};