SQLite access in Javascript

China☆狼群 提交于 2019-12-13 03:08:49

问题


I want to access Sql Lite Database with JavaScript code. The JavaScript code is used in html5 and has to be deployed on blackberry 10 platform. I use the following code without success:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
    <title>Prova</title>
</head>
<body>
    <script type="text/javascript">
//Provenia SRL ITC - Paola Savioli
//Questa funzione apre il database SQL Lite
//Il parametro che va cambiato è il nome del database
function ApriDatabase() {
    try {
        if (window.openDatabase) {
            var shortName = 'Ristoranti.sqllite';
            var version = '1.0';
            var displayName = 'Ristoranti italia';
            var maxSize = 65536; // in bytes
            db = openDatabase(shortName, version, displayName, maxSize);
        }
    } catch (e) {
        alert('Apri Database' + e);
    }
}
//Provenia SRL ITC - Paola Savioli
// Questa funzione eseque una query su un database aperto con la funzione ApriDatabase
function EseguiQuery($query, callback) {
    try {
        ApriDatabase();
        if (window.openDatabase) {
            db.transaction(

            function (tx) {
                tx.executeSql($query, [], function (tx, result) {
                    if (typeof (callback) == "function") {
                        callback(result);
                    } else {
                        if (callback != undefined) {
                            eval(callback + "(result)");
                        }
                    }
                }, function (tx, error) {});
            });
            return rslt;
        }
    } catch (e) {
        alert('Esegui Query' + e);
    }
}

function VisualizzaComuni() {
    try {
        var schemanode = document.GetElementById('RCOMUNI');
        schemanode.innerHTML = "";
        var result = EseguiQuery('SELECT * FROM COMUNE');
        for (var i = 0; i < result.rows.lenght; ++i) {
            var row = result.row.item(i);
            var notediv = document.createElement('div');
            notediv.innerHTML = 'Codice Provincia:' + row['PROVINCIA'] + 'Nome:' + row['NAME'];
            schemanode.appendchild(notediv);
        }
    } catch (e) {
        alert('Visualizza Comuni' + e);
    }
}
</script>
    <input type="button" name='select' onClick="VisualizzaComuni()"
        value='Visualizza Comuni'>
    <div id="RCOMUNI"></div>
</body>
</html>

回答1:


You may consider using the WebSQL API, which is supported on BlackBerry 7 and 10 according to http://caniuse.com/#feat=sql-storage.

Note that the API will never become an official standard and development on it has stopped. But if you just want to target BlackBerry, it may be a valid choice.




回答2:


There were a few problems with the code you've posted, including a reference to .lenght instead of .length and use of try catch blocks when there are success and error handlers built-in. So I worked up a demo.

First, it does not seem to make a difference, but this is HTML5 right? Instead of an HTML 4.01 Transitional doctype, use the HTML5 doctype:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>demo by userdude</title>
...

Next, I modified the markup for the purposes of the demonstration. In this case, we have:

<body>
<input type="button" id="run" value='Run Query'>
<div id="query"></div>
<table id="table" border="1" cellspacing="1" cellpadding="5"></table>
</body>
</html>

In the head element, I use an event listener to wait for the DOM to load. Keep in mind, I do not have a Blackberry to test this with, and with Blackberry or other devices, you should probably use deviceready instead of load. I think. I also attach the event handler for button that run's the query using .addEventListener, but notice I do that within the load handler. You have to wait before trying to access the DOM.

Also, IE supports attachEvent instead of addEventListener. I would imagine Blackberry supports the latter, but I'm not sure.

