[Exposed=(Window,Worker)]
interface IDBRequest : EventTarget {
  readonly attribute any                                        result;
  readonly attribute DOMException?                              error;
  readonly attribute (IDBObjectStore or IDBIndex or IDBCursor)? source;
  readonly attribute IDBTransaction?                            transaction;
  readonly attribute IDBRequestReadyState                       readyState;

  // Event handlers:
  attribute EventHandler onsuccess;
  attribute EventHandler onerror;
};

enum IDBRequestReadyState {
  "pending",
  "done"
};

[Exposed=(Window,Worker)]
interface IDBOpenDBRequest : IDBRequest {
  // Event handlers:
  attribute EventHandler onblocked;
  attribute EventHandler onupgradeneeded;
};

[Exposed=(Window,Worker),
 Constructor(DOMString type, optional IDBVersionChangeEventInit eventInitDict)]
interface IDBVersionChangeEvent : Event {
  readonly attribute unsigned long long  oldVersion;
  readonly attribute unsigned long long? newVersion;
};

dictionary IDBVersionChangeEventInit : EventInit {
  unsigned long long  oldVersion = 0;
  unsigned long long? newVersion = null;
};

partial interface WindowOrWorkerGlobalScope {
  [SameObject] readonly attribute IDBFactory indexedDB;
};

[Exposed=(Window,Worker)]
interface IDBFactory {
  IDBOpenDBRequest open(DOMString name,
                        [EnforceRange] optional unsigned long long version);
  IDBOpenDBRequest deleteDatabase(DOMString name);

  short cmp(any first, any second);
};

[Exposed=(Window,Worker)]
interface IDBDatabase : EventTarget {
  readonly attribute DOMString          name;
  readonly attribute unsigned long long version;
  readonly attribute DOMStringList      objectStoreNames;

  IDBTransaction transaction((DOMString or sequence<DOMString>) storeNames,
                             optional IDBTransactionMode mode = "readonly");
  void           close();

  IDBObjectStore createObjectStore(DOMString name,
                                   optional IDBObjectStoreParameters options);
  void           deleteObjectStore(DOMString name);

  // Event handlers:
  attribute EventHandler onabort;
  attribute EventHandler onclose;
  attribute EventHandler onerror;
  attribute EventHandler onversionchange;
};

dictionary IDBObjectStoreParameters {
  (DOMString or sequence<DOMString>)? keyPath = null;
  boolean                             autoIncrement = false;
};

[Exposed=(Window,Worker)]
interface IDBObjectStore {
           attribute DOMString      name;
  readonly attribute any            keyPath;
  readonly attribute DOMStringList  indexNames;
  readonly attribute IDBTransaction transaction;
  readonly attribute boolean        autoIncrement;

  IDBRequest put(any value, optional any key);
  IDBRequest add(any value, optional any key);
  IDBRequest delete(any query);
  IDBRequest clear();
  IDBRequest get(any query);
  IDBRequest getKey(any query);
  IDBRequest getAll(optional any query,
                    [EnforceRange] optional unsigned long count);
  IDBRequest getAllKeys(optional any query,
                        [EnforceRange] optional unsigned long count);
  IDBRequest count(optional any query);

  IDBRequest openCursor(optional any query,
                        optional IDBCursorDirection direction = "next");
  IDBRequest openKeyCursor(optional any query,
                           optional IDBCursorDirection direction = "next");

  IDBIndex   index(DOMString name);

  IDBIndex   createIndex(DOMString name,
                         (DOMString or sequence<DOMString>) keyPath,
                         optional IDBIndexParameters options);
  void       deleteIndex(DOMString indexName);
};

dictionary IDBIndexParameters {
  boolean unique = false;
  boolean multiEntry = false;
};

[Exposed=(Window,Worker)]
interface IDBIndex {
           attribute DOMString      name;
  readonly attribute IDBObjectStore objectStore;
  readonly attribute any            keyPath;
  readonly attribute boolean        multiEntry;
  readonly attribute boolean        unique;

  IDBRequest get(any query);
  IDBRequest getKey(any query);
  IDBRequest getAll(optional any query,
                    [EnforceRange] optional unsigned long count);
  IDBRequest getAllKeys(optional any query,
                        [EnforceRange] optional unsigned long count);
  IDBRequest count(optional any query);

  IDBRequest openCursor(optional any query,
                        optional IDBCursorDirection direction = "next");
  IDBRequest openKeyCursor(optional any query,
                           optional IDBCursorDirection direction = "next");
};

[Exposed=(Window,Worker)]
interface IDBKeyRange {
  readonly attribute any     lower;
  readonly attribute any     upper;
  readonly attribute boolean lowerOpen;
  readonly attribute boolean upperOpen;

  // Static construction methods:
  static IDBKeyRange only(any value);
  static IDBKeyRange lowerBound(any lower, optional boolean open = false);
  static IDBKeyRange upperBound(any upper, optional boolean open = false);
  static IDBKeyRange bound(any lower,
                           any upper,
                           optional boolean lowerOpen = false,
                           optional boolean upperOpen = false);

  boolean includes(any key);
};

[Exposed=(Window,Worker)]
interface IDBCursor {
  readonly attribute (IDBObjectStore or IDBIndex) source;
  readonly attribute IDBCursorDirection           direction;
  readonly attribute any                          key;
  readonly attribute any                          primaryKey;

  void advance([EnforceRange] unsigned long count);
  void continue(optional any key);
  void continuePrimaryKey(any key, any primaryKey);

  IDBRequest update(any value);
  IDBRequest delete();
};

enum IDBCursorDirection {
  "next",
  "nextunique",
  "prev",
  "prevunique"
};

[Exposed=(Window,Worker)]
interface IDBCursorWithValue : IDBCursor {
  readonly attribute any value;
};

[Exposed=(Window,Worker)]
interface IDBTransaction : EventTarget {
  readonly attribute DOMStringList      objectStoreNames;
  readonly attribute IDBTransactionMode mode;
  readonly attribute IDBDatabase        db;
  readonly attribute DOMException       error;

  IDBObjectStore objectStore(DOMString name);
  void           abort();

  // Event handlers:
  attribute EventHandler onabort;
  attribute EventHandler oncomplete;
  attribute EventHandler onerror;
};

enum IDBTransactionMode {
  "readonly",
  "readwrite",
  "versionchange"
};
