HTML5 Web SQL keeps making duplicates and breaks the old database - html

I'm making a database application for Safari purely. So I'm following this guide made by Apple: Link.
I have made this "class" prototype so far. It works, but it keeps making duplicates of the database (they just keep stacking up in the Safari Inspector tool) (without me changing the version from 1.0):
function Database() {
this.DB = null;
this.shortName = 'gamedb';
this.version = '1.0';
this.displayName = 'Database';
this.maxSize = 5 * 1024 * 1024;
init: (function() {
})
this.initDB = function() {
try {
if (!window.openDatabase) {
alert('Error: Databases are not supported.');
}
else {
this.DB = openDatabase(this.shortName, this.version, this.displayName, this.maxSize);
}
return true;
}
catch(e) {
if (e == 2) {
// Version number mismatch.
console.log("Error: Invalid database version.");
}
else {
console.log("Error: Unknown, " + e + ".");
}
return;
}
}
this.query = function(query) {
if (query == undefined) {
query = '';
}
query = query + ';'; // Add the ending semi-colon
this.DB.transaction(
function (transaction) {
transaction.executeSql(
query,
[],
this.nullDataHandler,
this.errorHandler
);
}
);
}
this.nullDataHandler = function() {
return 0;
}
this.errorHandler = function(error) {
return 0;
}
}
And here's my main.js file with my jQuery handle and the instantiation of the Database prototype:
$(document).ready(function() {
var DB = new Database();
DB.initDB();
DB.query('CREATE TABLE IF NOT EXISTS users(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)');
DB.query('INSERT INTO users(name) VALUES ("Jackson")');
});
Even just blankly running this line creates duplicates:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>X</title>
<style>
html, body {
background: #202020;
color: #8d9d6a;
}
</style>
<script type="text/javascript">
var shortName = 'mydatabase';
var version = '1.0';
var displayName = 'My Important Database';
var maxSize = 65536; // in bytes
var db = openDatabase(shortName, version, displayName, maxSize);
</script>
</head>
<body>
Content
</body>
</html>
Notes:
I have Extensions turned off
No changes in the Developer menu (nothing disabled or blocked)

I had this problem in both chrome and safari. When I saved a record it would appear several times and the inspector would show duplicates of the webSQL db (50 or more!). For me it turned out that I was calling a SELECT too soon after the save in order to update the view. I moved it into a success function and that fixed the problem. I can only think that the browser gets confused and spawns multiple DBs in the inspector. This might not be the same problem but it seemed close enough to mention.

Side information for anyone as new to this as myself.
I had a query selecting from more than one table which caused my display to duplicate. Stupid problem, simple fix by obviously selecting a single table
var showLearnerSQL = "SELECT * FROM tblLearnerInfo, tblDrive";// Not a great idea
var showLearnerSQL = "SELECT * FROM tblLearnerInfo; // Great idea

Related

Pulling data from localstorage

I am trying to retrieve data from local storage and then display this to the user.
What I want to happen is the user to be able to select a name from a drop down menu (this part works) and then display this data on screen (I can do this part).
The code to select a user is -
$scope.SelectedChanged = function() {
$scope.showBox = $scope.userSelected;
};
And the code to then cycle through the array of users, and take the correct data is -
$scope.LoadUserData = function() {
//console.log("Function run");
for (var i = 0; i < $localStorage.users.length; i++) {
//console.log("Function run");
var userTmp = $localStorage.users[i];
if (userTmp.name == $scope.userSelected) {
//PROBLEM IS HERE. ISNT ACCESSING USERSELECTED
console.log($scope.userSelected);
user = {
name: userTmp.name,
email: userTmp.email,
index: i
};
console.log(user);
}
}
};
When I test it, the Function run tests work correctly. So I think the issue is with the if statement, but i'm not sure as to why. Any advice?
Edit - Just to clarify, in local storage users are saved as objects names "users", with email and name being variables inside the object.
You can try something like the below code as I suggested to do in the comment section above. Also check this plunker link for the example scenario.
Template:
<select ng-model="selectedUser" ng-options="usr.name as usr.name for usr in userList" ng-change="LoadUserData(selectedUser);"></select>
Controller:
$scope.LoadUserData = function(selectedUser) {
var index = $scope.userList.map(function (usr) { return usr.name; }).indexOf(selectedUser);
$scope.activeUser = $scope.userList[index];
console.log($scope.activeUser);
};

Phonegap WebSql database table creation gets fail

