Simple.Odata.Client - Batch Processing - simple.odata.client

I am trying to implement Batch Process for one of our CRM entity.
I have 2 scenarios
1. Add an entity record then update the same entity record (because we can not add inactive record so need second call to make it inactive).
2. get the entity record and unlink the same from another entity.
Sample code is as below:
var record = client.For<entity1>().Filter(p => p.primaryKey == inputParam.entity1.primaryKey).
Set(new { statecode = 0 }).InsertEntryAsync(false);
client.For<entity1>().Filter(p => p.primaryKey == record.primaryKey).
Set(new { statecode = 1 }).UpdateEntryAsync(false);
Also please let me know if there is possibility to retrieve the record and update the record using Odata Batch.
I am using simple.Odata.Client library.
Thanks.
Paritosh

If you want to use the record in the UpdateEntry, you will have to call InsertEntryAsync with true to signal that you need the returned result before using that in your update request:
var record = await client
.For<entity1>()
.Filter(p => p.primaryKey == inputParam.entity1.primaryKey)
.Set(new { statecode = 0 })
.InsertEntryAsync(true);
await client
.For<entity1>()
.Filter(p => p.primaryKey == record.primaryKey)
.Set(new { statecode = 1 })
.UpdateEntryAsync(false);
For OData batch, you will have to make sure the server is supporting batch processing.
Then in your code, this is how to do it with Simple.OData.Client pushing a batch of max 100 request per batch:
ODataClientSettings oDataSettings = new ODataClientSettings
{
BaseUri = new Uri(ApiUrl)
};
var batch = new ODataBatch(oDataSettings);
var entryCount = 0;
foreach (var item in entityList)
{
entryCount++;
batch += async c => await client
.For<entity1>()
.Set(item)
.InsertEntryAsync(false);
if ((entryCount % 100 == 0) || entryCount == entityList.Count())
{
await batch.ExecuteAsync();
batch = new ODataBatch(oDataSettings);
}
}

Related

how to add conditional where parameters to sql query in node js

I have the below method that aims to filter records from a table. But sometimes, the user might only select one filter or two. I want to add where conditions only for parameters that the user sends. At the moment, it filters with all conditions. One possibility I know is to use some conditions to concatenate the string if true but I do not think this is the best way.
Any better way of doing this?
// Retrieve hotels by filter
app.get('/filter', (request, response) => {
var name = request.query.name;
var country = request.query.country;
var freeWifi = request.query.freeWifi;
var freeParking = request.query.freeParking;
var restaurant = request.query.restaurant;
var pool = request.query.pool;
var gym = request.query.gym;
var airconditioning = request.query.airconditioning;
let query = `select * from hotels h inner join hotelFilters hf on h.id = hf.hotelId where h.title like "%${isNullOrUndefined(name) ? '' : name}%"
and hf.freeWifi = ${freeWifi} and hf.freeParking = ${freeParking} and hf.restaurant = ${restaurant} and hf.outdoorPool = ${pool}
and hf.airConditioning = ${airconditioning}
and hf.gym = ${gym}`;
connection.query(query, (error, result) => {
if (error) {
console.log(error, 'Error occurred with hotels/filter API...');
}
if (result.length > 0) {
response.send({
result
})
}
})
});

Write rows to BigQuery via nodejs BigQuery Storage Write API

It seems quite new, but just hoping someone here has been able to use nodejs to write directly to BigQuery storage using #google-cloud/bigquery-storage.
There is an explanation of how the overall backend API works and how to write a collection of rows atomically using BigQuery Write API but no such documentation for nodejs yet. A recent release 2.7.0 documents the addition of said feature but there is no documentation, and the code is not easily understood.
There is an open issue requesting an example but thought I'd try my luck to see if anyone has been able to use this API yet.
Suppose you have a BigQuery table called student with three columns id,name and age. Following steps will get you to load data into the table with nodejs storage write api.
Define student.proto file as follows
syntax = "proto2";
message Student {
required int64 id = 1;
optional string name = 2;
optional int64 age = 3;
}
Run the following at the command prompt
protoc --js_out=import_style=commonjs,binary:. student.proto
It should generate student_pb.js file in the current directory.
Write the following js code in the current directory and run it
const {BigQueryWriteClient} = require('#google-cloud/bigquery-storage').v1;
const st = require('./student_pb.js')
const type = require('#google-cloud/bigquery-storage').protos.google.protobuf.FieldDescriptorProto.Type
const mode = require('#google-cloud/bigquery-storage').protos.google.cloud.bigquery.storage.v1.WriteStream.Type
const storageClient = new BigQueryWriteClient();
const parent = `projects/${project}/datasets/${dataset}/tables/student`
var writeStream = {type: mode.PENDING}
var student = new st.Student()
var protoDescriptor = {}
protoDescriptor.name = 'student'
protoDescriptor.field = [{'name':'id','number':1,'type':type.TYPE_INT64},{'name':'name','number':2,'type':type.TYPE_STRING},{'name':'age','number':3,'type':type.TYPE_INT64}]
async function run() {
try {
var request = {
parent,
writeStream
}
var response = await storageClient.createWriteStream(request);
writeStream = response[0].name
var serializedRows = []
//Row 1
student.setId(1)
student.setName('st1')
student.setAge(15)
serializedRows.push(student.serializeBinary())
//Row 2
student.setId(2)
student.setName('st2')
student.setAge(15)
serializedRows.push(student.serializeBinary())
var protoRows = {
serializedRows
}
var proto_data = {
writerSchema: {protoDescriptor},
rows: protoRows
}
// Construct request
request = {
writeStream,
protoRows: proto_data
};
// Insert rows
const stream = await storageClient.appendRows();
stream.on('data', response => {
console.log(response);
});
stream.on('error', err => {
throw err;
});
stream.on('end', async () => {
/* API call completed */
try {
var response = await storageClient.finalizeWriteStream({name: writeStream})
response = await storageClient.batchCommitWriteStreams({parent,writeStreams: [writeStream]})
}
catch(err) {
console.log(err)
}
});
stream.write(request);
stream.end();
}
catch(err) {
console.log(err)
}
}
run();
Make sure your environment variables are set correctly to point to the file containing google cloud credentials.
Change project and dataset values accordingly.

