loading sqlite database in javascript with sql.js - javascript

Can someone provide a simple complete example of loading an existing sqlite database not using node.js.
Assume that the sql db is sitting in same location as index.html
example:
I tried this example but "contents" is undefined. Also, I would not know how to access the data in "contents"? I could really use a complete example.
var xhr = new XMLHttpRequest();
xhr.open('GET', '/path/to/database.sqlite', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
var db = new SQL.Database(uInt8Array);
var contents = db.exec("SELECT * FROM my_table");
// contents is now [{columns:['col1','col2',...], values:[[first row], [second row], ...]}]
};
xhr.send();

I know this is old, but here you go my friend. You were right there, just a bit of tweaking. I am not sure if you are using the SQL.js library from GitHub but please do as it solves a lot of the browser security issues and makes the SQL side of things much easier on the brain.
If you didn't create the source or have some UTF issues the exceptions will be thrown. I wrote this in a night so I haven't run more than a few functions but I am assuming callbacks will be required to prevent SQLite issues during async processes. This is my first time using SQLite or the SQL.js library so I just don't know yet.
IMPORTANT!
This is a LOCAL solution only, it has more blatant vulnerabilities than a high school locker room. In no way should this ever be used on anything that is exposed to the internet.
This is all declared at the top of my class, not within a function. This is purposeful as I run multiple queries and didn't want the overhead of loading/unloading the object if it got too large.
Notice the fully qualified path on the source...relative paths didn't work for me.
var xhrLocal = new XMLHttpRequest();
xhrLocal.open('GET', 'http://localhost/mp3/data/media.sqlite', true);
xhrLocal.responseType = 'arraybuffer';
var localData;
xhrLocal.onload = function(e) {
var uInt8Array = new Uint8Array(this.response);
localData = new SQL.Database(uInt8Array);
};
xhrLocal.send();
At this point you have the database loaded into an object called localData and you can query it from anywhere. Here is a query I wrote to get Genre info.
function FillGenreLists() {
var sqlSel = 'SELECT * FROM GenreData';
var data = localData.exec(sqlSel);
var output = [];
$.each(data[0].values, function(key, value)
{
output.push('<option value="'+ value[0] +'">'+ value[1] +'</option>');
});
$('#selGenres').html(output.join(''));
}
The output from the SQL call is generally an array of arrays, don't worry about changing that, just output the result of your SQL call to the console and note the return fields and values, from there just use $.each to your hearts content.
Here is another query, same premise but with the goal of creating a SQL statement to push into MS SQL server and get FreeDB data about artists that are in my local collection.
Note: This could all be done in a single call by querying my local sqlite table, generating the sql and pushing it to the MS SQL using a different conn or even better by utilizing a generic proc but let's keep it simple for now.
function PrepareMSSQLFilteredFreeDBTables(StartLetter, EndLetter, TempTableName) {
var sqlSel = "SELECT * FROM ArtistData WHERE ArtistText BETWEEN '" + StartLetter + "' AND '" + EndLetter + "' ORDER BY ArtistText";
var data = localData.exec(sqlSel);
$('.array-cols').append('SELECT * INTO ' + TempTableName + ' FROM FreeDB WHERE DARTIST IN (');
var iLen = (data[0].values.length - 1);
$.each(data[0].values, function(a, b) {
var sRes;
if (a === iLen) { sRes = "'" + b[1].replace("'", "''") + "')"; }
else { sRes = "'" + b[1].replace("'", "''") + "', "; }
$('.array-cols').append(sRes);
});
}

Related

JavaScript - How to send multiple XMLHttp requests or force the XMLHTTP request to wait till I get the desired response?