When below Sample code of Phonegap app is executed in iPad, table gets created as well as records get inserted. But as soon as it navigates to next page using "window.location = 'main.html'" table disappears/delete. Some time it works properly and all records get displayed on main.html. Sample code:
db.transaction(function (transaction) {
transaction.executeSql('drop table if exists categoryType', null, function () {
transaction.executeSql('create table if not exists categoryType(id text primary key, code text, name text)', null, function () {
for (var i = 0; i < category_types.length; i++)
{
var insert_count = 0;
transaction.executeSql('insert into categoryType(id, code, name) values(?,?,?)', [category_types[i].id, category_types[i].code , category_types[i].name],
function()
{
insert_count++;
if ( insert_count == category_types.length)
window.location = "main.html";
});
}
});
});
});
If we add timeout in above code before navigating to main.html page issue gets resolved.
Sample code with timeout:
db.transaction(function (transaction) {
transaction.executeSql('drop table if exists categoryType', null, function () {
transaction.executeSql('create table if not exists categoryType(id text primary key, code text, name text)', null, function () {
for (var i = 0; i < category_types.length; i++)
{
var insert_count = 0;
transaction.executeSql('insert into categoryType(id, code, name) values(?,?,?)', [category_types[i].id, category_types[i].code , category_types[i].name],
function()
{
insert_count++;
if ( insert_count == category_types.length)
{
setTimeout(function() {
window.location = "main.html";
}, 5000);
}
});
}
});
});
});
I can run the code successfully using a timeout, but I don't want to depend on arbitrary timeout period. Earlier the same code was working properly but now it is causing issue recently. Is there any solution??

chrome.omnibox ceases working after period of time. Begins working after restarting extension

I'm leveraging Google Chrome's omnibox API in my extension.
Current users, including myself, have noticed that the omnibox ceases responding entirely after an undetermined state change or a period of time lapsing. Typing the word to trigger entering into "omnibox" stops having any effect and the URL bar does not shift into omnibox mode.
Restarting Google Chrome does not fix the issue, but restarting my plugin by unchecking and then re-checking the 'enabled' checkbox on chrome://extensions does resolve the issue.
Does anyone have any suggestions on what to investigate? Below is the code used. It is only loaded once through my permanently persisted background page:
// Displays streamus search suggestions and allows instant playing in the stream
define([
'background/collection/streamItems',
'background/model/video',
'common/model/youTubeV2API',
'common/model/utility'
], function (StreamItems, Video, YouTubeV2API, Utility) {
'use strict';
console.log("Omnibox LOADED", chrome.omnibox);
var Omnibox = Backbone.Model.extend({
defaults: function () {
return {
suggestedVideos: [],
searchJqXhr: null
};
},
initialize: function () {
console.log("Omnibox INITIALIZED");
var self = this;
chrome.omnibox.setDefaultSuggestion({
// TODO: i18n
description: 'Press enter to play.'
});
// User has started a keyword input session by typing the extension's keyword. This is guaranteed to be sent exactly once per input session, and before any onInputChanged events.
chrome.omnibox.onInputChanged.addListener(function (text, suggest) {
// Clear suggested videos
self.get('suggestedVideos').length = 0;
var trimmedSearchText = $.trim(text);
// Clear suggestions if there is no text.
if (trimmedSearchText === '') {
suggest();
} else {
// Do not display results if searchText was modified while searching, abort old request.
var previousSearchJqXhr = self.get('searchJqXhr');
if (previousSearchJqXhr) {
previousSearchJqXhr.abort();
self.set('searchJqXhr', null);
}
var searchJqXhr = YouTubeV2API.search({
text: trimmedSearchText,
// Omnibox can only show 6 results
maxResults: 6,
success: function(videoInformationList) {
self.set('searchJqXhr', null);
var suggestions = self.buildSuggestions(videoInformationList, trimmedSearchText);
suggest(suggestions);
}
});
self.set('searchJqXhr', searchJqXhr);
}
});
chrome.omnibox.onInputEntered.addListener(function (text) {
// Find the cached video data by url
var pickedVideo = _.find(self.get('suggestedVideos'), function(suggestedVideo) {
return suggestedVideo.get('url') === text;
});
// If the user doesn't make a selection (commonly when typing and then just hitting enter on their query)
// take the best suggestion related to their text.
if (pickedVideo === undefined) {
pickedVideo = self.get('suggestedVideos')[0];
}
StreamItems.addByVideo(pickedVideo, true);
});
},
buildSuggestions: function(videoInformationList, text) {
var self = this;
var suggestions = _.map(videoInformationList, function (videoInformation) {
var video = new Video({
videoInformation: videoInformation
});
self.get('suggestedVideos').push(video);
var safeTitle = _.escape(video.get('title'));
var textStyleRegExp = new RegExp(Utility.escapeRegExp(text), "i");
var styledTitle = safeTitle.replace(textStyleRegExp, '<match>$&</match>');
var description = '<dim>' + video.get('prettyDuration') + "</dim> " + styledTitle;
return {
content: video.get('url'),
description: description
};
});
return suggestions;
}
});
return new Omnibox();
});
As far as I'm aware the code itself is fine and wouldn't have any effect on whether I see omnibox or not.
You can find full source code here: https://github.com/MeoMix/StreamusChromeExtension/blob/master/src/js/background/model/omnibox.js

