Re: [IndexedDB] Implicit transactions

2010-08-06 Thread Jeremy Orlow
On Fri, Aug 6, 2010 at 1:56 PM, Jeremy Orlow jor...@chromium.org wrote:

 On Thu, Aug 5, 2010 at 8:56 PM, Jonas Sicking jo...@sicking.cc wrote:

 Ok, I'm going to start by taking a step back here.

 There is no such thing as implicit transactions.

 db.objectStore(foo, mode)

 is just syntactic sugar for

 db.transaction([foo], mode).objectStore(foo)

 so it always starts a new transaction. I think for now, lets take
 db.objectStore(..) out of the discussion and focus on how we want
 db.transaction() to work. In the end we may or may not want to keep
 db.objectStore() if it causes too much confusion.

 One thing that we have to first realize is that every IDBObjectStore
 instance is tied to a specific transaction. This is required to avoid
 ambiguity in what transaction a request is made against. Consider the
 following code

 trans1 = db.transaction([foo, bar], READ_WRITE);
 trans2 = db.transaction([foo, students], READ_ONLY);
 os1 = trans1.objectStore(foo);
 os2 = trans2.objectStore(foo);
 alert(os1 === os2);
 os1.get(someKey).onsuccess = ...;

 In this code, the alert will always display false. The os1 and os2
 are two distinct objects. They have to be, otherwise we wouldn't know
 which transaction to place the get() request against.

 Once a transaction has been committed or aborted, using any of the
 IDBObjectStore objects connected with it will throw an error. So the
 example mentioned earlier in the thread (i'll use different syntax
 than used previously in the thread):

 var gMyos = null;
 function fun1() {
  gMyos = db.transaction([foo]).objectStore(foo);
  gMyos.get(someKey).onsuccess = ...;
 }
 function fun2() {
  gMyos.get(someOtherKey);
 }

 If we return to the main even loop between calling fun1 and fun2, the
 .get() call in fun2 will *always* throw. IMHO it's a good thing that
 this consistently throws. Consider also

 function fun3() {
  var trans = db.transaction([foo, bar], READ_WRITE);
  trans.objectStore(bar).openCursor(...).onsuccess = ...;
 }

 It would IMHO be a bad thing if calling fun3 right before calling fun2
 all of a sudden made fun2 not throw and instead place a request
 against the transaction created in fun3.

 While I definitely think it can be confusing that there are several
 IDBObjectStore instances referring to the same underlying objectStore,
 I think this is ultimately a good thing as it reduces the risk of
 accidentally placing a request against the wrong transaction. It means
 that in order to place a request against a transaction, you must
 either have a reference to that transaction, or a reference to an
 objectStore retrieved from that transaction.

 Another way to think of it is this. You generally don't place requests
 against an objectStore or index. You place them against a transaction.
 By tying IDBObjectStores to a given transaction, it's always explicit
 which transaction you are using.

 On Thu, Aug 5, 2010 at 3:04 AM, Jeremy Orlow jor...@chromium.org wrote:
  On Wed, Aug 4, 2010 at 7:47 PM, Shawn Wilsher sdwi...@mozilla.com
 wrote:
 
   On 8/4/2010 10:53 AM, Jeremy Orlow wrote:
 
 
  Whoatransaction() is synchronous?!?  Ok, so I guess the entire
  premise
  of my question was super confused.  :-)
 
  It is certainly spec'd that way [1].  The locks do not get acquired
 until
  the first actual bit of work is done though.
 
  I fully understand how the trick works.  I just didn't comprehend the
 fact
  that the Mozilla proposal (what's now in the spec) was removing any way
 to
  get into an IDBTransactionEvent handler besides doing an initial data
  access.  I wouldn't have agreed to the proposal had I realized this.
  Lets say I had the following bit of initialization code in my program:
  var myDB = ...
  var myObjectStore = myDB.objectStore(someObjectStore);
  var myIndex = myObjectStore.index(someIndex);
  var anotherObjectStore = myDB.objectStore(anotherObjectStore);

 As described above, grabbing references like this is not what you want
 to do. If we were to allow this I think we would run a severe risk of
 making it very hard to understand which transaction you are placing
 requests against.

  And then I wanted to start a transaction that'd access some key and then
  presumably do some other work.  As currently specced, here's what I'd
 need
  to do:
 
 myDB.transaction().objectStore(someObjectStore).index(someIndex).get(someKey).onsuccess(function()
  {
  anotherObjectStore.get(someOtherKey).onsuccess(...);
  });
  vs doing something like this:
  myDB.asyncTransaction().onsuccess(function() {
  myIndex.get(someKey).onsuccess(function() {
  anotherObjectStore.get(someOtherKey).onsuccess(...);
  });
  });
  With the former, we actually have more typing and the code is harder to
  read.  Sure, when I'm writing short code snipits, the synchronous form
 can
  be more convenient and readable, but forcing this upon every situation
 is
  going to be a hinderance.
  Please, lets add back in a transaction method that returns an
 

Re: [IndexedDB] Implicit transactions

2010-08-06 Thread Andrei Popescu
On Fri, Aug 6, 2010 at 1:56 PM, Jeremy Orlow jor...@chromium.org wrote:
 On Thu, Aug 5, 2010 at 8:56 PM, Jonas Sicking jo...@sicking.cc wrote:

 Ok, I'm going to start by taking a step back here.

 There is no such thing as implicit transactions.

 db.objectStore(foo, mode)

 is just syntactic sugar for

 db.transaction([foo], mode).objectStore(foo)

 so it always starts a new transaction. I think for now, lets take
 db.objectStore(..) out of the discussion and focus on how we want
 db.transaction() to work. In the end we may or may not want to keep
 db.objectStore() if it causes too much confusion.

 One thing that we have to first realize is that every IDBObjectStore
 instance is tied to a specific transaction. This is required to avoid
 ambiguity in what transaction a request is made against. Consider the
 following code

 trans1 = db.transaction([foo, bar], READ_WRITE);
 trans2 = db.transaction([foo, students], READ_ONLY);
 os1 = trans1.objectStore(foo);
 os2 = trans2.objectStore(foo);
 alert(os1 === os2);
 os1.get(someKey).onsuccess = ...;

 In this code, the alert will always display false. The os1 and os2
 are two distinct objects. They have to be, otherwise we wouldn't know
 which transaction to place the get() request against.

 Once a transaction has been committed or aborted, using any of the
 IDBObjectStore objects connected with it will throw an error. So the
 example mentioned earlier in the thread (i'll use different syntax
 than used previously in the thread):

 var gMyos = null;
 function fun1() {
  gMyos = db.transaction([foo]).objectStore(foo);
  gMyos.get(someKey).onsuccess = ...;
 }
 function fun2() {
  gMyos.get(someOtherKey);
 }

 If we return to the main even loop between calling fun1 and fun2, the
 .get() call in fun2 will *always* throw. IMHO it's a good thing that
 this consistently throws. Consider also

 function fun3() {
  var trans = db.transaction([foo, bar], READ_WRITE);
  trans.objectStore(bar).openCursor(...).onsuccess = ...;
 }

 It would IMHO be a bad thing if calling fun3 right before calling fun2
 all of a sudden made fun2 not throw and instead place a request
 against the transaction created in fun3.

 While I definitely think it can be confusing that there are several
 IDBObjectStore instances referring to the same underlying objectStore,
 I think this is ultimately a good thing as it reduces the risk of
 accidentally placing a request against the wrong transaction. It means
 that in order to place a request against a transaction, you must
 either have a reference to that transaction, or a reference to an
 objectStore retrieved from that transaction.

 Another way to think of it is this. You generally don't place requests
 against an objectStore or index. You place them against a transaction.
 By tying IDBObjectStores to a given transaction, it's always explicit
 which transaction you are using.

 On Thu, Aug 5, 2010 at 3:04 AM, Jeremy Orlow jor...@chromium.org wrote:
  On Wed, Aug 4, 2010 at 7:47 PM, Shawn Wilsher sdwi...@mozilla.com
  wrote:
 
   On 8/4/2010 10:53 AM, Jeremy Orlow wrote:
 
 
  Whoatransaction() is synchronous?!?  Ok, so I guess the entire
  premise
  of my question was super confused.  :-)
 
  It is certainly spec'd that way [1].  The locks do not get acquired
  until
  the first actual bit of work is done though.
 
  I fully understand how the trick works.  I just didn't comprehend the
  fact
  that the Mozilla proposal (what's now in the spec) was removing any way
  to
  get into an IDBTransactionEvent handler besides doing an initial data
  access.  I wouldn't have agreed to the proposal had I realized this.
  Lets say I had the following bit of initialization code in my program:
  var myDB = ...
  var myObjectStore = myDB.objectStore(someObjectStore);
  var myIndex = myObjectStore.index(someIndex);
  var anotherObjectStore = myDB.objectStore(anotherObjectStore);

 As described above, grabbing references like this is not what you want
 to do. If we were to allow this I think we would run a severe risk of
 making it very hard to understand which transaction you are placing
 requests against.

  And then I wanted to start a transaction that'd access some key and then
  presumably do some other work.  As currently specced, here's what I'd
  need
  to do:
 
  myDB.transaction().objectStore(someObjectStore).index(someIndex).get(someKey).onsuccess(function()
  {
      anotherObjectStore.get(someOtherKey).onsuccess(...);
  });
  vs doing something like this:
  myDB.asyncTransaction().onsuccess(function() {
      myIndex.get(someKey).onsuccess(function() {
          anotherObjectStore.get(someOtherKey).onsuccess(...);
      });
  });
  With the former, we actually have more typing and the code is harder to
  read.  Sure, when I'm writing short code snipits, the synchronous form
  can
  be more convenient and readable, but forcing this upon every situation
  is
  going to be a hinderance.
  Please, lets add back in a transaction method that returns 

Re: [IndexedDB] Implicit transactions

2010-08-06 Thread Jonas Sicking
On Fri, Aug 6, 2010 at 6:52 AM, Jeremy Orlow jor...@chromium.org wrote:
 On Fri, Aug 6, 2010 at 1:56 PM, Jeremy Orlow jor...@chromium.org wrote:

 On Thu, Aug 5, 2010 at 8:56 PM, Jonas Sicking jo...@sicking.cc wrote:

 Ok, I'm going to start by taking a step back here.

 There is no such thing as implicit transactions.

 db.objectStore(foo, mode)

 is just syntactic sugar for

 db.transaction([foo], mode).objectStore(foo)

 so it always starts a new transaction. I think for now, lets take
 db.objectStore(..) out of the discussion and focus on how we want
 db.transaction() to work. In the end we may or may not want to keep
 db.objectStore() if it causes too much confusion.

 One thing that we have to first realize is that every IDBObjectStore
 instance is tied to a specific transaction. This is required to avoid
 ambiguity in what transaction a request is made against. Consider the
 following code

 trans1 = db.transaction([foo, bar], READ_WRITE);
 trans2 = db.transaction([foo, students], READ_ONLY);
 os1 = trans1.objectStore(foo);
 os2 = trans2.objectStore(foo);
 alert(os1 === os2);
 os1.get(someKey).onsuccess = ...;

 In this code, the alert will always display false. The os1 and os2
 are two distinct objects. They have to be, otherwise we wouldn't know
 which transaction to place the get() request against.

 Once a transaction has been committed or aborted, using any of the
 IDBObjectStore objects connected with it will throw an error. So the
 example mentioned earlier in the thread (i'll use different syntax
 than used previously in the thread):

 var gMyos = null;
 function fun1() {
  gMyos = db.transaction([foo]).objectStore(foo);
  gMyos.get(someKey).onsuccess = ...;
 }
 function fun2() {
  gMyos.get(someOtherKey);
 }

 If we return to the main even loop between calling fun1 and fun2, the
 .get() call in fun2 will *always* throw. IMHO it's a good thing that
 this consistently throws. Consider also

 function fun3() {
  var trans = db.transaction([foo, bar], READ_WRITE);
  trans.objectStore(bar).openCursor(...).onsuccess = ...;
 }

 It would IMHO be a bad thing if calling fun3 right before calling fun2
 all of a sudden made fun2 not throw and instead place a request
 against the transaction created in fun3.

 While I definitely think it can be confusing that there are several
 IDBObjectStore instances referring to the same underlying objectStore,
 I think this is ultimately a good thing as it reduces the risk of
 accidentally placing a request against the wrong transaction. It means
 that in order to place a request against a transaction, you must
 either have a reference to that transaction, or a reference to an
 objectStore retrieved from that transaction.

 Another way to think of it is this. You generally don't place requests
 against an objectStore or index. You place them against a transaction.
 By tying IDBObjectStores to a given transaction, it's always explicit
 which transaction you are using.

 On Thu, Aug 5, 2010 at 3:04 AM, Jeremy Orlow jor...@chromium.org wrote:
  On Wed, Aug 4, 2010 at 7:47 PM, Shawn Wilsher sdwi...@mozilla.com
  wrote:
 
   On 8/4/2010 10:53 AM, Jeremy Orlow wrote:
 
 
  Whoatransaction() is synchronous?!?  Ok, so I guess the entire
  premise
  of my question was super confused.  :-)
 
  It is certainly spec'd that way [1].  The locks do not get acquired
  until
  the first actual bit of work is done though.
 
  I fully understand how the trick works.  I just didn't comprehend the
  fact
  that the Mozilla proposal (what's now in the spec) was removing any way
  to
  get into an IDBTransactionEvent handler besides doing an initial data
  access.  I wouldn't have agreed to the proposal had I realized this.
  Lets say I had the following bit of initialization code in my program:
  var myDB = ...
  var myObjectStore = myDB.objectStore(someObjectStore);
  var myIndex = myObjectStore.index(someIndex);
  var anotherObjectStore = myDB.objectStore(anotherObjectStore);

 As described above, grabbing references like this is not what you want
 to do. If we were to allow this I think we would run a severe risk of
 making it very hard to understand which transaction you are placing
 requests against.

  And then I wanted to start a transaction that'd access some key and
  then
  presumably do some other work.  As currently specced, here's what I'd
  need
  to do:
 
  myDB.transaction().objectStore(someObjectStore).index(someIndex).get(someKey).onsuccess(function()
  {
      anotherObjectStore.get(someOtherKey).onsuccess(...);
  });
  vs doing something like this:
  myDB.asyncTransaction().onsuccess(function() {
      myIndex.get(someKey).onsuccess(function() {
          anotherObjectStore.get(someOtherKey).onsuccess(...);
      });
  });
  With the former, we actually have more typing and the code is harder to
  read.  Sure, when I'm writing short code snipits, the synchronous form
  can
  be more convenient and readable, but forcing this upon every situation
  is
  going to 

Re: [IndexedDB] Implicit transactions

2010-08-06 Thread Jeremy Orlow
On Fri, Aug 6, 2010 at 4:04 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Fri, Aug 6, 2010 at 6:52 AM, Jeremy Orlow jor...@chromium.org wrote:
  On Fri, Aug 6, 2010 at 1:56 PM, Jeremy Orlow jor...@chromium.org
 wrote:
 
  On Thu, Aug 5, 2010 at 8:56 PM, Jonas Sicking jo...@sicking.cc wrote:
 
  Ok, I'm going to start by taking a step back here.
 
  There is no such thing as implicit transactions.
 
  db.objectStore(foo, mode)
 
  is just syntactic sugar for
 
  db.transaction([foo], mode).objectStore(foo)
 
  so it always starts a new transaction. I think for now, lets take
  db.objectStore(..) out of the discussion and focus on how we want
  db.transaction() to work. In the end we may or may not want to keep
  db.objectStore() if it causes too much confusion.
 
  One thing that we have to first realize is that every IDBObjectStore
  instance is tied to a specific transaction. This is required to avoid
  ambiguity in what transaction a request is made against. Consider the
  following code
 
  trans1 = db.transaction([foo, bar], READ_WRITE);
  trans2 = db.transaction([foo, students], READ_ONLY);
  os1 = trans1.objectStore(foo);
  os2 = trans2.objectStore(foo);
  alert(os1 === os2);
  os1.get(someKey).onsuccess = ...;
 
  In this code, the alert will always display false. The os1 and os2
  are two distinct objects. They have to be, otherwise we wouldn't know
  which transaction to place the get() request against.
 
  Once a transaction has been committed or aborted, using any of the
  IDBObjectStore objects connected with it will throw an error. So the
  example mentioned earlier in the thread (i'll use different syntax
  than used previously in the thread):
 
  var gMyos = null;
  function fun1() {
   gMyos = db.transaction([foo]).objectStore(foo);
   gMyos.get(someKey).onsuccess = ...;
  }
  function fun2() {
   gMyos.get(someOtherKey);
  }
 
  If we return to the main even loop between calling fun1 and fun2, the
  .get() call in fun2 will *always* throw. IMHO it's a good thing that
  this consistently throws. Consider also
 
  function fun3() {
   var trans = db.transaction([foo, bar], READ_WRITE);
   trans.objectStore(bar).openCursor(...).onsuccess = ...;
  }
 
  It would IMHO be a bad thing if calling fun3 right before calling fun2
  all of a sudden made fun2 not throw and instead place a request
  against the transaction created in fun3.
 
  While I definitely think it can be confusing that there are several
  IDBObjectStore instances referring to the same underlying objectStore,
  I think this is ultimately a good thing as it reduces the risk of
  accidentally placing a request against the wrong transaction. It means
  that in order to place a request against a transaction, you must
  either have a reference to that transaction, or a reference to an
  objectStore retrieved from that transaction.
 
  Another way to think of it is this. You generally don't place requests
  against an objectStore or index. You place them against a transaction.
  By tying IDBObjectStores to a given transaction, it's always explicit
  which transaction you are using.
 
  On Thu, Aug 5, 2010 at 3:04 AM, Jeremy Orlow jor...@chromium.org
 wrote:
   On Wed, Aug 4, 2010 at 7:47 PM, Shawn Wilsher sdwi...@mozilla.com
   wrote:
  
On 8/4/2010 10:53 AM, Jeremy Orlow wrote:
  
  
   Whoatransaction() is synchronous?!?  Ok, so I guess the entire
   premise
   of my question was super confused.  :-)
  
   It is certainly spec'd that way [1].  The locks do not get acquired
   until
   the first actual bit of work is done though.
  
   I fully understand how the trick works.  I just didn't comprehend the
   fact
   that the Mozilla proposal (what's now in the spec) was removing any
 way
   to
   get into an IDBTransactionEvent handler besides doing an initial data
   access.  I wouldn't have agreed to the proposal had I realized this.
   Lets say I had the following bit of initialization code in my
 program:
   var myDB = ...
   var myObjectStore = myDB.objectStore(someObjectStore);
   var myIndex = myObjectStore.index(someIndex);
   var anotherObjectStore = myDB.objectStore(anotherObjectStore);
 
  As described above, grabbing references like this is not what you want
  to do. If we were to allow this I think we would run a severe risk of
  making it very hard to understand which transaction you are placing
  requests against.
 
   And then I wanted to start a transaction that'd access some key and
   then
   presumably do some other work.  As currently specced, here's what I'd
   need
   to do:
  
  
 myDB.transaction().objectStore(someObjectStore).index(someIndex).get(someKey).onsuccess(function()
   {
   anotherObjectStore.get(someOtherKey).onsuccess(...);
   });
   vs doing something like this:
   myDB.asyncTransaction().onsuccess(function() {
   myIndex.get(someKey).onsuccess(function() {
   anotherObjectStore.get(someOtherKey).onsuccess(...);
   });
   });
   With the former, we actually have more 

Re: [IndexedDB] Implicit transactions

2010-08-06 Thread Jonas Sicking
On Fri, Aug 6, 2010 at 8:06 AM, Jeremy Orlow jor...@chromium.org wrote:
 On Fri, Aug 6, 2010 at 4:04 PM, Jonas Sicking jo...@sicking.cc wrote:

 On Fri, Aug 6, 2010 at 6:52 AM, Jeremy Orlow jor...@chromium.org wrote:
  On Fri, Aug 6, 2010 at 1:56 PM, Jeremy Orlow jor...@chromium.org
  wrote:
 
  On Thu, Aug 5, 2010 at 8:56 PM, Jonas Sicking jo...@sicking.cc wrote:
 
  Ok, I'm going to start by taking a step back here.
 
  There is no such thing as implicit transactions.
 
  db.objectStore(foo, mode)
 
  is just syntactic sugar for
 
  db.transaction([foo], mode).objectStore(foo)
 
  so it always starts a new transaction. I think for now, lets take
  db.objectStore(..) out of the discussion and focus on how we want
  db.transaction() to work. In the end we may or may not want to keep
  db.objectStore() if it causes too much confusion.
 
  One thing that we have to first realize is that every IDBObjectStore
  instance is tied to a specific transaction. This is required to avoid
  ambiguity in what transaction a request is made against. Consider the
  following code
 
  trans1 = db.transaction([foo, bar], READ_WRITE);
  trans2 = db.transaction([foo, students], READ_ONLY);
  os1 = trans1.objectStore(foo);
  os2 = trans2.objectStore(foo);
  alert(os1 === os2);
  os1.get(someKey).onsuccess = ...;
 
  In this code, the alert will always display false. The os1 and os2
  are two distinct objects. They have to be, otherwise we wouldn't know
  which transaction to place the get() request against.
 
  Once a transaction has been committed or aborted, using any of the
  IDBObjectStore objects connected with it will throw an error. So the
  example mentioned earlier in the thread (i'll use different syntax
  than used previously in the thread):
 
  var gMyos = null;
  function fun1() {
   gMyos = db.transaction([foo]).objectStore(foo);
   gMyos.get(someKey).onsuccess = ...;
  }
  function fun2() {
   gMyos.get(someOtherKey);
  }
 
  If we return to the main even loop between calling fun1 and fun2, the
  .get() call in fun2 will *always* throw. IMHO it's a good thing that
  this consistently throws. Consider also
 
  function fun3() {
   var trans = db.transaction([foo, bar], READ_WRITE);
   trans.objectStore(bar).openCursor(...).onsuccess = ...;
  }
 
  It would IMHO be a bad thing if calling fun3 right before calling fun2
  all of a sudden made fun2 not throw and instead place a request
  against the transaction created in fun3.
 
  While I definitely think it can be confusing that there are several
  IDBObjectStore instances referring to the same underlying objectStore,
  I think this is ultimately a good thing as it reduces the risk of
  accidentally placing a request against the wrong transaction. It means
  that in order to place a request against a transaction, you must
  either have a reference to that transaction, or a reference to an
  objectStore retrieved from that transaction.
 
  Another way to think of it is this. You generally don't place requests
  against an objectStore or index. You place them against a transaction.
  By tying IDBObjectStores to a given transaction, it's always explicit
  which transaction you are using.
 
  On Thu, Aug 5, 2010 at 3:04 AM, Jeremy Orlow jor...@chromium.org
  wrote:
   On Wed, Aug 4, 2010 at 7:47 PM, Shawn Wilsher sdwi...@mozilla.com
   wrote:
  
    On 8/4/2010 10:53 AM, Jeremy Orlow wrote:
  
  
   Whoatransaction() is synchronous?!?  Ok, so I guess the entire
   premise
   of my question was super confused.  :-)
  
   It is certainly spec'd that way [1].  The locks do not get acquired
   until
   the first actual bit of work is done though.
  
   I fully understand how the trick works.  I just didn't comprehend
   the
   fact
   that the Mozilla proposal (what's now in the spec) was removing any
   way
   to
   get into an IDBTransactionEvent handler besides doing an initial
   data
   access.  I wouldn't have agreed to the proposal had I realized this.
   Lets say I had the following bit of initialization code in my
   program:
   var myDB = ...
   var myObjectStore = myDB.objectStore(someObjectStore);
   var myIndex = myObjectStore.index(someIndex);
   var anotherObjectStore = myDB.objectStore(anotherObjectStore);
 
  As described above, grabbing references like this is not what you want
  to do. If we were to allow this I think we would run a severe risk of
  making it very hard to understand which transaction you are placing
  requests against.
 
   And then I wanted to start a transaction that'd access some key and
   then
   presumably do some other work.  As currently specced, here's what
   I'd
   need
   to do:
  
  
   myDB.transaction().objectStore(someObjectStore).index(someIndex).get(someKey).onsuccess(function()
   {
       anotherObjectStore.get(someOtherKey).onsuccess(...);
   });
   vs doing something like this:
   myDB.asyncTransaction().onsuccess(function() {
       myIndex.get(someKey).onsuccess(function() {
           

Re: [IndexedDB] Implicit transactions

2010-08-05 Thread Jeremy Orlow
On Wed, Aug 4, 2010 at 7:47 PM, Shawn Wilsher sdwi...@mozilla.com wrote:

  On 8/4/2010 10:53 AM, Jeremy Orlow wrote:



 Whoatransaction() is synchronous?!?  Ok, so I guess the entire premise
 of my question was super confused.  :-)

  It is certainly spec'd that way [1].  The locks do not get acquired until
 the first actual bit of work is done though.


I fully understand how the trick works.  I just didn't comprehend the fact
that the Mozilla proposal (what's now in the spec) was removing any way to
get into an IDBTransactionEvent handler besides doing an initial data
access.  I wouldn't have agreed to the proposal had I realized this.

Lets say I had the following bit of initialization code in my program:

var myDB = ...
var myObjectStore = myDB.objectStore(someObjectStore);
var myIndex = myObjectStore.index(someIndex);
var anotherObjectStore = myDB.objectStore(anotherObjectStore);

And then I wanted to start a transaction that'd access some key and then
presumably do some other work.  As currently specced, here's what I'd need
to do:

myDB.transaction().objectStore(someObjectStore).index(someIndex).get(someKey).onsuccess(function()
{
anotherObjectStore.get(someOtherKey).onsuccess(...);
});

vs doing something like this:

myDB.asyncTransaction().onsuccess(function() {
myIndex.get(someKey).onsuccess(function() {
anotherObjectStore.get(someOtherKey).onsuccess(...);
});
});

With the former, we actually have more typing and the code is harder to
read.  Sure, when I'm writing short code snipits, the synchronous form can
be more convenient and readable, but forcing this upon every situation is
going to be a hinderance.

Please, lets add back in a transaction method that returns an IDBRequest.

J


Re: [IndexedDB] Implicit transactions

2010-08-05 Thread Jonas Sicking
Ok, I'm going to start by taking a step back here.

There is no such thing as implicit transactions.

db.objectStore(foo, mode)

is just syntactic sugar for

db.transaction([foo], mode).objectStore(foo)

so it always starts a new transaction. I think for now, lets take
db.objectStore(..) out of the discussion and focus on how we want
db.transaction() to work. In the end we may or may not want to keep
db.objectStore() if it causes too much confusion.

One thing that we have to first realize is that every IDBObjectStore
instance is tied to a specific transaction. This is required to avoid
ambiguity in what transaction a request is made against. Consider the
following code

trans1 = db.transaction([foo, bar], READ_WRITE);
trans2 = db.transaction([foo, students], READ_ONLY);
os1 = trans1.objectStore(foo);
os2 = trans2.objectStore(foo);
alert(os1 === os2);
os1.get(someKey).onsuccess = ...;

In this code, the alert will always display false. The os1 and os2
are two distinct objects. They have to be, otherwise we wouldn't know
which transaction to place the get() request against.

Once a transaction has been committed or aborted, using any of the
IDBObjectStore objects connected with it will throw an error. So the
example mentioned earlier in the thread (i'll use different syntax
than used previously in the thread):

var gMyos = null;
function fun1() {
  gMyos = db.transaction([foo]).objectStore(foo);
  gMyos.get(someKey).onsuccess = ...;
}
function fun2() {
  gMyos.get(someOtherKey);
}

If we return to the main even loop between calling fun1 and fun2, the
.get() call in fun2 will *always* throw. IMHO it's a good thing that
this consistently throws. Consider also

function fun3() {
  var trans = db.transaction([foo, bar], READ_WRITE);
  trans.objectStore(bar).openCursor(...).onsuccess = ...;
}

It would IMHO be a bad thing if calling fun3 right before calling fun2
all of a sudden made fun2 not throw and instead place a request
against the transaction created in fun3.

While I definitely think it can be confusing that there are several
IDBObjectStore instances referring to the same underlying objectStore,
I think this is ultimately a good thing as it reduces the risk of
accidentally placing a request against the wrong transaction. It means
that in order to place a request against a transaction, you must
either have a reference to that transaction, or a reference to an
objectStore retrieved from that transaction.

Another way to think of it is this. You generally don't place requests
against an objectStore or index. You place them against a transaction.
By tying IDBObjectStores to a given transaction, it's always explicit
which transaction you are using.

On Thu, Aug 5, 2010 at 3:04 AM, Jeremy Orlow jor...@chromium.org wrote:
 On Wed, Aug 4, 2010 at 7:47 PM, Shawn Wilsher sdwi...@mozilla.com wrote:

  On 8/4/2010 10:53 AM, Jeremy Orlow wrote:


 Whoatransaction() is synchronous?!?  Ok, so I guess the entire
 premise
 of my question was super confused.  :-)

 It is certainly spec'd that way [1].  The locks do not get acquired until
 the first actual bit of work is done though.

 I fully understand how the trick works.  I just didn't comprehend the fact
 that the Mozilla proposal (what's now in the spec) was removing any way to
 get into an IDBTransactionEvent handler besides doing an initial data
 access.  I wouldn't have agreed to the proposal had I realized this.
 Lets say I had the following bit of initialization code in my program:
 var myDB = ...
 var myObjectStore = myDB.objectStore(someObjectStore);
 var myIndex = myObjectStore.index(someIndex);
 var anotherObjectStore = myDB.objectStore(anotherObjectStore);

As described above, grabbing references like this is not what you want
to do. If we were to allow this I think we would run a severe risk of
making it very hard to understand which transaction you are placing
requests against.

 And then I wanted to start a transaction that'd access some key and then
 presumably do some other work.  As currently specced, here's what I'd need
 to do:
 myDB.transaction().objectStore(someObjectStore).index(someIndex).get(someKey).onsuccess(function()
 {
     anotherObjectStore.get(someOtherKey).onsuccess(...);
 });
 vs doing something like this:
 myDB.asyncTransaction().onsuccess(function() {
     myIndex.get(someKey).onsuccess(function() {
         anotherObjectStore.get(someOtherKey).onsuccess(...);
     });
 });
 With the former, we actually have more typing and the code is harder to
 read.  Sure, when I'm writing short code snipits, the synchronous form can
 be more convenient and readable, but forcing this upon every situation is
 going to be a hinderance.
 Please, lets add back in a transaction method that returns an IDBRequest.

The current design of the spec is that which IDBObjectStore you place
a request against determines which transaction you are using.

It sounds to me like you want a design where each IDBObjectStore
instance represents just a objectStore 

Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Andrei Popescu
On Wed, Aug 4, 2010 at 4:42 PM, Jeremy Orlow jor...@chromium.org wrote:
 In the IndexedDB spec, there are two ways to create a transaction.  One is
 explicit (by calling IDBDatabase.transaction()) and one is implicit (for
 example, by calling IDBDatabase.objectStore.get(someKey)).  I have
 questions about the latter, but before bringing these up, I think it might
 be best to give a bit of background (as I understand it) to make sure we're
 all on the same page:

 Belief 1:
 No matter how the transaction is started, any subsequent calls done within
 an IDBTransactionEvent (which is the event fired for almost every
 IDBRequest.onsuccess call since almost all of them are for operations done
 within the context of a transaction) will continue running in the same
 transaction.  So, for example, the following code will atomically increment
 a counter:
 myDB.transaction().onsuccess(function() {
     myDB.objectStore(someObjectStore).get(counter).onsuccess(function()
 {
         myDB.objectStore(someObjectStore).put(counter, event.result +
 1);
     });
 });

 Belief 2:
 Let's say I ran the following code:
 myDB.transaction().onsuccess(function() { window.myObjectStore =
 myDB.objectStore(someObjectStore); /* do some other work */ });
 And then at any point later in the program (after that first transaction had
 committed) I could do the following:
 myDB.transaction().onsuccess(function() { window.myObjectStore.get(some
 value).onsuccess(...); });
 Even though myObjectStore was originally fetched during some other
 transaction, it's quite clear that I'm accessing values from that object
 store in this new transaction's context, and thus that's exactly what
 happens and this is allowed.



I think it's only allowed as long as the object store in question is
in the scope of this other transaction.

 Implicitly created transactions:
 At a high level, the intent is
 for IDBDatabase.objectStore.get(someKey).onsuccess(...); to just work,
 even when not called in an IDBTransactionEvent handler.  But what happens if
 I run the following code (outside of an IDBTransactionEvent handler):
 for (var i=0; i5; ++i)
     myDB.objectStore(someObjectStore).get(someKey).onsuccess(...);
 Do we want that to create 5 separate transactions or 5 requests within the
 same transaction?

As currently specced, I think that would indeed start 5 separate
transactions. But couldn't you save the object store in a variable
before the loop?

 And what if we run my earlier example (that stored an object store to
 window.myObjectStore within a transaction we started explicitly) and then
 run the following code (outside of an IDBTransactionEventHandler):
 window.myObjectStore.get(someKey).onsuccess(...);
 myDB.objectStore(someObjectStore).get(someKey).onsuccess(...)
 Should both be legal?  Will this create one or two transactions?


I think simply calling window.myObjectStore.get() would not create a
transaction. I think it would just throw?

myDB.objectStore().get() would create a transaction.

 Speccing such transactions:
 After thinking about this, I only see a couple options for how to spec
 implicitly created transactions:
 When an operation that needs to be done in a transaction (i.e. anything
 that touches data) is done outside of an IDBTransactionEvent handler...
 1) that operation will be done in its own, newly created transaction.
 2) if there already exists an implicitly created transaction for that
 objectStore, it'll be done in that transaction.  Otherwise a new one will be
 created.
 3) if there already exists _any_ transaction with access to that
 objectStore, it'll be done in that transaction.  Otherwise a new one will be
 created.
 2 seems like it'd match the users intention in a lot of cases, but its
 biggest problem is that it's non-deterministic.  If you do one .get() and
 then set a time out and do another, you don't know whether they'll be in the
 same transaction or not.

That's right, it seems like a problem to me.

  3 seems to have the same problem except it's even
 less predictable.  So, but process of elimination, it seems as though 1 is
 our only option in terms of how to spec this.  Or am I missing something?


Well, what's wrong with what's specced today:

- you can only call get/put/etc in the context of a transaction. If
you don't, they'll throw.
- in the context of a transaction means in a transaction callback or
after you created an implicit transaction and until control returns to
the main browser event loop.

 Read-only by default too?
 Another somewhat related question: should implicitly created transactions be
 read-only (which is the default for explicitly created ones)?  If so, that
 means that we expect the following to fail:
 myDB.objectStore(someObjectStore).get(counter).onsuccess(function() {
     myDB.objectStore(someObjectStore).put(counter, event.result + 1);
 });
 Unfortunately, it seems as though a lot of use cases for implicitly created
 transactions would involve more than just reads.  But if we 

Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Jeremy Orlow
On Wed, Aug 4, 2010 at 5:26 PM, Andrei Popescu andr...@google.com wrote:

 On Wed, Aug 4, 2010 at 4:42 PM, Jeremy Orlow jor...@chromium.org wrote:
  In the IndexedDB spec, there are two ways to create a transaction.  One
 is
  explicit (by calling IDBDatabase.transaction()) and one is implicit (for
  example, by calling IDBDatabase.objectStore.get(someKey)).  I have
  questions about the latter, but before bringing these up, I think it
 might
  be best to give a bit of background (as I understand it) to make sure
 we're
  all on the same page:
 
  Belief 1:
  No matter how the transaction is started, any subsequent calls done
 within
  an IDBTransactionEvent (which is the event fired for almost every
  IDBRequest.onsuccess call since almost all of them are for operations
 done
  within the context of a transaction) will continue running in the same
  transaction.  So, for example, the following code will atomically
 increment
  a counter:
  myDB.transaction().onsuccess(function() {
 
  myDB.objectStore(someObjectStore).get(counter).onsuccess(function()
  {
  myDB.objectStore(someObjectStore).put(counter, event.result +
  1);
  });
  });
 
  Belief 2:
  Let's say I ran the following code:
  myDB.transaction().onsuccess(function() { window.myObjectStore =
  myDB.objectStore(someObjectStore); /* do some other work */ });
  And then at any point later in the program (after that first transaction
 had
  committed) I could do the following:
  myDB.transaction().onsuccess(function() { window.myObjectStore.get(some
  value).onsuccess(...); });
  Even though myObjectStore was originally fetched during some other
  transaction, it's quite clear that I'm accessing values from that object
  store in this new transaction's context, and thus that's exactly what
  happens and this is allowed.
 


 I think it's only allowed as long as the object store in question is
 in the scope of this other transaction.


Of course.  (I should have explicitly mentioned that though.)


   Implicitly created transactions:
  At a high level, the intent is
  for IDBDatabase.objectStore.get(someKey).onsuccess(...); to just
 work,
  even when not called in an IDBTransactionEvent handler.  But what happens
 if
  I run the following code (outside of an IDBTransactionEvent handler):
  for (var i=0; i5; ++i)
  myDB.objectStore(someObjectStore).get(someKey).onsuccess(...);
  Do we want that to create 5 separate transactions or 5 requests within
 the
  same transaction?

 As currently specced, I think that would indeed start 5 separate
 transactions. But couldn't you save the object store in a variable
 before the loop?


To be clear, you're suggesting that the following would result in 1
transaction?

var myOS = myDB.objectStore(someObjectStore);
for (var i=0; i5; ++i)
myOS.get(someKey).onsuccess(...);

This would seem to imply that, when used outside of an IDBTransactionEvent
context, each instance of an objectStore object will be linked to its own
transaction?  I'd assume that any children (for example IDBIndex objects)
that come from that IDBObjectStore would also be linked to the same
transaction?

What about the following:

var myOS = myDB.objectStore(someObjectStore);
myOS.get(someKey).onsuccess(...);
/* do other stuff for a while...onsuccess above fired and thus the
implicitly created transaction was committed implicitly */
myOS.get(anotherKey).onsuccess(...);

The implicitly created transaction has completed before the second .get()
call.  Would the second call throw or would it start another implicit
transaction?


  And what if we run my earlier example (that stored an object store to
  window.myObjectStore within a transaction we started explicitly) and then
  run the following code (outside of an IDBTransactionEventHandler):
  window.myObjectStore.get(someKey).onsuccess(...);
  myDB.objectStore(someObjectStore).get(someKey).onsuccess(...)
  Should both be legal?  Will this create one or two transactions?
 

 I think simply calling window.myObjectStore.get() would not create a
 transaction. I think it would just throw?

 myDB.objectStore().get() would create a transaction.


If the second .get in my last example would fail (i.e. ObjectStores are
somehow bound to a transaction, and once that transaction finishes, it
cannot be used outside of an IDBTransactionEvent context), then I could see
this making sense.  Otherwise could you please explain why this is?


  Speccing such transactions:
  After thinking about this, I only see a couple options for how to spec
  implicitly created transactions:
  When an operation that needs to be done in a transaction (i.e. anything
  that touches data) is done outside of an IDBTransactionEvent handler...
  1) that operation will be done in its own, newly created transaction.
  2) if there already exists an implicitly created transaction for that
  objectStore, it'll be done in that transaction.  Otherwise a new one will
 be
  created.
  3) if there already exists _any_ transaction 

Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Andrei Popescu
On Wed, Aug 4, 2010 at 5:46 PM, Jeremy Orlow jor...@chromium.org wrote:
 On Wed, Aug 4, 2010 at 5:26 PM, Andrei Popescu andr...@google.com wrote:

 On Wed, Aug 4, 2010 at 4:42 PM, Jeremy Orlow jor...@chromium.org wrote:
  In the IndexedDB spec, there are two ways to create a transaction.  One
  is
  explicit (by calling IDBDatabase.transaction()) and one is implicit (for
  example, by calling IDBDatabase.objectStore.get(someKey)).  I have
  questions about the latter, but before bringing these up, I think it
  might
  be best to give a bit of background (as I understand it) to make sure
  we're
  all on the same page:
 
  Belief 1:
  No matter how the transaction is started, any subsequent calls done
  within
  an IDBTransactionEvent (which is the event fired for almost every
  IDBRequest.onsuccess call since almost all of them are for operations
  done
  within the context of a transaction) will continue running in the same
  transaction.  So, for example, the following code will atomically
  increment
  a counter:
  myDB.transaction().onsuccess(function() {
 
   myDB.objectStore(someObjectStore).get(counter).onsuccess(function()
  {
          myDB.objectStore(someObjectStore).put(counter, event.result
  +
  1);
      });
  });
 
  Belief 2:
  Let's say I ran the following code:
  myDB.transaction().onsuccess(function() { window.myObjectStore =
  myDB.objectStore(someObjectStore); /* do some other work */ });
  And then at any point later in the program (after that first transaction
  had
  committed) I could do the following:
  myDB.transaction().onsuccess(function() { window.myObjectStore.get(some
  value).onsuccess(...); });
  Even though myObjectStore was originally fetched during some other
  transaction, it's quite clear that I'm accessing values from that object
  store in this new transaction's context, and thus that's exactly what
  happens and this is allowed.
 


 I think it's only allowed as long as the object store in question is
 in the scope of this other transaction.

 Of course.  (I should have explicitly mentioned that though.)


  Implicitly created transactions:
  At a high level, the intent is
  for IDBDatabase.objectStore.get(someKey).onsuccess(...); to just
  work,
  even when not called in an IDBTransactionEvent handler.  But what
  happens if
  I run the following code (outside of an IDBTransactionEvent handler):
  for (var i=0; i5; ++i)
      myDB.objectStore(someObjectStore).get(someKey).onsuccess(...);
  Do we want that to create 5 separate transactions or 5 requests within
  the
  same transaction?

 As currently specced, I think that would indeed start 5 separate
 transactions. But couldn't you save the object store in a variable
 before the loop?

 To be clear, you're suggesting that the following would result in 1
 transaction?
 var myOS = myDB.objectStore(someObjectStore);
 for (var i=0; i5; ++i)
     myOS.get(someKey).onsuccess(...);
 This would seem to imply that, when used outside of an IDBTransactionEvent
 context, each instance of an objectStore object will be linked to its own
 transaction?  I'd assume that any children (for example IDBIndex objects)
 that come from that IDBObjectStore would also be linked to the same
 transaction?

