Convert SQLContainer to IndexedContainer

I welcome!

This example http://demo.vaadin.com/sampler#TextFieldTextChangeEvent uses IndexedContainer for maintenance of a filtration of contents of the table.

I use SQLContainer, and to achieve a filtration it is not possible.

Whether it is possible - as that to transform SQLContainer to IndexedContainer?

You can always query for the rows in the database directly, and then populate what ever container, like IndexedContainer or BeanItemContainer directly. However SQLContainer 1.1.0 has a new Filtering system based on the one that was introduced in Vaadin 6.6.0 (the one you linked to)

Hi Ivanov,

Indexing database containers is not a good idea IMHO unless you can ensure repeatable reads across the live of an ItemID or assume that the Item referenced by an ItemId can change at all.

something like:


 container.remove(getIdByIndex(IndexOfId(itemId))); 

May fail removing the wrong row if someone add/remove a row in the middle of two Container.Indexed calls.

If the container try to use the PK of table as itemId (as most do) the only implementation possible of the method indexOfId() for most databases, as far as i known, is doing something like: (you can query MS SQL to get the row of a index and save moving the data on the wire, but is not portable)


while(!page.contains(id)) {
    loadPage(page);
}

ie, load all records by pages until get the key. This performs poorly unless you query for index in sequence.

So i think that the best way to get a database container indexed is accept that the item referenced by an itemId can change and use the index as itemId, that performs well and have a trivial implementation :).

Best regards,

I welcome you Jens Jansson! I welcome you, Jose Luis Martin!

Many thanks for answers! I am very grateful to you!

Finally, I’ve found the way to do this. I put it here for who’s interested in it. This resolves not-working sorting in SQLContainer tables.

If SQLContainer had properties AAA (BigDecimal), BBB (String) and CCC (String), this method would be valid:

@SuppressWarnings("unchecked")
public static IndexedContainer getIndexedContainerFromSQLContainer(SQLContainer container) {
	IndexedContainer indexedContainer = new IndexedContainer();
	
	for (int i=0;i<container.getItemIds().size();i++){
		Object itemId = container.getIdByIndex(i);
		Item item = container.getItem(itemId);
		
		if (i==0){
			String id = null;
			ColumnProperty itemProperty = null;
			Class<?> type = null;
			
			id = "AAA";
			while (id!=null){
				itemProperty = (ColumnProperty)item.getItemProperty(id);
				type = itemProperty.getType();
				
				indexedContainer.addContainerProperty(id, (type!=BigDecimal.class)?type:Integer.class, null);
				
				if (id.equals("AAA")) id = "BBB";
				else if (id.equals("BBB")) id = "CCC";
				else if (id.equals("CCC")) id = null;
			}
		} 

		BigDecimal aaa = (BigDecimal)item.getItemProperty("AAA").getValue();
		String bbb = (String)item.getItemProperty("BBB").getValue();
		String ccc = (String)item.getItemProperty("CCC").getValue();
		
		Item indexedContainerItem = indexedContainer.getItem(indexedContainer.addItem());
		
		indexedContainerItem.getItemProperty("AAA").setValue(Integer.valueOf(aaa.intValue()));
		indexedContainerItem.getItemProperty("BBB").setValue(bbb);
		indexedContainerItem.getItemProperty("CCC").setValue(ccc);
	}
	
	return indexedContainer;
}