Updating a value in SQL (better-sqlite3) with Node.JS

I currently have a database of people with each individual person and they hold a status value. I am trying to change their status value.
const id = parseInt(req.params.id , 10);
const { valid, messageObj } = validateId(id);
if (!valid) {
res.status(400).send(messageObj);
}
let { status, priority } = req.body;
let people = db.prepare('select * from people').all();
const person = people.find(person => person.id === id);
if(status !== 'none' & status == 'ready' || status == 'done'){
let updates = db.query(
'UPDATE people SET ? WHERE ?',
[{ status: status }, { id: id }]
);
}
I keep getting an error of db.query is not a function but I get that for every function that I try.
Pretty new to SQL but just trying to figure this out or any documentation that will help me as the better-sqlite3 doesn't have any update functions in the official documentation.
I cannot find a function called query() in the better-sqlite3 API for the Database class. I think that you would need to prepare() a Statement object, then run() it.
Also, column names cannot be passed as bound parameters. Your query should look like:
UPDATE people SET status = ? WHERE name = ?
You would need to change this:
let updates =
db.query('UPDATE people SET ? WHERE ?', [{ status: status }, { id: id }]);
To:
const stmt = db.prepare('UPDATE people SET status = ? WHERE id = ?');
const updates = stmt.run(status, id);
According to templates you can use javascript syntax to replace variables to its value.
let updates = db.exec(`UPDATE people SET status='${status}' WHERE id='${id}'`);

Update google sheet by rowid using API

I have employee in one sheet and I get row id of the searched employee on the page now I want to update the same record with the row id so that my time of searching the employee is saved. Is there any way to do this?
function getEmployeeName_(){
try{
var username = getUserName_();
var formObject = {verb:'GET',url:'/Employees?Emp_Email='+g_obj.current_user_email};
var response_obj = processForm(formObject);
response_obj = JSON.parse(response_obj);
var userObj = {};
if(response_obj != undefined && response_obj.status != undefined && response_obj.status == 'success'){
if(response_obj['data'].length >0){
userObj = response_obj['data'][0];
}
}
return userObj.Emp_Name;
}catch(e){
Logger.log(e.message);
return { status: 'error', message: 'Something went wrong while fetching User Name.'};
}
}
To update values in Sheets API, use spreadsheets.values.update. The rowId you're talking about will be a part of range property using A1Notation.
To check samples on using sheets values.update, check Sheet Operations.

How to send the index of a for loop into the promise of a function in a Vue Resource call?

I am looping through an object however in the asynchronous part the i variable is always five.
How can I maintain that value, or pass it into the function
getProductData: function() {
var vm = this;
for (var i = 0; i < vm.recommendationResponse['recommendedItems'].length; i++) {
var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
// get body data
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
}, response => {
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
});
}
}
I I do something like this:
vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then((response, i) => ...
then i is undefined
Who do I keep the index of the loop or should I go about it a different way?
Always use let to initialize variables in for loop when dealing with async operations. Similar things goes to having for loops in intervals. By using let you make sure you always have a unique variable assigned to i.
for (let i = 0, recommendationlength = vm.recommendationResponse['recommendedItems'].length; i < recommendationlength; i++)
Little bonus, if you cache array length in the beginning you get a small performance boost :-)
You could use Array.prototype.forEach instead:
var vm = this;
vm.recommendataionResponse['recommendedItems'].forEach((item, i) => {
var sku = vm.recommendationResponse['recommendedItems'][i]['items'][0]['id'];
vm.$http.get('http://127.0.0.1:8000/models/api/productimage/' + sku).then(response => {
// get body data
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = response.body['product_image_url'];
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = response.body['price'];
}, response => {
vm.recommendationResponse['recommendedItems'][i]['items'][0]['image_url'] = '';
vm.recommendationResponse['recommendedItems'][i]['items'][0]['price'] = '';
});
})
This way, since there is a unique scope for each i value, each .then callback will be able to reference the correct value.