That's my understanding, yes.


 What about the following:
 var myOS = myDB.objectStore(someObjectStore);
 myOS.get(someKey).onsuccess(...);
 /* do other stuff for a while...onsuccess above fired and thus the
 implicitly created transaction was committed implicitly */

 myOS.get(anotherKey).onsuccess(...);
 The implicitly created transaction has completed before the second .get()
 call.  Would the second call throw or would it start another implicit
 transaction?


My understanding is that it would throw.


  And what if we run my earlier example (that stored an object store to
  window.myObjectStore within a transaction we started explicitly) and
  then
  run the following code (outside of an IDBTransactionEventHandler):
  window.myObjectStore.get(someKey).onsuccess(...);
  myDB.objectStore(someObjectStore).get(someKey).onsuccess(...)
  Should both be legal?  Will this create one or two transactions?
 

 I think simply calling window.myObjectStore.get() would not create a
 transaction. I think it would just throw?

 myDB.objectStore().get() would create a transaction.

 If the second .get in my last example would fail (i.e. ObjectStores are
 somehow bound to a transaction, and once that transaction finishes, it
 cannot be used outside of an IDBTransactionEvent context), then I could see
 this making sense.  Otherwise could you please explain why this is?


Yes, it would throw as that object store is no longer in the scope of
any transaction.


  Speccing such transactions:
  After thinking about this, I only see a couple options for how to spec
  implicitly created transactions:
  When an operation that needs to be done in a transaction (i.e. anything
  that touches data) is done outside of an IDBTransactionEvent handler...
  1) that 

Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Jeremy Orlow
I talked to Andrei in person.  He seemed to think this was discussed and
agreed upon sometime earlier but agreed the spec could be more clear.