I am making a GET request to the api using XMLHttpRequests. The api takes in a "uuid" value denoted by the variable "a" here as a parameter, uses that value for processing and is supposed to spit out some information that I am trying to print to the console.
However, the problem I am running into is that, whenever the api successfully receives the uuid value it returns a message where the newresponse.response.status is Initiated. However I want to wait till the newresponse.response.status is Success (this usually takes a short bit like 3-4 seconds more).
The original code is shown below:
function getrequestresults(status, response) {
let parse = JSON.parse(response);
let a = parse.uuid;
let newrequest = new XMLHttpRequest();
newrequest.open('GET', "http://localhost:5000/api/v1/dags/results" + "?" + "uuid" + "=" + a, true);
newrequest.onload = function() {
//console.log(newrequest.status);
console.log(newrequest.response);
};
newrequest.send();
}
One of the attempts I made at fixing this was as follows:
function getrequestresults(status, response) {
let parse = JSON.parse(response);
let a = parse.uuid;
let newrequest = new XMLHttpRequest();
newrequest.open('GET', "http://localhost:5000/api/v1/dags/results" + "?" + "uuid" + "=" + a, true);
newrequest.onload = function() {
while (newrequest.response.status != "Success") {
//the following line was just to see what's going on, idea was to keep looping till, desired status is reached
console.log(newrequest.response);
}
//console.log(newrequest.status);
console.log(newrequest.response);
};
newrequest.send();
}
However, this did not work as it seems that the "onload" function only runs once, whereas I need it to run multiple times until newrequest.response.status is Success.
I am quite new with sending XMLHttpRequests and some help would be appreciated. Thanks.

Springboot with Javascript and MYSQL

