Al igual que con los otros complementos de webtoapp, su aplicación debe esperar el evento deviceready
.
Para abrir una base de datos:
var db = null; document.addEventListener('deviceready', function() { db = window.sqlitePlugin.openDatabase({ name: 'my.db', location: 'default', }); });
Using DRAFT standard transaction API
Para completar una base de datos utilizando la API de transacciones estándar BORRADOR:
db.transaction(function(tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS DemoTable (name, score)'); tx.executeSql('INSERT INTO DemoTable VALUES (?,?)', ['Alice', 101]); tx.executeSql('INSERT INTO DemoTable VALUES (?,?)', ['Betty', 202]); }, function(error) { console.log('Transaction ERROR: ' + error.message); }, function() { console.log('Populated database OK'); });
o utilizando parámetros numerados como se documenta en https://www.sqlite.org/c3ref/bind_blob.html
db.transaction(function(tx) { tx.executeSql('CREATE TABLE IF NOT EXISTS DemoTable (name, score)'); tx.executeSql('INSERT INTO DemoTable VALUES (?1,?2)', ['Alice', 101]); tx.executeSql('INSERT INTO DemoTable VALUES (?1,?2)', ['Betty', 202]); }, function(error) { console.log('Transaction ERROR: ' + error.message); }, function() { console.log('Populated database OK'); });
Para verificar los datos utilizando la API de transacción estándar BORRADOR:
db.transaction(function(tx) { tx.executeSql('SELECT count(*) AS mycount FROM DemoTable', [], function(tx, rs) { console.log('Record count (expected to be 2): ' + rs.rows.item(0).mycount); }, function(tx, error) { console.log('SELECT error: ' + error.message); }); });
Using plugin-specific API calls
Para completar una base de datos utilizando la API por lotes de SQL:
db.sqlBatch([ 'CREATE TABLE IF NOT EXISTS DemoTable (name, score)', [ 'INSERT INTO DemoTable VALUES (?,?)', ['Alice', 101] ], [ 'INSERT INTO DemoTable VALUES (?,?)', ['Betty', 202] ], ], function() { console.log('Populated database OK'); }, function(error) { console.log('SQL batch ERROR: ' + error.message); });
o utilizando parámetros numerados como se documenta en https://www.sqlite.org/c3ref/bind_blob.html
db.sqlBatch([ 'CREATE TABLE IF NOT EXISTS DemoTable (name, score)', [ 'INSERT INTO DemoTable VALUES (?1,?2)', ['Alice', 101] ], [ 'INSERT INTO DemoTable VALUES (?1,?2)', ['Betty', 202] ], ], function() { console.log('Populated database OK'); }, function(error) { console.log('SQL batch ERROR: ' + error.message); });
Para comprobar los datos utilizando la API de declaración SQL única:
db.executeSql('SELECT count(*) AS mycount FROM DemoTable', [], function(rs) { console.log('Record count (expected to be 2): ' + rs.rows.item(0).mycount); }, function(error) { console.log('SELECT SQL statement ERROR: ' + error.message); });
AutoTest
Pruebe los siguientes programas para verificar la instalación y el funcionamiento exitosos:
verifique la instalación y compilación exitosas:
document.addEventListener('deviceready', function() { window.sqlitePlugin.echoTest(function() { console.log('ECHO test OK'); }); });
verificar automáticamente las operaciones básicas de acceso a la base de datos, incluida la apertura de una base de datos; operaciones CRUD básicas (crear datos en una tabla, leer los datos de la tabla, actualizar los datos y eliminar los datos); cerrar y eliminar la base de datos:
document.addEventListener('deviceready', function() { window.sqlitePlugin.selfTest(function() { console.log('SELF test OK'); }); });
Prueba de cadena SQL
Esta prueba verifica que puede abrir una base de datos, ejecutar una declaración SQL básica y obtener los resultados (debe ser TEST STRING):
document.addEventListener('deviceready', function() { var db = window.sqlitePlugin.openDatabase({name: 'test.db', location: 'default'}); db.transaction(function(tr) { tr.executeSql("SELECT upper('Test string') AS upperString", [], function(tr, rs) { console.log('Got upperString result: ' + rs.rows.item(0).upperString); }); }); });
Aquí hay una variación que usa un parámetro SQL en lugar de una cadena literal:
document.addEventListener('deviceready', function() { var db = window.sqlitePlugin.openDatabase({name: 'test.db', location: 'default'}); db.transaction(function(tr) { tr.executeSql('SELECT upper(?) AS upperString', ['Test string'], function(tr, rs) { console.log('Got upperString result: ' + rs.rows.item(0).upperString); }); }); });
Abrir una base de datos
Para abrir un objeto de identificador de acceso a la base de datos (en la nueva ubicación predeterminada):
var db = window.sqlitePlugin.openDatabase({name: 'my.db', location: 'default'}, successcb, errorcb);
Advertencia: en caso de que una aplicación acceda a la misma base de datos utilizando varios complementos, existe el riesgo de corrupción de datos ref: como se describe en https://www.sqlite.org/howtocorrupt.html . La solución es utilizar la androidDatabaseProvider: 'system'
configuración como se describe en la sección de implementación de SQLite de Android a continuación.
Web SQL replacement tip
para sobrescribir window.openDatabase
window.openDatabase = function(dbname, ignored1, ignored2, ignored3) { return window.sqlitePlugin.openDatabase({ name: dbname, location: 'default' }); };
Proveedor de base de datos de Android
De forma predeterminada, este complemento utiliza android-sqlite-native-ndk-connector
, que es liviano y debería ser más eficiente que el proveedor de bases de datos del sistema Android. Para utilizar en su lugar la implementación del proveedor de base de datos integrado del sistema Android:
var db = window.sqlitePlugin.openDatabase({ name: 'my.db', location: 'default', androidDatabaseProvider: 'system' });
Solución alternativa para el problema de bloqueo de la base de datos de Android
- (a veces) hay un bloqueo inesperado en la base de datos
- los datos que se insertaron se pierden.
Esto no es un problema cuando android-sqlite-native-ndk-connector
se utiliza la implementación de base de datos predeterminada, que es el caso cuando no se utiliza androidDatabaseProvider
ninguna configuración.androidDatabaseImplementation
Existe una solución alternativa que simplemente cierra y vuelve a abrir el archivo de la base de datos al final de cada transacción confirmada. La solución alternativa se habilita abriendo la base de datos con las siguientes opciones:
var db = window.sqlitePlugin.openDatabase({ name: 'my.db', location: 'default', androidDatabaseProvider: 'system' androidLockWorkaround: 1 });
NOTA IMPORTANTE: Esta solución alternativa solo se aplica cuando se usa db.sqlBatch
o db.transaction()
, no se aplica cuando se ejecuta executeSql()
en el objeto de la base de datos.
Transacciones SQL
Esta versión del complemento admite los siguientes tipos de transacciones SQL:
- Transacciones de un solo estado de cuenta
- Transacciones por lotes SQL
- BORRADOR Transacciones asíncronas estándar
NOTA: Las solicitudes de transacciones se mantienen en una cola por base de datos y se ejecutan en orden secuencial, de acuerdo con la API HTML5/Web SQL (DRAFT).
ADVERTENCIA: Es posible solicitar una lista de declaraciones SQL como «SELECT 1; SELECT 2» dentro de una única cadena de declaraciones SQL; sin embargo, el complemento solo ejecutará la primera declaración e ignorará silenciosamente las demás. Esto podría provocar una pérdida de datos si se incluye dicha lista de declaraciones SQL con declaraciones INSERT o UPDATE.
Muestra con INSERTAR:
db.executeSql('INSERT INTO MyTable VALUES (?)', ['test-value'], function (resultSet) { console.log('resultSet.insertId: ' + resultSet.insertId); console.log('resultSet.rowsAffected: ' + resultSet.rowsAffected); }, function(error) { console.log('SELECT error: ' + error.message); });
o usando parámetros numerados como se documenta en https://www.sqlite.org/c3ref/bind_blob.html:
db.executeSql('INSERT INTO MyTable VALUES (?1)', ['test-value'], function (resultSet) { console.log('resultSet.insertId: ' + resultSet.insertId); console.log('resultSet.rowsAffected: ' + resultSet.rowsAffected); }, function(error) { console.log('SELECT error: ' + error.message); });
Muestra con SELECT:
db.executeSql("SELECT LENGTH('tenletters') AS stringlength", [], function (resultSet) { console.log('got stringlength: ' + resultSet.rows.item(0).stringlength); }, function(error) { console.log('SELECT error: ' + error.message); });
NOTA/error menor: el objeto devuelto por resultSet.rows.item(rowNumber) no es inmutable. Además, varias llamadas a resultSet.rows.item(rowNumber) con el mismo número de fila en el mismo objeto resultSet devuelven el mismo objeto. Por ejemplo, el siguiente código mostrará el segundo resultado de texto superior: OTRO:
db.executeSql("SELECT UPPER('First') AS uppertext", [], function (resultSet) { var obj1 = resultSet.rows.item(0); obj1.uppertext = 'ANOTHER'; console.log('Second uppertext result: ' + resultSet.rows.item(0).uppertext); console.log('SELECT error: ' + error.message); });
Transacciones por lotes SQL
Muestra:
db.sqlBatch([ 'DROP TABLE IF EXISTS MyTable', 'CREATE TABLE MyTable (SampleColumn)', [ 'INSERT INTO MyTable VALUES (?)', ['test-value'] ], ], function() { db.executeSql('SELECT * FROM MyTable', [], function (resultSet) { console.log('Sample column value: ' + resultSet.rows.item(0).SampleColumn); }); }, function(error) { console.log('Populate table error: ' + error.message); });
o usando parámetros numerados como se documenta en https://www.sqlite.org/c3ref/bind_blob.html:
db.sqlBatch([ 'CREATE TABLE MyTable IF NOT EXISTS (name STRING, balance INTEGER)', [ 'INSERT INTO MyTable VALUES (?1,?2)', ['Alice', 100] ], [ 'INSERT INTO MyTable VALUES (?1,?2)', ['Betty', 200] ], ], function() { console.log('MyTable is now populated.'); }, function(error) { console.log('Populate table error: ' + error.message); });
En caso de error, todos los cambios en un lote de SQL se descartan automáticamente mediante ROLLBACK.
Transacciones asíncronas estándar
Las transacciones asíncronas estándar BORRADOR siguen la API HTML5/Web SQL (DRAFT) que está muy bien documentada y utiliza BEGIN y COMMIT o ROLLBACK para mantener las transacciones a salvo de fallos. Aquí hay un ejemplo simple:
Muestra con SELECT:
db.transaction(function(tx) { tx.executeSql('DROP TABLE IF EXISTS MyTable'); tx.executeSql('CREATE TABLE MyTable (SampleColumn)'); tx.executeSql('INSERT INTO MyTable VALUES (?)', ['test-value'], function(tx, resultSet) { console.log('resultSet.insertId: ' + resultSet.insertId); console.log('resultSet.rowsAffected: ' + resultSet.rowsAffected); }, function(tx, error) { console.log('INSERT error: ' + error.message); }); }, function(error) { console.log('transaction error: ' + error.message); }, function() { console.log('transaction ok'); });
o usando parámetros numerados como se documenta en https://www.sqlite.org/c3ref/bind_blob.html:
db.transaction(function(tx) { tx.executeSql('DROP TABLE IF EXISTS MyTable'); tx.executeSql('CREATE TABLE MyTable (SampleColumn)'); tx.executeSql('INSERT INTO MyTable VALUES (?1)', ['test-value'], function(tx, resultSet) { console.log('resultSet.insertId: ' + resultSet.insertId); console.log('resultSet.rowsAffected: ' + resultSet.rowsAffected); }, function(tx, error) { console.log('INSERT error: ' + error.message); }); }, function(error) { console.log('transaction error: ' + error.message); }, function() { console.log('transaction ok'); });
En el caso de una transacción de solo lectura, es posible utilizar readTransaction que no utilizará BEGIN, COMMIT ni ROLLBACK:
db.readTransaction(function(tx) { tx.executeSql("SELECT UPPER('Some US-ASCII text') AS uppertext", [], function(tx, resultSet) { console.log("resultSet.rows.item(0).uppertext: " + resultSet.rows.item(0).uppertext); }, function(tx, error) { console.log('SELECT error: ' + error.message); }); }, function(error) { console.log('transaction error: ' + error.message); }, function() { console.log('transaction ok'); });
Muestra con función PRAGMA
Crea una tabla, agrega una sola entrada y luego consulta el recuento para verificar si el elemento se insertó como se esperaba. Tenga en cuenta que se crea una nueva transacción en medio de la primera devolución de llamada.
// Wait for webtoappx to load document.addEventListener('deviceready', onDeviceReady, false); // webtoappx is ready function onDeviceReady() { var db = window.sqlitePlugin.openDatabase({name: 'my.db', location: 'default'}); db.transaction(function(tx) { tx.executeSql('DROP TABLE IF EXISTS test_table'); tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (id integer primary key, data text, data_num integer)'); // demonstrate PRAGMA: db.executeSql("pragma table_info (test_table);", [], function(res) { console.log("PRAGMA res: " + JSON.stringify(res)); }); tx.executeSql("INSERT INTO test_table (data, data_num) VALUES (?,?)", ["test", 100], function(tx, res) { console.log("insertId: " + res.insertId + " -- probably 1"); console.log("rowsAffected: " + res.rowsAffected + " -- should be 1"); db.transaction(function(tx) { tx.executeSql("select count(id) as cnt from test_table;", [], function(tx, res) { console.log("res.rows.length: " + res.rows.length + " -- should be 1"); console.log("res.rows.item(0).cnt: " + res.rows.item(0).cnt + " -- should be 1"); }); }); }, function(e) { console.log("ERROR: " + e.message); }); }); }
NOTA IMPORTANTE: Las declaraciones PRAGMA deben ejecutarse en executeSql()
el objeto de la base de datos (es decir db.executeSql()
, ) y NO dentro de una transacción.
Ejemplo con anidamiento a nivel de transacción
En este caso, la misma transacción en la primera devolución de llamada de ejecutarSql() se reutiliza para ejecutar ejecutarSql() nuevamente.
document.addEventListener('deviceready', onDeviceReady, false); // webtoappx is ready function onDeviceReady() { var db = window.sqlitePlugin.openDatabase({name: 'my.db', location: 'default'}); db.transaction(function(tx) { tx.executeSql('DROP TABLE IF EXISTS test_table'); tx.executeSql('CREATE TABLE IF NOT EXISTS test_table (id integer primary key, data text, data_num integer)'); tx.executeSql("INSERT INTO test_table (data, data_num) VALUES (?,?)", ["test", 100], function(tx, res) { console.log("insertId: " + res.insertId + " -- probably 1"); console.log("rowsAffected: " + res.rowsAffected + " -- should be 1"); tx.executeSql("select count(id) as cnt from test_table;", [], function(tx, res) { console.log("res.rows.length: " + res.rows.length + " -- should be 1"); console.log("res.rows.item(0).cnt: " + res.rows.item(0).cnt + " -- should be 1"); }); }, function(tx, e) { console.log("ERROR: " + e.message); }); }); }
Este caso también funcionará con Safari (WebKit), suponiendo que lo reemplace window.sqlitePlugin.openDatabase
con window.openDatabase
.
Cerrar un objeto de base de datos
Esto invalidará todos los objetos de identificador de acceso para la base de datos que está cerrada:
db.close(successcb, errorcb);
Está bien cerrar la base de datos dentro de una devolución de llamada de transacción, pero NO dentro de una devolución de llamada de declaración. El siguiente ejemplo está bien:
db.transaction(function(tx) { tx.executeSql("SELECT LENGTH('tenletters') AS stringlength", [], function(tx, res) { console.log('got stringlength: ' + res.rows.item(0).stringlength); }); }, function(error) { // OK to close here: console.log('transaction error: ' + error.message); db.close(); }, function() { // OK to close here: console.log('transaction ok'); db.close(function() { console.log('database is closed ok'); }); });
El siguiente ejemplo NO ESTÁ BIEN:
// BROKEN: db.transaction(function(tx) { tx.executeSql("SELECT LENGTH('tenletters') AS stringlength", [], function(tx, res) { console.log('got stringlength: ' + res.rows.item(0).stringlength); // BROKEN - this will trigger the error callback: db.close(function() { console.log('database is closed ok'); }, function(error) { console.log('ERROR closing database'); }); }); });
ERROR: Actualmente NO es posible cerrar una base de datos en una db.executeSql
devolución de llamada. Por ejemplo:
// BROKEN DUE TO BUG: db.executeSql("SELECT LENGTH('tenletters') AS stringlength", [], function (res) { var stringlength = res.rows.item(0).stringlength; console.log('got stringlength: ' + res.rows.item(0).stringlength); // BROKEN - this will trigger the error callback DUE TO BUG: db.close(function() { console.log('database is closed ok'); }, function(error) { console.log('ERROR closing database'); }); });
SEGUNDO ERROR: Cuando se cierra una conexión de base de datos, todas las transacciones en cola quedan suspendidas. TODO: Todas las transacciones pendientes deben generar errores cada vez que se cierra una conexión a la base de datos.
Borrar database
window.sqlitePlugin.deleteDatabase({name: 'my.db', location: 'default'}, successcb, errorcb);
ERROR: Cuando se elimina una base de datos, todas las transacciones en cola para esa base de datos quedan suspendidas. TODO: Todas las transacciones pendientes deben tener errores cuando se elimina una base de datos.
Prueba de instalación
Utilice window.sqlitePlugin.echoTest y/o window.sqlitePlugin.selfTest como se describe arriba (espere el evento de dispositivo listo).
window.sqlitePlugin.openDatabase({ name: 'hello-world.db', location: 'default' }, function (db) { db.executeSql("select length('tenletters') as stringlength", [], function (res) { var stringlength = res.rows.item(0).stringlength; console.log('got stringlength: ' + stringlength); document.getElementById('deviceready').querySelector('.received').innerHTML = 'stringlength: ' + stringlength; }); });
Abra la base de datos y cree una tabla.
Llame a la función openDatabase() para comenzar, pasando el nombre y la ubicación de la base de datos.
var db = window.sqlitePlugin.openDatabase({ name: 'my.db', location: 'default' }, function (db) { // Here, you might create or open the table. }, function (error) { console.log('Open database ERROR: ' + JSON.stringify(error)); });
Cree una tabla con tres columnas para nombre, apellido y número de cuenta de cliente. Si la tabla ya existe, esta instrucción SQL abre la tabla.
db.transaction(function (tx) { // ... tx.executeSql('CREATE TABLE customerAccounts (firstname, lastname, acctNo)'); }, function (error) { console.log('transaction error: ' + error.message); }, function () { console.log('transaction ok'); });
Al incluir la llamada a la función ejecutarSql() anterior en db.transaction(), haremos que estas tareas sean asincrónicas. Si lo desea, puede utilizar varias declaraciones de ejecución SQL() dentro de una sola transacción (no se muestra).
Agregar una fila a la base de datos
Agregue una fila a la base de datos usando la instrucción INSERT INTO SQL.
function addItem(first, last, acctNum) { db.transaction(function (tx) { var query = "INSERT INTO customerAccounts (firstname, lastname, acctNo) VALUES (?,?,?)"; tx.executeSql(query, [first, last, acctNum], function(tx, res) { console.log("insertId: " + res.insertId + " -- probably 1"); console.log("rowsAffected: " + res.rowsAffected + " -- should be 1"); }, function(tx, error) { console.log('INSERT error: ' + error.message); }); }, function(error) { console.log('transaction error: ' + error.message); }, function() { console.log('transaction ok'); }); }
Para agregar algunas filas reales en su aplicación, llame a la función addItem varias veces.
addItem("Fred", "Smith", 100); addItem("Bob", "Yerunkle", 101); addItem("Joe", "Auzomme", 102); addItem("Pete", "Smith", 103);
Leer datos de la base de datos.
Agregue código para leer de la base de datos usando una instrucción SELECT. Incluya una condición WHERE para hacer coincidir el conjunto de resultados con el apellido pasado.
function getData(last) { db.transaction(function (tx) { var query = "SELECT firstname, lastname, acctNo FROM customerAccounts WHERE lastname = ?"; tx.executeSql(query, [last], function (tx, resultSet) { for(var x = 0; x < resultSet.rows.length; x++) { console.log("First name: " + resultSet.rows.item(x).firstname + ", Acct: " + resultSet.rows.item(x).acctNo); } }, function (tx, error) { console.log('SELECT error: ' + error.message); }); }, function (error) { console.log('transaction error: ' + error.message); }, function () { console.log('transaction ok'); }); }
Eliminar una fila de la base de datos
Agregue una función para eliminar una fila de la base de datos que coincida con el número de cuenta del cliente pasado.
function removeItem(acctNum) { db.transaction(function (tx) { var query = "DELETE FROM customerAccounts WHERE acctNo = ?"; tx.executeSql(query, [acctNum], function (tx, res) { console.log("removeId: " + res.insertId); console.log("rowsAffected: " + res.rowsAffected); }, function (tx, error) { console.log('DELETE error: ' + error.message); }); }, function (error) { console.log('transaction error: ' + error.message); }, function () { console.log('transaction ok'); }); }
Actualizar filas en la base de datos.
Agregue una función para actualizar filas en la base de datos para registros que coincidan con el número de cuenta del cliente pasado. De esta forma, el extracto actualizará varias filas si los números de cuenta no son únicos.
function updateItem(first, id) { // UPDATE Cars SET Name='Skoda Octavia' WHERE Id=3; db.transaction(function (tx) { var query = "UPDATE customerAccounts SET firstname = ? WHERE acctNo = ?"; tx.executeSql(query, [first, id], function(tx, res) { console.log("insertId: " + res.insertId); console.log("rowsAffected: " + res.rowsAffected); }, function(tx, error) { console.log('UPDATE error: ' + error.message); }); }, function(error) { console.log('transaction error: ' + error.message); }, function() { console.log('transaction ok'); }); }
Para llamar a la función anterior, agregue código como este en su aplicación.
updateItem("Yme", 102);
Cerrar Base de datos
Cuando haya terminado con sus transacciones, cierre la base de datos. Llame a closeDB dentro de las devoluciones de llamada de éxito o fracaso de la transacción (en lugar de las devoluciones de llamada para ejecutarSql()).
function closeDB() { db.close(function () { console.log("DB closed!"); }, function (error) { console.log("Error closing DB:" + error.message); }); }