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

Fix BUG 666 (WIP) #668

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 111 additions & 4 deletions SQLitePlugin.coffee.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,21 @@

if !!success then success @

txLock = txLocks[@dbname]
if !!txLock && txLock.queue.length > 0 && !txLock.inProgress
@startNextTransaction()
readycb = (ignored1, ignored2) =>
txLock = txLocks[@dbname]
if !!txLock && txLock.queue.length > 0 && !txLock.inProgress
@startNextTransaction()
return

tropts = []

tropts.push
#qid: null
sql: 'ROLLBACK'
params: []

cordova.exec readycb, null, 'SQLitePlugin', 'backgroundExecuteSqlBatch', [{dbargs: {dbname: @dbname}, executes: tropts}]

return

openerrorcb = =>
Expand Down Expand Up @@ -732,7 +744,7 @@

if resutSet.rows.item(0).upperText isnt 'TEST'
return SelfTest.finishWithError errorcb,
"Incorrect resutSet.rows.item(0).upperText value: #{resutSet.rows.item(0).data} (expected: 'TEST')"
"Incorrect resutSet.rows.item(0).upperText value: #{resutSet.rows.item(0).upperText} (expected: 'TEST')"

check1 = true
return
Expand Down Expand Up @@ -762,6 +774,101 @@
return

start3: (successcb, errorcb) ->
SQLiteFactory.openDatabase {name: SelfTest.DBNAME, location: 'default'}, (db) ->
check2 = false
db.transaction (tx) ->
tx.executeSql 'SELECT 1 AS myResult', [], (ignored, resutSet) ->
if !resutSet.rows
return SelfTest.finishWithError errorcb, 'Missing resutSet.rows'

if !resutSet.rows.length
return SelfTest.finishWithError errorcb, 'Missing resutSet.rows.length'

if resutSet.rows.length isnt 1
return SelfTest.finishWithError errorcb,
"Incorrect resutSet.rows.length value: #{resutSet.rows.length} (expected: 1)"

if !resutSet.rows.item(0).myResult
return SelfTest.finishWithError errorcb,
'Missing resutSet.rows.item(0).myResult'

if resutSet.rows.item(0).myResult isnt 1
return SelfTest.finishWithError errorcb,
"Incorrect resutSet.rows.item(0).myResult value: #{resutSet.rows.item(0).myResult} (expected: 1)"

check2 = true
return

, (sql_err) ->
SelfTest.finishWithError errorcb, "SQL error: #{sql_err}"
return

, (tx_err) ->
SelfTest.finishWithError errorcb, "TRANSACTION error: #{tx_err}"
return

, () ->
if !check2
return SelfTest.finishWithError errorcb,
'Did not get expected myResult result data'

# SIMULATE SCENARIO IN BUG litehelpers/Cordova-sqlite-storage#666:
db.executeSql 'BEGIN', null, (resutSet) ->
# DELETE INTERNAL STATE to simulate the effects of location refresh or change:
delete db.openDBs[SelfTest.DBNAME]
delete txLocks[SelfTest.DBNAME]

SelfTest.start4 successcb, errorcb
return

, (open_err) ->
SelfTest.finishWithError errorcb, "Open database error: #{open_err}"
return

start4: (successcb, errorcb) ->
SQLiteFactory.openDatabase {name: SelfTest.DBNAME, location: 'default'}, (db) ->
# VERIFY FIX FOR BUG litehelpers/Cordova-sqlite-storage#666:
check3 = false
db.transaction (tx) ->
tx.executeSql 'SELECT 1 AS myResult', [], (ignored, resutSet) ->
if !resutSet.rows
return SelfTest.finishWithError errorcb, 'Missing resutSet.rows'

if !resutSet.rows.length
return SelfTest.finishWithError errorcb, 'Missing resutSet.rows.length'

if resutSet.rows.length isnt 1
return SelfTest.finishWithError errorcb,
"Incorrect resutSet.rows.length value: #{resutSet.rows.length} (expected: 1)"

if !resutSet.rows.item(0).myResult
return SelfTest.finishWithError errorcb,
'Missing resutSet.rows.item(0).myResult'

if resutSet.rows.item(0).myResult isnt 1
return SelfTest.finishWithError errorcb,
"Incorrect resutSet.rows.item(0).myResult value: #{resutSet.rows.item(0).myResult} (expected: 1)"