I'm creating a filter page in springboot that works fine. When I add my javascript to the html page to make a query using an .change event listener, I want to use this query to live show available results before submitting the form. It looks like this (shorter version, otherwise its just var declaration that's not part of the problem)
$("#leadsForm").change(function () {
//revenue
var revMin = document.getElementById("revenueMin").value
var revMax = document.getElementById("revenueMax").value
//reg date
var regDateMin = document.getElementById("regDateMin").value
var regDateMax = document.getElementById("regDateMax").value
var mainBranch = $('#mainBranch').val();
var specificBranch = $('#specificBranch').val();
var county = $('#county').val();
var tel = document.getElementById("containsTel").value
var contactPerson = document.getElementById("containsContactPerson").checked
var location = document.getElementById("containsLocation").checked
var employed = document.getElementById("containsEmployed").checked
var keyValues = document.getElementById("containsKeyValues").checked
var email = document.getElementById("containsEmail").checked
var website = document.getElementById("containsWebsite").checked
var wholeQuery = "SELECT "+selectedColumns + " from company" + " WHERE " + revenueSelector +
regDateSelector + branchSelector +
countySelector + telSelector + keyValuesSelector + contactPersonSelector + emailSelector +
websiteSelector + locationSelector + employedSelector;
console.log(wholeQuery)
I want to find a way to use this query, JAVASCRIPT SIDE to make the available result change on the .change eventlistener based on userinput, variables above in my variable "wholeQuery".
I use the code
const mysql = require((["mysql"]))
const db = mysql.createConnection({
host : "localhost",
user : "*****",
password: "*****",
database: "mydb"
})
console.log(db)
but get the Error:
Uncaught Error: Script error for "mysql"
https://requirejs.org/docs/errors.html#scripterror
at makeError (require.js:5)
at HTMLScriptElement.onScriptError (require.js:5)
The problem is that I can't connect to my SQL database through Javascript, is there any other way than the one above? I'm doing the solution most other threads recommend but its not working in my case because my project is not a node.js project.
I am a little confused, why connect directly to MySQL in the javascript? Wouldn't it make more sense to have a API call in Springboot that the js side talks to to get this? Judging by your code fragment you have a node.js project of some sort like this one?
If you are using Springboot, I think you need to create a API that talks to MySQL, so your javascript will call the API (using something like Axios maybe?)

Copying Files based on a custom column value between document libraries in SharePoint using javascript

I am new to Javascript and currently working on a task where I need to copy files based on a custom column name "PID" from One Document Library to the other.
I was able to get the below code to work which copies all the files
$scope.copyFiles=function()
{
var sourceLib = '/sites/Protocol/ProtocolDocument';
var destLib = '/sites/Protocol/FinalProtocolDocuments';
var context = new SP.ClientContext.get_current();
var web = context.get_web().get_lists();
var folderSrc = web.getFolderByServerRelativeUrl(sourceLib);
//var cq = "<Query><Where><Eq><FieldRef Name="ProtocolID" LookupId="TRUE"/><Value Type="Text">' + 466 + '</Value></Eq></Where></Query>"
context.load(folderSrc,'Files');
context.executeQueryAsync(
function() {
console.log("Got the source folder right here!");
var files = folderSrc.get_files();
var e = files.getEnumerator();
var dest = [];
while (e.moveNext()) {
var file = e.get_current();
var destLibUrl = destLib + "/" + file.get_name();
dest.push(destLibUrl); //delete this when we're happy we got the file paths right
file.copyTo(destLibUrl, true);
}
console.log(dest); //delete this when we're happy we got the file paths right
context.executeQueryAsync(function() { console.log("Files moved successfully!");}, function(sender, args) {console.log("error: ") + args.get_message()});
},
function(sender, args){console.log("Sorry, something messed up: " + args.get_message());}
);
}
I did some research online to get the Filenames based on a custom column value with no luck
Also tried to use CAML , however not sure how to use it in the code.
Would appreciate if anyone could help me get the filenames from a Document Library based on custom column name "PID" so that only selected/filtered files are moved to the destination Library.
UPDATED CODE
$scope.copyFiles=function()
{
var sourceLib = '/sites/Protocol/ProtocolDocument';
var destLib = '/sites/Protocol/FinalProtocolDocuments';
PID='466'
var context = new SP.ClientContext();
var list = context.get_web().get_lists().getByTitle("ProtocolDocument");
var cq = new SP.CamlQuery();
cq.set_viewXml("<View><Query>" +
"<Where>" +
"<Eq><FieldRef Name=\"ProtocolID\"/><Value Type=\"Text\">PID</Value></Eq>" +
"</Where>" +
"</Query>" +
"</View>");
var items = list.getItems(cq);
context.load(items);
context.executeQueryAsync(
function() {
var e = items.getEnumerator();
var dest = [];
while (e.moveNext())
{
var file = e.get_current();
var destLibUrl = destLib + "/" + file.get_name();
dest.push(destLibUrl); //delete this when we're happy we got the file paths right
file.copyTo(destLibUrl, true);
}
console.log(dest); //delete this when we're happy we got the file paths right
context.executeQueryAsync(function() { console.log("Files moved successfully!");}, function(sender, args) {console.log("error: ") + args.get_message()});
},
function(sender, args){console.log("Sorry, something messed up: " + args.get_message());}
);
}
});
Here is my attempt. I tested it successfully on SharePoint 2013, and it copies files from one document library to another, but only the files with a lookup field set to a specific value. I have included a short summary, but if you only want the code then jump down to Now to the actual code.
Please note that I have used syntax not supported by Internet Explorer, so let me know if you need to support that browser. I also believe that a function or method should only do one thing, so I split the functionality into three separate functions. This also helps keep the code clean and easier to read.
To summarize: The first function, findAndCopyFiles(), will run once and find all the files with the lookup field value you set. It will then send each file to the loadAndCopyFile() function to load the file object. This function will run once for every file that should be copied. When the file object is loaded, it is sent to the third and final function, copyFileTo(), that will actually copy the file to the destination document library. This function will also run once per file.
Now to the actual code
First you need to set these configuration variables according to your setup:
const destinationLibraryPath = 'The path to your destination document library';
const sourceLibraryName = 'The name (not path) of your source document library';
const lookupField = 'The name of your lookup field';
const lookupValue = 'The value your lookup field should equal for files to be copied';
findAndCopyFiles()
This function is responsible for finding all the files in the source document library with the lookup field set to the value of lookupValue. We use what is known as a CAML query to filter the files. You can filter on all available fields and columns, not only lookup fields.
const findAndCopyFiles = () => {
const clientContext = SP.ClientContext.get_current();
const sourceList = clientContext.get_web().get_lists().getByTitle(sourceLibraryName);
const camlQuery = new SP.CamlQuery();
const whereQuery = `<Eq><FieldRef Name="${lookupField}"/><Value Type="Text">${lookupValue}</Value></Eq>`;
camlQuery.set_viewXml(`<View><Query><Where>${whereQuery}</Where></Query></View>`);
const sourceListItems = sourceList.getItems(camlQuery);
clientContext.load(sourceListItems);
clientContext.executeQueryAsync(
() => {
const filesEnumerator = sourceListItems.getEnumerator();
while (filesEnumerator.moveNext()) {
loadAndCopyFile(filesEnumerator.get_current(), clientContext);
}
},
(_sender, args) => {
console.log(args.get_message());
}
);
}
When the query executes, we use the getEnumerator() method to iterate through all the files returned by the query, in other words all the files that will be copied.
loadAndCopyFile()
After finding all the relevant files, we send each file to the next function to continue our process. This function will load the file object (as in the actual file) and construct the destination URL using the path to the destination document library and the filename of the file.
const loadAndCopyFile = (file, clientContext) => {
const fileRef = file.get_file();
clientContext.load(fileRef);
clientContext.executeQueryAsync(
() => {
const destinationUrl = `${destinationLibraryPath}/${fileRef.get_name()}`;
copyFileTo(fileRef, destinationUrl, clientContext);
},
(_sender, args) => {
console.log(args.get_message());
}
);
}
copyFileTo()
The final function is responsible for actually copying the file to the destination document library. It is quite simple, and looks like this:
const copyFileTo = (file, destinationUrl, clientContext) => {
file.copyTo(destinationUrl, true);
clientContext.executeQueryAsync(
() => {
console.log(`File copied to ${destinationUrl}!`);
},
(_sender, args) => {
console.log(args.get_message());
}
);
}
Putting it all together
And finally, we execute the findAndCopyFiles() function when all the required libraries are ready:
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', () => {
findAndCopyFiles();
});
Disclaimer: I wrote this post on another computer than the one where I tested the code, so if something does not work it may be because of a simple syntax error. In that case, add a comment and let me know!