On Wed, Aug 4, 2010 at 5:46 PM, Jeremy Orlow jor...@chromium.org wrote:

 On Wed, Aug 4, 2010 at 5:26 PM, Andrei Popescu andr...@google.com wrote:

 On Wed, Aug 4, 2010 at 4:42 PM, Jeremy Orlow jor...@chromium.org wrote:
  In the IndexedDB spec, there are two ways to create a transaction.  One
 is
  explicit (by calling IDBDatabase.transaction()) and one is implicit (for
  example, by calling IDBDatabase.objectStore.get(someKey)).  I have
  questions about the latter, but before bringing these up, I think it
 might
  be best to give a bit of background (as I understand it) to make sure
 we're
  all on the same page:
 
  Belief 1:
  No matter how the transaction is started, any subsequent calls done
 within
  an IDBTransactionEvent (which is the event fired for almost every
  IDBRequest.onsuccess call since almost all of them are for operations
 done
  within the context of a transaction) will continue running in the same
  transaction.  So, for example, the following code will atomically
 increment
  a counter:
  myDB.transaction().onsuccess(function() {
 
  myDB.objectStore(someObjectStore).get(counter).onsuccess(function()
  {
  myDB.objectStore(someObjectStore).put(counter, event.result
 +
  1);
  });
  });
 
  Belief 2:
  Let's say I ran the following code:
  myDB.transaction().onsuccess(function() { window.myObjectStore =
  myDB.objectStore(someObjectStore); /* do some other work */ });
  And then at any point later in the program (after that first transaction
 had
  committed) I could do the following:
  myDB.transaction().onsuccess(function() { window.myObjectStore.get(some
  value).onsuccess(...); });
  Even though myObjectStore was originally fetched during some other
  transaction, it's quite clear that I'm accessing values from that object
  store in this new transaction's context, and thus that's exactly what
  happens and this is allowed.
 


 I think it's only allowed as long as the object store in question is
 in the scope of this other transaction.


 Of course.  (I should have explicitly mentioned that though.)


   Implicitly created transactions:
  At a high level, the intent is
  for IDBDatabase.objectStore.get(someKey).onsuccess(...); to just
 work,
  even when not called in an IDBTransactionEvent handler.  But what
 happens if
  I run the following code (outside of an IDBTransactionEvent handler):
  for (var i=0; i5; ++i)
  myDB.objectStore(someObjectStore).get(someKey).onsuccess(...);
  Do we want that to create 5 separate transactions or 5 requests within
 the
  same transaction?

 As currently specced, I think that would indeed start 5 separate
 transactions. But couldn't you save the object store in a variable
 before the loop?


 To be clear, you're suggesting that the following would result in 1
 transaction?

 var myOS = myDB.objectStore(someObjectStore);
 for (var i=0; i5; ++i)
 myOS.get(someKey).onsuccess(...);

 This would seem to imply that, when used outside of an IDBTransactionEvent
 context, each instance of an objectStore object will be linked to its own
 transaction?  I'd assume that any children (for example IDBIndex objects)
 that come from that IDBObjectStore would also be linked to the same
 transaction?

 What about the following:

 var myOS = myDB.objectStore(someObjectStore);
 myOS.get(someKey).onsuccess(...);
 /* do other stuff for a while...onsuccess above fired and thus the
 implicitly created transaction was committed implicitly */
 myOS.get(anotherKey).onsuccess(...);

 The implicitly created transaction has completed before the second .get()
 call.  Would the second call throw or would it start another implicit
 transaction?


