I query Hazelcast data map using Predicate with "in" condition like below.
List<String> liveVideoSourceIdList=new ArrayList(){"my_filter"};
Predicate predicate=Predicates.in("myField",liveVideoSourceIdList.toArray(new String[0]));
When i filter map with the created predicate,all the values are duplicated.
If i use "like" instead of "in" like below,no duplication happens. Is there any thoughts about this problem ?
Predicate predicate=Predicates.like("myField",liveVideoSourceIdList.get(0));
I have been unable to reproduce your issue, using 3.9-SNAPSHOT
which version are you using ?
I am using
int min = random.nextInt( keyDomain - range );
int max = min+range;
String values = new String();
for (int i = min; i < max ; i++) {
values += i+", ";
}
SqlPredicate sqlPredicate = new SqlPredicate("personId IN ("+values+")");
Collection<Personable> res = map.values(sqlPredicate);
if(res.size()!=range){
throw new AssertionException(sqlPredicate+" on map "+map.getName()+" returned "+res.size()+" expected "+range);
}
Set<Personable> set = new HashSet<Personable>(res);
if(res.size()!=set.size()){
throw new AssertionException(sqlPredicate+" on map "+map.getName()+" returned Duplicates");
}
for (Personable person : res) {
if(person.getPersonId() < min || person.getPersonId() >= max ){
throw new AssertionException(map.getName()+" "+person+" != "+sqlPredicate);
}
}
Related
This code should probably go in code review but I won't get quick response there (Only 2 groovy questions there).
I have the following code for importing data from excel into my grails application. The problem is that I didn't test for >1000 rows in the excel file so my app froze when my client tried to upload 13k rows. I have checked the stacktrace.log (app is in production) but no exception. The system admin thinks the jvm ran out of memory. We have increased the size of the heap memory. However, I want to ask if there's a better way to implement this. I am using apache poi and creating domain objects as I read each row from excel. After that, I pass the list of objects to the controller that validates and saves them in the database. Should I tell my client to limit number of items imported at a time? Is there a better way to write this code?
def importData(file, user){
def rows = []
def keywords = Keyword.list()
int inventoryCount = Inventory.findAllByUser(user).size()
def inventory = new Inventory(name:"Inventory ${inventoryCount +1}", user:user)
Workbook workbook = WorkbookFactory.create(file)
Sheet sheet = workbook.getSheetAt(0)
int rowStart = 1;
int rowEnd = sheet.getLastRowNum() + 1 ;
for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
Row r = sheet.getRow(rowNum);
if(r != null && r?.getCell(0, Row.RETURN_BLANK_AS_NULL)!=null ){
def rowData =[:]
int lastColumn = 8;
for (int cn = 0; cn < lastColumn; cn++) {
Cell c = r.getCell(cn, Row.RETURN_BLANK_AS_NULL);
if (c == null) {
return new ExcelFormatException("Empty cell not allowed",rowNum+1, cn+1)
} else {
def field = properties[cn+1]
if(field.type==c.getCellType()){
if(c.getCellType()==text){
rowData<<[(field.name):c.getStringCellValue().toString()]
}else if(c.getCellType()==numeric){
if(field.name.equalsIgnoreCase("price") ){
rowData<<[(field.name):c.getNumericCellValue().toDouble()]
}else{
rowData<<[(field.name):c.getNumericCellValue().toInteger()]
}
}
}else{
return new ExcelFormatException("Invalid value found", rowNum+1, cn+1)
}
}
}
def item = new InventoryItem(rowData)
String keyword = retrieveKeyword(item.description, keywords)
String criticality = keyword?"Critical":"Not known"
int proposedMin = getProposedMin(item.usagePerYear)
int proposedMax = getProposedMax(proposedMin, item.price, item.usagePerYear, item?.currentMin)
String inventoryLevel = getInventoryLevel(item.usagePerYear, item.quantity, proposedMin, item.currentMin)
item.proposedMin = proposedMin
item.proposedMax = proposedMax
item.inventoryLevel = inventoryLevel
item.keyword = keyword
item.criticality = criticality
inventory.addToItems(item)
}
}
return inventory
}
Functions used in above code:
def retrieveKeyword(desc, keywords){
def keyword
for (key in keywords){
if(desc.toLowerCase().contains(key.name.toLowerCase())){
keyword = key.name
break
}
}
return keyword
}
int getProposedMin(int usage){
(int) ((((usage/12)/30) *7) + 1)
}
int getProposedMax(int pmin, double price, int usage, int cmin){
int c = price == 0? 1: ((Math.sqrt((24 * (usage/12)*5)/(0.15*price))) + (pmin - 1))
if(cmin >= c){
return pmin
}
return c
}
String getInventoryLevel(int usage, int qty, int proposedMin, int currentMin){
if(qty != 0){
double c = usage/qty
if(usage==0)
return "Excess"
if(c<0.75){
return "Inactive"
}else if(proposedMin<currentMin){
return "Excess"
}else if(c>=0.75){
return "Active"
}
}else if(usage==0 && qty == 0){
return "Not used"
}else if(usage>3 && qty ==0){
return "Insufficient"
}else if(proposedMin > currentMin){
return "Insufficient"
}
}
Controller action:
def importData(){
if(request.post){
def file = request.getFile("excelFile")
//validate file
def file_types = ["application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"]
if(!file_types.contains(file.getContentType())){
render view:"importData", model:[error:"Invalid File type"]
return
}
def inv = excelService.importData(file.getInputStream(),User.get(principal.id))
if(inv){
if(inv instanceof ExcelFormatException){
def err = (ExcelFormatException) inv
render view:"importData", model:[error:err.message +". Error occurred at: Row: "+err.row+" Col: "+err.col]
return
}else{
render view:"viewData", model:[inventory:inv]
return
}
}
}
}
Hibernate and GORM require some tuning when dealing with bulk imports. Two suggestions:
Follow the techniques found here: http://naleid.com/blog/2009/10/01/batch-import-performance-with-grails-and-mysql (written with MySQL in mind, but the concepts are pertinent to any RDBMS)
Don't use a collection to map the relationship between Inventory and InventoryItem. Remove the items collection from Inventory and instead add an Inventory field to your InventoryItem class. Burt Beckwith covers this in great detail here: http://burtbeckwith.com/blog/?p=1029
Using a plugin would be a better option.
I use this plugin - http://grails.org/plugin/excel-import
I have three textboxes.In textbox1 and in textbox2 i entered a number Like ->
Textbox1-0123456789
Textbox2-0123-456-789
Textboxe3-0123-456-789
Now on server side i.e on aspx.cs page i need to check the numbers is it same or not and only one distinct number will be saved in database
//Get the values from text box and form a list
//validate against a regular expression to make them pure numeric
//now check if they are all same
List<string> lst = new List<string>()
{
"0123-456-A789",
"0123-456-A789",
"0123-456-789"
};
Regex rgx = new Regex("[^a-zA-Z0-9]");
//s1 = rgx.Replace(s1, "");
for (int i = 0; i < lst.Count; i++)
{
var value = lst[i];
value = rgx.Replace(value, "");
lst[i] = value;
}
if (lst.Any(num => num != lst[0]))
{
Console.WriteLine("All are not same");
}
else
{
Console.WriteLine("All are same");
}
//if all are same, pick an entry from the list
// if not throw error
HOPE THIS MAY GIVE U AN IDEA !!!!
If we apply replace("-","") than from every textbox it will remove dash.The number which is same like in
textbox1-0123456789
textbox2=0123-456-789
textbox3=678-908-999
than replace will remove dash from textbox3 also which we dont want.
so For this we have to apply not exists operation of linq.
List strMobileNos = new List();
Regex re = new Regex(#"\d{10}|\d{3}\s*-\s*\d{3}\s*-\s*\d{4}");
!strMobileNos.Exists(l => l.Replace("-", "") == Request.Form["txtMobNo2"].Replace("Mobile2", "").Replace("-", ""))
I want to convert a Guid to a UUID or a string version of the same so that the following CQL query will work.
if (cassandraDb.ExecuteQuery(string.Format("SELECT OrderGroupId FROM Order WHERE OrderGroupId={0}", orderGroupId)).Count() <= 0) {
The variable 'orderGroupId' is a Guid. Obviously this is using FluentCassandra in a C#/.NET environmnet. Any hints?
Thank you.
To convert System.Guid to FluentCassandra.Types.UUIDType you just need to assign one into the other.
Same goes for FluentCassandra.Types.TimeUUIDType.
Execute the CQL query directly as a string by using the .ToString() property.
string.Format("SELECT OrderGroupId FROM Order WHERE OrderGroupId={0}", orderGroupId.ToString())
Should work fine. If it does not... you may want to try this (which I found on a comment thread on one of the C# clients):
protected static string ToCqlString(Guid guid) {
var bytes = guid.ToByteArray();
StringBuilder sb = new StringBuilder(bytes.Length * 2);
for (int i = 0; i < 16; i++) {
if (i == 4 || i == 6 || i == 8 || i == 10) {
sb.Append("-");
}
var b = bytes[i];
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
Cheers,
Allison
I have string value like this:
string strRole = "ab=Admin,ca=system,ou=application,role=branduk|ab=Manager,ca=system,ou=application,role=brankdusa|ab=sale,ca=system,ou=application,role=brandAu";
I just need to retrieve role to string array. I wonder if there is the best way to split the string in C# 4.0
string[] arrStrRole = strRole.Split('|').Select .. ??
Basically, I need brandUK, brandUsa, brandAu to string[] arrStrRole.
Thanks.
string[] arrStrRole = strRole.Split('|').Select(r => r.Split(new []{"role="}, StringSplitOptions.None)[1]).ToArray()
results in an string array with three strings:
branduk
brankdusa
brandAu
you can use string[] arrStrRole = strRole.Split('|',','); and this will split according to | and , characters
You can use String.Split in this LINQ query:
var roles = from token in strRole.Split('|')
from part in token.Split(',')
where part.Split('=')[0] == "role"
select part.Split('=')[1];
Note that this is yet prone to error and requires the data always to have this format. I mention it because you've started with Split('|').Select.... You can also use nested loops.
If you need it as String[] you just need to call ToArray:
String[] result = roles.ToArray();
I would go with Regex rather than splitting string. In combination with your intended Select solution, it could look like this:
var roles = Regex.Matches(strRole, #"role=(\w+)")
.Cast<Match>()
.Select(x => x.Groups[1].Value).ToArray();
You could use an extension like this which would allow you to test it easily.
public static string[] ParseRolesIntoList(this string csvGiven)
{
var list = new List<string>();
if (csvGiven == null) return null;
var csv = csvGiven.Split(',');
foreach (var s in csv)
{
if (string.IsNullOrEmpty(s)) continue;
if(!s.StartsWith("role")) continue;
var upperBound = s.IndexOf("|");
if (upperBound <= 0) upperBound = s.Length;
var role = s.Substring(s.IndexOf("=") + 1,
upperBound - s.IndexOf("=") - 1);
list.Add(role);
}
return list.ToArray();
}
Test below found brankdusa typo in your example. Some of the other answers would not deal with brandAu as it matches slightly differently. Try running this test against them if you like
[Test]
public void Should_parse_into_roles()
{
//GIVEN
const string strRole = "ab=Admin,ca=system,ou=application,role=branduk|ab=Manager,ca=system,ou=application,role=brankdusa|ab=sale,ca=system,ou=application,role=brandAu";
//WHEN
var roles = strRole.ParseRolesIntoList();
//THEN
Assert.That(roles.Length, Is.EqualTo(3));
Assert.That(roles[0], Is.EqualTo("branduk"));
Assert.That(roles[1], Is.EqualTo("brankdusa"));
Assert.That(roles[2], Is.EqualTo("brandAu"));
}
This gives an array of the 3 values.
void Main()
{
string strRole = "ab=Admin,ca=system,ou=application,role=branduk|ab=Manager,ca=system,ou=application,role=brankdusa|ab=sale,ca=system,ou=application,role=brandAu";
var arrStrRole = strRole.Split('|',',')
.Where(a => a.Split('=')[0] == "role")
.Select(b => b.Split('=')[1]);
arrStrRole.Dump();
}
I am currently developing a testing framework for a web data entry application that is using the Telerik ASP.Net framework and have run into a blocker. If I step through my code in debug mode the test will find the text box that I am looking for and enter some test data and then save that data to the database. The problem that I am running into is that when I let the test run on it's own the test fails saying that it couldn't fine the column that was declared. Here is my code:
/*Method to enter test data into cell*/
private TableCell EditFieldCell(string columnHeader)
{
var columnIndex = ColumnIndex(columnHeader);
if (columnIndex == -1)
throw new InvalidOperationException(String.Format("Column {0} not found.", columnHeader));
return NewRecordRow.TableCells[columnIndex];
}
/*Method to return column index of column searching for*/
public int ColumnIndex(string columnHeader)
{
var rgTable = GridTable;
var rgCount = 0;
var rgIndex = -1;
foreach (var rgRow in rgTable.TableRows)
{
foreach (var rgElement in rgRow.Elements)
{
if (rgElement.Text != null)
{
if (rgElement.Text.Equals(columnHeader))
{
rgIndex = rgCount;
break;
}
}
rgCount++;
}
return rgIndex;
}
My thinking is that something with my nested for loops is presenting the problem because the rgIndex value that is returned when I let the program run is -1 which tells me that the code in the for loops isn't being run.
TIA,
Bill Youngman
Code that gets the table Column index. You need to pass the Table(verify that the table exists while debug):
public int GetColumnIndex(Table table, string headerName)
{
ElementCollection headerElements = table.TableRows[0].Elements; //First row contains the header
int counter = 0;
foreach (var header in headerElements)
{
if (header.ClassName != null && header.ClassName.Contains(headerName)) //In this case i use class name of the header you can use the text
{
return counter;
}
counter++;
}
// If not found
return -1;
}