WebRTC SDP object (local description) by Firefox does not contain DataChannel info unlike Chrome?

I'm testing WebRTC procedure step by step for my sake.
I wrote some testing site for server-less WebRTC.
http://webrtcdevelop.appspot.com/
In fact, STUN server by google is used, but no signalling server deployed.
Session Description Protocol (SDP) is exchanged manually by hand that is CopyPaste between browser windows.
So far, here is the result I've got with the code:
'use strict';
var peerCon;
var ch;
$(document)
.ready(function()
{
init();
$('#remotebtn2')
.attr("disabled", "");
$('#localbtn')
.click(function()
{
offerCreate();
$('#localbtn')
.attr("disabled", "");
$('#remotebtn')
.attr("disabled", "");
$('#remotebtn2')
.removeAttr("disabled");
});
$('#remotebtn')
.click(function()
{
answerCreate(
new RTCSessionDescription(JSON.parse($('#remote')
.val())));
$('#localbtn')
.attr("disabled", "");
$('#remotebtn')
.attr("disabled", "");
$('#remotebtn')
.attr("disabled", "");
});
$('#remotebtn2')
.click(function()
{
answerGet(
new RTCSessionDescription(JSON.parse($('#remote')
.val())));
$('#remotebtn2')
.attr("disabled", "");
});
$('#msgbtn')
.click(function()
{
msgSend($('#msg')
.val());
});
});
var init = function()
{
//offer------
peerCon =
new RTCPeerConnection(
{
"iceServers": [
{
"url": "stun:stun.l.google.com:19302"
}]
},
{
"optional": []
});
var localDescriptionOut = function()
{
console.log(JSON.stringify(peerCon.localDescription));
$('#local')
.text(JSON.stringify(peerCon.localDescription));
};
peerCon.onicecandidate = function(e)
{
console.log(e);
if (e.candidate === null)
{
console.log('candidate empty!');
localDescriptionOut();
}
};
ch = peerCon.createDataChannel(
'ch1',
{
reliable: true
});
ch.onopen = function()
{
dlog('ch.onopen');
};
ch.onmessage = function(e)
{
dlog(e.data);
};
ch.onclose = function(e)
{
dlog('closed');
};
ch.onerror = function(e)
{
dlog('error');
};
};
var msgSend = function(msg)
{
ch.send(msg);
}
var offerCreate = function()
{
peerCon
.createOffer(function(description)
{
peerCon
.setLocalDescription(description, function()
{
//wait for complete of peerCon.onicecandidate
}, error);
}, error);
};
var answerCreate = function(descreption)
{
peerCon
.setRemoteDescription(descreption, function()
{
peerCon
.createAnswer(
function(description)
{
peerCon
.setLocalDescription(description, function()
{
//wait for complete of peerCon.onicecandidate
}, error);
}, error);
}, error);
};
var answerGet = function(description)
{
peerCon.setRemoteDescription(description, function()
{ //
console.log(JSON.stringify(description));
dlog('local-remote-setDescriptions complete!');
}, error);
};
var error = function(e)
{
console.log(e);
};
var dlog = function(msg)
{
var content = $('#onmsg')
.html();
$('#onmsg')
.html(content + msg + '<br>');
}
Firefox(26.0):
RtpDataChannels
onopen event is fired successfully, but send fails.
Chrome(31.0):
RtpDataChannels
onopen event is fired successfully, and send also succeeded.
A SDP object by Chrome is as follows:
{"sdp":".................. cname:L5dftYw3P3clhLve
\r\
na=ssrc:2410443476 msid:ch1 ch1
\r\
na=ssrc:2410443476 mslabel:ch1
\r\
na=ssrc:2410443476 label:ch1
\r\n","type":"offer"}
where the ch1 information defined in the code;
ch = peerCon.createDataChannel(
'ch1',
{
reliable: false
});
is bundled properly.
However, a SDP object (local description) by Firefox does not contain DataChannel at all, and moreover, the SDP is much shorter than Chrome, and less information bundled.
What do I miss?
Probably, I guess the reason that send fails on DataChannel is due to this lack of information in the SDP object by firefox.
How could I fix this?
I investigated sources of various working libraries, such as peerJS, easyRTC, simpleWebRTC, but cannot figure out the reason.
Any suggestion and recommendation to read is appreciated.
[not an answer, yet]
I leave this here just trying to help you. I am not much of a WebRTC developer. But, curious i am, this quite new and verry interresting for me.
Have you seen this ?
DataChannels
Supported in Firefox today, you can use DataChannels to send peer-to-peer
information during an audio/video call. There is
currently a bug that requires developers to set up some sort of
audio/video stream (even a “fake” one) in order to initiate a
DataChannel, but we will soon be fixing that.
Also, i found this bug hook, witch seems to be related.
One last point, your version of adapter.js is different from the one served on code.google. And .. alot. the webrtcDetectedVersion part is missing in yours.
https://code.google.com/p/webrtc/source/browse/stable/samples/js/base/adapter.js
Try that, come back to me with good newz. ?
After last updating, i have this line in console after clicking 'get answer'
Object { name="INVALID_STATE", message="Cannot set remote offer in
state HAVE_LOCAL_OFFER", exposedProps={...}, more...}
but this might be useless info ence i copy pasted the same browser offre to answer.
.. witch made me notice you are using jQuery v1.7.1 jquery.com.
Try updating jQuery (before i kill a kitten), and in the meantime, try make sure you use all updated versions of scripts.
Woups, after fast reading this : https://developer.mozilla.org/en-US/docs/Web/Guide/API/WebRTC/WebRTC_basics then comparing your javascripts, i see no SHIM.
Shims
As you can imagine, with such an early API, you must use the browser
prefixes and shim it to a common variable.
> var PeerConnection = window.mozRTCPeerConnection ||
> window.webkitRTCPeerConnection; var IceCandidate =
> window.mozRTCIceCandidate || window.RTCIceCandidate; var
> SessionDescription = window.mozRTCSessionDescription ||
> window.RTCSessionDescription; navigator.getUserMedia =
> navigator.getUserMedia || navigator.mozGetUserMedia ||
> navigator.webkitGetUserMedia;

Where can I learn about how to use html5 for client-side database apps?

I would like to begin using the client-side database functionality of html5, but I don't know where to go for a good introduction/tutorial/how-to. I've been coding (x)html for years and years, so I'm not so much interested in a "here's the <head> element" type of introduction; I want to learn about what's new in html5 in general, and client-side db in particular. Any suggestions?
Alex,
I wrote up a detailed method of how to do it at: http://wecreategames.com/blog/?p=219 - including source code to download. Here's a few snippets:
function picsInitDatabase() {
try {
if (!window.openDatabase) {
console.log('Databases are not supported in this browser');
} else {
var shortName = 'picsGeoDB';
var version = '1.0';
var displayName = 'Pictures Geotagged database';
var maxSize = 5000000; // in bytes
picsDB = openDatabase(shortName, version, displayName, maxSize);
console.log("Database is setup: "+picsDB);
}
} catch(e) {
// Error handling code goes here.
if (e == 2) {
// Version number mismatch.
console.log("Invalid database version.");
} else {
console.log("Unknown error "+e+".");
}
return;
}
}
And here's a function to update the table:
function picsUpdateTables(dataID) {
picsDB.transaction(
function (transaction) {
var p = data[dataID];
transaction.executeSql("INSERT INTO geopictures (id, secret, server, farm, title, latitude, longitude, accuracy, datetaken, ownername) VALUES (?,?,?,?,?,?,?,?,?,?);",
[p.id, p.secret, p.server, p.farm, p.title, p.latitude, p.longitude, p.accuracy, p.datetaken, p.ownername] );
transaction.executeSql("INSERT INTO photodata (picid, encodedtext) VALUES (?, ?)", [p.id, serializeCanvasByID(p.id)] );
}
);
}
See the blog post for examples of how to do SQL SELECTS, and a video showing how to test it on a few browsers.
Here: http://www.weboshelp.net/webos-tutorials/156-palm-webos-html5-database-storage-tutorial :)
Another useful link:
http://www.scribd.com/doc/4012693/Abusing-HTML-5-Structured-Clientside-Storage