IndexedDB range limits - google-chrome-extension

I'm using IndexedDb to store a person's city, email id and created_at.
I want to get all the people in a for a certain city with a valid email and sort by the created_at date.
I have a compound index query like so:
var city = "chennai";
var index_name = "city, " + "email, " + "created_at";
var index = store.index(index_name);
var boundedKeyRange = IDBKeyRange.bound([city, "", 0], [city, ??, ""]);
index.openCursor(boundedKeyRange, "prev").onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) {
// Check if email is valid and add it to an array
}
else {
// resolve a promise
}
}
The problem I have is that I don't know how to set the 'upper range' for email id's since # is a special character I'm not sure set the upper range to have all the email ids in the query.
Thank you
Deepak

The upper bound of a string can be taken as '\uFFFF' or [].
Anyways, your query will not work because you have two range query, "email" and "created_at". You can have only one key range query.

Related

Mongoose, NodeJS & Express: Sorting by column given by api call

I'm currently writing a small API for a cooking app. I have a Recipe model and would like to implement sorting by columns based on the req Parameter given.
I'd like to sort by whatever is passed in the api call. the select parameter works perfectly fine, I can select the columns to be displayed but when I try to sort anything (let's say by rating) the return does sort but I'm not sure what it does sort by.
The code i'm using:
query = Recipe.find(JSON.parse(queryStr));
if(req.query.select){
const fields = req.query.select.split(',').join(' ');
query = query.select(fields);
}
if(req.query.sort){
const sortBy = req.query.sort.split(',').join(' ');
query = query.sort({ sortBy: 1 });
} else {
query = query.sort({ _id: -1 });
}
The result, when no sorting is set: https://pastebin.com/rPLv8n5s
vs. the result when I pass &sort=rating: https://pastebin.com/7eYwAvQf
also, when sorting my name the result is also mixed up.
You are not using the value of sortBy but the string "sortBy". You will need to create an object that has the rating as an object key.
You need the sorting object to look like this.
{
rating: 1
}
You can use something like this so it will be dynamic.
if(req.query.sort){
const sortByKey = req.query.sort.split(',').join(' ');
const sortByObj = {};
sortByObj[sortByKey] = 1; // <-- using sortBy as the key
query = query.sort(sortByObj);
} else {
query = query.sort({ _id: -1 });
}

How to filter results by multiple query parameters if I don't know beforehand how many query strings I may receive from client side?

I want to send in response some data according to searching by query parameters (using .find function of mongoose) from the client side. What do I need to do is a search according to the parameters received?
What I mean is :
I may receive
localhost:5000/admin/customers?customer_id=1&customer_email=abc#gmail.com
I could have used this code to send results according to this query :
Customer.find({
customer_id = req.query.customer_id,
customer_email = req.query.customer_email,
}, (err,docs)=> {
res.json(docs);
})
or
just
localhost:5000/admin/customers?customer_id=1
I could have used this code to send results according to this query :
Customer.find({
customer_id = req.query.customer_id
}, (err,docs)=> {
res.json(docs);
})
or
may be
localhost:5000/admin/customers?no_of_items_purchased=15
I could have used this code to send results according to this query :
Customer.find({
no_of_items_purchased = req.query.no_of_items_purchased
}, (err,docs)=> {
res.json(docs);
})
But what I want is to use .find function on anything received from query params. Like a general code to achieve this.
PS: Also please help with : "How to filter req.query so it only contains fields that are defined in your schema ?"
You can create a query variable to keep the field that you want to filter.
Suppose that your Customer model structure is:
{
customer_id: ...,
customer_name: ...,
customer_email: ...,
no_of_items_purchased: ...
}
Then your code will be:
let {customer_id, customer_name, customer_email, no_of_items_purchased} = req.query;
let query = {};
if (customer_id != null) query.customer_id = customer_id;
if (customer_name != null) query.customer_name = customer_name;
if (customer_email != null) query.customer_email = customer_email;
if (no_of_items_purchased != null) query.no_of_items_purchased = no_of_items_purchased;
let result = await Customer.find(query);
Just pass request.query as a parameter directly on find method:
Customer.find(request.query)

SQL Server : lower camelcase for each result

I am creating an API with SQL Server as the database. My tables and columns are using Pascal case (CountryId, IsDeleted, etc) that cannot be changed.
So when I do this:
const mssql = require('mssql');
var sqlstr =
'select * from Country where CountryId = #countryId';
var db = await koaApp.getDb();
let result = await db.request()
.input('countryId', mssql.Int, countryId)
.query(sqlstr);
My resulting object is
{
CountryId: 1,
CountryName: "Germany"
}
But I want it to be
{
countryId: 1,
countryName: "Germany"
}
I know there is a "row" event, but I wanted something more performant (since I may be returning several rows from the query, above is just an example).
Any suggestions?
PS: I want to avoid the FOR JSON syntax
Posting this as an actual answer, as it proved helpful to the OP:
if it's viable, you may try simply specifying the columns in the query as such:
select
CountryID countryId,
CountryName countryName
from
Country
where
CountryId = #countryId
Typically it's not best practice to use select * within queries anyways because of performance.
A simple explanation, putting a space and a new name (or perhaps better practice, within square brackets after each column name, such as CountryName [countryName] - this allows for characters such as spaces to be included within the new names) is aliasing the name with a new name of your choosing when returned from SQL.
I'd suggest using the lodash utility library to convert the column names, there is a _.camelCase function for this:
CamelCase documentation
_.camelCase('Foo Bar');
// => 'fooBar'
_.camelCase('--foo-bar--');
// => 'fooBar'
_.camelCase('__FOO_BAR__');
// => 'fooBar'
You can enumerate the result keys using Object.entries then do a reduce, e.g.
let result = {
CountryId: 1,
CountryName: "Germany"
};
let resultCamelCase = Object.entries(result).reduce((obj,[key,value]) => {
obj[_.camelCase(key)] = value;
return obj;
}, {});
console.log(resultCamelCase);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Get Saved Search values for multiple "formula" columns

