SuiteScript N/query SuiteQL how to select one transaction like Estimate - suitescript

I try some demo SuiteQL in NetSuite by following the demo that the SuiteScript 2.0API provides, but the demo seemed too little for me, I still cannot figure out the right way to use it properly, and I had to come back to module N/search.
so I wanna ask for some demo about SuiteQL, especially for Transaction.
Thank you!

Here is an example how you could use the query module to achieve your goal. In this example you would pass whatever type of transaction you wanted to query by using the function queryTransactionsFilteredByStatus defined below and pass to it whatever status you would like. This could obviously be expanded on to fit your use case more specifically.
define(['N/query'], (query) => {
const queryTransactionsFilteredByStatus = (status) => {
const sql = `select * from transaction as t where t.status = ?`;
return query.runSuiteQL({
query: sql,
params: [status]
}).asMappedResults();
}
// The rest of your code here...
}

Related

DynamoDB PartiQL pagination using SDK

I'm currently working on pagination in DynamoDB using the JS AWS-SDK's executeStatement using PartiQL, but my returned object does not contain a NextToken (only the Items array), which is used to paginate.
This is what the code looks like (pretty simple):
const statement = `SELECT "user", "id" FROM "TABLE-X" WHERE "activity" = 'XXXX'`;
const params = {Statement: statement};
try {
const posted = await dynamodb.executeStatement(params).promise();
return { posted: posted };
} catch(err) {
throw new Error(err);
}
I was wondering if anyone has dealt with pagination using PartiQL for DynamoDB.
Could this be because my partition key is a string type?
Still trying to figure it out.
Thanks, in advance!
It turns out that if you want a NextToken DO NOT use version 2 of the AWS SDK for JavaScript. Use version 3. Version 3 will always return a NextToken, even if it is undefined.
From there you can figure out your limits, etc (default limit until you actually get a NextToken is 1MB). You'll need to look into the dynamodb v3 execute statement method.
You can also look into dynamodb paginators, which I've never used, but plan on studying.

onUpdate change diff or patch value?

I am using the onUpdate event handler in Firebase Cloud Functions for the Realtime Database. Works great and I get the before / after snapshot values from the change object, as depicted here :
Before change : { '-M0ONRMFJxvClvoFnHP_': true, '-MNxnG-xnFrYOoU_H0U7': false }
After change : { '-M0ONRMFJxvClvoFnHP_': true }
I am curious if there's an "easy" way to get the diff or patch equivalent for this update operation ? Do I have to dive through the Javascript rabbit-hole and dig up a library (any suggestions ?) or is there a built-in feature inside the change object ?
Note : there's a reference to a fieldMask but I am not really seeing any ways to set this up (doesn't seem documented).
Thanks !
Well, I didn't find anything too exciting, so I just wrote the following that fits my specific purpose :
let beforeKeys = Object.keys(change.before.val() || {});
let afterKeys = Object.keys(change.after.val() || {});
let deletions = [];
let insertions = [];
deletions = beforeKeys.filter(item => !afterKeys.includes(item));
insertions = afterKeys.filter(item => !beforeKeys.includes(item));
and then I mapped the elements of each array to an async call for removal and addition to specific references in my realtime DB.
There's probably a more efficient way to achieve this, but that should work for now.
Thanks for coming to my TED Talk. 🙄

Is it possible to validate a GQL query in cloud datastore before submitting it? Any examples preferably using the Java lib

From the google code examples:
public QueryResults<?> newQuery(String kind) {
// [START newQuery]
String gqlQuery = "select * from " + kind;
Query<?> query = Query.newGqlQueryBuilder(gqlQuery).build();
QueryResults<?> results = datastore.run(query);
// Use results
// [END newQuery]
return results;
}
Is it possible to validate the gqlQuery before officially running the query?
It looks like you can't. Your best option would be to test your queries with the LocalDatastoreHelper class, like it's done in here. Check how it's set up and the assertValidKey and the GQL methods there.
Again, this is not actual validation of the query, but it seems like the best shot. Also, upon failures, the exception thrown would be DatastoreException, so, you can try and catch said exception in your code.

Pagination in DynamoDB