Andrei said the second .get (assuming the code is not literal...since
there's no way an onsuccess could fire unless we returned control to
JavaScript) should not fire.


   And what if we run my earlier example (that stored an object store to
  window.myObjectStore within a transaction we started explicitly) and
 then
  run the following code (outside of an IDBTransactionEventHandler):
  window.myObjectStore.get(someKey).onsuccess(...);
  myDB.objectStore(someObjectStore).get(someKey).onsuccess(...)
  Should both be legal?  Will this create one or two transactions?
 

 I think simply calling window.myObjectStore.get() would not create a
 transaction. I think it would just throw?

 myDB.objectStore().get() would create a transaction.


 If the second .get in my last example would fail (i.e. ObjectStores are
 somehow bound to a transaction, and once that transaction finishes, it
 cannot be used outside of an IDBTransactionEvent context), then I could see
 this making sense.  Otherwise could you please explain why this is?


This does seem to be loosely what's intended...more below...


   Speccing such transactions:
  After thinking about this, I only see a couple options 

Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Shawn Wilsher

 On 8/4/2010 10:24 AM, Jeremy Orlow wrote:

Jonas/Shawn: Since it seems you've been getting some feedback on your
implementation, do you have any data to suggest that implicit transactions
are being used and considered helpful in the wild?