Morning Gurus,
I have a saved search within Netsuite with multiple "formula" columns.
For example, there are several formulapercent' named columns, although thelabel' for each is unique.
However when using nlobjSearchResult.getValue('formulapercent') naturally I only get the first formulapercent column value.
How do I specify in getValue which of the formula columns I want to return the value for?
I really don't want to use a column number, in case I need to insert a new column to the saved search within Netsuite later.
Hoping for something along the lines of nlobjSearchResult.getValue('formulapercent','<label>')
I have tried the multi parameter option, but it does not work.
Simple fix?
Cheers
Steve
What I generally do is add a label to the saved search formula columns. Then:
var f1Val, f2Val, etc;
results.forEach(function(res){
var cols = res.getAllColumns();
cols.forEach(function(col){
switch(col.getLabel()){
case 'formula1' : f1Val = res.getValue(col); break;
case 'formula2' : f2Val = res.getValue(col); break;
...
}
});
});
Thought I'd add an answer I have since learned.
Instead of generically numbering the columns. For example:
var column = []
column[0] = new nlobjSearchColumn('formulanumeric').setFormula('myformula1');
column[1] = new nlobjSearchColumn('formulanumeric').setFormula('myformula2');
searchresults = nlapiSearchRecord(.......);
Instead of this, I found the easiest way to retrieve the formula column values was to uniquely define the columns:
var colformula1 = new nlobjSearchColumn('formulanumeric').setFormula('myformula1');
var colformula2 = new nlobjSearchColumn('formulanumeric').setFormula('myformula2');
var searchresults = nlapiSearchRecord('item',null,filters,[colformula1,colformula2]);
To then grab the formula results:
var formulares1 = searchresults[i].getValue(colformula1');
var formulares2 = searchresults[i].getValue(colformula2');
Removes the issue if column orders change.
Thought this might help somebody.
There is a method in the nlobjSearchResult object called getAllColumns(). Then I use the index of the formula columns to get the value.
I dont't know of any other way to get the values of the formula columns. Do note that if you use this method, if you change the order of the columns in the saved search it will break your script.
This works for me using SuiteScript 2.0. Place this into a function and pass in the needed variables
if(join){
if(summary){
if(String(name).startsWith("formula")){
return result.getValue(result.columns[column])
}else{
var searchResult = result.getValue({
name: name,
join: join,
summary:summary
});
return searchResult
}
}else{
if(String(name).startsWith("formula")){
return result.getValue(result.columns[column])
}else{
var searchResult = result.getValue({
name: name,
join: join
});
return searchResult
}
}
}else{
if(summary){
if(String(name).startsWith("formula")){
return result.getValue(result.columns[column])
}else{
var searchResult = result.getValue({
name: name,
summary: summary,
});
if((column==7 || column ==8 || column==10 || column==12) && type=='cases'){
return dropDown_Obj[column].getKeyByValue(searchResult)
}
return searchResult
}
}else{
if(String(name).startsWith("formula")){
return result.getValue(result.columns[column])
}else{
var searchResult = result.getValue({
name: name
});
return searchResult
}
}
}

how to use in operator in dynamo db

I have a user table with a field username. I need to write something equivalent to this in dynamo db: Select * from user where username in('a','b','c');
Adding more from code prosepective i have usernames in an array say var arr=['a','b','c'];
I so far tried this which is giving me zero result
this.dynamo.client.scanAsync({
TableName: this.dynamo.table('users'),
FilterExpression: 'username IN (:list)',
ExpressionAttributeValues: {
':list': arr.toString()
}
}).then((response) => {
console.log(response);
return {
userFriends: result.Item.friends
};
});
When I pass one element in array it give me result searching passed single element in user table but its not working with more than one element in array.
The individual users should be given as comma separated String variables. JavaScript array is equivalent to List in AWS DynamoDB data type. The DynamoDB can't compare the String data type in database with List attribute (i.e. Array in JavaScript).
var params = {
TableName : "Users",
FilterExpression : "username IN (:user1, :user2)",
ExpressionAttributeValues : {
":user1" : "john",
":user2" : "mike"
}
};
Construct the object from array for FilterExpression:-
Please refer the below code for forming the object dynamically based on Array value.
var titleValues = ["The Big New Movie 2012", "The Big New Movie"];
var titleObject = {};
var index = 0;
titleValues.forEach(function(value) {
index++;
var titleKey = ":titlevalue"+index;
titleObject[titleKey.toString()] = value;
});
var params = {
TableName : "Movies",
FilterExpression : "title IN ("+Object.keys(titleObject).toString()+ ")",
ExpressionAttributeValues : titleObject
};
Note:-
I don't think IN clause with 1000s of usernames is a good idea in terms of performance.

Resources