DynamoDB Pagination - java

I am doing pagination in DynamoDb and see that the result not like my expected, but I still don't know where wrong in my code.
I have searched for this document and see that I just need to set evaluated key which I got last evaluated key from last request to pass to next request.
Here is my code :
public QueryResultPage<SbmBookingInfo> getListBooking(String email, int size,
String lastTimeStamp, String lastBookingId, boolean isForward) {
DynamoDBMapper mapper = new DynamoDBMapper(getClient());
Map<String, AttributeValue> expressionAttributeValues = new HashMap<>();
expressionAttributeValues.put(":email", new AttributeValue().withS(email));
if (lastBookingId == null) {
DynamoDBQueryExpression<SbmBookingInfo> queryExpression = new DynamoDBQueryExpression<SbmBookingInfo>()
.withIndexName("practitioner-index").withKeyConditionExpression("email=:email")
.withExpressionAttributeValues(expressionAttributeValues).withConsistentRead(false).withLimit(size);
QueryResultPage<SbmBookingInfo> result = mapper.queryPage(SbmBookingInfo.class, queryExpression);
m_log.info("Last evaluated key " + result.getLastEvaluatedKey());
return result;
} else {
Map<String, AttributeValue> lastEvaluatedKey = new HashMap<>();
lastEvaluatedKey.put("timeStamp", new AttributeValue().withN(lastTimeStamp));
lastEvaluatedKey.put("bookingId", new AttributeValue().withN(lastBookingId));
lastEvaluatedKey.put("email", new AttributeValue().withS(email));
DynamoDBQueryExpression<SbmBookingInfo> queryExpression = new DynamoDBQueryExpression<SbmBookingInfo>().withLimit(size)
.withIndexName("practitioner-index").withKeyConditionExpression("email=:email")
.withExpressionAttributeValues(expressionAttributeValues).withConsistentRead(false)
.withScanIndexForward(isForward).withExclusiveStartKey(lastEvaluatedKey);
m_log.info("Exclusive key" + queryExpression.getExclusiveStartKey());
return mapper.queryPage(SbmBookingInfo.class, queryExpression);
}
}
This table has three key: bookingId is hashkey, index: email, and timeStamp is rangeKey.
I checked this function by making the first request and I receive last evaluated key then I make second request with passing the info that I received but seem like it didn't work.
Please help me at this case. Thanks

Related

Why my var return incompatibility problem with error 13?

