WIP
This commit is contained in:
parent
c80a08bb07
commit
14759635c0
|
@ -0,0 +1,163 @@
|
||||||
|
#indexedDBViewer {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
font-family: Courier;
|
||||||
|
font-size: 12px;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0px;
|
||||||
|
right: 0px;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 999999;
|
||||||
|
background-color: lightgray;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewer li {
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewer ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px 0px 0px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewer h1 {
|
||||||
|
padding: 0px 0px 5px 0px;
|
||||||
|
margin: 0px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerHeader {
|
||||||
|
height: 15px;
|
||||||
|
width: 100%;
|
||||||
|
cursor: row-resize;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerHeader span {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 13px;
|
||||||
|
width: 13px;
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: 0px;
|
||||||
|
border: 1px solid black;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerNavigation {
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
|
min-width: 200px;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 2px 2px 2px 2px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContent {
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
width: auto;
|
||||||
|
min-width: 400px;
|
||||||
|
vertical-align: top;
|
||||||
|
padding: 2px 2px 2px 12px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentObjectStoresTable {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentObjectStoresRowHeaderName {
|
||||||
|
width: auto;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentObjectStoresRowHeaderKeyPath {
|
||||||
|
width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentObjectStoresRowHeaderAutoIncrement {
|
||||||
|
width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexTable {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderName {
|
||||||
|
width: auto;
|
||||||
|
min-width: 150px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderKeyPath {
|
||||||
|
width: auto;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderObjectStore {
|
||||||
|
width: auto;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderMultiEntry {
|
||||||
|
width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderUnique {
|
||||||
|
width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentObjectStoreRowHeaderKey {
|
||||||
|
width: auto;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentObjectStoreRowHeaderValue {
|
||||||
|
width: auto;
|
||||||
|
min-width: 400px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderKey {
|
||||||
|
width: auto;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderPrimaryKey {
|
||||||
|
width: auto;
|
||||||
|
min-width: 100px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentIndexRowHeaderValue {
|
||||||
|
width: auto;
|
||||||
|
min-width: 400px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewerContentObjectStoreTable td, #indexedDBViewerContentIndexTable td {
|
||||||
|
vertical-align: top;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#indexedDBViewer .clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
|
@ -0,0 +1,317 @@
|
||||||
|
/// <reference path="jquery-1.7.2.js" />
|
||||||
|
/// <reference path="Linq2IndexedDB.js" />
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
function initializeViewer() {
|
||||||
|
var placeholder = $("#indexedDBViewer");
|
||||||
|
var dbName = placeholder.attr("data-dbName");
|
||||||
|
createHeader('indexedDBViewerHeader', placeholder);
|
||||||
|
var navigation = retrieveOrCreateElement('indexedDBViewerNavigation', 'div', placeholder);
|
||||||
|
var menu = retrieveOrCreateElement('indexedDBViewerMenu', 'ul', navigation);
|
||||||
|
var menuOverview = expandableListItem('indexedDBViewerMenuOverview', dbName, menu, viewDb, { dbName: dbName, objectStore: null, index: null });
|
||||||
|
|
||||||
|
navigation.addClass('nav');
|
||||||
|
|
||||||
|
linq2indexedDB.prototype.core.db(dbName).then(function () {
|
||||||
|
var connection = arguments[0][0];
|
||||||
|
|
||||||
|
linq2indexedDB.prototype.core.dbStructureChanged.addListener(linq2indexedDB.prototype.core.databaseEvents.databaseBlocked, function () {
|
||||||
|
connection.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
var menuObjectStores = retrieveOrCreateElement('indexedDBViewerMenuObjectStores', 'ul', menuOverview);
|
||||||
|
|
||||||
|
for (var i = 0; i < connection.objectStoreNames.length; i++) {
|
||||||
|
var storeName = connection.objectStoreNames[i];
|
||||||
|
var menuObjectStore = expandableListItem('indexedDBViewerMenuObjectStore' + storeName, storeName, menuObjectStores, viewDb, { dbName: dbName, objectStore: storeName, index: null });
|
||||||
|
|
||||||
|
linq2indexedDB.prototype.core.objectStore(linq2indexedDB.prototype.core.transaction(connection, storeName, linq2indexedDB.prototype.core.transactionTypes.READ_ONLY, false), storeName).then(function (args) {
|
||||||
|
var store = args[1];
|
||||||
|
|
||||||
|
var menuObjectStore = retrieveOrCreateElement('indexedDBViewerMenuObjectStore' + storeName, 'li', menuObjectStores);
|
||||||
|
var menuIndexes = retrieveOrCreateElement('indexedDBViewerMenuObjectStore' + store.name + 'Indexes', 'ul', menuObjectStore);
|
||||||
|
|
||||||
|
for (var j = 0; j < store.indexNames.length; j++) {
|
||||||
|
var indexName = store.indexNames[i];
|
||||||
|
expandableListItem('indexedDBViewerMenuObjectStore' + store.name + 'Index' + indexName, indexName, menuIndexes, viewDb, { dbName: dbName, objectStore: store.name, index: indexName });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, null, function (args) {
|
||||||
|
if (args[1].type == "upgradeneeded") {
|
||||||
|
args[0].abort();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewDb(e) {
|
||||||
|
var dbName = e.data.dbName;
|
||||||
|
var objectStore = e.data.objectStore;
|
||||||
|
var index = e.data.index;
|
||||||
|
var content = retrieveOrCreateElement('indexedDBViewerContent', 'div', $("#indexedDBViewer"));
|
||||||
|
content.empty();
|
||||||
|
|
||||||
|
if (objectStore != null) {
|
||||||
|
if (index != null) {
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentGeneral', 'h1', content).text(index);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentGeneral', 'h1', content).text(objectStore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
linq2indexedDB.prototype.core.db(dbName).then(function () {
|
||||||
|
var connection = arguments[0][0];
|
||||||
|
|
||||||
|
if (objectStore == null) {
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentGeneral', 'h1', content).text("General");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentGeneralName', 'span', content).text("Name: " + connection.name);
|
||||||
|
content.append("<br/>");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentGeneralVersion', 'span', content).text("Version: " + connection.version);
|
||||||
|
content.append("<br/>");
|
||||||
|
content.append("<br/>");
|
||||||
|
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStores', 'h1', content).text("Object stores");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoresTable', 'table', content);
|
||||||
|
content.append("<br/>");
|
||||||
|
content.append("<br/>");
|
||||||
|
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndex', 'h1', content).text("Indexes");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexTable', 'table', content);
|
||||||
|
content.append("<br/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
linq2indexedDB.prototype.core.dbStructureChanged.addListener(linq2indexedDB.prototype.core.databaseEvents.databaseBlocked, function () {
|
||||||
|
connection.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (var i = 0; i < connection.objectStoreNames.length; i++) {
|
||||||
|
var storeName = connection.objectStoreNames[i];
|
||||||
|
linq2indexedDB.prototype.core.objectStore(linq2indexedDB.prototype.core.transaction(connection, storeName, linq2indexedDB.prototype.core.transactionTypes.READ_ONLY, false), storeName).then(function (args) {
|
||||||
|
var store = args[1];
|
||||||
|
if (objectStore == null) {
|
||||||
|
viewObjectStoreDefinition(store.name, store.keyPath, store.autoIncrement, content);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (index == null && store.name == objectStore) {
|
||||||
|
linq2indexedDB.prototype.core.cursor(store).then(function () {
|
||||||
|
|
||||||
|
}, function () {
|
||||||
|
}, function (args1) {
|
||||||
|
var keyValue = args1[0];
|
||||||
|
viewObjectStoreData(keyValue.key, keyValue.data, content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var j = 0; j < store.indexNames.length; j++) {
|
||||||
|
linq2indexedDB.prototype.core.index(store, store.indexNames[j], false).then(function (args1) {
|
||||||
|
var ix = args1[1];
|
||||||
|
if (objectStore == null) {
|
||||||
|
viewIndexDefinition(ix.name, ix.keyPath, ix.objectStore.name, ix.multiEntry || ix.multiRow, ix.unique, content);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (index != null && ix.name == index) {
|
||||||
|
linq2indexedDB.prototype.core.cursor(ix).then(function () {
|
||||||
|
var x = 1;
|
||||||
|
}, function () {
|
||||||
|
}, function (args1) {
|
||||||
|
var keyValue = args1[0];
|
||||||
|
viewIndexData(args1[1].key, args1[1].primaryKey, keyValue.data, content);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewObjectStoreDefinition(name, keyPath, autoIncrement, parent) {
|
||||||
|
var table = retrieveOrCreateElement('indexedDBViewerContentObjectStoresTable', 'table', parent);
|
||||||
|
var headerRow = retrieveOrCreateElement('indexedDBViewerContentObjectStoresRowHeader', 'tr', table);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoresRowHeaderName', 'th', headerRow).text("name");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoresRowHeaderKeyPath', 'th', headerRow).text("keyPath");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoresRowHeaderAutoIncrement', 'th', headerRow).text("autoIncrement");
|
||||||
|
|
||||||
|
|
||||||
|
var dataRow = retrieveOrCreateElement('indexedDBViewerContentObjectStoresRow' + name, 'tr', table);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoresRow' + name + 'Name', 'td', dataRow).text(name);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoresRow' + name + 'KeyPath', 'td', dataRow).text(keyPath);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoresRow' + name + 'AutoIncrement', 'td', dataRow).text(autoIncrement);
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewIndexDefinition(name, keyPath, objectStore, multiEntry, unique, parent) {
|
||||||
|
var table = retrieveOrCreateElement('indexedDBViewerContentIndexTable', 'table', parent);
|
||||||
|
var headerRow = retrieveOrCreateElement('indexedDBViewerContentIndexRowHeader', 'tr', table);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderName', 'th', headerRow).text("name");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderKeyPath', 'th', headerRow).text("keyPath");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderObjectStore', 'th', headerRow).text("objectStore");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderMultiEntry', 'th', headerRow).text("multiEntry");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderUnique', 'th', headerRow).text("unique");
|
||||||
|
|
||||||
|
|
||||||
|
var dataRow = retrieveOrCreateElement('indexedDBViewerContentIndexRow' + name, 'tr', table);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRow' + name + 'Name', 'td', dataRow).text(name);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRow' + name + 'KeyPath', 'td', dataRow).text(keyPath);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRow' + name + 'ObjectStore', 'td', dataRow).text(objectStore);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRow' + name + 'MultiEntry', 'td', dataRow).text(multiEntry);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRow' + name + 'Unique', 'td', dataRow).text(unique);
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewObjectStoreData(key, value, parent) {
|
||||||
|
var table = retrieveOrCreateElement('indexedDBViewerContentObjectStoreTable', 'table', parent);
|
||||||
|
var headerRow = retrieveOrCreateElement('indexedDBViewerContentObjectStoreRowHeader', 'tr', table);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoreRowHeaderKey', 'th', headerRow).text("key");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentObjectStoreRowHeaderValue', 'th', headerRow).text("value");
|
||||||
|
|
||||||
|
|
||||||
|
var dataRow = retrieveOrCreateElement('indexedDBViewerContentObjectStoreRow' + key, 'tr', table);
|
||||||
|
viewData(key, retrieveOrCreateElement('indexedDBViewerContentObjectStoreRow' + key + 'Key', 'td', dataRow));
|
||||||
|
viewData(value, retrieveOrCreateElement('indexedDBViewerContentObjectStoreRow' + key + 'Value', 'td', dataRow));
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewIndexData(key, primaryKey, value, parent) {
|
||||||
|
var table = retrieveOrCreateElement('indexedDBViewerContentIndexTable', 'table', parent);
|
||||||
|
var headerRow = retrieveOrCreateElement('indexedDBViewerContentIndexRowHeader', 'tr', table);
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderKey', 'th', headerRow).text("key");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderPrimaryKey', 'th', headerRow).text("primary key");
|
||||||
|
retrieveOrCreateElement('indexedDBViewerContentIndexRowHeaderValue', 'th', headerRow).text("value");
|
||||||
|
|
||||||
|
|
||||||
|
var dataRow = retrieveOrCreateElement('indexedDBViewerContentIndexRow' + primaryKey, 'tr', table);
|
||||||
|
viewData(key, retrieveOrCreateElement('indexedDBViewerContentIndexRow' + primaryKey + 'Key', 'td', dataRow));
|
||||||
|
viewData(primaryKey, retrieveOrCreateElement('indexedDBViewerContentIndexRow' + primaryKey + 'PrimaryKey', 'td', dataRow));
|
||||||
|
viewData(value, retrieveOrCreateElement('indexedDBViewerContentIndexRow' + primaryKey + 'Value', 'td', dataRow));
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewData(value, parent, propName) {
|
||||||
|
var text;
|
||||||
|
|
||||||
|
if (propName) {
|
||||||
|
text = propName + value;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parent = retrieveOrCreateElement(null, 'ul', parent);
|
||||||
|
text = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof (value) === "object" && !(value instanceof Date)) {
|
||||||
|
var object = expandableListItem(null, text, parent);
|
||||||
|
var properties = retrieveOrCreateElement(null, 'ul', object);
|
||||||
|
for (prop in value) {
|
||||||
|
viewData(value[prop], properties, prop + ": ");
|
||||||
|
}
|
||||||
|
object.find('.expendable')[0].click();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
retrieveOrCreateElement(null, 'li', parent).text(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function expandableListItem(id, text, parent, clickEvent, clickEventData) {
|
||||||
|
var li = retrieveOrCreateElement(id, 'li', parent);
|
||||||
|
var col = retrieveOrCreateElement(null, 'span', li);
|
||||||
|
col.text(' - ');
|
||||||
|
col.data('status', 'open');
|
||||||
|
col.click(function () {
|
||||||
|
if ($(this).data('status') == 'closed') {
|
||||||
|
$($($(this)[0].parentElement).find('ul')[0]).show();
|
||||||
|
col.text(' - ');
|
||||||
|
col.data('status', 'open');
|
||||||
|
}
|
||||||
|
else if ($(this).data('status') == 'open') {
|
||||||
|
$($($(this)[0].parentElement).find('ul')[0]).hide();
|
||||||
|
col.text(' + ');
|
||||||
|
col.data('status', 'closed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
col.addClass("clickable");
|
||||||
|
col.addClass("expendable");
|
||||||
|
|
||||||
|
var item = retrieveOrCreateElement(null, 'span', li);
|
||||||
|
item.text(text);
|
||||||
|
|
||||||
|
if (clickEvent) {
|
||||||
|
item.click(clickEventData, clickEvent);
|
||||||
|
item.addClass("clickable");
|
||||||
|
}
|
||||||
|
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createHeader(id, parent) {
|
||||||
|
var header = retrieveOrCreateElement(id, 'div', parent);
|
||||||
|
var col = retrieveOrCreateElement(null, 'span', header);
|
||||||
|
col.text(' - ');
|
||||||
|
col.data('status', 'open');
|
||||||
|
col.addClass("clickable");
|
||||||
|
col.addClass("expendable");
|
||||||
|
col.click(function () {
|
||||||
|
if ($(this).data('status') == 'closed') {
|
||||||
|
$('#indexedDBViewer').height(170);
|
||||||
|
$('#indexedDBViewer').width('100%');
|
||||||
|
$('#indexedDBViewerNavigation').show();
|
||||||
|
$('#indexedDBViewerContent').show();
|
||||||
|
col.text(' - ');
|
||||||
|
col.data('status', 'open');
|
||||||
|
}
|
||||||
|
else if ($(this).data('status') == 'open') {
|
||||||
|
$('#indexedDBViewer').height($(this).outerHeight());
|
||||||
|
$('#indexedDBViewer').width($(this).outerWidth());
|
||||||
|
$('#indexedDBViewerNavigation').hide();
|
||||||
|
$('#indexedDBViewerContent').hide();
|
||||||
|
col.text(' + ');
|
||||||
|
col.data('status', 'closed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function retrieveOrCreateElement(id, element, parent) {
|
||||||
|
var el;
|
||||||
|
|
||||||
|
if (id && id != null && id != '') {
|
||||||
|
if ($('#' + id).length > 0) {
|
||||||
|
el = $('#' + id);
|
||||||
|
} else {
|
||||||
|
el = $('<' + element + ' id="' + id + '"></' + element + '>');
|
||||||
|
parent.append(el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
el = $('<' + element + '></' + element + '>');
|
||||||
|
parent.append(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeViewer();
|
||||||
|
|
||||||
|
// mousedown, mousemove, mouseup and mouseleave for resizing the placeholder
|
||||||
|
$(window).bind('mousedown', function (event) {
|
||||||
|
var location = $(window).height() - $("#indexedDBViewer").height();
|
||||||
|
if ((location - 2) <= event.pageY && event.pageY <= (location + 5)) {
|
||||||
|
$(window).bind('mousemove', resize);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).bind('mouseup', function () {
|
||||||
|
$(window).unbind('mousemove', resize);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).bind('mouseleave', function () {
|
||||||
|
$(window).unbind('mousemove', resize);
|
||||||
|
});
|
||||||
|
|
||||||
|
function resize(event) {
|
||||||
|
var pageHeight = $(window).height();
|
||||||
|
if (pageHeight - event.pageY >= 50) {
|
||||||
|
$("#indexedDBViewer").height(pageHeight - event.pageY);
|
||||||
|
var height = $("#indexedDBViewer").height() - $("#indexedDBViewerHeader").height();
|
||||||
|
$("#indexedDBViewerNavigation").height(height);
|
||||||
|
$("#indexedDBViewerContent").height(height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="stdout"></div>
|
||||||
|
</body>
|
||||||
|
<script src="../lib/crypto-js/rollups/sha256.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
console.log(CryptoJS.SHA256('/').toString(CryptoJS.enc.hex));
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</html>
|
|
@ -16,45 +16,70 @@ require.config({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
require(["src/indexeddb"], function(idb) {
|
require(["src/indexeddb2"], function(idb) {
|
||||||
|
|
||||||
var db;
|
var opened = idb.open('test').then(
|
||||||
idb.open('test').then(
|
|
||||||
function(event) {
|
function(event) {
|
||||||
db = event.target.result;
|
return event.db;
|
||||||
var transaction = db.transaction(['FILES'], 'readwrite');
|
|
||||||
var files = transaction.objectStore('FILES');
|
|
||||||
return files.clear();
|
|
||||||
},
|
},
|
||||||
function(event) {
|
function(event) {
|
||||||
console.error('error:', event);
|
console.error('error:', event);
|
||||||
},
|
},
|
||||||
function(event) {
|
function(event) {
|
||||||
db = event.target.result;
|
if('upgradeneeded' == event.type) {
|
||||||
if(db.objectStoreNames().contains('FILES')) {
|
db = event.target.result;
|
||||||
db.deleteObjectStore('FILES');
|
if(db.objectStoreNames.contains('FILES')) {
|
||||||
|
db.deleteObjectStore('FILES');
|
||||||
|
}
|
||||||
|
var files = db.createObjectStore('FILES');
|
||||||
}
|
}
|
||||||
var files = db.createObjectStore('FILES');
|
|
||||||
}
|
}
|
||||||
).then(
|
);
|
||||||
|
|
||||||
|
opened.then(
|
||||||
|
function(db) {
|
||||||
|
console.log(db);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
var db = idb.open('test');
|
||||||
|
db.progress(
|
||||||
function(event) {
|
function(event) {
|
||||||
var transaction = db.transaction(['FILES'], 'readwrite');
|
if('upgradeneeded' == event.type) {
|
||||||
|
db = event.target.result;
|
||||||
|
if(db.objectStoreNames.contains('FILES')) {
|
||||||
|
db.deleteObjectStore('FILES');
|
||||||
|
}
|
||||||
|
var files = db.createObjectStore('FILES');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
db.otherwise(
|
||||||
|
function(event) {
|
||||||
|
console.error('error:', event);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
db.transaction(['FILES'], 'readwrite')(
|
||||||
|
function(transaction) {
|
||||||
var files = transaction.objectStore('FILES');
|
var files = transaction.objectStore('FILES');
|
||||||
return files.put('value', 'key');
|
return files.clear();
|
||||||
}
|
}
|
||||||
).then(
|
).transaction(['FILES'], 'readonly')(
|
||||||
function(event) {
|
function(transaction) {
|
||||||
var transaction = db.transaction(['FILES'], 'readwrite');
|
|
||||||
var files = transaction.objectStore('FILES');
|
|
||||||
return files.get('key');
|
|
||||||
}
|
}
|
||||||
).then(
|
);
|
||||||
function(event) {
|
|
||||||
console.info('result', event.target.result);
|
db.transaction(['FILES'], 'readwrite')(
|
||||||
|
function(transaction) {
|
||||||
|
|
||||||
}
|
}
|
||||||
).otherwise(function(event) {
|
);
|
||||||
console.error('error: ', event);
|
|
||||||
});
|
*/
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="stdout"></div>
|
||||||
|
</body>
|
||||||
|
<script src="../lib/require.js"></script>
|
||||||
|
<script>
|
||||||
|
require.config({
|
||||||
|
baseUrl: "../lib",
|
||||||
|
paths: {
|
||||||
|
"src": "../src"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
require(["src/fs2"], function(IDBFS) {
|
||||||
|
|
||||||
|
var flags = 'FORMAT';
|
||||||
|
//var flags = undefined;
|
||||||
|
|
||||||
|
var fs = new IDBFS.FileSystem('test', flags);
|
||||||
|
fs.promise.otherwise(
|
||||||
|
function(error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
function make_tmp_directory() {
|
||||||
|
return fs.mkdir('/tmp');
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.promise.then(make_tmp_directory);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</html>
|
|
@ -1,12 +1,29 @@
|
||||||
var fs = new FileSystem('packages');
|
var write_buffer = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||||
|
var read_buffer = new Uint8Array(16);
|
||||||
|
|
||||||
|
var fs = new FileSystem('local');
|
||||||
|
|
||||||
|
fs.then(
|
||||||
|
function() {
|
||||||
|
return this.mkdir('/tmp');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
var fd = fs.open('/myfile.txt', fs.RW);
|
var fd = fs.open('/myfile.txt', fs.RW);
|
||||||
|
|
||||||
var buffer = new Uint8Array(16);
|
fd.then(
|
||||||
|
function() {
|
||||||
fd.write(buffer).then(function(nbytes) {
|
return this.write(write_buffer);
|
||||||
fd.seek(-nbytes);
|
}
|
||||||
return fd.read(buffer);
|
).then(
|
||||||
}).then(function(nbytes) {
|
function(nbytes) {
|
||||||
|
this.seek(-nbytes);
|
||||||
|
return this.read(read_buffer);
|
||||||
|
}
|
||||||
|
).then(
|
||||||
|
function(nbytes) {
|
||||||
|
console.log(read_buffer);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
});
|
});
|
|
@ -0,0 +1,14 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<link rel='stylesheet' href='IndexedDBViewer.css'></link>
|
||||||
|
</head>
|
||||||
|
<script src="jquery-1.10.0.min.js"></script>
|
||||||
|
<script src="Linq2IndexedDB.js"></script>
|
||||||
|
<script src="IndexedDBViewer.js"></script>
|
||||||
|
<body>
|
||||||
|
<div id="stdout"></div>
|
||||||
|
<div id="indexedDBViewer" data-dbName="test"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -746,13 +746,11 @@ define(function () {
|
||||||
// capture setTimeout to avoid being caught by fake timers used in time based tests
|
// capture setTimeout to avoid being caught by fake timers used in time based tests
|
||||||
setTimeout = global.setTimeout;
|
setTimeout = global.setTimeout;
|
||||||
// Prefer setImmediate, cascade to node, vertx and finally setTimeout
|
// Prefer setImmediate, cascade to node, vertx and finally setTimeout
|
||||||
/*
|
|
||||||
nextTick = typeof setImmediate === 'function' ? setImmediate.bind(global)
|
nextTick = typeof setImmediate === 'function' ? setImmediate.bind(global)
|
||||||
: typeof process === 'object' && process.nextTick ? process.nextTick
|
: typeof process === 'object' && process.nextTick ? process.nextTick
|
||||||
: typeof vertx === 'object' ? vertx.runOnLoop // vert.x
|
: typeof vertx === 'object' ? vertx.runOnLoop // vert.x
|
||||||
: function(task) { setTimeout(task, 0); }; // fallback
|
: function(task) { setTimeout(task, 0); }; // fallback
|
||||||
*/
|
// nextTick = function(task) { task.call(); };
|
||||||
nextTick = function(task) { task.call(); };
|
|
||||||
|
|
||||||
// Safe function calls
|
// Safe function calls
|
||||||
funcProto = Function.prototype;
|
funcProto = Function.prototype;
|
||||||
|
|
308
src/fs2.js
308
src/fs2.js
|
@ -1,10 +1,12 @@
|
||||||
define function(require) {
|
define(function(require) {
|
||||||
|
|
||||||
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||||
|
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var when = require('when');
|
var when = require('when');
|
||||||
var Path = require('src/path');
|
var Path = require('src/path');
|
||||||
|
var guid = require("src/guid");
|
||||||
|
require("crypto-js/rollups/sha256"); var Crypto = CryptoJS;
|
||||||
|
|
||||||
var METADATA_STORE_NAME = 'metadata';
|
var METADATA_STORE_NAME = 'metadata';
|
||||||
var FILE_STORE_NAME = 'files';
|
var FILE_STORE_NAME = 'files';
|
||||||
|
@ -12,46 +14,320 @@ define function(require) {
|
||||||
var IDB_RO = 'readonly';
|
var IDB_RO = 'readonly';
|
||||||
var IDB_RW = 'readwrite';
|
var IDB_RW = 'readwrite';
|
||||||
|
|
||||||
function Operation(fs, stores, mode) {
|
var MODE_FILE = 'FILE';
|
||||||
|
var MODE_DIRECTORY = 'DIRECTORY';
|
||||||
|
var MODE_SYMBOLIC_LINK = 'SYMLINK';
|
||||||
|
|
||||||
|
var BINARY_MIME_TYPE = 'application/octet-stream';
|
||||||
|
var JSON_MIME_TYPE = 'application/json';
|
||||||
|
|
||||||
|
var ROOT_DIRECTORY_NAME = '/'; // basename(normalize(path))
|
||||||
|
var ROOT_NODE_ID = '8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1'; // sha256(ROOT_DIRECTORY_NAME)
|
||||||
|
|
||||||
|
// FileSystem flags
|
||||||
|
var FS_FORMAT = 'FORMAT';
|
||||||
|
|
||||||
|
// FileSystem readyState
|
||||||
|
var FS_READY = 'READY';
|
||||||
|
var FS_PENDING = 'PENDING';
|
||||||
|
var FS_ERROR = 'ERROR';
|
||||||
|
|
||||||
|
function nop() {};
|
||||||
|
|
||||||
|
function hash(string) {
|
||||||
|
return Crypto.SHA256(string).toString(Crypto.enc.hex);
|
||||||
};
|
};
|
||||||
|
|
||||||
var FS_FORMAT = 'format';
|
function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, links, version) {
|
||||||
|
var now = Date.now();
|
||||||
|
|
||||||
|
this.id = id || hash(guid()),
|
||||||
|
this.mode = mode || MODE_FILE; // node type (file, directory, etc)
|
||||||
|
this.size = size || 0; // size (bytes for files, entries for directories)
|
||||||
|
this.atime = atime || now; // access time
|
||||||
|
this.ctime = ctime || now; // creation time
|
||||||
|
this.mtime = mtime || now; // modified time
|
||||||
|
this.flags = flags || ''; // file flags
|
||||||
|
this.xattrs = xattrs || {}; // extended attributes
|
||||||
|
this.links = links || 0; // links count
|
||||||
|
this.version = version || 0; // node version
|
||||||
|
this.data = hash(id) // id for data object
|
||||||
|
};
|
||||||
|
|
||||||
|
function DirectoryEntry(id, type) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type || MODE_FILE;
|
||||||
|
};
|
||||||
|
|
||||||
|
function read_object(objectStore, id, callback) {
|
||||||
|
var getRequest = objectStore.get(id);
|
||||||
|
getRequest.onsuccess = function onsuccess(event) {
|
||||||
|
var result = event.target.result;
|
||||||
|
callback(undefined, result);
|
||||||
|
};
|
||||||
|
getRequest.onerror = function onerror(error) {
|
||||||
|
callback(error);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
function write_object(objectStore, object, id, callback) {
|
||||||
|
var putRequest = objectStore.put(object, id);
|
||||||
|
putRequest.onsuccess = function onsuccess(event) {
|
||||||
|
var result = event.target.result;
|
||||||
|
callback(undefined, result);
|
||||||
|
};
|
||||||
|
putRequest.onerror = function onerror(error) {
|
||||||
|
callback(error);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// in: file or directory path
|
||||||
|
// out: node structure, or error
|
||||||
|
function find_node(objectStore, path, callback) {
|
||||||
|
path = Path.normalize(path);
|
||||||
|
var name = Path.basename(path);
|
||||||
|
|
||||||
|
if(ROOT_DIRECTORY_NAME == name) {
|
||||||
|
function check_root_directory_node(error, rootDirectoryNode) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else if(!rootDirectoryNode) {
|
||||||
|
callback(new Error('ENOENT'));
|
||||||
|
} else {
|
||||||
|
callback(undefined, rootDirectoryNode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
read_object(objectStore, ROOT_NODE_ID, check_root_directory_node);
|
||||||
|
} else {
|
||||||
|
// in: parent directory node
|
||||||
|
// out: parent directory data
|
||||||
|
function read_parent_directory_data(error, parentDirectoryNode) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else if(!_(parentDirectoryNode).has('data') || !parentDirectoryNode.type == MODE_DIRECTORY) {
|
||||||
|
callback(new Error('ENOTDIR'));
|
||||||
|
} else {
|
||||||
|
read_object(objectStore, parentDirectoryNode.data, get_node_id_from_parent_directory_data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// in: parent directory data
|
||||||
|
// out: searched node id
|
||||||
|
function get_node_id_from_parent_directory_data(error, parentDirectoryData) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
if(!_(parentDirectoryData).has(name)) {
|
||||||
|
callback(new Error('ENOENT'));
|
||||||
|
} else {
|
||||||
|
var nodeId = parentDirectoryData[name].id;
|
||||||
|
read_object(objectStore, nodeId, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var parentPath = Path.dirname(path);
|
||||||
|
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function make_root_directory(objectStore, callback) {
|
||||||
|
var directoryNode;
|
||||||
|
var directoryData;
|
||||||
|
|
||||||
|
function write_directory_node(error, existingNode) {
|
||||||
|
if(!error && existingNode) {
|
||||||
|
callback(new Error('EEXIST'));
|
||||||
|
} else if(error && 'ENOENT' != error.message) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
directoryNode = new Node(ROOT_NODE_ID, MODE_DIRECTORY);
|
||||||
|
directoryNode.links += 1;
|
||||||
|
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function write_directory_data(error) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
directoryData = {};
|
||||||
|
write_object(objectStore, directoryData, directoryNode.data, callback);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
find_node(objectStore, ROOT_DIRECTORY_NAME, write_directory_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_directory(objectStore, path, callback) {
|
||||||
|
path = Path.normalize(path);
|
||||||
|
var name = Path.basename(path);
|
||||||
|
var parentPath = Path.dirname(path);
|
||||||
|
|
||||||
|
var _directoryNode;
|
||||||
|
var _directoryData;
|
||||||
|
var _parentDirectoryNode;
|
||||||
|
var _parentDirectoryData;
|
||||||
|
|
||||||
|
function check_if_directory_exists(error, existingNode) {
|
||||||
|
if(!error && existingNode) {
|
||||||
|
callback(new Error('EEXIST'));
|
||||||
|
} else if(error && 'ENOENT' != error.message) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_parent_directory_data(error, parentDirectoryNode) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
_parentDirectoryNode = parentDirectoryNode;
|
||||||
|
read_object(objectStore, _parentDirectoryNode.data, write_directory_node);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function write_directory_node(error, parentDirectoryData) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
_parentDirectoryData = parentDirectoryData;
|
||||||
|
_directoryNode = new Node(undefined, MODE_DIRECTORY);
|
||||||
|
_directoryNode.links += 1;
|
||||||
|
write_object(objectStore, _directoryNode, _directoryNode.id, write_directory_data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function write_directory_data(error) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
_directoryData = {};
|
||||||
|
write_object(objectStore, _directoryData, _directoryNode.data, update_parent_directory_data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function update_parent_directory_data(error) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
_parentDirectoryData[name] = new DirectoryEntry(_directoryNode.id, MODE_DIRECTORY);
|
||||||
|
write_object(objectStore, _parentDirectoryData, _parentDirectoryNode.data, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
find_node(objectStore, path, check_if_directory_exists);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FileSystem
|
||||||
|
*/
|
||||||
|
|
||||||
function FileSystem(name, flags) {
|
function FileSystem(name, flags) {
|
||||||
var format = _(flags).contains(FS_FORMAT);
|
var format = _(flags).contains(FS_FORMAT);
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var deferred = when.defer();
|
||||||
|
this.promise = deferred.promise;
|
||||||
|
|
||||||
var openRequest = indexedDB.open(name);
|
var openRequest = indexedDB.open(name);
|
||||||
|
openRequest.onupgradeneeded = function onupgradeneeded(event) {
|
||||||
|
var db = event.target.result;
|
||||||
|
|
||||||
|
if(db.objectStoreNames.contains(FILE_STORE_NAME)) {
|
||||||
|
db.deleteObjectStore(FILE_STORE_NAME);
|
||||||
|
}
|
||||||
|
var files = db.createObjectStore(FILE_STORE_NAME);
|
||||||
|
|
||||||
|
if(db.objectStoreNames.contains(METADATA_STORE_NAME)) {
|
||||||
|
db.deleteObjectStore(METADATA_STORE_NAME);
|
||||||
|
}
|
||||||
|
var metadata = db.createObjectStore(METADATA_STORE_NAME);
|
||||||
|
|
||||||
|
format = true;
|
||||||
|
};
|
||||||
|
openRequest.onsuccess = function onsuccess(event) {
|
||||||
|
var db = event.target.result;
|
||||||
|
|
||||||
|
function complete(error) {
|
||||||
|
if(error) {
|
||||||
|
that.readyState = FS_ERROR;
|
||||||
|
deferred.reject(error);
|
||||||
|
} else {
|
||||||
|
that.readyState = FS_READY;
|
||||||
|
that.db = db;
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(format) {
|
||||||
|
var transaction = db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
|
||||||
|
var clearRequest = files.clear();
|
||||||
|
clearRequest.onsuccess = function onsuccess(event) {
|
||||||
|
make_root_directory(files, complete);
|
||||||
|
};
|
||||||
|
clearRequest.onerror = function onerror(error) {
|
||||||
|
complete(error);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
complete();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
openRequest.onerror = function onerror(error) {
|
||||||
|
this.readyState = FS_ERROR;
|
||||||
|
deferred.reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.readyState = FS_PENDING;
|
||||||
|
this.db = null;
|
||||||
};
|
};
|
||||||
FileSystem.prototype.open = function open(transaction, path, flags, mode) {
|
FileSystem.prototype.open = function open(path, flags, mode) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.opendir = function opendir(transaction, path) {
|
FileSystem.prototype.opendir = function opendir(path) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.mkdir = function mkdir(transaction, path) {
|
FileSystem.prototype.mkdir = function mkdir(path) {
|
||||||
|
var deferred = when.defer();
|
||||||
|
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
|
||||||
|
function check_result(error) {
|
||||||
|
if(error) {
|
||||||
|
deferred.reject(error);
|
||||||
|
} else {
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
make_directory(files, path, check_result);
|
||||||
|
return deferred.promise();
|
||||||
|
};
|
||||||
|
FileSystem.prototype.rmdir = function rmdir(path) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.rmdir = function rmdir(transaction, path) {
|
FileSystem.prototype.stat = function stat(path) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.stat = function stat(transaction, path) {
|
FileSystem.prototype.link = function link(oldpath, newpath) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.link = function link(transaction, oldpath, newpath) {
|
FileSystem.prototype.unlink = function unlink(path) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.unlink = function unlink(transaction, path) {
|
FileSystem.prototype.getxattr = function getxattr(path, name) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.getxattr = function getxattr(transaction, path, name) {
|
FileSystem.prototype.setxattr = function setxattr(path, name, value) {
|
||||||
|
|
||||||
};
|
|
||||||
FileSystem.prototype.setxattr = function setxattr(transaction, path, name, value) {
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
FileSystem: FileSystem
|
FileSystem: FileSystem,
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
});
|
116
src/indexeddb.js
116
src/indexeddb.js
|
@ -16,6 +16,74 @@ define(function(require) {
|
||||||
this.result = result || idbTarget.result;
|
this.result = result || idbTarget.result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cursor
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Cursor(idbCursor) {
|
||||||
|
this.idbCursor = idbCursor;
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'source', {
|
||||||
|
get: function() {
|
||||||
|
return idbCursor.source;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'direction', {
|
||||||
|
get: function() {
|
||||||
|
return idbCursor.direction;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'key', {
|
||||||
|
get: function() {
|
||||||
|
return idbCursor.key;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'primaryKey', {
|
||||||
|
get: function() {
|
||||||
|
return idbCursor.primaryKey;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Cursor.prototype.update = function update(value) {
|
||||||
|
var idbCursor = this.idbCursor;
|
||||||
|
var deferred = when.defer();
|
||||||
|
|
||||||
|
var request = idbCursor.update(value);
|
||||||
|
request.onsuccess = function(event) {
|
||||||
|
deferred.resolve(event);
|
||||||
|
};
|
||||||
|
request.onerror = function(event) {
|
||||||
|
deferred.reject(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
};
|
||||||
|
Cursor.prototype.advance = function advance(count) {
|
||||||
|
var idbCursor = this.idbCursor;
|
||||||
|
return idbCursor.advance(count);
|
||||||
|
};
|
||||||
|
Cursor.prototype.continue = function continue(key) {
|
||||||
|
var idbCursor = this.idbCursor;
|
||||||
|
return idbCursor.continue(key);
|
||||||
|
};
|
||||||
|
Cursor.prototype.delete = function delete() {
|
||||||
|
var idbCursor = this.idbCursor;
|
||||||
|
var deferred = when.defer();
|
||||||
|
|
||||||
|
var request = idbCursor.delete();
|
||||||
|
request.onsuccess = function(event) {
|
||||||
|
deferred.resolve(event);
|
||||||
|
};
|
||||||
|
request.onerror = function(event) {
|
||||||
|
deferred.reject(event);
|
||||||
|
};
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ObjectStore
|
* ObjectStore
|
||||||
*/
|
*/
|
||||||
|
@ -27,7 +95,7 @@ define(function(require) {
|
||||||
var idbObjectStore = this.idbObjectStore;
|
var idbObjectStore = this.idbObjectStore;
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
|
|
||||||
var request = idbObjectStore.add.call(idbObjectStore, value, key);
|
var request = idbObjectStore.add(value, key);
|
||||||
request.onsuccess = function(event) {
|
request.onsuccess = function(event) {
|
||||||
deferred.resolve(event);
|
deferred.resolve(event);
|
||||||
};
|
};
|
||||||
|
@ -67,7 +135,7 @@ define(function(require) {
|
||||||
};
|
};
|
||||||
ObjectStore.prototype.createIndex = function createIndex(name, keyPath, optionalParameters) {
|
ObjectStore.prototype.createIndex = function createIndex(name, keyPath, optionalParameters) {
|
||||||
var idbObjectStore = this.idbObjectStore;
|
var idbObjectStore = this.idbObjectStore;
|
||||||
return idbObjectStore.createIndex.call(idbObjectStore, name, keyPath, optionalParameters);
|
return idbObjectStore.createIndex(name, keyPath, optionalParameters);
|
||||||
};
|
};
|
||||||
ObjectStore.prototype.delete = function delete(key) {
|
ObjectStore.prototype.delete = function delete(key) {
|
||||||
var idbObjectStore = this.idbObjectStore;
|
var idbObjectStore = this.idbObjectStore;
|
||||||
|
@ -85,7 +153,7 @@ define(function(require) {
|
||||||
};
|
};
|
||||||
ObjectStore.prototype.deleteIndex = function deleteIndex(name) {
|
ObjectStore.prototype.deleteIndex = function deleteIndex(name) {
|
||||||
var idbObjectStore = this.idbObjectStore;
|
var idbObjectStore = this.idbObjectStore;
|
||||||
return idbObjectStore.deleteIndex.call(idbObjectStore, name);
|
return idbObjectStore.deleteIndex(name);
|
||||||
};
|
};
|
||||||
ObjectStore.prototype.get = function get(key) {
|
ObjectStore.prototype.get = function get(key) {
|
||||||
var idbObjectStore = this.idbObjectStore;
|
var idbObjectStore = this.idbObjectStore;
|
||||||
|
@ -109,9 +177,15 @@ define(function(require) {
|
||||||
var idbObjectStore = this.idbObjectStore;
|
var idbObjectStore = this.idbObjectStore;
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
|
|
||||||
var request = idbObjectStore.openCursor(range, direction);
|
var request = (!(range || direction)) ? idbObjectStore.openCursor() : idbObjectStore.openCursor(range, direction);
|
||||||
request.onsuccess = function(event) {
|
request.onsuccess = function(event) {
|
||||||
deferred.resolve(event);
|
var wrappedEvent = new Event(event);
|
||||||
|
wrappedEvent.result = event.result;
|
||||||
|
if(!event.result) {
|
||||||
|
deferred.resolve(wrappedEvent);
|
||||||
|
} else {
|
||||||
|
deferred.notify(wrappedEvent);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
request.onerror = function(event) {
|
request.onerror = function(event) {
|
||||||
deferred.reject(event);
|
deferred.reject(event);
|
||||||
|
@ -156,8 +230,24 @@ define(function(require) {
|
||||||
|
|
||||||
function Database(idbDatabase) {
|
function Database(idbDatabase) {
|
||||||
this.idbDatabase = idbDatabase;
|
this.idbDatabase = idbDatabase;
|
||||||
this.name = idbDatabase.name;
|
|
||||||
this.version = idbDatabase.version;
|
Object.defineProperty(this, 'name', {
|
||||||
|
get: function() {
|
||||||
|
return idbDatabase.name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'version', {
|
||||||
|
get: function() {
|
||||||
|
return idbDatabase.version;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'objectStoreNames', {
|
||||||
|
get: function() {
|
||||||
|
return idbDatabase.objectStoreNames;
|
||||||
|
}
|
||||||
|
});
|
||||||
};
|
};
|
||||||
Database.prototype.createObjectStore = function createObjectStore(name, optionalParameters) {
|
Database.prototype.createObjectStore = function createObjectStore(name, optionalParameters) {
|
||||||
var idbDatabase = this.idbDatabase;
|
var idbDatabase = this.idbDatabase;
|
||||||
|
@ -189,12 +279,12 @@ define(function(require) {
|
||||||
|
|
||||||
var request = indexedDB.open(name);
|
var request = indexedDB.open(name);
|
||||||
request.onupgradeneeded = function(event) {
|
request.onupgradeneeded = function(event) {
|
||||||
var result = new Event(event, new Target(event.target, new Database(event.target.result)));
|
var wrappedEvent = new Event(event, new Target(event.target, new Database(event.target.result)));
|
||||||
deferred.notify(result);
|
deferred.notify(wrappedEvent);
|
||||||
};
|
};
|
||||||
request.onsuccess = function(event) {
|
request.onsuccess = function(event) {
|
||||||
var result = new Event(event, new Target(event.target, new Database(event.target.result)));
|
var wrappedEvent = new Event(event, new Target(event.target, new Database(event.target.result)));
|
||||||
deferred.resolve(result);
|
deferred.resolve(wrappedEvent);
|
||||||
};
|
};
|
||||||
request.onerror = function(event) {
|
request.onerror = function(event) {
|
||||||
deferred.reject(event);
|
deferred.reject(event);
|
||||||
|
@ -222,7 +312,9 @@ define(function(require) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
open: open,
|
open: open,
|
||||||
deleteDatabase: deleteDatabase
|
deleteDatabase: deleteDatabase,
|
||||||
|
KeyRange: indexedDB.KeyRange,
|
||||||
|
when: when,
|
||||||
};
|
};
|
||||||
|
|
||||||
});
|
});
|
|
@ -0,0 +1,108 @@
|
||||||
|
define(function(require) {
|
||||||
|
|
||||||
|
var when = require('when');
|
||||||
|
|
||||||
|
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Transaction
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Transaction(idbDatabase, storeNames, mode) {
|
||||||
|
this.idbTransaction = idbDatabase.transaction(storeNames, mode);
|
||||||
|
};
|
||||||
|
Transaction.prototype.objectStore = function objectStore(name) {
|
||||||
|
var idbTransaction = this.idbTransaction;
|
||||||
|
return new ObjectStore(idbTransaction, name);
|
||||||
|
};
|
||||||
|
Transaction.prototype.abort = function abort() {
|
||||||
|
var idbTransaction = this.idbTransaction;
|
||||||
|
return idbTransaction.abort();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Database
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Database(idbDatabase) {
|
||||||
|
this.idbDatabase = idbDatabase;
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'name', {
|
||||||
|
get: function() {
|
||||||
|
return idbDatabase.name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'version', {
|
||||||
|
get: function() {
|
||||||
|
return idbDatabase.version;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.defineProperty(this, 'objectStoreNames', {
|
||||||
|
get: function() {
|
||||||
|
return idbDatabase.objectStoreNames;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Database.prototype.createObjectStore = function createObjectStore(name, optionalParameters) {
|
||||||
|
var idbDatabase = this.idbDatabase;
|
||||||
|
return idbDatabase.createObjectStore(name, optionalParameters);
|
||||||
|
};
|
||||||
|
Database.prototype.deleteObjectStore = function deleteObjectStore(name) {
|
||||||
|
var idbDatabase = this.idbDatabase;
|
||||||
|
return idbDatabase.deleteObjectStore(name);
|
||||||
|
};
|
||||||
|
Database.prototype.transaction = function transaction(storeNames, mode) {
|
||||||
|
var idbDatabase = this.idbDatabase;
|
||||||
|
return new Transaction(idbDatabase, storeNames, mode);
|
||||||
|
};
|
||||||
|
Database.prototype.close = function close() {
|
||||||
|
var idbDatabase = this.idbDatabase;
|
||||||
|
return idbDatabase.close();
|
||||||
|
};
|
||||||
|
Database.prototype.objectStoreNames = function objectStoreNames() {
|
||||||
|
var idbDatabase = this.idbDatabase;
|
||||||
|
return idbDatabase.objectStoreNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Factory
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Factory() {
|
||||||
|
this.when = when;
|
||||||
|
};
|
||||||
|
Factory.prototype.open = function open(name, version) {
|
||||||
|
var deferred = when.defer();
|
||||||
|
|
||||||
|
var request = indexedDB.open(name);
|
||||||
|
request.onupgradeneeded = function(idbEvent) {
|
||||||
|
var db = new Database(idbEvent.target.result);
|
||||||
|
var event = {
|
||||||
|
type: 'upgradeneeded',
|
||||||
|
db: db
|
||||||
|
};
|
||||||
|
deferred.notify(event);
|
||||||
|
};
|
||||||
|
request.onsuccess = function(idbEvent) {
|
||||||
|
var db = new Database(idbEvent.target.result);
|
||||||
|
var event = {
|
||||||
|
type: 'success',
|
||||||
|
db: db
|
||||||
|
};
|
||||||
|
deferred.resolve(event);
|
||||||
|
};
|
||||||
|
request.onerror = function(idbError) {
|
||||||
|
deferred.reject(idbError);
|
||||||
|
};
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
};
|
||||||
|
Factory.prototype.deleteDatabase = function deleteDatabase(name) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Factory();
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in New Issue