Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Safari - "14 unable to open database file" #233

Closed
Abrissirba opened this issue Dec 29, 2015 · 2 comments
Closed

Safari - "14 unable to open database file" #233

Abrissirba opened this issue Dec 29, 2015 · 2 comments
Assignees
Milestone

Comments

@Abrissirba
Copy link

I get the following error after I have done around 400 calls to indexedDB.open() in safari: (14 unable to open database file). After some googling I found this blogpost, http://zacster.blogspot.se/2015/10/safari-web-sql-14-unable-to-open.html, which says that safari doesn't garbage collect db handles from openDatabas calls.

The solution I'm currently using is to cache open databases in an object and reuse that connection. This is how the openDB(oldVersion) method at line 366 looks for me now.

function openDB(oldVersion) {
    openDatabases[name + oldVersion] = openDatabases[name + oldVersion] || window.openDatabase(name, 1, name, DEFAULT_DB_SIZE);
    var db = openDatabases[name + oldVersion];

Do you think this is a solid solution? If so I'm happy to make a PR.

@Abrissirba
Copy link
Author

After some testing I discovered a new problem I think is related to my suggested solution. When my app has been running for a while, new transactions will fail with the error message: "database has been closed". I haven't found any really good way to see if the database has been closed or not without creating a transaction which will call the error callback.

My very ugly solution to this at the moment is to reuase the connections but before each transaction make a dummy transaction that checks that the database is open. If not I reopen the database again

(function (idbModules) {
    idbModules.DatabasePool = {};

    idbModules.DatabasePool.openConnections = {}

    var DEFAULT_DB_SIZE = 49 * 1024 * 1024;

    idbModules.DatabasePool.getConnection = function (name, version, size, callback) {
        size = size || DEFAULT_DB_SIZE;
        var cachedDB = idbModules.DatabasePool.openConnections[name + version]

        if (!cachedDB) {
            cachedDB = idbModules.DatabasePool.openConnections[name + version] = window.openDatabase(name, 1, name, size);
            callback(cachedDB);
        }
        else {
            cachedDB.transaction(function (tx) {
                callback(cachedDB)
            }, function () {
                cachedDB = idbModules.DatabasePool.openConnections[name + version] = window.openDatabase(name, 1, name, size);
                callback(cachedDB);
            })
        }        
    }
}(idbModules));

and in IDBTransaction.prototype.__executeRequests I wrap the transaction:

idbModules.DatabasePool.getConnection(me.db.name, me.db.version, null, function (db) {
    db.transaction(function executeRequests(tx) {

@brettz9 brettz9 added this to the 3.0.0 milestone Jan 20, 2017
@brettz9 brettz9 added this to Safari in Browser bugs Feb 16, 2017
@brettz9
Copy link
Collaborator

brettz9 commented May 4, 2017

Recent code (including the latest 3.0.0 RCs) included such caching. Feel free to give it a shot. Closing, but feel free to report if you experience any difficulties.

@brettz9 brettz9 closed this as completed May 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Browser bugs
Safari/iOS
Development

No branches or pull requests

2 participants