How can I use an ajax request to fire Webservice calls in Javascript

I am currently working on some javascript that can be included in the header of surveys that use TrueSample, and will dynamically generate and fire Webservice calls for the survey. One of the requirements of Truesample is that after every page, it is sent the amount of time spend on that page, as well as some other arbitrary information generated in the beginning of the survey. I am trying to automate the every page web service call, so that I don't have to have hundreds of web services in every survey.
I am pretty far along, and have found some cool tricks to make this all work, but I am struggling with firing the webservice using javascript.
Here is what I have so far:
Qualtrics.SurveyEngine.addOnload(function()
{
var pageStart = new Date();
var beginning = pageStart.getTime();
// Necessary Variables
var account-id = parseInt("${e://Field/account-id}");
var passcode = parseInt("${e://Field/passcode}");
var survey-country = parseInt("${e://Field/survey-country}");
var end-client-id = parseInt("${e://Field/end-client-id}");
var page-exposure-duration;
var page-id = parseInt("${e://Field/pageID}");
var platform-id = parseInt("${e://Field/platform-id}");
var respondent-id = parseInt("${e://Field/respondent-id}");
var response-id = parseInt("${e://Field/response-id}");
var source-id = parseInt("${e://Field/source-id}");
var survey-id = parseInt("${e://Field/survey-id}");
var api-version = parseInt("${e://Field/api-version}");
//End Variables
var that = this;
that.hideNextButton();
var para = document.createElement("footnote");
var test = document.getElementById("Buttons");
var node = document.createElement('input');
var next = document.getElementById("NextButton");
node.id = "tsButton";
node.type = "button";
node.name = "tsButton";
node.value = " >> ";
node.onclick = function trueSample(){
var pageEnd = new Date();
var end = pageEnd.getTime();
var time = end - beginning;
window.alert(pageID + ", time spent on page = " + time);
Qualtrics.SurveyEngine.setEmbeddedData("pageID", pageID + 1);
new Ajax.Request('webserviceURL', {
parameters: {
account-id: account-id,
passcode: passcode,
survey-country: surveycountry,
end-client-id: end-client-id,
page-exposure-duration: time,
page-id: page-id,
platform-id: platform-id,
respondent-id: respondent-id,
response-id: response-id,
source-id: source-id,
survey-id: survey-id,
api-version: api-version}
});
that.clickNextButton();
};
para.appendChild(node);
test.insertBefore(para, next);
});
Does anyone have experience with firing webservice calls out of Javascript? And if so, do you have any ideas on how to finalize the ajax request and make it work? Or is there another(potentially better) method that I could use for these calls that would work? I understand that there is information on this on Stack Overflow, but I am having a hard time understanding how specific use cases apply to mine.
Also, please note that, while I would love to use JQuery, I am limited to vanilla Javascript, and Prototype.JS.
Using Traditional javascript XmlHttpRequest you can make an AJAX call. For a Webservice, we need couple of HTTP Headers. Like: SOAPAction, Content-Type, Accept. The values for these headers MUST be like below:
SOAPAction:""
Content-Type:text/xml
Accept:text/xml
So, additionally, your code should look something like this for making an AJAX call to the Webservice:
//Get XML Request Object
var request = new XMLHttpRequest();
// Define the URL
var url="http://your.end.point.url?wsdl";
//Define HTTP Method. Always POST for a Webservice
request.open("POST", url, true); // Remember that all the Webservice calls should be POST
//Setting Request Headers
request.setRequestHeader("SOAPAction", "\"\"");//Not sure of the escape sequence. The value should be "".
request.setRequestHeader("Accept","text/xml");
request.setRequestHeader("Content-Type","text/xml");
//Make your AJAX call
request.send(soap); // where soap is you SOAP Request Payload.
Parsing the response:
request.onreadystatechange=stateChanged;
function stateChanged()
{
if (request.status==200)
{
// Success. Parse the SOAP Response
}
if(request.status==500)
{
//Failure. Handle the SOAP Fault
}
}