I'm trying to parse Json in VBA.
I'm collecting data from an API that returns a json format in a string.
I use JsonConverter to parse my string.
Now when i want to search on it, i got an error 13 incompatibility type.
See my Java API below :
#GetMapping("/rest/collectData/excel/exportAll")
public HashMap<Object, Object> collectAll(){
HashMap<Object, Object> result = new HashMap<>();
String sql = "SELECT affair_code AS codeAffair, name, amount, end_date AS state FROM service_record WHERE affair_code IS NOT NULL AND affair_code != ''";
List<Map<String, Object>> allServiceRecords = jdbcTemplate.queryForList(sql);
if(allServiceRecords != null && allServiceRecords.size() >0){
result.put("result", true);
for(Map<String, Object> serviceRecord : allServiceRecords){
HashMap<Object, Object> details = new HashMap<>();
if(result.containsKey(serviceRecord.get("codeAffair"))){
details.put("alone", false);
details.put("message", "Plusieurs prestations ont été trouvées.");
} else {
details.put("alone", true);
details.put("name", (String) serviceRecord.get("name"));
details.put("amount", (Double) serviceRecord.get("amount"));
details.put("state", ((Date) serviceRecord.get("state")).compareTo(new Date()) < 0 ? "En cours" : "Clos");
}
result.put(serviceRecord.get("codeAffair"), details);
}
} else{
result.put("result", false);
result.put("error", "La liste n'est pas définie, ou vide.");
}
return result;
}
It returns json :
{"03-045251":{"alone":true,"amount":0.0,"name":"name1","state":"En cours"},"03_05494":{"alone":true,"amount":16743.0,"name":"name2","state":"En cours"}}
First, i execute sql request to collect my data and put it in a map.
Then, i send this map to my excel VBA.
Now see my VBA :
Sub JsonDataSqwal()
firstRow = Range("A" & 11).End(xlDown).Row
lastRow = Range("A" & Rows.Count).End(xlUp).Row
Dim httpObject As Object
Set httpObject = CreateObject("MSXML2.XMLHTTP")
sUrl = "http://localhost/rest/collectData/excel/exportAll"
sRequest = sUrl
httpObject.Open "GET", sRequest, False
httpObject.send
sGetResult = httpObject.responseText
If Not IsNull(sGetResult) Then
Dim oJson As Object
JsonConverter.JsonOptions.AllowUnquotedKeys = True
Set oJson = JsonConverter.ParseJson(sGetResult)
Dim i As Long
For i = firstRow To lastRow
Dim codeAffString As String
codeAffString = Cells(i, 4)
Debug.Print oJson(codeAffString)("name")
Next i
End If
End Sub
For the moment, i try to print my data. the loop collects values from a column, which contains all my codeAffair as 00_00000 or 00-00000
It is this data that i try to use in my vba code with the var codeAffString.
When i execute my code, i'm always getting error 13 about type incompatibility.
To solve this, i tried many things :
to add quote to my var
To rename my HashMap as HashMap<String, Object>
To allow unquoting keys
To change my back office program
To replace my value like """" + codeAffairString + """"
To replace my var with a fix String "00_00000". It works in this case.
To check the type of my var with VarTyp function which returns 8 for String index.
Now i Have no other idea to solve my problem..
If someone see where is my mistake..
Thank you !
Just a quick test:
I used the JSON string you gave and the value you gave for codeAffString to build a minimal reproducible example and it does not produce any errors:
Sub test()
Const JsonString As String = "{""03-045251"":{""alone"":true,""amount"":0.0,""name"":""name1"",""state"":""En cours""},""03_05494"":{""alone"":true,""amount"":16743.0,""name"":""name2"",""state"":""En cours""}}"
Const codeAffString As String = "03-045251"
Dim oJson As Object
JsonConverter.JsonOptions.AllowUnquotedKeys = True
Set oJson = JsonConverter.ParseJson(JsonString)
Debug.Print oJson(codeAffString)("name") ' outputs name1
End Sub
The error you describe occurs if codeAffString cannot be found in the JSON.
Test it by the following in your code:
For i = firstRow To lastRow
Dim codeAffString As String
codeAffString = Cells(i, 4)
If IsEmpty(oJson(codeAffString)) Then
Debug.Print codeAffString & " does not exist in the json"
Else
Debug.Print oJson(codeAffString)("name")
End If
Next i

DynamoDB: How to use a query filter to check for conditions in a MAP

