Showing posts with label Debugging. Show all posts
Showing posts with label Debugging. Show all posts

Wednesday, November 14, 2012

IndexedDBViewer: Take a look inside your indexedDB

Some days ago I released a new version of the IndexedDBViewer 1.1.0. The IndexedDBViewer is intended for web developers who want to sneak into their indexedDB database. It allows you to inspect the structure of your database as well as the data stored inside this structure. The difference with the previous version is that it no longer needs the jQueryUI library. This way I eliminated at least one reference. The following references are still necessary:

If you are using nuget, you can get all the resource by searching for the indexedDBViewer.

The second major change is that the viewer can easily be added to an existing page. The only thing you need to do is add a div with “indexedDBViewer” as id and data-dbName attribute to pass the database you want to inspect. The rest will be handled by the script in the viewer

   1: <div id="indexedDBViewer" data-dbName="database name"></div>

Once this is done and you navigate to the page with the viewer, you will get the following result


image


In the bottom you will see the view appear. On the left pane you get an overview of the database structure. This a list with on top the name of the database. Under that you will find child nodes that represent the object stores present in the database. If we descend an other level we can see the indexes present on the object store. If you click on the “+” or “-“ next to the names, you can expand or hide the structure beneath.


If you click on the database name in the navigation pane, you will get information about the database and it’s structure.



  • In the general block you will see the name of the database and the version it is currently in
  • The object stores block gives you an overview of all the object stores present and how they are configured.
  • The indexes block shows all the present indexes and how they are configured.

image


When you click on one of the object store names in the navigation pane, you will get all the data present in the object store. Because the data is saved as a key/value pair, you will see the key with his corresponding value. If the value is an object or contains objects, then you can inspect them by clicking on the “+” to expand and “-” to hide the details.


image


If you click on one of the index names in the navigation pane, you will get – similar as for object stores – all the data present in the object store. But in this case you will see a little more. Besides the key of the index and the value you will see the key the value has in the object store. This can be found under the “primary” key column.


image


As last there are some little extra features:



  • If you click on the top border of the viewer and drag it up or down, then you can change the height of the viewer.
  • if you click on the “-” in the right top of the viewer, you can hide the viewer. If you want it to appear again, then you have to click on the “+” on the right bottom of the page.

image


Conclusion


With this Chrome like indexedDBViewer you can inspect the structure of your database inclusive all data stored within it. This with the advantage that it runs inside the browser, so you can use it cross-browser.

Thursday, August 9, 2012

Promises: jQuery deferred object vs WinJS Promise

When I was adjusting my Linq2IndexedDB library to enable Windows 8 development, I had some little issues porting the jQuery promises to WinJS promises. In this post I will show you some differences I had issues with and how I fixed them.

Passing context

The first problem I ran into: WinJS promises doesn’t support passing a context. Because I don’t take advantage of the context yet, this wasn’t an issue for me yet. I easily solved it by writing a wrapper around the 2 promises. In case of the jQuery promise, the context gets passed. And in case of the WinJS promise, I just ignore it for the moment and hope it will get implemented in the future.

   1: function promiseWrapper(promise) {
   2:     if (isMetroApp) {
   3:         return new WinJS.Promise(function(completed, error, progress){
   4:             promise({
   5:                 complete: function (context, args) {
   6:                     completed(args);
   7:                 },
   8:                 error: function (context, args) {
   9:                     error(args);
  10:                 },
  11:                 progress: function (context, args) {
  12:                     progress(args);
  13:                 }
  14:             });
  15:         });
  16:     } else if (typeof ($) === "function" && $.Deferred) {
  17:         return $.Deferred(function (dfd) {
  18:             promise({
  19:                 complete: function (context, args) {
  20:                     dfd.resolveWith(context, [args]);
  21:                 },
  22:                 error: function (context, args) {
  23:                     dfd.rejectWith(context, [args]);
  24:                 },
  25:                 progress: function (context, args) {
  26:                     dfd.notifyWith(context, [args]);
  27:                 }
  28:             });
  29:         }).promise();
  30:     }
  31: }

Passing multiple parameters