Reading file dynamically with javascript

I'm trying to post values from a file to a textfield on a website. These values will be updated every 5 seconds. I am able to read the values using xmlHTTPrequest, however, when I try to use setInterval to run the function again, the values don't change. It detects if the file is no longer there, but as I put it back and change values, they are the same as before. This is my code:
setInterval(getrecent, 5000);
function getrecent () {
sourcestr = "../userdata/" + sessionStorage.getItem("DoB");
var x = new XMLHttpRequest();
x.open("GET", sourcestr + "/recentdata.txt", false);
x.send();
if (x.status == 404) {
document.getElementById("babypic").src = "../../Notrunning.png";
}
else {
var myTextfile = x.responseText;
// alert(myTextfile);
document.getElementById("babypic").src = sourcestr + "/picture.jpeg" + '?rand=' + Math.random();
var split = myTextFile.split(" ");
document.getElementById("pulse").value = split[0];
document.getElementById("resp").value = split[1];
}
}
I found the error but I'm not sure what to do with it. "Uncaught referenceerror, myTextFile not defined" on row 117 which is "var split = myTextFile.split(" ");
Solved: Added "meta http-equiv="cache-control" content="no-cache" " to the head to avoid caching and corrected spelling of myTextFile. Website works just fine now.
You have written the variable myTextfile in two different casing: myTextFile and myTextfile are not identical variables.
Please correct the casing and think about using an IDE that can point out such errors, it will make your life a lot easier!

Categories

Resources