I have not yet seen any specific feedback about it as of yet.

Cheers,

Shawn



smime.p7s
Description: S/MIME Cryptographic Signature


Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Shawn Wilsher

 On 8/4/2010 8:42 AM, Jeremy Orlow wrote:

In the IndexedDB spec, there are two ways to create a transaction.  One is
explicit (by calling IDBDatabase.transaction()) and one is implicit (for
example, by calling IDBDatabase.objectStore.get(someKey)).  I have
questions about the latter, but before bringing these up, I think it might
be best to give a bit of background (as I understand it) to make sure we're
all on the same page:

If I recall correctly, the original proposal from us basically said that 
IDBDatabase.objectStore(foo, [mode]) was just a shortcut for 
IDBDatabase.transaction(foo, [mode]).getObjectStore(foo);  I'm not 
sure if putting some text like that would help make things clearer though.


Cheers,

Shawn



smime.p7s
Description: S/MIME Cryptographic Signature


Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Jeremy Orlow
On Wed, Aug 4, 2010 at 6:33 PM, Shawn Wilsher sdwi...@mozilla.com wrote:

  On 8/4/2010 8:42 AM, Jeremy Orlow wrote:

 In the IndexedDB spec, there are two ways to create a transaction.  One is
 explicit (by calling IDBDatabase.transaction()) and one is implicit (for
 example, by calling IDBDatabase.objectStore.get(someKey)).  I have
 questions about the latter, but before bringing these up, I think it might
 be best to give a bit of background (as I understand it) to make sure
 we're
 all on the same page:

  If I recall correctly, the original proposal from us basically said that
 IDBDatabase.objectStore(foo, [mode]) was just a shortcut for
 IDBDatabase.transaction(foo, [mode]).getObjectStore(foo);  I'm not sure
 if putting some text like that would help make things clearer though.


