Trying to use localstorage example in Qt 5.14, the database is locked and can't be deleted.
on Qt documentation it's saying:
"Database connections are automatically closed during Javascript garbage collection."
but that is not the case...
function dbInit()
{
var db = LocalStorage.openDatabaseSync("Activity_Tracker_DB", "", "Track exercise", 1000000)
try {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS trip_log (date text,trip_desc text,distance numeric)')
})
} catch (err) {
console.log("Error creating table in database: " + err)
};
}
function dbGetHandle()
{
try {
var db = LocalStorage.openDatabaseSync("Activity_Tracker_DB", "",
"Track exercise", 1000000)
} catch (err) {
console.log("Error opening database: " + err)
}
return db
}
function dbInsert(Pdate, Pdesc, Pdistance)
{
var db = dbGetHandle()
var rowid = 0;
db.transaction(function (tx) {
tx.executeSql('INSERT INTO trip_log VALUES(?, ?, ?)',
[Pdate, Pdesc, Pdistance])
var result = tx.executeSql('SELECT last_insert_rowid()')
rowid = result.insertId
})
return rowid;
}
function dbReadAll()
{
var db = dbGetHandle()
db.transaction(function (tx) {var results = tx.executeSql(
'SELECT rowid,date,trip_desc,distance FROM trip_log order by rowid desc')
for (var i = 0; i < results.rows.length; i++) {
listModel.append({
id: results.rows.item(i).rowid,
checked: " ",
date: results.rows.item(i).date,
trip_desc: results.rows.item(i).trip_desc,
distance: results.rows.item(i).distance
})
}
})
}
How can I unlock/close the database?
Related
I have a table that has more than 25 items and wrote a basic script to break them into sub arrays of 25 items each then loops thru that collection of sub arrays to run a batch write item command in the AWS DynamoDB Client. The issue I am getting is a returned validation error. When I run the same seed file via the aws-cli it seeds the table perfectly. This makes me think it has something to do with my script. See anything I am missing? Thanks in advance!
var { DynamoDB } = require('aws-sdk');
var db = new DynamoDB.DocumentClient({
region: 'localhost',
endpoint: 'http://localhost:8000',
});
const allItems = require('./allItems.json');
const tableName = 'some-table-name';
console.log({ tableName, allItems });
var batches = [];
var currentBatch = [];
var count = 0;
for (let i = 0; i < allItems.length; i++) {
//push item to the current batch
count++;
currentBatch.push(allItems[i]);
if (count === 25) {
batches.push(currentBatch);
currentBatch = [];
}
}
//if there are still items left in the curr batch, add to the collection of batches
if (currentBatch.length > 0 && currentBatch.length !== 25) {
batches.push(currentBatch);
}
var completedRequests = 0;
var errors = false;
//request handler for DynamoDB
function requestHandler(err, data) {
console.log('In the request handler...');
return function (err, data) {
completedRequests++;
errors = errors ? true : err;
//log error
if (errors) {
console.error('Request caused a DB error.');
console.error('ERROR: ' + err);
console.error(JSON.stringify(err, null, 2));
} else {
var res = {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Methods': 'GET,POST,OPTIONS',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': true,
},
body: JSON.stringify(data),
isBase64Encoded: false,
};
console.log(`Success: returned ${data}`);
return res;
}
if (completedRequests == batches.length) {
return errors;
}
};
}
//Make request
var params;
for (let j = 0; j < batches.length; j++) {
//items go in params.RequestedItems.id array
//format for the items is {PutRequest : {Item: ITEM_OBJECT}}
params = '{"RequestItems": {"' + tableName + '": []}}';
params = JSON.parse(params);
params.RequestItems[tableName] = batches[j];
console.log('before db.batchWriteItem: ', params);
try {
//send to db
db.batchWrite(params, requestHandler(params));
} catch{
console.error(err)
}
}
Here is the formatted request object and the error:
before db.batchWriteItem:
{ RequestItems:
{ 'some-table-name': [ [Object], [Object], [Object], [Object] ] }
}
In the request handler...
Request caused a DB error.
ERROR: ValidationException: Invalid attribute value type
{
"message": "Invalid attribute value type",
"code": "ValidationException",
"time": "2020-08-04T10:51:13.751Z",
"requestId": "dd49628c-6ee9-4275-9349-6edca29636fd",
"statusCode": 400,
"retryable": false,
"retryDelay": 47.94198279972915
}
You are using the DocumentClient in the nodejs code. This will automatically convert the data format used by DynamoDB to a more easily consumable format.
e.g.
{
"id": {
"S": "A string value"
}
}
would become
{
"id": "A string value"
}
The CLI does not perform this data conversion.
You can use the regular DynamoDB client to not perform this conversion in Nodejs. e.g. const db = new Dynamodb()
I am using Ionic v1 and trying to INSERT a few JSON records into a SQLite database on Android Kitkat. If I use a static variable it works but only inserts first item in array, but if I try to make the variable names dynamic I get an error:
Cannot read property 'mac_id' of undefined
I have tried the two following code segments, first works but only inserts the first item in the JSON array, second does not working:
Works:
But only inserts first item (multiple times)
for ( var i = 0; i < data.length; i++)
{
var mac_id = data[i].mac_id;
var device_type = data[i].device_type;
var machine_id = data[i].machine_id;
var machine_name = data[i].machine_name;
var date_created = data[i].date_created;
db.transaction(function (tx) {
var query = "INSERT INTO devices (mac_id, device_type,machine_id,machine_name,date_created) VALUES (?,?,?,?,?)";
tx.executeSql(query, [mac_id , device_type , machine_id , machine_name , date_created ], function(tx, res) {
},
function(tx, error) {
console.log(' device INSERT error: ' + error.message);
});
}, function(error) {
console.log(' device transaction error: ' + error.message);
}, function() {
console.log('device INSERT ok');
});
}
Not Working
for ( var i = 0; i < data.length; i++)
{
db.transaction(function (tx) {
var query = "INSERT INTO devices (mac_id, device_type,machine_id,machine_name,date_created) VALUES (?,?,?,?,?)";
tx.executeSql(query, [data[i].mac_id, data[i].device_type, data[i].machine_id, data[i].machine_name, data[i].date_created ], function(tx, res) {
},
function(tx, error) {
console.log(' device INSERT error: ' + error.message);
});
}, function(error) {
console.log(' device transaction error: ' + error.message);
}, function() {
console.log('device INSERT ok');
});
}
JSON array
[
{
"id": "3",
"mac_id": "fsdf324324",
"device_type": "redvfsdfds",
"machine_id": "3",
"machine_name": "sdfsdfsdf",
"date_created": "3322342"
},
{
"id": "2",
"mac_id": "243434",
"device_type": "fredssd",
"machine_id": "2",
"machine_name": "fdsfsdf",
"date_created": "43434"
},
{
"id": "1",
"mac_id": "1324324234",
"device_type": "bweight",
"machine_id": "1",
"machine_name": "dffdgf",
"date_created": "4324234"
}
]
db.transaction(function (tx) {
for ( var i = 0; i < $scope.data.length; i++)
{
var query = "INSERT INTO devices (mac_id, device_type,machine_id,machine_name,date_created) VALUES (?,?,?,?,?)";
tx.executeSql(query, [data[i].mac_id, data[i].device_type, data[i].machine_id, data[i].machine_name, data[i].date_created ], function(tx, res) {
},function(tx, error) {
console.log(' device INSERT error: ' + error.message);
});
}
}, function(error) {
console.log(' device transaction error: ' + error.message);
}, function() {
console.log('device INSERT ok');
});
You should use for loop inside transaction . Use it like this . hope this helps :)
I am new to ionic.I want to add data into SQLite which is coming from remote server. I have successfully populated data into list.so how can i store this data into sqlite. here is my code. how do i pass this data to query.I am unable to do this.
service.js
angular.module('starter.service',[]).
factory('userServices',['$http',function($http){
var users = [];
return {
get: function(){
return $http.get("http://xxxxxxxxx-info").then(function(response){
users = response.data;
return users;
});
},
remove:function(content){
users.splice(users.indexOf(content),1);
},
getUser:function(chatId)
{
for(var i=0; i<users.length;i++){
if(users[i].content_id === parseInt(chatId)){
return users[i];
}
}
return null;
}
}
}]);
controller.js
angular.module('shoppingPad.controller', [])
.controller('ChatCtrl', function ($scope, userServices, $ionicModal, $cordovaSQLite) {
console.log('inside controller');
userServices.get().then(function (users) {
//users is an array of user objects
$scope.contents = users;
console.log($scope.contents);
var query = "INSERT INTO content (content_id, display_name) VALUES (?,?)";
$cordovaSQLite.execute(db, query, [users.content_id, users.display_name]).then(function (res) {
alert(res);
alert('Inserted');
}, function (e) {
alert('Error:' + e.message);
});
});
Where did you define db? It's necessary to wait until device is ready.
$ionicPlatform.ready(function () {
var db = $cordovaSQLite.openDB({ name: "my.db" });
// just first time you need to define content table
$cordovaSQLite.execute(db,"CREATE TABLE content (content_id integer, display_name text)");
userServices.get().then(function (users) {
//users is an array of user objects
$scope.contents = users;
console.log($scope.contents);
var query = "INSERT INTO content (content_id, display_name) VALUES (?,?)";
$cordovaSQLite.execute(db, query, [users.content_id, users.display_name]).then(function (res) {
alert(res);
alert('Inserted');
}, function (e) {
alert('Error:' + e.message);
});
});
});
Are you sure, that your object users look like
{
"content_id":12,
"display_name":"hello world"
}
and not like
[
{
"content_id":12,
"display_name":"hello world"
},
{
"content_id":13,
"display_name":"stackoverflow"
},
...
]
I just ask, because users sounds like more than one entry.
function outDb(outData) {
var temp;
var db = window.sqlitePlugin.openDatabase({ name: "test" });
db.executeSql("SELECT " + outData + " FROM test", [], function (res) {
switch (outData) {
case "goal": temp = res.rows.item(0).GOAL;
break;
case "curDate": temp = res.rows.item(0).CURDATE;
break;
case "Day1": temp = res.rows.item(0).DAY1;
break;
case "Day2": temp = res.rows.item(0).DAY2;
break;
case "Day3": temp = res.rows.item(0).DAY3;
break;
default: temp = "is default";
}
});
return temp;
}
I want to save data into myData;
var myData = outDb("goal");
But this is not working, because the return statement happens faster than the data is assigned to my variable.
What can I do?
You should use callback function because Cordova-sqlite-storage works asynchronously.
function getFromDB(_n, fn) {
var db = ...
db.transaction(function(tx) {
var query = "SELECT * FROM <table_name> WHERE <field_name> = ?";
tx.executeSql(query, [_n], function (tx, rs) {
for(var x = 0; x < rs.rows.length; x++) {
_res = rs.rows.item(x).value;
fn(_res);
}
}, function (tx, error) {
console.log('select error: ' + error.message);
});
}, function (error) {
console.log('transaction error: ' + error.message);
}, function () {
console.log('transaction ok.');
});}
getFromDB(<name>, function(val) {
console.log(val);});
All sqlite commands are event driven. That means, that you have to wait for values until the event is finished.
In your case: You will never get a return value, because your return is outside of the success function.
You could do a rewrite of your function like:
function outDb(outData) {
var temp;
var db = window.sqlitePlugin.openDatabase({ name: "test" });
db.executeSql("SELECT " + outData + " FROM test", [], function (res) {
switch (outData) {
case "goal": temp = res.rows.item(0).GOAL;
break;
case "curDate": temp = res.rows.item(0).CURDATE;
break;
case "Day1": temp = res.rows.item(0).DAY1;
break;
case "Day2": temp = res.rows.item(0).DAY2;
break;
case "Day3": temp = res.rows.item(0).DAY3;
break;
default: temp = "is default";
}
return temp;
});
}
A much better way is like I showed in this answer:
How to compact SQL instructions in Cordova?
This is my javascript for Adobe Air:
$(document).ready(function(e) {
setupDB();
var tasks = getTasks();
$("#tasks").empty();
var numRecords = tasks.data.length;
for(i=0; i<numRecords; i++) {
$("<li/>").append('<span>'+ tasks.data[i].id +' - '+ tasks.data[i].task +'</span>').appendTo("#tasks");
}
});
var db = new air.SQLConnection();
function setupDB() {
var dbFile = air.File.applicationStorageDirectory.resolvePath("airTasks.db");
try {
db.open(dbFile);
} catch (error) {
alert("DB Error: "+ error.message);
alert("Details: "+ error.details);
air.trace("DB Error: "+ error.message);
air.trace("Details: "+ error.details);
}
}
function getTasks() {
var query = new air.SQLStatement();
query.sqlConnection = db;
query.text = "SELECT id, task FROM tasks";
try {
query.execute();
} catch(error) {
alert("Error getting tasks from DB: "+ error.message +", DETAILS: "+ error.details);
air.trace("Error getting tasks from DB: "+ error);
air.trace(error.message);
return;
}
return query.getResults();
}
Here is a screenshot of the Database Version 3 - airTasks.db
I keep getting:
ERROR: Table "tasks" not found.
Double check that your filepath being opened actually exists. If it doesn't, SQLite creates one for you.
Try this to troubleshoot before you call db.open():
alert(dbFile);
Is this the correct path to your db?