Calculate size of indexedDB database

IndexedDB has no built-in mechanism for calculating the size of a database. Below is a code snippet that shows how to calculate the ‘approximate’ size if you are storing strings. In my case we are storing Base64 images.

Depending on what data type you are storing here are some suggestions on how to calculate the size:

  • String. The example shown below simply uses the String.length property. You can typically get a one-to-one ratio where each character is equal to one byte. For example, if length equals 20, you can roughly assume that the size of the string is 20 bytes. However, if you have many uncommon characters in your strings those can equal 2 bytes each. For more information see this page on the Mozilla Developer Network.
  • Array. The size of an array depends on the array type and what you are storing in it. If it’s just a plain old Array of strings, such as [“a”,”test”,”something”],  you can parse the array for strings and then measure the size of each item within it as I just mentioned. If it’s a typed array you’ll have to take into account if it’s 8-bit, 16-bit, 32-bit or 64-bit. If you have numbers in your array, I believe all JavaScript numbers are 8 bytes each.
  • Blob. Access the Blob.size property.
/**
 * Provides the size of database in bytes
 * @param callback callback(size, null) or callback(null, error)
 */
var size = function(callback){
    if(this._db != null){
        var size = 0;

        var transaction = this._db.transaction(["your_db"])
            .objectStore("your_db")
            .openCursor();

        transaction.onsuccess = function(event){
            var cursor = event.target.result;
            if(cursor){
                var storedObject = cursor.value;
                var json = JSON.stringify(storedObject);
                size += json.length;
                cursor.continue();
            }
            else{
                callback(size,null);
            }
        }.bind(this);
        transaction.onerror = function(err){
            callback(null,err);
        }
    }
    else{
        callback(null,null);
    }
}

Usage

Here’s how you would use this in your application:

getSize(function(size,err){
     if(size > 0){
         console.log("Database size = " + size + " bytes");
     }
     if(err != null){
         console.log("There was a problem getting database size: " + err);
     }
}

Reference

W3C Specification for IndexedDB Database API
MDN – Blog

The problem with JavaScript Obfuscators and Minification – Tracking down errors

JavaScript obfuscators and minifiers do their job well. In fact, some obfuscators have anti-debugging features. However, if you are a legitimate developer building applications against one of these libraries, chances are you’ve gotten an indecipherable error such as “z=null line 14300” and it brings your development efforts to a halt. Error messages like this provide no useful information on what the problem really is, or give any hints on how you might be able solve it. You’ve probably even looked at the jumbled source code in a last ditch attempt to make some sense out of the error. And, whether it’s your own library or a mainstream ones as jQuery or Dojo, it doesn’t matter. The amount of productivity lost because of these errors in probably very large, not to mention the frustration it causes.

I hope the the developers of these obfuscators are reading this…because I have a proposed solution to the problem.

Now, I want to start out by mentioning that I fully understand why obfuscators exist for reasons such as source code protection and decreasing download size. What I propose takes this fully into account, yet makes your library developer friendly in a secure way:

During the obfuscation process create an index file that maps each variable, function and class to a real line number and store this file in a web folder.  Then create a small html file that lets you search the index and return the real line number. Provide an option for return the variable, function or class name, too.

The concept is that if there is an error, like the  “z=null line 14300” I mentioned above, developers can then at least have some hope of narrowing down the general area of the code where it might be occurring.

The bonus is, if you own an obfuscated commercial library, now your tech support people can also look up the general area where a customer might be having a problem. For security reasons you don’t have to share the index file, But, even then, there isn’t enough information in it to de-compile the library. Now, if I post my error to the forum:  What is “z=null line 14300”? Tech support will be able to tell me that I’m missing a custom property on a widget’s HTML DIV element. It’s a win-win situation.

What do you think?