Using Cordova-sqlite-storage plugin - javascript

I am using Cordova-sqlite plugin in order to select and insert data to database embedded in an Android device. In my case I create the database from the native code and then I am trying to read some data from JavaScript source. But, I think that JavaScript is not reading from the same location as Android do.
This is my JS file :
var db = window.sqlitePlugin.openDatabase({name: 'db',iosDatabaseLocation: 'Library'});
var session = this._sessionInfoService.getSessionInfo();
db.transaction(function (tx)
{
var firstName = session.firstName;
var lastName = session.lastName;
var userId = session.id;
tx.executeSql("CREATE TABLE IF NOT EXISTS user (user_id INTEGER, firstname VARCHAR, lastname VARCHAR)");
tx.executeSql('SELECT * FROM user', [], function (tx, results) {
var len = results.rows.length, i;
console.log(len);
for (i = 0; i < len; i++){
var id =results.rows.item(i).user_id;
console.log(results.rows.item(i).user_id );
if(id!=userId){
var dialogTitle = "Another user is already registred for this device";
var dialogText = "Do you want to override it ";
WL.SimpleDialog.show(dialogTitle, dialogText, [ {
text : 'Override',
handler : function(){
db = window.sqlitePlugin.openDatabase({name: 'db',iosDatabaseLocation: 'Library'});
db.transaction(function (tx)
{
tx.executeSql("UPDATE user SET user_id =?, firstname=?, lastname=?", [userId,firstName,lastName]);
}
}
}, {
text : 'No',
handler : function(){
db = window.sqlitePlugin.openDatabase({name: 'db',iosDatabaseLocation: 'Library'});
db.transaction(function (tx)
{
tx.executeSql("INSERT INTO user (user_id,firstname, lastname) VALUES(?,?,?)", [userId,firstName,lastName]);
}
}
}
]);
}
else{
}
}
}, null);
}
});
}
and this is my java file in native source
#Override
public void onStart(Intent intent, int startId) {
final SQLiteDatabase db = openOrCreateDatabase("db",
Context.MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS user (user_id INT, firstname VARCHAR, lastname VARCHAR);");
Log.i("e2", "yes");
db.execSQL("INSERT INTO user (user_id,firstname,lastname) VALUES(91,'ess','ess');");
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
String query = "SELECT * FROM user";
Cursor c = db.rawQuery(query, null);
if (c != null && c.moveToFirst()) {
int userId=c.getInt(1);
System.out.println("userId"+userId);
Log.i("userId",String.valueOf(userId));
}
}
catch(e){}
}
});
thread.start();
}
When try to create my database and my user table from JavaScript and then do the select from java file I am facing an exception : the table user is unknown and when I select users from the JS I always get an empty list . That's why I think that my code creates two databases with the same name but in two different locations.

Related

Procedure or function "registerStudent" expects parameter "#EmailUsername", which was not supplied.'