I have a table and the structure looks like this:
When I do a query, I would like to be able to do a query filter on the data map; but I'm not exactly sure how to setup the query.
This is what I have so far:
HashMap<String, AttributeValue> map = new HashMap<String, AttributeValue>();
map.put("byUserId", new AttributeValue().withS("vl49uga5ljjcoln65rcaspmg8u"));
queryExpression
.withQueryFilterEntry("data", new Condition()
.withAttributeValueList(new AttributeValue().withM(map))
.withComparisonOperator(ComparisonOperator.CONTAINS));
but the way I'm building the filter is not correct and I keep running into the following error:
Exception in thread "main" com.amazonaws.AmazonServiceException: One or more parameter values were invalid: ComparisonOperator CONTAINS is not valid for M AttributeValue type (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: CHIOME68L1HVGO81URD7CIOS6BVV4KQNSO5AEMVJF66Q9ASUAAJG)
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:1077)
at com.amazonaws.http.AmazonHttpClient.executeOneRequest(AmazonHttpClient.java:725)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:460)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:295)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:3106)
at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.query(AmazonDynamoDBClient.java:1118)
So what is a comparison operator I should be using (since IN is for list types), and how do I build the query filter such that I can specify a comparison inside of the MAP.
Thanks!
Try comparing the map attribute data.byUserId instead of the entire map structure:
Table table = dynamoDB.getTable(tableName);
Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":x", "vl49uga5ljjcoln65rcaspmg8u");
QuerySpec spec = new QuerySpec()
.withHashKey("HashKeyAttribute", "HashKeyAttributeValue")
.withFilterExpression("data.byUserId = :x")
.withValueMap(expressionAttributeValues);
ItemCollection<QueryOutcome> items = table.query(spec);
Iterator<Item> iterator = items.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}
Some important guidelines:
Make sure the variable tableName has the correct table name represented as a string.
Make sure to replace the string HashKeyAttribute with the attribute name that represents your Hash Key.
Make sure to replace the string HashKeyAttributeValue with the value that represents the Hash Key that you want to match.
Make sure the matched record has the data.byUserId with the value provided in the comparison expression. In the example the value "vl49uga5ljjcoln65rcaspmg8u" was provided.
Here is another example having the id attribute as the Hash Key:
Table table = dynamoDB.getTable(tableName);
Map<String, Object> expressionAttributeValues = new HashMap<String, Object>();
expressionAttributeValues.put(":x", "vl49uga5ljjcoln65rcaspmg8u");
QuerySpec spec = new QuerySpec()
.withHashKey("id", "25g77vmummpr4mc5mb9vq36q43")
.withFilterExpression("data.byUserId = :x")
.withValueMap(expressionAttributeValues);
ItemCollection<QueryOutcome> items = table.query(spec);
Iterator<Item> iterator = items.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().toJSONPretty());
}

Java: Accessing fields in Downloaded Object

I'm new to Java, but know Objective-C. I need to access fields < keys, values > in a downloaded Object.
Below is the code:
car is an Schema and car_id is the field to query
Map<String, List<SMObject>> feedback = new HashMap<String, List<SMObject>>();
List<SMCondition> query = new ArrayList<SMCondition>();
DataService ds = serviceProvider.getDataService();
List<SMObject> results;
try {
query.add(new SMEquals("car_id", new SMString(make)));
results = ds.readObjects("car", query);
if (results != null && results.size() > 0) {
feedback.put(make, results);
}
}
....
results is an Object downloaded from a remote Database that is basically a HashMap. Assuming there is only one object that is returned each time, what would be the code to access Key & Values in the returned results object?
Complete Code in case you want to see it.
EDIT
Can I do something like this:
SMObject resultObj;
if (results != null && results.size() > 0) {
resultObj = results[0];
resultObj.put("resolved", "1");
resultObj.put("accepted", "1");
resultObj.put("declined", "0");
String model = (String)resultObj.get("model");
}
If you wanted all the keys, you would do:
Map<String, List<SMObject>> feedback = new HashMap<String, List<SMObject>>();
List<String> myKeys = feedback.keySet();
To get the values, you would use the get method:
Map<String, List<SMObject>> feedback = new HashMap<String, List<SMObject>>();
feedback.get("yourKey");
For more info, check out: http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
EDIT:
SMObject resultObj;
if (results != null && results.size() > 0) {
List<SMObject> myResults = feedback.get(make);
resultObj = myResults.get(0);
resultObj.put("resolved", "1");
resultObj.put("accepted", "1");
resultObj.put("declined", "0");
String model = (String)resultObj.get("model");
}
The general concept is that you use the key, to get the value from the hashMap. That value happens to be a list of objects; therefore, you need to iterate over that list as well and retrieve each object from the list.

Use HashMap in XMLRPC result