check3 = true
return

, (txError) ->
SelfTest.finishWithError errorcb, "TRANSACTION error: #{tx_err}"
return

, () ->
if !check3
return SelfTest.finishWithError errorcb,
'Did not get expected myResult result data'

SelfTest.start5 successcb, errorcb
return

, (open_err) ->
SelfTest.finishWithError errorcb, "Open database error: #{open_err}"
return

start5: (successcb, errorcb) ->
SQLiteFactory.openDatabase {name: SelfTest.DBNAME, location: 'default'}, (db) ->
db.sqlBatch [
'CREATE TABLE TestTable(id integer primary key autoincrement unique, data);'
Expand Down
59 changes: 59 additions & 0 deletions spec/www/spec/db-sql-operations-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ var mytests = function() {
db.executeSql("select upper('second') as uppertext", [], okcb);
}, MYTIMEOUT);


});
}

Expand Down Expand Up @@ -1617,6 +1618,64 @@ var mytests = function() {
});
});

it(suiteName + 'transaction after db.executeSql("BEGIN")', function(done) {
// SIMILAR BEHAVIOR TO litehelpers/Cordova-sqlite-storage#666:
var db = openDatabase("DB-sql-tx-after-begin.db", "1.0", "Demo", DEFAULT_SIZE);
expect(db).toBeDefined();

var check1 = false;
var check2 = false;

db.executeSql('BEGIN', null, function(rsIgnored) {
expect(check1).toBe(false);
expect(check2).toBe(false);
check1 = true;
});

db.executeSql('SELECT 1', null, function(rsIgnored) {
expect(check1).toBe(true);
expect(check2).toBe(false);
check2 = true;
});

// NOTE: This transaction should fail with ROLLBACK,
// then next transaction should be able to succeed.
db.transaction(function(tx1) {
expect(check1).toBe(true);
expect(check2).toBe(true);
tx1.executeSql('SELECT 1', null, function(txIgnored, rs) {
// NOT EXPECTED:
expect(false).toBe(true);
});
}, function(err) {
// EXPECTED RESULT:
expect(err).toBeDefined();
expect(err.message).toBeDefined();
expect(err.message).toMatch(/unable to begin transaction: cannot start a transaction within a transaction/);
//expect(err.message).toMatch(/--/);

db.transaction(function(tx2) {
tx2.executeSql('SELECT 1', null, function(txIgnored, rs) {
expect(rs).toBeDefined();
expect(rs.rows).toBeDefined();
expect(rs.rows.length).toBe(1);
//expect(rs.rows.length).toBe('--');
db.close(done, done);
});
}, function(err) {
// NOT EXPECTED:
expect(false).toBe(true);
expect(err.message).toMatch(/--/);
db.close(done, done);
});

}, function() {
// NOT EXPECTED:
expect(false).toBe(true);
db.close(done, done);
});
}, MYTIMEOUT);

});
}