Whoatransaction() is synchronous?!?  Ok, so I guess the entire premise
of my question was super confused.  :-)

But I'm not sure I like that at all since it means that I will have to
open at least one object store every time I do any transaction.  I.e. I
can't save my favorite object stores and indexes to variables and then use
them freely within transactions, which is something I expect most users will
want want to do.

Having a cute shortcut to cut down on one async call per transaction might
be a good idea.  But forcing me to call .objectStore() (and possibly
.index() or others) for the first operation of every transaction seems
sub-optimal.  I can double check with some real web developers around
Google, but I'm pretty sure they'll much rather make an asynchronous call to
start a transaction to get back execution within an IDBTransactionEvent
context rather than having to do repeated objectStore() and .index() calls
to start every single transaction.

And the more I think about this, the more I'm skeptical that any sort
of synchronous transaction starting code is worth the complicated semantics.
 I mean, in reality, it saves very little code.  And although it makes
sample code a bit prettier to look at (I believe this was one of the
original selling points), I think it's going to confuse developers more than
it'll help them--in the long run.

J


Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Shawn Wilsher

 On 8/4/2010 10:53 AM, Jeremy Orlow wrote:



Whoatransaction() is synchronous?!?  Ok, so I guess the entire premise
of my question was super confused.  :-)

It is certainly spec'd that way [1].  The locks do not get acquired 
until the first actual bit of work is done though.


Cheers,

Shawn

[1] 
http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#database-interface




smime.p7s
Description: S/MIME Cryptographic Signature


Re: [IndexedDB] Implicit transactions

2010-08-04 Thread Mikeal Rogers
For what it's worth I haven't found using it this way to be that hard or
confusing but that could be because I'm a little more aware of the
underlying implications when opening object stores.

-Mikeal

On Wed, Aug 4, 2010 at 11:47 AM, Shawn Wilsher sdwi...@mozilla.com wrote:

  On 8/4/2010 10:53 AM, Jeremy Orlow wrote:



 Whoatransaction() is synchronous?!?  Ok, so I guess the entire premise
 of my question was super confused.  :-)

  It is certainly spec'd that way [1].  The locks do not get acquired until
 the first actual bit of work is done though.

 Cheers,

 Shawn

 [1]
 http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#database-interface