A second problem I had was the fact that the WinJS only allows one argument to be passed when calling a complete, error or progress callback. Because I needed to pass multiple values in my library, I needed to rewrite every complete, error and progress method I called. Instead of just passing multiple arguments to the callback methods, I needed to wrap the arguments into an array so they could be passed as single argument.


But that wasn’t enough. Because the jQuery promise is smart enough to convert an array of arguments into a callback with multiple arguments, I needed to wrap the array of arguments into an other array (If you look in the sample above, you will see in case of the jQuery promise, brackets (‘[]’) were added around the args argument.). I needed to do this, because it was the only way to get the same signature when working with the WinJS & jQuery promise.



   1: promiseWrapper(function (pw) {
   2:     pw.complete(context, [arg1, arg2]);
   3: });

Progress Event Doesn’t fire in Winjs promise


The last issue I suffered was the fact that a progress event in didn’t fire in some cases. After a little investigation, I came to the conclusion that I was calling the progress event, before the promise object got created. I first noticed this when I was creating a transaction on the IndexedDB API. When a transaction was created, I fired a progress event with the transaction data. In other methods, where I needed the transaction, I used this the progress call to execute my queries. Once the transaction was committed, the complete event got fired. Because the progress call never got called, the query was never executed. This way the transaction was immediately committed and the complete callback got called without any action taken.


To fix this I delayed the progress call a little bit. By adding a setTimeout of 1 ms I noticed my problem was solved, and my progress events got called.



   1: if (isMetroApp) {
   2:     setTimeout(function () {
   3:         var txn = db.transaction(objectStoreNames, transactionType); 
   4:         txn.oncomplete = function (e) {
   5:             pw.complete(txn, [txn, e]);
   6:         };   
   7:         pw.progress(txn, [txn]);
   8:     }, 1);
   9: }

Conclusion


As seen above working with the WinJS is a slice different of working with the deferred object in jQuery. But with the given workarounds, it is possible to solve the most issues. I hope that Microsoft will take a look at the jQuery deferred object in the future and add some of the jQuery capabilities (context, multiple arguments) into the WinJS promises. And hopefully the progress bug gets solved, so the ugly setTimeout can disappear in my code.

Tuesday, July 24, 2012

Linq2IndexedDB: Debugging IndexedDB

In my latest version of the Linq2IndexedDB 1.0.7, I added the viewer object. This object allows you to inspect your IndexedDB database and gives you an overview of all the object stores and indexes that are present. It even gives you details about how they are configured and what data they contain. Also using this, you can take a look at your database in various debugging tools like:
  • Google Chrome Developer tools
  • Firefox Developer tools
  • IE Developer tools
  • Visual Studio
The viewer object contains 4 properties:
  1. configuration: In here you will find the way the Linq2IndexedDB framework is configured. (The same properties as you can define in the configuration object are present +  a property indicating if framework is running in auto create mode.)
  2. name: The name of the IndexedDB database
  3. objectStores: A collection of all the object stores that are present in the database
  4. version: The current version of the database
image
Inside an object store object, we can see the following:
  1. autoIncrement: indicates if the keys for the object store are generated by the IndexedDB API
  2. data: A collection of all the data available in the object store. These data objects are shown as key/value pair objects.
  3. indexes: A collection of all the indexes available on the object store.
  4. keyPath: The property inside the object that keeps the key
  5. name: The name of the object store
image
The last level we can take a look at, are the indexes. The following information will be provided:
  1. data: A collection of all the data available in the object store. These data objects are shown as key/value pair objects.
  2. keyPath: The property inside the object that keeps the key
  3. multiEntry: Determines if a key is only once defined in the index (which means the value keeps an array of all the values in the object store who match) or the key can be present multiple times (once for every value that matches in the object store.)
  4. name: The name of the index
image

conclusion

I hope this debugging information can help you speed up your software development and finding bugs while working with the IndexedDB API. The latest version of the framework can be found on codeplex, nuget and MyGet.

Update 28/07/2012

I added a new version of the framework, because there were some little bugs with the viewer. The following things change:
  • The viewer no longer blocks the deletion or upgrade of the database
  • The viewer now gets updated when the structure of the database changes
  • The viewer is default disabled for performance issues. If you want to enable it, add true as 3th argument on the function to create a linq2indexeddb function
   1: var db = $.linq2indexedDB("test", null, true);