window.addEventListener('load', function load(){
    var run = document.getElementById('run'),
        data = document.getElementById('table'),
        qtext = document.getElementById('query'),
        dropped = false,
        created = false,
        cities = ['Houston', 'Dallas', 'Paris', 'New York', 'Buenos Aires', 'London'],
        shortName = 'Cities',
        version = '1.0',
        displayName = 'Cities Demo',
        maxSize = 5 * 1024 * 1024,
        db = false,
        queries = [];

    run.addEventListener('click', query);

This establishes my database, including running the initial call to populate() so we have some data use.

    open();

This is the function I added to the run button.

    function query() {
        transact('SELECT * FROM Cities', view);
    }

This is just meant to add data to the database. See the cities variable above.

    function populate(tx) {
        var city,
            i = 0;

I block this from running once I've emptied the cities array of entries to INSERT. dropped and created do the same thing for the DROP and CREATE transactions.

Take special note how I'm doing this; see the transact('...', populate)? I use populate in this situation to loop back until I've finished adding all of the cities entries. This is asynchronous, so you have to setup the callbacks to wait if necessary for the previous queries to run. In this case, I could end up dropping the table after adding my rows. So I have to wait, then loop through the cities list.

        if (cities) {
            if (!dropped) {
                dropped = true;
                transact('DROP TABLE IF EXISTS Cities', populate);

                return;
            }

            if (!created) {
                created = true;
                transact('CREATE TABLE IF NOT EXISTS Cities (id unique, City)', populate);

                return;

            }

I don't need to iterate back to populate here, since I just need to INSERT and move on.

            while (city = cities.pop()) {
                transact('INSERT INTO Cities (id, City) VALUES (' + i++ + ', "' + city + '")');
            }

            cities = false;
        }
    }

All this function does is give either an opened or new reference to the database, or return false. This short-circuits the execution of transact().

    function open() {
        if (!db && window.openDatabase) {
            db = window.openDatabase(shortName, version, displayName, maxSize);
        }

        if (cities) {
            db.transaction(populate);
        }

        return db;
    }

This is the meat of the script. I call it from query(), and the callback in this case is view, which points to the function which runs through the result set and creates a table from the set.

    function transact(query, callback) {
        var cb = callback,
            qel = document.createElement('p'),
            qid = queries.length;

        if (!open()) {
            console.log('HTML5 Database not supported.');

            return false;
        }

        db.transaction(transact_cb);

        qel.innerHTML = query + ' Query Result: <span id="q' + qid + '">Pending...</span>';

        qtext.appendChild(qel);

        queries[qid] = query;

Note the last two arguments, transact_success, transact_error. This is how you handle these asynchronous calls.

        function transact_cb(tx) {
            tx.executeSql(query, [], transact_success, transact_error);
        }

Not quite sure why there's an eval in there...?

        function transact_success(tx, result) {
            var rtext = document.getElementById('q' + qid);

            rtext.className = 'success';
            rtext.innerHTML = 'Success.';

            if (typeof cb == "function") {
                cb(result);
            } else if (cb != undefined) {
                eval(cb + "(result)");
            }
        }

Note the console.log(error);.

        function transact_error(tx, error) {
            var rtext = document.getElementById('q' + qid);

            rtext.className = 'error';
            rtext.innerHTML = 'Error logged to console.';

            console.log(error);
        }
    }

And this function creates the table result set view. You'll probably notice I loop through each row, and each row's columns.

    function view(result) {
        var thead = '<thead><tr>',
            tbody = '<tbody>',
            row,
            col;

        for (var i = 0, rows = result.rows.length; i < rows; ++i) {
            row = result.rows.item(i);

            tbody += '<tr>';

            for (col in row) {
                if (i === 0) {
                    thead += "<th>" + col + "</th>";
                }

                tbody += '<td>' + row[col] + '</td>';
            }

            tbody += '</tr>';
        }

        thead += '</tr></thead>';
        tbody += '</tbody>';

        data.innerHTML = thead + tbody;
    }

});

You can download the file and run it locally (due to a security error, it won't run on jsFiddle) by downloading the HTML file here:

http://pastebin.com/FcSiu6ZZ

So there you go. Hopefully that will help make this easier to understand. Let me know if you have any questions.



来源:https://stackoverflow.com/questions/14057140/sqlite-access-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!