Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added Indexed Database API (http://www.w3.org/TR/IndexedDB). #319

Merged
merged 8 commits into from

2 participants

aschoenebeck Nikhil Kothari
aschoenebeck

Only asynchronous database API implemented. But this should be the default anyway. Issue was #316.

aschoenebeck aschoenebeck referenced this pull request
Closed

IndexedDB Support #316

Nikhil Kothari
Owner

Couple of quick comments on an initial quick pass over the diff, but first thanks ... it will be great to have coverage for this part of the HTML5 scenarios and APIs.

  • The I in front of every class name is a bit confusing for c# developers, who are probably more used to seeing that used for interfaces. Could we just use IndexedDB as the the prefix instead for these types?

  • The IDBEvent class should probably be IndexedDBEventArgs and derive from EventArgs. And to go hand-in-hand, the ???Delegate types should probably be ???EventHandler types. Its uncommon to see Delegate in the actual names of delegate types.

  • Does IndexedDB support addEventListener/removeEventListener style of event registration rather than setting properties like OnAbort? Haven't tried or looked into the spec. However, if it did, that would allow events to be mapped as actual events in c# and have the compiler generate script to add/removeEventListener pattern.

  • Alternatively, if these are conceptually better thought of as callbacks, then the delegate types would be better named ???Callback and the IDBEvent types as some sort of notification/message types.

aschoenebeck

Hi nikhil,

  • The IDB prefix is for IndexedDB. All classes and are officially named like that in the spec.
  • I will change IDBEvent to IDBEventArgs and derive from EventArgs. I will see about EventHandler types for callbacks.
  • IndexedDB object do support the addEventListener/removeEventListener style e.g. interface IDBRequest : EventTarget { ... }. Can you show me an example how to implement this pattern on IDB classes?
  • Naming these ...Callback is fine as an alternative.
Nikhil Kothari
Owner

So most of the HTML specs are actually defining interfaces, and seems reasonable they have an "I" prefix. I think that fact + combined with the desire to make the model not completely out of place in the c# world, I think we should honor those naming patterns.

See this for an example of using [ScriptEvent] to customize events. https://github.com/nikhilk/scriptsharp/blob/cc/src/Libraries/Node/Node.Core/IO/WritableStream.cs

So we'd have IndexedDBEventArgs, and types such as IndexedDBEventHandler where TEventArgs is a type derived from IndexedDBEventArgs.

aschoenebeck

The javascript spec IDL "interfaces" are class interfaces and not interfaces in the c# sense. The "I" in IDB comes from IndexedDB, which is unfortunate, but well...

I've used the [ScriptEvent] for all callbacks and renamed the delegates to ...callback.

I'll keep IDBEvent and not use EventArgs and EventHandler<>. IndexedDB callbacks are not providing the sender object in callbacks so EventHandler<> is wrong.

aschoenebeck aschoenebeck reopened this
aschoenebeck added some commits
aschoenebeck aschoenebeck Revert "Using event registration for IndexedDB API callbacks"
This reverts commit c70faaf0a4003c0dd620e0b9b50347cfb6b17571.
5364bf0
aschoenebeck aschoenebeck Reimplemented event registration for IndexedDB API callbacks
The IndexedDB API specifies two methods for event registration on its
interfaces. Direct callback funtions and the EventTarget scheme.

To make the interface as standards conformant as possible, I derive
classes providing callbacks from IDBEventTarget base class (proviedes
add-/removeEventListener) and provide fields for direct callback
functions.
c9f43f6
aschoenebeck

The IndexedDB API specifies two methods for event registration on its interfaces. Direct callback funtions and the EventTarget scheme.

To make the interface as standards conformant as possible, I now derive classes providing callbacks from IDBEventTarget base class (provides add-/removeEventListener) and provide fields for direct callback functions as before.

Now to register the handler you can do it both ways, just like the standard defines:

        IDBOpenDBRequest openrequest = Window.IndexedDB.Open(storagekey);
        openrequest.OnSuccess = delegate(IDBEvent<IDBRequest> e) {
            // Direct callback
        };
        openrequest.AddEventListener("success", delegate(IDBEvent<IDBRequest> e) {
            // EventTarget callback
        });
Nikhil Kothari
Owner

So, there is no reason really to propagate what you called "unfortunate". There are other precedents for writing imported APIs such that they work better or more naturally in the c# context. Seeing the code above makes me even more convinced the "I" prefix is misleading.

If you're really averse to putting "Indexed" as the prefix, I think we should move all of this to an "IndexedDB" subnamespace (Html.Data.IndexedDB), and have all the classes simply be DBOpenRequest, DBEvent etc. I think this will be generally good anyway, as we don't want a mix of WebSQL and IndexedDB APIs in the same namespace. I'll move the SQL ones into a subnamespace as well.

Some more comments.

Why do we need both OnSuccess and AddEventListener("success")? At the c# level, we should simply surface the event as an actual event member (assumption is there is no behavioral difference as far as the event handler is concerned), because its confusing which one to pick... the natural event syntax or the property assignment.

Thanks...

aschoenebeck

Now I have renamed the classes to DBRequest etc. and put them in their own namespace System.Html.Data.IndexedDB. Nice and clean.

Regarding the callbacks, I have at least one good use for the callback fields. There is a javascript IndexedDB shim I use for older browsers and that only supports simple callback fields.

aschoenebeck

So is this ready to merge or are there more things to discuss/change?

Nikhil Kothari
Owner

I think this is good. There are some things around coding style guidelines, but I'll take care of those so as to not prolong this any further. Hope to merge the pull request in next day or two.

Nikhil Kothari nikhilk merged commit b517c1b into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 16, 2013
  1. aschoenebeck
Commits on Jan 17, 2013
  1. aschoenebeck
  2. aschoenebeck
  3. aschoenebeck
  4. aschoenebeck
Commits on Jan 18, 2013
  1. aschoenebeck

    Revert "Using event registration for IndexedDB API callbacks"

    aschoenebeck authored
    This reverts commit c70faaf0a4003c0dd620e0b9b50347cfb6b17571.
  2. aschoenebeck

    Reimplemented event registration for IndexedDB API callbacks

    aschoenebeck authored
    The IndexedDB API specifies two methods for event registration on its
    interfaces. Direct callback funtions and the EventTarget scheme.
    
    To make the interface as standards conformant as possible, I derive
    classes providing callbacks from IDBEventTarget base class (proviedes
    add-/removeEventListener) and provide fields for direct callback
    functions.
Commits on Jan 19, 2013
  1. aschoenebeck
This page is out of date. Refresh to see the latest.
50 src/Libraries/Web/Html/Data/IndexedDB/DBCursor.cs
View
@@ -0,0 +1,50 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public class DBCursor {
+
+ protected DBCursor() {
+ }
+
+ [ScriptField]
+ public object Source {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public string Direction {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public object Key {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public object PrimaryKey {
+ get { return null; }
+ }
+
+ public DBRequest Update(object value) {
+ return null;
+ }
+
+ public void Advance(long count) {
+ }
+
+ public void Continue() {
+ }
+
+ public void Continue(object key) {
+ }
+
+ public DBRequest Delete(object value) {
+ return null;
+ }
+ }
+}
20 src/Libraries/Web/Html/Data/IndexedDB/DBCursorWithValue.cs
View
@@ -0,0 +1,20 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public class DBCursorWithValue : DBCursor {
+
+ private DBCursorWithValue() {
+ }
+
+ [ScriptField]
+ public object Value {
+ get {
+ return null;
+ }
+ }
+ }
+}
68 src/Libraries/Web/Html/Data/IndexedDB/DBDatabase.cs
View
@@ -0,0 +1,68 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public sealed class DBDatabase : DBEventTarget {
+
+ private DBDatabase() {
+ }
+
+ [ScriptField]
+ public string Name {
+ get { return default(string); }
+ }
+
+ [ScriptField]
+ public long Version {
+ get { return default(long); }
+ }
+
+ [ScriptField]
+ public string[] ObjectStoreNames {
+ get { return default(string[]); }
+ }
+
+ public DBObjectStore CreateObjectStore(string name) {
+ return default(DBObjectStore);
+ }
+
+ public DBObjectStore CreateObjectStore(string name, DBObjectStoreParameters optionalParameters) {
+ return default(DBObjectStore);
+ }
+
+ public void DeleteObjectStore(string name) {
+ }
+
+ public DBTransaction Transaction(string[] storenames) {
+ return default(DBTransaction);
+ }
+
+ public DBTransaction Transaction(string[] storenames, string mode) {
+ return default(DBTransaction);
+ }
+
+ public void Close() {
+ }
+
+ [ScriptName("onabort")]
+ public DBDatabaseCallback OnAbort;
+
+ [ScriptName("onerror")]
+ public DBDatabaseCallback OnError;
+
+ [ScriptName("onversionchange")]
+ public DBDatabaseVersionChangeCallback OnVersionChange;
+ }
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public delegate void DBDatabaseCallback(DBEvent<DBDatabase> e);
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public delegate void DBDatabaseVersionChangeCallback(DBVersionChangeEvent<DBDatabase> e);
+
+}
36 src/Libraries/Web/Html/Data/IndexedDB/DBEvent.cs
View
@@ -0,0 +1,36 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public class DBEvent<T> {
+
+ [ScriptField]
+ public string Type {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public T Target {
+ get { return default(T); }
+ }
+ }
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public class DBVersionChangeEvent<T> : DBEvent<T> {
+
+ [ScriptField]
+ public long OldVersion {
+ get { return default(long); }
+ }
+
+ [ScriptField]
+ public long NewVersion {
+ get { return default(long); }
+ }
+ }
+
+}
26 src/Libraries/Web/Html/Data/IndexedDB/DBEventTarget.cs
View
@@ -0,0 +1,26 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public class DBEventTarget {
+
+ public void AddEventListener<T>(string type, Action<T> listener) {
+ }
+
+ public void AddEventListener<T>(string type, Action<T> listener, bool useCapture) {
+ }
+
+ public void RemoveEventListener<T>(string type, Action<T> listener) {
+ }
+
+ public void RemoveEventListener<T>(string type, Action<T> listener, bool useCapture) {
+ }
+
+ public bool DispatchEvent<T>(DBEvent<T> e) {
+ return false;
+ }
+ }
+}
29 src/Libraries/Web/Html/Data/IndexedDB/DBFactory.cs
View
@@ -0,0 +1,29 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public sealed class DBFactory {
+
+ private DBFactory() {
+ }
+
+ public DBOpenDBRequest Open(string name) {
+ return null;
+ }
+
+ public DBOpenDBRequest Open(string name, long version) {
+ return null;
+ }
+
+ public DBOpenDBRequest DeleteDatabase(string name) {
+ return null;
+ }
+
+ public short Cmp(object first, object last) {
+ return default(short);
+ }
+ }
+}
78 src/Libraries/Web/Html/Data/IndexedDB/DBIndex.cs
View
@@ -0,0 +1,78 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public sealed class DBIndex {
+
+ private DBIndex() {
+ }
+
+ [ScriptField]
+ public string Name {
+ get { return default(string); }
+ }
+
+ [ScriptField]
+ public DBObjectStore ObjectStore {
+ get { return default(DBObjectStore); }
+ }
+
+ [ScriptField]
+ public string KeyPath {
+ get { return default(string); }
+ }
+
+ [ScriptField]
+ public bool MultiEntry {
+ get { return default(bool); }
+ }
+
+ [ScriptField]
+ public bool Unique {
+ get { return default(bool); }
+ }
+
+ public DBRequest OpenCursor() {
+ return null;
+ }
+
+ public DBRequest OpenCursor(object range) {
+ return null;
+ }
+
+ public DBRequest OpenCursor(object range, string direction) {
+ return null;
+ }
+
+ public DBRequest OpenKeyCursor() {
+ return null;
+ }
+
+ public DBRequest OpenKeyCursor(object range) {
+ return null;
+ }
+
+ public DBRequest OpenKeyCursor(object range, string direction) {
+ return null;
+ }
+
+ public DBRequest Get(object key) {
+ return null;
+ }
+
+ public DBRequest GetKey(object key) {
+ return null;
+ }
+
+ public DBRequest Count() {
+ return null;
+ }
+
+ public DBRequest Count(object key) {
+ return null;
+ }
+ }
+}
29 src/Libraries/Web/Html/Data/IndexedDB/DBIndexParameters.cs
View
@@ -0,0 +1,29 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ [ScriptName("Object")]
+ public sealed class DBIndexParameters {
+
+ [ScriptField]
+ public bool Unique {
+ get {
+ return false;
+ }
+ set {
+ }
+ }
+
+ [ScriptField]
+ public bool MultiEntry {
+ get {
+ return false;
+ }
+ set {
+ }
+ }
+ }
+}
101 src/Libraries/Web/Html/Data/IndexedDB/DBObjectStore.cs
View
@@ -0,0 +1,101 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public sealed class DBObjectStore {
+
+ private DBObjectStore() {
+ }
+
+ [ScriptField]
+ public string Name {
+ get { return default(string); }
+ }
+
+ [ScriptField]
+ public string KeyPath {
+ get { return default(string); }
+ }
+
+ [ScriptField]
+ public string[] IndexNames {
+ get { return default(string[]); }
+ }
+
+ [ScriptField]
+ public DBTransaction Transaction {
+ get { return default(DBTransaction); }
+ }
+
+ [ScriptField]
+ public bool AutoIncremenent {
+ get { return default(bool); }
+ }
+
+ public DBRequest Put(object value) {
+ return null;
+ }
+
+ public DBRequest Put(object value, object key) {
+ return null;
+ }
+
+ public DBRequest Add(object value) {
+ return null;
+ }
+
+ public DBRequest Add(object value, object key) {
+ return null;
+ }
+
+ public DBRequest Delete(object key) {
+ return null;
+ }
+
+ public DBRequest Get(object key) {
+ return null;
+ }
+
+ public DBRequest Clear() {
+ return null;
+ }
+
+ public DBRequest OpenCursor() {
+ return null;
+ }
+
+ public DBRequest OpenCursor(object range) {
+ return null;
+ }
+
+ public DBRequest OpenCursor(object range, string direction) {
+ return null;
+ }
+
+ public DBIndex CreateIndex(string name, object keyPath) {
+ return default(DBIndex);
+ }
+
+ public DBIndex CreateIndex(string name, object keyPath, DBIndexParameters optionalParameters) {
+ return default(DBIndex);
+ }
+
+ public DBIndex Index(string name) {
+ return default(DBIndex);
+ }
+
+ public void DeleteIndex(string indexName) {
+ }
+
+ public DBRequest Count() {
+ return null;
+ }
+
+ public DBRequest Count(object key) {
+ return null;
+ }
+ }
+}
30 src/Libraries/Web/Html/Data/IndexedDB/DBObjectStoreParameters.cs
View
@@ -0,0 +1,30 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ [ScriptName("Object")]
+ public sealed class DBObjectStoreParameters {
+
+ [ScriptField]
+ public string KeyPath {
+ get {
+ return null;
+ }
+ set {
+ }
+ }
+
+ [ScriptField]
+ public bool AutoIncrement {
+ get {
+ return false;
+ }
+ set {
+ }
+ }
+ }
+}
+
27 src/Libraries/Web/Html/Data/IndexedDB/DBOpenDBRequest.cs
View
@@ -0,0 +1,27 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public class DBOpenDBRequest : DBRequest {
+
+ protected DBOpenDBRequest() {
+ }
+
+ [ScriptName("onblocked")]
+ public DBOpenDBRequestCallback OnBlocked;
+
+ [ScriptName("onupgradeneeded")]
+ public DBOpenDBRequestVersionChangeCallback OnUpgradeNeeded;
+ }
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public delegate void DBOpenDBRequestCallback(DBEvent<DBOpenDBRequest> e);
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public delegate void DBOpenDBRequestVersionChangeCallback(DBVersionChangeEvent<DBOpenDBRequest> e);
+}
49 src/Libraries/Web/Html/Data/IndexedDB/DBRequest.cs
View
@@ -0,0 +1,49 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public class DBRequest : DBEventTarget {
+
+ protected DBRequest() {
+ }
+
+ [ScriptField]
+ public object Result {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public object Error {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public object Source {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public DBTransaction Transaction {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public string ReadyState {
+ get { return null; }
+ }
+
+ [ScriptName("onsuccess")]
+ public DBRequestCallback OnSuccess;
+
+ [ScriptName("onerror")]
+ public DBRequestCallback OnError;
+ }
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public delegate void DBRequestCallback(DBEvent<DBRequest> e);
+
+}
50 src/Libraries/Web/Html/Data/IndexedDB/DBTransaction.cs
View
@@ -0,0 +1,50 @@
+using System;
+using System.Runtime.CompilerServices;
+
+namespace System.Html.Data.IndexedDB {
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public sealed class DBTransaction : DBEventTarget {
+
+ private DBTransaction() {
+ }
+
+ [ScriptField]
+ public string Mode {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public DBDatabase Db {
+ get { return null; }
+ }
+
+ [ScriptField]
+ public object Error {
+ get { return null; }
+ }
+
+ public DBObjectStore ObjectStore(string name) {
+ return null;
+ }
+
+ public void Abort() {
+ }
+
+ [ScriptName("onabort")]
+ public DBTransactionCallback OnAbort;
+
+ [ScriptName("oncomplete")]
+ public DBTransactionCallback OnComplete;
+
+ [ScriptName("onerror")]
+ public DBTransactionCallback OnError;
+
+ }
+
+ [ScriptIgnoreNamespace]
+ [ScriptImport]
+ public delegate void DBTransactionCallback(DBEvent<DBTransaction> e);
+
+}
9 src/Libraries/Web/Html/Window.cs
View
@@ -5,6 +5,7 @@
using System;
using System.Html.Data;
+using System.Html.Data.IndexedDB;
using System.Runtime.CompilerServices;
namespace System.Html {
@@ -410,6 +411,14 @@ public sealed class Window {
return null;
}
+ [ScriptField]
+ public static DBFactory IndexedDB {
+ get {
+ return null;
+ }
+ }
+
+
public static void PostMessage(string message, string targetOrigin) {
}
13 src/Libraries/Web/Web.csproj
View
@@ -48,6 +48,19 @@
<Compile Include="Html\CheckBoxElement.cs" />
<Compile Include="Html\CanvasElement.cs" />
<Compile Include="Html\ClientRectList.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBCursor.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBCursorWithValue.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBDatabase.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBEvent.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBEventTarget.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBIndex.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBIndexParameters.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBObjectStore.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBObjectStoreParameters.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBOpenDBRequest.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBRequest.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBFactory.cs" />
+ <Compile Include="Html\Data\IndexedDB\DBTransaction.cs" />
<Compile Include="Html\ElementEventListener.cs" />
<Compile Include="Html\GestureEvent.cs" />
<Compile Include="Html\CustomEvent.cs" />
Something went wrong with that request. Please try again.