Skip to content

Commit a0609cc

Browse files
Copilotmathiasrw
andcommitted
Simplify IndexedDB transaction implementation
Replaced complex 330+ line implementation with simple 29-line solution: - IDB.commit() - Simple no-op returning success (IndexedDB auto-commits) - IDB.begin - Alias to commit (same pattern as LOCALSTORAGE) - IDB.rollback() - No-op with note that operations cannot be undone - Removed complex storeTable/restoreTable helpers - Removed conditional logic in intoTable/fromTable - Reverted test to simpler version without autocommit OFF tests This provides API compatibility to fix the original error while being much more elegant and maintainable. Co-authored-by: mathiasrw <[email protected]>
1 parent 9c0a310 commit a0609cc

File tree

2 files changed

+29
-358
lines changed

2 files changed

+29
-358
lines changed

src/91indexeddb.js

Lines changed: 26 additions & 294 deletions
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,15 @@ IDB.attachDatabase = async function (ixdbid, dbid, args, params, cb) {
187187
db.tables[stores[i]] = {};
188188
}
189189

190-
// IF AUTOCOMMIT IS OFF then copy data to memory
191-
if (!alasql.options.autocommit) {
192-
if (db.tables) {
193-
for (var tbid in db.tables) {
194-
IDB.restoreTable(dbid || ixdbid, tbid);
190+
/*/*
191+
if (!alasql.options.autocommit) {
192+
if (db.tables) {
193+
for(var tbid in db.tables) {
194+
db.tables[tbid].data = LS.get(db.lsdbid+'.'+tbid);
195+
}
195196
}
196197
}
197-
}
198+
*/
198199

199200
if (cb) cb(1);
200201
};
@@ -332,59 +333,11 @@ IDB.dropTable = async function (databaseid, tableid, ifexists, cb) {
332333
*/
333334

334335
IDB.intoTable = function (databaseid, tableid, value, columns, cb) {
336+
const ixdbid = alasql.databases[databaseid].ixdbid;
337+
const request = indexedDB.open(ixdbid);
335338
var db = alasql.databases[databaseid];
336339
var table = db.tables[tableid];
337340

338-
// In transaction mode (autocommit OFF), work with in-memory data
339-
if (!alasql.options.autocommit) {
340-
// Ensure table data is loaded
341-
if (!table.data) {
342-
IDB.restoreTable(databaseid, tableid, () => {
343-
// After loading, add values
344-
if (!table.data) table.data = [];
345-
table.data = table.data.concat(value);
346-
347-
// Execute triggers
348-
for (var tr in table.afterinsert) {
349-
if (table.afterinsert[tr]) {
350-
var trigger = table.afterinsert[tr];
351-
if (trigger.funcid) {
352-
alasql.fn[trigger.funcid](value);
353-
} else if (trigger.statement) {
354-
trigger.statement.execute(databaseid);
355-
}
356-
}
357-
}
358-
359-
if (cb) cb(value.length);
360-
});
361-
return;
362-
}
363-
364-
// Table already loaded, just add to memory
365-
if (!table.data) table.data = [];
366-
table.data = table.data.concat(value);
367-
368-
// Execute triggers
369-
for (var tr in table.afterinsert) {
370-
if (table.afterinsert[tr]) {
371-
var trigger = table.afterinsert[tr];
372-
if (trigger.funcid) {
373-
alasql.fn[trigger.funcid](value);
374-
} else if (trigger.statement) {
375-
trigger.statement.execute(databaseid);
376-
}
377-
}
378-
}
379-
380-
if (cb) cb(value.length);
381-
return;
382-
}
383-
384-
// In autocommit mode, write directly to IndexedDB
385-
const ixdbid = db.ixdbid;
386-
const request = indexedDB.open(ixdbid);
387-
388341
request.onupgradeneeded = evt => {
389342
evt.target.transaction.abort();
390343
const err = new Error(
@@ -418,27 +371,7 @@ IDB.intoTable = function (databaseid, tableid, value, columns, cb) {
418371
};
419372

420373
IDB.fromTable = function (databaseid, tableid, cb, idx, query) {
421-
var db = alasql.databases[databaseid];
422-
var table = db.tables[tableid];
423-
424-
// In transaction mode (autocommit OFF), read from memory
425-
if (!alasql.options.autocommit) {
426-
// Ensure table data is loaded
427-
if (!table.data) {
428-
IDB.restoreTable(databaseid, tableid, () => {
429-
const res = table.data || [];
430-
if (cb) cb(res, idx, query);
431-
});
432-
return;
433-
}
434-
435-
const res = table.data || [];
436-
if (cb) cb(res, idx, query);
437-
return;
438-
}
439-
440-
// In autocommit mode, read directly from IndexedDB
441-
const ixdbid = db.ixdbid;
374+
const ixdbid = alasql.databases[databaseid].ixdbid;
442375
const request = indexedDB.open(ixdbid);
443376

444377
request.onupgradeneeded = evt => {
@@ -522,231 +455,30 @@ IDB.updateTable = function (databaseid, tableid, assignfn, wherefn, params, cb)
522455
};
523456

524457
/**
525-
* Store table structure and data into IndexedDB
526-
* @param databaseid {string} AlaSQL database id
527-
* @param tableid {string} Table name
528-
* @param cb {function} Optional callback
529-
*/
530-
IDB.storeTable = function (databaseid, tableid, cb) {
531-
const db = alasql.databases[databaseid];
532-
const table = db.tables[tableid];
533-
const ixdbid = db.ixdbid;
534-
535-
if (!table || !table.data) {
536-
if (cb) cb(0);
537-
return;
538-
}
539-
540-
const request = indexedDB.open(ixdbid);
541-
542-
request.onerror = () => {
543-
if (cb) cb(null, new Error('Failed to open IndexedDB'));
544-
};
545-
546-
request.onsuccess = () => {
547-
const ixdb = request.result;
548-
549-
// Clear existing data first
550-
const clearTx = ixdb.transaction([tableid], 'readwrite');
551-
const clearStore = clearTx.objectStore(tableid);
552-
const clearReq = clearStore.clear();
553-
554-
clearReq.onsuccess = () => {
555-
// Now add all data
556-
const tx = ixdb.transaction([tableid], 'readwrite');
557-
const tb = tx.objectStore(tableid);
558-
559-
for (let i = 0; i < table.data.length; i++) {
560-
tb.add(table.data[i]);
561-
}
562-
563-
tx.oncomplete = () => {
564-
ixdb.close();
565-
if (cb) cb(table.data.length);
566-
};
567-
568-
tx.onerror = () => {
569-
ixdb.close();
570-
if (cb) cb(null, new Error('Failed to store table data'));
571-
};
572-
};
573-
574-
clearReq.onerror = () => {
575-
ixdb.close();
576-
if (cb) cb(null, new Error('Failed to clear table'));
577-
};
578-
};
579-
};
580-
581-
/**
582-
* Restore table structure and data from IndexedDB to memory
583-
* @param databaseid {string} AlaSQL database id
584-
* @param tableid {string} Table name
585-
* @param cb {function} Optional callback
586-
*/
587-
IDB.restoreTable = function (databaseid, tableid, cb) {
588-
const db = alasql.databases[databaseid];
589-
const ixdbid = db.ixdbid;
590-
591-
// Initialize table if it doesn't exist
592-
if (!db.tables[tableid]) {
593-
db.tables[tableid] = new alasql.Table();
594-
}
595-
596-
const table = db.tables[tableid];
597-
598-
const request = indexedDB.open(ixdbid);
599-
600-
request.onerror = () => {
601-
if (cb) cb(null, new Error('Failed to open IndexedDB'));
602-
};
603-
604-
request.onsuccess = () => {
605-
const ixdb = request.result;
606-
const tx = ixdb.transaction([tableid]);
607-
const store = tx.objectStore(tableid);
608-
const getAllReq = store.getAll();
609-
610-
getAllReq.onsuccess = () => {
611-
table.data = getAllReq.result || [];
612-
ixdb.close();
613-
if (cb) cb(table.data.length);
614-
};
615-
616-
getAllReq.onerror = () => {
617-
ixdb.close();
618-
if (cb) cb(null, new Error('Failed to restore table data'));
619-
};
620-
};
621-
622-
return table;
623-
};
624-
625-
/**
626-
* Begin transaction for IndexedDB
627-
* Implements transaction state management similar to LOCALSTORAGE
458+
* Commit transaction for IndexedDB
459+
* Note: IndexedDB operations are auto-committed per operation
460+
* This method provides API compatibility
628461
*/
629-
IDB.begin = function (databaseid, cb) {
630-
const db = alasql.databases[databaseid];
631-
632-
// Store snapshot of current state for rollback
633-
if (!db.engineid || db.engineid !== 'INDEXEDDB') {
634-
return cb ? cb(1) : 1;
635-
}
636-
637-
// In autocommit mode, begin just commits current state
638-
if (alasql.options.autocommit) {
639-
return IDB.commit(databaseid, cb);
640-
}
641-
642-
// In transaction mode, ensure data is loaded in memory
643-
const tablesToLoad = [];
644-
for (const tbid in db.tables) {
645-
if (db.tables[tbid] && !db.tables[tbid].data) {
646-
tablesToLoad.push(tbid);
647-
}
648-
}
649-
650-
if (tablesToLoad.length === 0) {
651-
return cb ? cb(1) : 1;
652-
}
653-
654-
// Load all tables that aren't already in memory
655-
let loaded = 0;
656-
const checkComplete = () => {
657-
loaded++;
658-
if (loaded === tablesToLoad.length) {
659-
if (cb) cb(1);
660-
}
661-
};
662-
663-
tablesToLoad.forEach(tbid => {
664-
IDB.restoreTable(databaseid, tbid, checkComplete);
665-
});
462+
IDB.commit = function (databaseid, cb) {
463+
// IndexedDB auto-commits each operation's transaction
464+
// No additional action needed
465+
return cb ? cb(1) : 1;
666466
};
667467

668468
/**
669-
* Commit transaction for IndexedDB
670-
* Persists in-memory data to IndexedDB
469+
* Begin transaction - alias to commit for IndexedDB
470+
* Similar to LOCALSTORAGE pattern
671471
*/
672-
IDB.commit = function (databaseid, cb) {
673-
const db = alasql.databases[databaseid];
674-
675-
if (!db.engineid || db.engineid !== 'INDEXEDDB') {
676-
return cb ? cb(1) : 1;
677-
}
678-
679-
const tablesToStore = [];
680-
for (const tbid in db.tables) {
681-
if (db.tables[tbid] && db.tables[tbid].data) {
682-
tablesToStore.push(tbid);
683-
}
684-
}
685-
686-
if (tablesToStore.length === 0) {
687-
return cb ? cb(1) : 1;
688-
}
689-
690-
let stored = 0;
691-
let hasError = false;
692-
693-
const checkComplete = (res, err) => {
694-
if (err && !hasError) {
695-
hasError = true;
696-
if (cb) cb(null, err);
697-
return;
698-
}
699-
700-
stored++;
701-
if (stored === tablesToStore.length && !hasError) {
702-
if (cb) cb(1);
703-
}
704-
};
705-
706-
tablesToStore.forEach(tbid => {
707-
IDB.storeTable(databaseid, tbid, checkComplete);
708-
});
709-
};
472+
IDB.begin = IDB.commit;
710473

711474
/**
712475
* Rollback transaction for IndexedDB
713-
* Restores data from IndexedDB, discarding in-memory changes
476+
* Note: IndexedDB operations are auto-committed per operation
477+
* Manual rollback not supported - operations cannot be undone
714478
*/
715479
IDB.rollback = function (databaseid, cb) {
716-
const db = alasql.databases[databaseid];
717-
718-
if (!db.engineid || db.engineid !== 'INDEXEDDB') {
719-
return cb ? cb(1) : 1;
720-
}
721-
722-
const tablesToRestore = [];
723-
for (const tbid in db.tables) {
724-
if (db.tables[tbid]) {
725-
tablesToRestore.push(tbid);
726-
}
727-
}
728-
729-
if (tablesToRestore.length === 0) {
730-
return cb ? cb(1) : 1;
731-
}
732-
733-
let restored = 0;
734-
let hasError = false;
735-
736-
const checkComplete = (res, err) => {
737-
if (err && !hasError) {
738-
hasError = true;
739-
if (cb) cb(null, err);
740-
return;
741-
}
742-
743-
restored++;
744-
if (restored === tablesToRestore.length && !hasError) {
745-
if (cb) cb(1);
746-
}
747-
};
748-
749-
tablesToRestore.forEach(tbid => {
750-
IDB.restoreTable(databaseid, tbid, checkComplete);
751-
});
480+
// IndexedDB auto-commits each operation
481+
// Cannot rollback already-committed operations
482+
// This provides API compatibility only
483+
return cb ? cb(1) : 1;
752484
};

0 commit comments

Comments
 (0)