I have TreeMap using the Joda DateTime object and is does not seem to be sorting here is the definition:
TreeMap<DateTime, HolderAnswer> dateTimeTreeMap = new TreeMap<DateTime, HolderAnswer>();
I added in the values as follows (I'm just using a generic sql statement here);
//then get previously selected answers to move to the top of the list
String sql = "Select ActionDT, RecID, TextID, Text, Value from Foo";
Cursor c = DataBaseConnector.query(sql);
if (c != null) {
if (c.moveToFirst()) {
do {
HolderAnswer answer = null;
boolean valueAlreadyIn = false;
DateTime dt = formatter.parseDateTime(c.getString(c.getColumnIndex("ActionDT")));
//we will be adding in the options in the next section, setting to null for now.
answer = new HolderAnswer(c.getInt(c.getColumnIndex("RecID")),c.getInt(c.getColumnIndex("TextID")),null,count,c.getString(c.getColumnIndex("Text")));
//////////////////////////////////////////////////////////////
Iterator<Entry<DateTime, HolderAnswer>> it = dateTimeTreeMap.entrySet().iterator();
while (it.hasNext()) {
Entry<DateTime, HolderAnswer> pairs = it.next();
HolderAnswer tempAnswer = (HolderAnswer) pairs.getValue();
DateTime tempDateTime = (DateTime) pairs.getKey();
//if answers match, transfer over options
if (answer.getTextID() == tempAnswer.getTextID()) {
valueAlreadyIn = true;
}
}
if (!valueAlreadyIn) {
dateTimeTreeMap.put(dt,answer);
}
//////////////////////////////////////////////////////////////////
//count++;
} while(c.moveToNext());
c.close();
c = null;
}
}
When I print out the values, they don't seem to be sorted, they come out in no discernable pattern. Even doing:
dateTimeTreeMap.descendingMap();
Does nothing. Am I missing something?
The descendingMap() method is used to return a reverse order view of the mappings contained in this map so it looks like you're forgetting to assign the sorted map to the original one.
dateTimeTreeMap = dateTimeTreeMap.descendingMap();
Related
Im trying to delete all items in my table in dynamodb but it does not work.
try {
ScanRequest scanRequest = new ScanRequest().withTableName(table);
ScanResult scanResult = null;
do {
if (Check.nonNull(scanResult)) {
scanRequest.setExclusiveStartKey(scanResult.getLastEvaluatedKey());
}
scanResult = client.scan(scanRequest);
scanResult.getItems().forEach((Item) -> {
String n1 = Item.get("n1").toString();
String n2 = tem.get("n2").toString();
DeleteItemSpec spec = new DeleteItemSpec().withPrimaryKey("n1", n1, "n2", n2);
dynamodb.getTable(table).deleteItem(spec);
});
} while (Check.nonNull(scanResult.getLastEvaluatedKey()));
} catch (Exception e) {
throw new BadRequestException(e);
}
n1 is my Primary partition key
n2 is my Primary sort key
The best approach to delete all the items from DynamoDB is to drop the table and recreate it.
Otherwise, there are lot of read capacity and write capacity units being used which will cost you.
Dropping and recreating the table is the best approach.
PREAMBLE: While a scan operation is expensive, I was needing this answer for initialising a table for a test scenario (low volume). The table was being created by another process and I needed the test scenario on that table, I could therefore not delete and recreate the table.
ANSWER:
given:
DynamoDbClient db
static String TABLE_NAME
static String HASH_KEY
static String SORT_KEY
ScanIterable scanIterable = db.scanPaginator(ScanRequest.builder()
.tableName(TABLE_NAME)
.build());
for(ScanResponse scanResponse:scanIterable){
for( Map<String, AttributeValue> item: scanResponse.items()){
Map<String,AttributeValue> deleteKey = new HashMap<>();
deleteKey.put(HASH_KEY,item.get(HASH_KEY));
deleteKey.put(SORT_KEY,item.get(SORT_KEY));
db.deleteItem(DeleteItemRequest.builder()
.tableName(TRANSACTION_TABLE_NAME)
.key(deleteKey).build());
}
}
To delete all the items from the table first you need to perform scan operation over the table which will results you an scanoutcome. Using the iterator loop over the sacnoutcome with the primary key and it's primary key value.This will be one of the approach to delete all the items from the table. Hope that this code will work you. Thanks
Table table = dynamoDB.getTable(your_table);
ItemCollection<ScanOutcome> deleteoutcome = table.scan();
Iterator<Item> iterator = deleteoutcome.iterator();
while (iterator.hasNext()) {
your_table.deleteItem("PrimaryKey", iterator.next().get("primary key value"));
}
//May be we can make it look generic by reading key schema first as below
String strPartitionKey = null;
String strSortKey = null;
TableDescription description = table.describe();
List<KeySchemaElement> schema = description.getKeySchema();
for (KeySchemaElement element : schema) {
if (element.getKeyType().equalsIgnoreCase("HASH"))
strPartitionKey = element.getAttributeName();
if (element.getKeyType().equalsIgnoreCase("RANGE"))
strSortKey = element.getAttributeName();
}
ItemCollection<ScanOutcome> deleteoutcome = table.scan();
Iterator<Item> iterator = deleteoutcome.iterator();
while (iterator.hasNext()) {
Item next = iterator.next();
if (strSortKey == null && strPartitionKey != null)
table.deleteItem(strPartitionKey, next.get(strPartitionKey));
else if (strPartitionKey != null && strSortKey != null)
table.deleteItem(strPartitionKey, next.get(strPartitionKey), strSortKey, next.get(strSortKey));
}
I want to modify an existing *.rptdesign file and save it under a new name.
The existing file contains a Data Set with a template SQL select statement and several DS parameters.
I'd like to use an actual SQL select statement which uses only part of the DS parameters.
However, the following code results in the exception:
Exception in thread "main" `java.lang.RuntimeException`: *The structure is floating, and its handle is invalid!*
at org.eclipse.birt.report.model.api.StructureHandle.getStringProperty(StructureHandle.java:207)
at org.eclipse.birt.report.model.api.DataSetParameterHandle.getName(DataSetParameterHandle.java:143)
at org.eclipse.birt.report.model.api.DataSetHandle$DataSetParametersPropertyHandle.removeParamBindingsFor(DataSetHandle.java:851)
at org.eclipse.birt.report.model.api.DataSetHandle$DataSetParametersPropertyHandle.removeItems(DataSetHandle.java:694)
--
OdaDataSetHandle dsMaster = (OdaDataSetHandle) report.findDataSet("Master");
HashSet<String> bindVarsUsed = new HashSet<String>();
...
// find out which DS parameters are actually used
HashSet<String> bindVarsUsed = new HashSet<String>();
...
ArrayList<OdaDataSetParameterHandle> toRemove = new ArrayList<OdaDataSetParameterHandle>();
for (Iterator iter = dsMaster.parametersIterator(); iter.hasNext(); ) {
OdaDataSetParameterHandle dsPara = (OdaDataSetParameterHandle)iter.next();
String name = dsPara.getName();
if (name.startsWith("param_")) {
String bindVarName = name.substring(6);
if (!bindVarsUsed.contains(bindVarName)) {
toRemove.add(dsPara);
}
}
}
PropertyHandle paramsHandle = dsMaster.getPropertyHandle( OdaDataSetHandle.PARAMETERS_PROP );
paramsHandle.removeItems(toRemove);
What is wrong here?
Has anyone used the DE API to remove parameters from an existing Data Set?
I had similar issue. Resolved it by calling 'removeItem' multiple times and also had to re-evaluate parametersIterator everytime.
protected void updateDataSetParameters(OdaDataSetHandle dataSetHandle) throws SemanticException {
int countMatches = StringUtils.countMatches(dataSetHandle.getQueryText(), "?");
int paramIndex = 0;
do {
paramIndex = 0;
PropertyHandle odaDataSetParameterProp = dataSetHandle.getPropertyHandle(OdaDataSetHandle.PARAMETERS_PROP);
Iterator parametersIterator = dataSetHandle.parametersIterator();
while(parametersIterator.hasNext()) {
Object next = parametersIterator.next();
paramIndex++;
if(paramIndex > countMatches) {
odaDataSetParameterProp.removeItem(next);
break;
}
}
if(paramIndex < countMatches) {
paramIndex++;
OdaDataSetParameter dataSetParameter = createDataSetParameter(paramIndex);
odaDataSetParameterProp.addItem(dataSetParameter);
}
} while(countMatches != paramIndex);
}
private OdaDataSetParameter createDataSetParameter(int paramIndex) {
OdaDataSetParameter dataSetParameter = StructureFactory.createOdaDataSetParameter();
dataSetParameter.setName("param_" + paramIndex);
dataSetParameter.setDataType(DesignChoiceConstants.PARAM_TYPE_INTEGER);
dataSetParameter.setNativeDataType(1);
dataSetParameter.setPosition(paramIndex);
dataSetParameter.setIsInput(true);
dataSetParameter.setIsOutput(false);
dataSetParameter.setExpressionProperty("defaultValue", new Expression("<evaluation script>", ExpressionType.JAVASCRIPT));
return dataSetParameter;
}
I have verified that the entity I am looking for is in the datastore. I have verified that the list I pass as a method parameter contains this entity. I am trying to find all objects that have their 'userGmail' contained in the list of strings I pass.
Here is my code
#SuppressWarnings("unchecked")
#ApiMethod(name = "findFriendsByEmailList")
public CollectionResponse<ZeppaUser> findFriendsByEmailList(
#Named("emailsList") List<String> emailsList, User user)
throws OAuthRequestException {
if (user == null) {
throw new OAuthRequestException(
"Null User Authorization Exception, findFriendsByEmailList");
}
PersistenceManager mgr = null;
List<ZeppaUser> execute = null;
Query query = null;
try {
mgr = getPersistenceManager();
query = mgr.newQuery(ZeppaUser.class);
query.declareParameters("java.util.List emailListParam");
query.setFilter("emailListParam.contains( userGmail )");
execute = (List<ZeppaUser>) query.execute(emailsList);
query.closeAll();
} finally {
mgr.close();
}
return CollectionResponse.<ZeppaUser> builder().setItems(execute)
.build();
}
This is the stack trace I receive from it:
Something worth noting: I do not receive this error on lists I pass in that to not contain an element found in the datastore. Just when it does exist which leads me to believe that the Query has located the element but has not been closed or executed into a return parameter correctly. If it is preferable to return List that is more than ok. I have tried multiple variations of this with no success thus far. It is getting quite frustrating.
Ok so I found a way around it.
Lists cannot be passed into ApiEndpoints. That or I didn't figure out the correct way to do it and would LOVE an update on the proper way to do this.
Instead, in my client, I construct a String of emails seperated by a comma and send a string into the parameter as an 'encoded' string list then 'decode' it upon execution. Works well but seems hacky.
here are the methods I used. This is convenient though because it works with iOS as well.
public static String encodeListString(ArrayList<String> stringList){
StringBuilder stringbuilder = new StringBuilder();
stringbuilder.append(stringList.get(0));
if(stringList.size() > 1){
for( int i = 0; i < stringList.size(); i++){
stringbuilder.append(",");
stringbuilder.append(stringList.get(i));
}
}
return stringbuilder.toString();
}
public static List<String> decodeListString(String encodedString){
char[] characters = encodedString.toCharArray();
StringBuilder stringbuilder = new StringBuilder();
int position = 0;
ArrayList<String> stringList = new ArrayList<String>();
while(true){
try {
char character = characters[position];
if(character == ','){
String resultString = stringbuilder.toString();
stringList.add(resultString);
stringbuilder = new StringBuilder(); // clear it
} else {
stringbuilder.append(character);
}
position++;
} catch (ArrayIndexOutOfBoundsException aiex){
// List ended
String resultString = stringbuilder.toString();
if(!resultString.isEmpty())
stringList.add(resultString);
break;
}
}
return stringList;
}
Given the below code, is there some reason that when the final if-else statement steps into the else clause, if I un-comment the two lines of code and comment the "FOOZANAZABAR" and "TESTCAIRO" lines, that it would not add those lines into the LinkedHashSet? It appears to add
values.add(new BigDecimal(PEUNIT).multiply(new BigDecimal(1000)).toString());
correctly when the logic drops into the else clause, but will not add the BD.ZERO or the PEFAMT to that field DESPITE the fact they are strings.
As a note, the ZERO and PEFAMT are BigDecimal's that are converted to a string. These are the only two values that are giving me grief. Any direction would be greatly appreciated.
public static LinkedHashMap<String, LinkedHashSet<String>> convertTransactionTableData(ResultSet rs) {
LinkedHashMap<String, LinkedHashSet<String>> returnableMap = new LinkedHashMap<String, LinkedHashSet<String>> ();
try {
while (rs.next()){
String PEFAMT, PEPOLN, MCISST, PEBRCD, PEEFFY, PEPLAN;
String PEUNIT, PETRNC, PECO, PEITYP, ZERO;
PEPOLN = rs.getString("PEPOLN");
MCISST = rs.getString("MCISST");
PEBRCD = rs.getBigDecimal("PEBRCD").toString();
PEEFFY = rs.getBigDecimal("PEEFFY").toString();
PEPLAN = rs.getString("PEPLAN");
PEUNIT = rs.getBigDecimal("PEUNIT").toString();
PEFAMT = rs.getBigDecimal("PEFAMT").toString();
PETRNC = rs.getString("PETRNC");
PECO = rs.getString("PECO");
PEITYP = DataConverter.resetInsuranceType(rs.getString("PEITYP"));
ZERO = BigDecimal.ZERO.toPlainString();
String policyNumber = PEPOLN;
LinkedHashSet<String> values = new LinkedHashSet<String>();
values.add(MCISST);
values.add(PEBRCD);
values.add(PEEFFY);
values.add(PEPLAN);
values.add(PEUNIT);
if (PEPLAN.equalsIgnoreCase("HSRE")) {
values.add(new BigDecimal(PEUNIT).multiply(new BigDecimal(1000)).toString());
} else {
values.add(PEFAMT);
}
values.add(PETRNC);
values.add(PECO);
values.add(PEITYP);
if (DataConverter.testStringToInt(PETRNC)) {
if (Integer.valueOf(PETRNC) >= 20 && Integer.valueOf(PETRNC) <= 29) {
values.add(PEFAMT);
values.add(ZERO);
values.add(ZERO);
} else {
values.add("FOOZANZABAR");
values.add("TESTCAIRO");
// values.add(ZERO);
// values.add(PEFAMT);
values.add(new BigDecimal(PEUNIT).multiply(new BigDecimal(1000)).toString());
}
}
returnableMap.put(policyNumber, values);
}
} catch (SQLException sqlEx) {
logger.error("Problem converting the ResultSet. ", sqlEx);
}
return returnableMap;
}
Thank you in advance.
Josh
Please note that the underlying data structure you're using here is a SET which means it won't let you add duplicates. In all probability, the string values of BD.ZERO and PEFAMT must already be present in your values set and are hence getting ignored.
If this turns out to be the case simply switch to using LinkedList<String> that allows you to have duplicates.
I've a row in db returned by query below. Columns to select include rec, head, amount. I want to sort the rows by head column. I tried Map where string for head and list for other two columns.
I've hit the wall with my non-working code posted below. How would I append another list to list of repeated key. Documentation says it replaces the value for same key whereas I need it appended to the list value. I would be really greatful for any help.
Query q= session.createQuery("select tally_receipt_prefix, tally_receipt_no, tally_head, tally_amount from Tally_table where tally_system_date='"+fmtd_date+"' and tally_dbcr_indicator='DB' and tally_mode='Ca' order by tally_head,tally_receipt_prefix,tally_receipt_no"); System.out.println("query "+q);
List heads=new ArrayList();
for(Iterator it=q.iterate(); it.hasNext(); )
{
Object[] row= (Object[]) it.next();
payincash1=new LinkedHashMap<String, List>();
heads.add((String)row[2]);
List tails = null;
tails=new ArrayList();
tails.add((String)row[0]);
tails.add((String)row[1]);
tails.add((String)row[3]);
System.out.println("heads in dao from iter 1: "+heads);
System.out.println("tails in dao from iter1 on: "+tails);
if(heads.contains((String)row[2])) // for head in temp list
{
System.out.println("in first if");
if(payincash1.containsKey((String)row[2]))
{
System.out.println("map if repeat: "+payincash1);
payincash1.put((String)row[2],tails);
}
}
else
{
System.out.println("map if not repeat: "+payincash1);
payincash1.put((String)row[2], tails);
}
}
Sounds more like you want a list of lists
Something like Map<String, List<List>>
Then you'd end up with something like...
Map<String, List<List>> payincash1 = new LinkedHashMap<String, List<List>>();
heads.add((String) row[2]);
List tails = null;
tails = new ArrayList();
tails.add((String) row[0]);
tails.add((String) row[1]);
tails.add((String) row[3]);
System.out.println("heads in dao from iter 1: " + heads);
System.out.println("tails in dao from iter1 on: " + tails);
List master = payincash1.get((String)row[2]);
if (master == null) {
master = new List();
payincash1.put((String)row[2], master);
}
master.add(tails);
Now, personally, I'd be creating a "data" object that would contain all this information.
public class MyData {
private String rec, head, amount, ??; // Apparently you have another variable I don't know about
public MyData(String rec, String head, String amount, String ??) {
// Initalise...
}
// Setters and getters not inclueded
}
Then you could do something like this...
Map<String, List<MyData>> payincash1 = new LinkedHashMap<String, List<MyData>>();
MyData data = new MyData(row[0], row[1], row[2], row[3]);
List master = payincash1.get((String)row[2]);
if (master == null) {
master = new List<MyData>();
payincash1.put((String)row[2], master);
}
master.add(data);
Which is a little cleaner (IMHO)
From what I understand you need Multimap of guava library.