I have a requirement for to show the search result on the jsp with maxcount of 10 and it should have a pagination to traverse back and forward as pagination functionality.
Dynamodb has a lastevaluatedkey, but it doesn't help to go back to the previous page, though I can move to the next result set by the lastevaluatedKey.
Can anybody please help on this.
I am using Java SPRING and DynamoDB as the stack.
Thanks
Satya
To enable forward/backward, all you need is to keep
the first key, which is hash key + sort key of the first record of the previously returned page (null if you are about to query the first page).
and
the last key of the retrieved page, which is hash key + sort key of the last record of the previously returned page
Then to navigate forward or backward, you need to pass in below parameters in the query request:
Forward: last key as the ExclusiveStartKey, order = ascend
Backward: first key as the ExclusiveStartKey, order = descend
I have achieved this in a project in 2016. DynamoDB might provide some similar convenient APIs now, but I'm not sure as I haven't checked DynamoDB for a long time.
Building on Ray's answer, here's what I did. sortId is the sort key.
// query a page of items and create prev and next cursor
// cursor idea from this article: https://hackernoon.com/guys-were-doing-pagination-wrong-f6c18a91b232
async function queryCursor( cursor) {
const cursor1 = JSON.parse(JSON.stringify(cursor));
const pageResult = await queryPage( cursor1.params, cursor1.pageItems);
const result = {
Items: pageResult.Items,
Count: pageResult.Count
};
if ( cursor.params.ScanIndexForward) {
if (pageResult.LastEvaluatedKey) {
result.nextCursor = JSON.parse(JSON.stringify(cursor));
result.nextCursor.params.ExclusiveStartKey = pageResult.LastEvaluatedKey;
}
if ( cursor.params.ExclusiveStartKey) {
result.prevCursor = JSON.parse(JSON.stringify(cursor));
result.prevCursor.params.ScanIndexForward = !cursor.params.ScanIndexForward;
result.prevCursor.params.ExclusiveStartKey.sortId = pageResult.Items[0].sortId;
}
} else {
if (pageResult.LastEvaluatedKey) {
result.prevCursor = JSON.parse(JSON.stringify(cursor));
result.prevCursor.params.ExclusiveStartKey = pageResult.LastEvaluatedKey;
}
if ( cursor.params.ExclusiveStartKey) {
result.nextCursor = JSON.parse(JSON.stringify(cursor));
result.nextCursor.params.ScanIndexForward = !cursor.params.ScanIndexForward;
result.nextCursor.params.ExclusiveStartKey.sortId = pageResult.Items[0].sortId;
}
}
return result;
}
You will have to keep a record of the previous key in a session var, query string, or something similar you can access later, then execute the query using that key when you want to go backwards. Dynamo does not keep track of that for you.
For a simple stateless forward and reverse navigation with dynamodb check out my answer to a similar question: https://stackoverflow.com/a/64179187/93451.
In summary it returns the reverse navigation history in each response, allowing the user to explicitly move forward or back until either end.
GET /accounts -> first page
GET /accounts?next=A3r0ijKJ8 -> next page
GET /accounts?prev=R4tY69kUI -> previous page

How to work with async code in Mongoose virtual properties?

I'm trying to work with associating documents in different collections (not embedded documents) and while there is an issue for that in Mongooose, I'm trying to work around it now by lazy loading the associated document with a virtual property as documented on the Mongoose website.
The problem is that the getter for a virtual takes a function as an argument and uses the return value for the virtual property. This is great when the virtual doesn't require any async calls to calculate it's value, but doesn't work when I need to make an async call to load the other document. Here's the sample code I'm working with:
TransactionSchema.virtual('notebook')
.get( function() { // <-- the return value of this function is used as the property value
Notebook.findById(this.notebookId, function(err, notebook) {
return notebook; // I can't use this value, since the outer function returns before we get to this code
})
// undefined is returned here as the properties value
});
This doesn't work since the function returns before the async call is finished. Is there a way I could use a flow control library to make this work, or could I modify the first function so that I pass the findById call to the getter instead of an anonymous function?
You can define a virtual method, for which you can define a callback.
Using your example:
TransactionSchema.method('getNotebook', function(cb) {
Notebook.findById(this.notebookId, function(err, notebook) {
cb(notebook);
})
});
And while the sole commenter appears to be one of those pedantic types, you also should not be afraid of embedding documents. Its one of mongos strong points from what I understand.
One uses the above code like so:
instance.getNotebook(function(nootebook){
// hey man, I have my notebook and stuff
});
While this addresses the broader problem rather than the specific question, I still thought it was worth submitting:
You can easily load an associated document from another collection (having a nearly identical result as defining a virtual) by using Mongoose's query populate function. Using the above example, this requires specifying the ref of the ObjectID in the Transaction schema (to point to the Notebook collection), then calling populate(NotebookId) while constructing the query. The linked Mongoose documentation addresses this pretty thoroughly.
I'm not familiar with Mongoose's history, but I'm guessing populate did not exist when these earlier answers were submitted.
Josh's approach works great for single document look-ups, but my situation was a little more complex. I needed to do a look-up on a nested property for an entire array of objects. For example, my model looked more like this:
var TransactionSchema = new Schema({
...
, notebooks: {type: [Notebook]}
});
var NotebookSchema = new Schema({
...
, authorName: String // this should not necessarily persist to db because it may get stale
, authorId: String
});
var AuthorSchema = new Schema({
firstName: String
, lastName: String
});
Then, in my application code (I'm using Express), when I get a Transaction, I want all of the notebooks with author last name's:
...
TransactionSchema.findById(someTransactionId, function(err, trans) {
...
if (trans) {
var authorIds = trans.notebooks.map(function(tx) {
return notebook.authorId;
});
Author.find({_id: {$in: authorIds}, [], function(err2, authors) {
for (var a in authors) {
for (var n in trans.notebooks {
if (authors[a].id == trans.notebooks[n].authorId) {
trans.notebooks[n].authorLastName = authors[a].lastName;
break;
}
}
}
...
});
This seems wildly inefficient and hacky, but I could not figure out another way to accomplish this. Lastly, I am new to node.js, mongoose, and stackoverflow so forgive me if this is not the most appropriate place to extend this discussion. It's just that Josh's solution was the most helpful in my eventual "solution."
As this is an old question, I figured it might use an update.
To achieve asynchronous virtual fields, you can use mongoose-fill, as stated in mongoose's github issue: https://github.com/Automattic/mongoose/issues/1894

Resources