Other people have ran into this similar issue, however I am pretty positive that I'm passing in parameters as necessary, and that I have command type set to stored procedure. I also do a console log in JavaScript file to output whatever is in the textboxes, and yet there is still some error with the API it seems. I need another set of eyes to hopefully find something that I'm missing. Thanks for any help in advance.
JavaScript Code
function registerStudent()
{
var studentID = document.getElementById('id').value;
var studentEmail = document.getElementById('email').value;
var studentEmailPassword = document.getElementById('password').value;
var studentFirstName = document.getElementById('firstname').value;
var studentLastName = document.getElementById('lastname').value;
console.log(studentID + "," + studentEmail + "," + studentEmailPassword + "," + studentFirstName + "," + studentLastName);
if ((studentID=='') || (studentEmail=='') || (studentEmailPassword=='') || (studentFirstName=='') || (studentLastName==''))
{
alert("Please fill in all fields to register");
return false;
}
var postObj = {
ID: studentID,
EmailUsername: studentEmail,
EmailPassword: studentEmailPassword,
FirstName: studentFirstName,
LastName: studentLastName
};
var apiRequest = new XMLHttpRequest();
apiRequest.open('POST', 'https://localhost:44379/api/JSON/registerStudent', true);
apiRequest.setRequestHeader('Content-Type', 'application/json');
apiRequest.onreadystatechange = function()
{
if (this.readyState === XMLHttpRequest.DONE && this.status === 200)
{
if (apiRequest.response=="-1")
{
alert("User already exists");
return false;
}
if (apiRequest.response=="1")
{
alert("User registered");
return false;
}
}
}
apiRequest.send(JSON.stringify(postObj));
return false;
}
C# ASP.NET RESTFUL WEB API CODE
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.IO;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Http.Cors;
namespace AiAngelsAPI.Controllers
{
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class JSONController : ApiController
{
/********************
* Register Student
********************/
[System.Web.Http.HttpPost]
public object registerStudent(Models.RegisterStudent student)
{
var response = Request.CreateResponse(HttpStatusCode.OK);
string sqlStoredProcedureName = "registerStudent";
var json = ExecuteRegisterStudent(sqlStoredProcedureName, student.id, student.email, student.password, student.firstname, student.lastname);
response.Content = new StringContent(json);
return response;
}
private static string ExecuteRegisterStudent(string storedProcedureNameSqlQuery, string studentID, string emailUsername, string emailPassword, string firstname, string lastname)
{
string json = "";
string connectionString = ConfigurationManager.AppSettings["databaseConnection"].ToString();
using (SqlConnection databaseConnection = new SqlConnection(connectionString))
{
databaseConnection.Open();
// 1. create a command object identifying the stored procedure
SqlCommand command = new SqlCommand(storedProcedureNameSqlQuery, databaseConnection);
// 2. set the command object so it knows to execute a stored procedure
command.CommandType = CommandType.StoredProcedure;
// 3. add parameter to command, which will be passed to the stored procedure
command.Parameters.Add(new SqlParameter("#ID", studentID));
command.Parameters.Add(new SqlParameter("#EmailUsername", emailUsername));
command.Parameters.Add(new SqlParameter("#EmailPassword", emailPassword));
command.Parameters.Add(new SqlParameter("#FirstName", firstname));
command.Parameters.Add(new SqlParameter("#Lastname", lastname));
// execute the command
using (SqlDataReader returnData = command.ExecuteReader())
{
// iterate through results, printing each to console
while (returnData.Read())
{
json = (string)returnData[0].ToString();
}
}
}
return json;
}
}
}
SQL Stored Procedure Code
ALTER PROCEDURE [dbo].[registerStudent]
-- variables that will be passed into stored procedure (input)
#ID varchar(16),
#EmailUsername varchar(100),
#EmailPassword varchar(50),
#FirstName varchar(100),
#LastName varchar(100)
AS
BEGIN
-- if structure to check if student already exists/has registered
if 1 = (select count(*)
from [dbo].[Student]
where [studentEmailUsername] = #EmailUsername)
begin
select -1; -- student already exists, returns -1 as indicator
return;
end
-- inserts input into table/registers student by adding to database
insert into [dbo].[Student] (studentID,studentEmailUsername,studentEmailPassword,studentFirstName,studentLastName)
values (#ID,#EmailUsername,#EmailPassword,#FirstName,#LastName)
select 1; -- student is added to database, returns 1 as indicator
return;
END
Error in API
Click here to see error that comes up in API

nodejs sql error Error converting data type varchar to int [duplicate]

I am changing my application's database from MySQL to MSSQL. I send parameters like below for MySQL database.
var sql = require('./db.js');
sql.query("select * from table where field1 = ? or field2 = ? ", [field1val, field2val], function (error, results) {
if(error){
//handle error
}
else{
//handle the results
}
}
How to do this in MSSQL or is it even possible to do this way? (I am using mssql module).
The stored procedure is the only way to achieve it? If so, how to do that in Nodejs mssql module?
What is the best practice to run a query in SQL server if we can't send parameter (which escapes the string in mysql automatically)?
I do parameterized SQL queries like this:
var sql = require('mssql');
var myFirstInput = "foo bar";
var mySecondInput = "hello world";
sql.input('inputField1', sql.VarChar, myFirstInput);
sql.input('inputField2', sql.VarChar, mySecondInput);
sql.query("SELECT * FROM table WHERE field1 = #inputField1 OR field2 = #inputField2")
.then(function(results)
{
//do whatever you want with the results
console.log(results)
})
.catch(function(error)
{
//do whatever when you get an error
console.log(error)
})
What happens here is that the sql.input('inputField1', sql.VarChar, myFirstInput) will change out the #inputField1 with the variable named myFirstInput. Same thing will happen for #inputField2 with mySecondInput.
This will help it from SQL injections
var sql = require('./db.js');
sql.query(`select * from table where field1 = ${field1val} or field2 = ${field2val}`, function (error, results) {
if(error){
//handle error
}
else{
//handle the results
}
}
I think, it works for you :)
You can use try like this
var id = 1234
var query = (SQL
`SELECT fname, lname, email
FROM users
WHERE id = ${id}`
)
var sql = require('./db.js');
sql.query("select * from table where field1 = ${field1val} or field2 = ${field2val} ", [field1val, field2val], function (error, results) {
if(error){
//handle error
}
else{
//handle the results
}
}

ASP.NET web app with Javascript - properly populate database columns

Creating a CRUD app in ASP.NET with C#, Javascript and SQL Server 2017.
The database table has three columns, Country, CountryCode and CountryCodeId that I'm attempting to populate with a create function (yes I'm aware of the relational design flaw here - that's outside of the scope of the question)...
I have an enum class that looks like this:
public enum Country
{
[Description("Afghanistan")] AFG = 1,
[Description("Ă…land Islands")] ALA = 2,
[Description("Albania")] ALB = 3,
}
I have a dropdown menu in the UI which displays the names of the country as shown in the Description piece above. Let's say the chosen value of the dropdown is Afghanistan. What I need to do upon execution of the create function is populate the Country column of the database with Afghanistan, the CountryCodecolumn with AFG and the CountryCodeId column with 1.
My Javascript skills are what are the most lacking, and I can only get the CountryCodeId to work, out of the three. This is my JS code - the question marks are where I'm lost:
async function newRecord(form) {
var record = {};
record.countryCodeId = $('#country').val();
record.countryCode = $("???").val();
record.country = $("???").val();
var response = await fetch(`${endpoint}api/record`, {
method: 'POST',
crossDomain: true,
cache: 'no-cache',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(record)
});
EDIT 1: as requested, here is the C# Insertfunction:
public bool Insert(Record record)
{
SqlConnection connection = new SqlConnection(_configuration.GetConnectionString("Production"));
connection.Open();
using (connection)
{
string query = "INSERT INTO [dbo].[Table]" +
"([Country]" +
",[CountryCode]" +
",[CountryCodeId]")
"VALUES " +
"(#Country" +
",#CountryCode" +
",#CountryCodeId")";
return connection.Execute(query, record) > 0;
}
}
EDIT 2:
Controller action method for Insert:
[HttpPost]
public JsonResult Insert(Record record)
{
try
{
bool result = _repository.Insert(record);
return new JsonResult(new OperationResult { Success = true });
}
catch (Exception ex)
{
return new JsonResult(new OperationResult { Success = false, Error = ex.Message });
}
}
Try this: -
using System.ComponentModel;
.
.
void ProcessCountry(string countryCode)
{
Country country;
// i.e. countryCode = "AFG"
if (Enum.TryParse(countryCode, out country))
{
string description = null;
try
{
FieldInfo fieldInfo = country.GetType().GetField(country.ToString());
DescriptionAttribute[] attributes =
(DescriptionAttribute[])
fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
description = ((attributes.Length != 0) ?
attributes[0].Description :
country.ToString());
}
catch (System.NullReferenceException)
{
}
finally
{
if (string.IsNullOrEmpty(description))
{
description = "Unknown";
}
}
int value = Convert.ToInt32(country);
Console.Write($"countryCode: {countryCode}, description: {description}, value: {value}");
}
}
The FieldInfo/DescriptionAttribute stuff pulls the description out of the System.ComponentModel.Description attribute, and as you've given your enum values INT values then you can parse them as Int.

better approach to access datatabase and creating models in cross platform apps

for example , i have been using following approach in my cross platform apps to accessing sqlite database as follows
To access database i have made a saperate .js for UserProfile table
function DBUserProfile()
{
this.selectUserName = function(userId, callback)
{
try
{
//Get Data
localDB.transaction(function selectUserProfileData(tx)
{
var objDBDatabaseSchema = new DBDatabaseSchema();
var sqlCommand = 'SELECT username FROM '
+ objDBDatabaseSchema.UserProfileMetaData.USER_PROFILE_TABLE_NAME
+' WHERE engineer_id='
+ '="' + userId + '"';
objDBDatabaseSchema = null;
tx.executeSql(sqlCommand,[],function selectUserNameResult(tx, results)
{
if (results.rows.length > 0 )
{
var userId = results.rows.item(0).username ;
callback(userId);
}
else
{
var userId = "";
callback(userId);
}
}, errorDB);
}, errorDB);
}
catch (e)
{
// TODO: handle exception
console.log("DBUserProfile - selectUserName " + e);
}
};
}
and this is how i use them in a pages
var objDBUserProfile = new DBUserProfile();
objDBUserProfile.selectUserName("3443" , function(id){
//
});
but the above approach is pretty time consuming i have been end up creating lot of models and db files to access tables and lot of new objects , so does anyone has a better approach in jquery to cut down the development time. any suggestions are welcome

SQlite count query on virtual table always comes out to 1

I have a virtual table in sqlite and I'm running queries against it looking for matches of keywords but the count always comes out to 1. The structure is as follows.
var insertStatement2 = "INSERT INTO pagesfts3 (url,content) VALUES (?, ?)";
var createStatement2 = "CREATE VIRTUAL TABLE pagesfts3 USING fts3 (url VARCHAR,content TEXT)";
var selectStatement2 = "SELECT COUNT(*),url FROM pagesfts3 WHERE content MATCH ? GROUP BY url";
try {
var db = openDatabase("search", "1.0", "search engine", 200000);
db.transaction(function(tx) {
//for example use drop table on each load
tx.executeSql(dropStatement, [], null, onError);
tx.executeSql(dropStatement2, [], null, onError);
tx.executeSql(createStatement, [], null, onError);
tx.executeSql(createStatement2, [], null, onError);
});
db.transaction(function(tx) {
});
}
catch (error) {
$('body').prepend('<div class="alert alert-danger">This script requires a SQlite compatible browser<br/> try Safari 4, iOS OS3, Chrome 5, or Opera 10.5</div>');
}
function onError(tx, error) {
alert(error.message);
}
So basically I save a webpage data and its corresponding url. When I go to query the page I run this
var query = $('#query').val().toLowerCase();
var searchResults = $('#queryResult');
searchResults.html('');
db.transaction(function(tx) {
//run static select statment 2 on the virtual table
tx.executeSql(selectStatement2, [query], function(tx, result) {
var dataset = result.rows;
if (dataset.length > 0) {
for (var i = 0, item = null; i < dataset.length; i++) {
item = dataset.item(i);
console.debug(item);
var url = item['url'];
var count = item['COUNT(*)'];
var str = '<p>' + url + ' has the word <b>' + query + '</b></p>';
searchResults.append(str);
}
}else{
searchResults.append('no results');
}
});
});
But the column count(*) is always 1 even though I know they keyword is present more than 1 times. I'm not too familiar with virtual tables so maybe I'm missing something.

Categories

Resources