Expand Down
110 changes: 104 additions & 6 deletions www/SQLitePlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
console.log('OPEN database: ' + this.dbname);
opensuccesscb = (function(_this) {
return function() {
var txLock;
var readycb, tropts;
console.log('OPEN database: ' + _this.dbname + ' - OK');
if (!_this.openDBs[_this.dbname]) {
console.log('database was closed during open operation');
Expand All @@ -185,10 +185,26 @@
if (!!success) {
success(_this);
}
txLock = txLocks[_this.dbname];
if (!!txLock && txLock.queue.length > 0 && !txLock.inProgress) {
_this.startNextTransaction();
}
readycb = function(ignored1, ignored2) {
var txLock;
txLock = txLocks[_this.dbname];
if (!!txLock && txLock.queue.length > 0 && !txLock.inProgress) {
_this.startNextTransaction();
}
};
tropts = [];
tropts.push({
sql: 'ROLLBACK',
params: []
});
cordova.exec(readycb, null, 'SQLitePlugin', 'backgroundExecuteSqlBatch', [
{
dbargs: {
dbname: _this.dbname
},
executes: tropts
}
]);
};
})(this);
openerrorcb = (function(_this) {
Expand Down Expand Up @@ -655,7 +671,7 @@
return SelfTest.finishWithError(errorcb, 'Missing resutSet.rows.item(0).upperText');
}
if (resutSet.rows.item(0).upperText !== 'TEST') {
return SelfTest.finishWithError(errorcb, "Incorrect resutSet.rows.item(0).upperText value: " + (resutSet.rows.item(0).data) + " (expected: 'TEST')");
return SelfTest.finishWithError(errorcb, "Incorrect resutSet.rows.item(0).upperText value: " + (resutSet.rows.item(0).upperText) + " (expected: 'TEST')");
}
check1 = true;
}, function(sql_err) {
Expand All @@ -676,6 +692,88 @@
});
},
start3: function(successcb, errorcb) {
SQLiteFactory.openDatabase({
name: SelfTest.DBNAME,
location: 'default'
}, function(db) {
var check2;
check2 = false;
return db.transaction(function(tx) {
return tx.executeSql('SELECT 1 AS myResult', [], function(ignored, resutSet) {
if (!resutSet.rows) {
return SelfTest.finishWithError(errorcb, 'Missing resutSet.rows');
}
if (!resutSet.rows.length) {
return SelfTest.finishWithError(errorcb, 'Missing resutSet.rows.length');
}
if (resutSet.rows.length !== 1) {
return SelfTest.finishWithError(errorcb, "Incorrect resutSet.rows.length value: " + resutSet.rows.length + " (expected: 1)");
}
if (!resutSet.rows.item(0).myResult) {
return SelfTest.finishWithError(errorcb, 'Missing resutSet.rows.item(0).myResult');
}
if (resutSet.rows.item(0).myResult !== 1) {
return SelfTest.finishWithError(errorcb, "Incorrect resutSet.rows.item(0).myResult value: " + (resutSet.rows.item(0).myResult) + " (expected: 1)");
}
check2 = true;
}, function(sql_err) {
SelfTest.finishWithError(errorcb, "SQL error: " + sql_err);
});
}, function(tx_err) {
SelfTest.finishWithError(errorcb, "TRANSACTION error: " + tx_err);
}, function() {
if (!check2) {
return SelfTest.finishWithError(errorcb, 'Did not get expected myResult result data');
}
return db.executeSql('BEGIN', null, function(resutSet) {
delete db.openDBs[SelfTest.DBNAME];
delete txLocks[SelfTest.DBNAME];
SelfTest.start4(successcb, errorcb);
});
});
}, function(open_err) {
return SelfTest.finishWithError(errorcb, "Open database error: " + open_err);
});
},
start4: function(successcb, errorcb) {
SQLiteFactory.openDatabase({
name: SelfTest.DBNAME,
location: 'default'
}, function(db) {
var check3;
check3 = false;
return db.transaction(function(tx) {
return tx.executeSql('SELECT 1 AS myResult', [], function(ignored, resutSet) {
if (!resutSet.rows) {
return SelfTest.finishWithError(errorcb, 'Missing resutSet.rows');
}
if (!resutSet.rows.length) {
return SelfTest.finishWithError(errorcb, 'Missing resutSet.rows.length');
}
if (resutSet.rows.length !== 1) {
return SelfTest.finishWithError(errorcb, "Incorrect resutSet.rows.length value: " + resutSet.rows.length + " (expected: 1)");
}
if (!resutSet.rows.item(0).myResult) {
return SelfTest.finishWithError(errorcb, 'Missing resutSet.rows.item(0).myResult');
}
if (resutSet.rows.item(0).myResult !== 1) {
return SelfTest.finishWithError(errorcb, "Incorrect resutSet.rows.item(0).myResult value: " + (resutSet.rows.item(0).myResult) + " (expected: 1)");
}
check3 = true;
});
}, function(txError) {
SelfTest.finishWithError(errorcb, "TRANSACTION error: " + tx_err);
}, function() {
if (!check3) {
return SelfTest.finishWithError(errorcb, 'Did not get expected myResult result data');
}
SelfTest.start5(successcb, errorcb);
});
}, function(open_err) {
return SelfTest.finishWithError(errorcb, "Open database error: " + open_err);
});
},
start5: function(successcb, errorcb) {
SQLiteFactory.openDatabase({
name: SelfTest.DBNAME,
location: 'default'
Expand Down