I am new in Android development, and I am trying to receive a HashMap in RESULT by using XMLRPC but every time it's crash the application, this is my code please advice me :
Object RESULT = XMLRPCClient.callEx(methodname,new Object[] {params});
Map FRESULT= (Map) RESULT;
I have been dealing with this also and managed to get the values this way:
try {
Object[] answer = (Object[]) client.call("call", sessionId, method, params);
HashMap map = (HashMap) answer[0]; // get first item of the response because in my case the response was an array of Objects with one item in it holding the HashMap
Object[] records = (Object[]) map.get("records"); // I only needed values from "records" key
for (int i = 0; i < records.length; i++) {
HashMap record = (HashMap) records[i]; // create another map from the records values, in my case uid's of categories
Category cat = new Category(); // creating new instance of my Category class
cat.setCatUid((String) record.get("uid")); // calling a method of the Category class to set Uid to the value from record HashMap
m_categories.add(cat); // this adds it to my ArrayList<Category>
}
} catch (XMLRPCException e) {
Log.e(method, "Exception", e);
}
I'm sure it's a mess, I'm noob in Java myself, but it worked for me. Hope it helps :)
Now the Application pass this peacefully after implementing :
Object RESULT = XmlRpcConnect.ServerCall_a(method,new Object[] {params});
Map<String, Object> FRESULT= (HashMap<String, Object>) RESULT;
with some changes in my XmlRpcConnect Class:
#SuppressWarnings("unchecked");
public static Object ServerCall_a(String method, Object[] params){
XMLRPCClient client = new XMLRPCClient(server);
HashMap<String, Object> result=null;
try{
result = (HashMap<String, Object>) client.callEx(method, params);
}
catch(XMLRPCFault f){
// result = ("Fault message: " + f.getMessage());
}
catch(XMLRPCException e){
// result = ("Exception message: " + e.getMessage());
}
return result;
}
but when trying to extract the values it's crash again , any advice :
if (FRESULT.get("status") == null) {
result = (String) FRESULT.get("status");
toastDialog(result);
}

multiple HashMap implementation

I am trying to implement the use of two HashMaps and it seems to be more or less successful also.But now my problem is i want to update the value of a hashMap based on a check.ie if userId is already existing in the hash i need to update the timestamp corresponding to it...
Below given is my code.How can we accomplish the updation of values .Can that be done usiong setValue..?but how..?please help me friends..
public static void main(String[] args)
{
HashMap sessionTimeStampHash = new HashMap<Long, Long>(); //sessionID is the key and timeStamp is the value
//userID is the key and sessionTimeStampHash object is the value
HashMap<String, HashMap<Long, Long>> userSessionHash = new HashMap<String, HashMap<Long, Long>>();
sessionTimeStampHash.put("sessionID", "timeStamp");
userSessionHash.put("userID", sessionTimeStampHash);
// System.out.println(userSessionHash);
sessionTimeStampHash = new HashMap();
sessionTimeStampHash.put("sessionID1", "timeStamp1");
userSessionHash.put("userID1", sessionTimeStampHash);
// System.out.println(userSessionHash);
sessionTimeStampHash = new HashMap();
sessionTimeStampHash.put("sessionID2", "timeStamp2");
userSessionHash.put("userID2", sessionTimeStampHash);
// System.out.println(userSessionHash);
sessionTimeStampHash = new HashMap();
sessionTimeStampHash.put("sessionID3", "timeStamp3");
userSessionHash.put("userID3", sessionTimeStampHash);
// System.out.println(userSessionHash);
for (Entry<String, HashMap<Long, Long>> entry : userSessionHash.entrySet())
{
String key = entry.getKey();
System.out.println(key);
System.out.println(entry.getValue());
String userId = "userID3";
if (key.equals(userId))
{
System.out.println("Check Successful");
String TimeStamp = newTime;
entry.setValue() // how can i change my timeStamp
}
}
}
You can do without for loop
if(userSessionHash.get(userId)!=null)
userSessionHash.get(userId).put(userSessionHash.get(userId).keySet().toArray[0], timestamp);
Loop on your second map (I assume you want to update all the sessionIds for the user) and modify the value.
if (key.equals(userId))
{
System.out.println("Check Successful");
String TimeStamp=newTime;
for ( String sessionId : entry.getValue().keySet() )
{
entry.put(sessionid, timeStamp);
}
}
String userId = "userID3";
Long timeStamp = userSessionHash.containsKey(userId) ? userSessionHash.get(userSessionHash) : 0;
userSessionHash.put(userId,new AtomicLong(request.getSession(false).getMaxInactiveInterval()))

Categories