Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    ResultSet correct usage?

    I would like to use a few ResultSets to dynamically create Listgrid data (transposing and customized value maps etc).

    I want to confirm the following is a reasonable way to use a ResultSet.

    Code:
     ResultSet resultSet = new ResultSet(dataSource);
     //I want to load all records
     resultSet.setFetchMode(FetchMode.LOCAL);
    
    ...
    
     //add some handlers to respond to changes to the ResultSet (I know that this is only add/remove/re-order records)
     resultSet.addDataChangedHandler(new DataChangedHandler() {
    	@Override
    	public void onDataChanged(DataChangedEvent event) {
    	   //update based on change
    				}
    			});
    
     resultSet.addDataArrivedHandler(new DataArrivedHandler() {
    	   //update based on fetch
    				}
    			});
    
     //force a fetch to the result set - after this it should be all cached right?
     resultSet.toArray();

    #2
    I'm still navigating my way through ResultSet. I'd like to get this figured out.

    I noticed something pretty strange: ResultSet.allRowsCached causes onDataChanged to be fired.

    Code:
    SomeClassIWrote$22$2.onDataChanged(DataChangedEvent) line: 1377	
    DataChangedEvent.dispatch(DataChangedHandler) line: 61	
    DataChangedEvent.dispatch(EventHandler) line: 1	
    SimpleEventBus.doFire(GwtEvent<H>, Object) line: 204	
    SimpleEventBus.fireEvent(GwtEvent<?>) line: 103	
    HandlerManager.fireEvent(GwtEvent<?>) line: 101	
    ResultSet(BaseClass).fireEvent(GwtEvent<?>) line: 485	
    NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]	
    NativeMethodAccessorImpl.invoke(Object, Object[]) line: not available	
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available	
    Method.invoke(Object, Object...) line: not available	
    MethodAdaptor.invoke(Object, Object...) line: 103	
    MethodDispatch.invoke(JsValue, JsValue[], JsValue) line: 71	
    OophmSessionHandler.invoke(BrowserChannelServer, BrowserChannel$Value, int, BrowserChannel$Value[]) line: 157	
    BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer$SessionHandlerServer) line: 326	
    BrowserChannelServer.invokeJavascript(CompilingClassLoader, JsValueOOPHM, String, JsValueOOPHM[], JsValueOOPHM) line: 207	
    ModuleSpaceOOPHM.doInvoke(String, Object, Class<?>[], Object[]) line: 129	
    ModuleSpaceOOPHM(ModuleSpace).invokeNative(String, Object, Class<?>[], Object[]) line: 561	
    ModuleSpaceOOPHM(ModuleSpace).invokeNativeObject(String, Object, Class<?>[], Object[]) line: 269	
    JavaScriptHost.invokeNativeObject(String, Object, Class<?>[], Object[]) line: 91	
    ResultSet.create() line: not available	
    ResultSet(BaseClass).getOrCreateJsObj() line: 112	
    GeneratedMethodAccessor320.invoke(Object, Object[]) line: not available	
    DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: not available	
    Method.invoke(Object, Object...) line: not available	
    MethodAdaptor.invoke(Object, Object...) line: 103	
    MethodDispatch.invoke(JsValue, JsValue[], JsValue) line: 71	
    OophmSessionHandler.invoke(BrowserChannelServer, BrowserChannel$Value, int, BrowserChannel$Value[]) line: 157	
    BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer$SessionHandlerServer) line: 326	
    BrowserChannelServer.invokeJavascript(CompilingClassLoader, JsValueOOPHM, String, JsValueOOPHM[], JsValueOOPHM) line: 207	
    ModuleSpaceOOPHM.doInvoke(String, Object, Class<?>[], Object[]) line: 129	
    ModuleSpaceOOPHM(ModuleSpace).invokeNative(String, Object, Class<?>[], Object[]) line: 561	
    ModuleSpaceOOPHM(ModuleSpace).invokeNativeBoolean(String, Object, Class<?>[], Object[]) line: 184	
    JavaScriptHost.invokeNativeBoolean(String, Object, Class<?>[], Object[]) line: 35	
    ResultSet.allRowsCached() line: not available

    Comment


      #3
      Originally posted by atomatom
      I'm still navigating my way through ResultSet. I'd like to get this figured out.
      I noticed something pretty strange: ResultSet.allRowsCached causes onDataChanged to be fired.

      After updating gwt to 2.3, and smartgwt to 2011-06-07 nightly, I noticed that my onDataChanged events were being called all over the place, when doing simple findAll() calls. I rely heavily on ResultSet updates, as my architecture is meta-model driven. Has something changed in this area? With the build from sometime in March this seemed to behave correctly. Can anyone shed some light on this please?

      regards,
      Andrius J.

      Comment


        #4
        It would be great if there was a complete example of how to use a ResultSet properly - if only to help identify test cases/etc. I actually gave up figuring it out after getting extremely frustrated with it. Would love to see how your code looks Andrius.

        My general pattern is along the lines of

        1) Use a DataSource.fetch to load the data. Create the ResultSet in the callback and set the initial data.

        2) Add the onChanged listeners.

        I really like the ResultSet and would like better documentation and more examples. I guess one thing I could do is look at the SmartClient code for how ListGrid interacts with it.

        I hit another bug yesterday where ResultSet.valueMap(KEY,VALUE) returns a String->String map instead of the Long -> String map (the keys were stored incorrectly).

        Comment


          #5
          @phuqit can you show a minimal standalone test case for a situation where you believe DataChanged is firing inappropriately?

          Comment


            #6
            Originally posted by Isomorphic
            @phuqit can you show a minimal standalone test case for a situation where you believe DataChanged is firing inappropriately?

            Ok, here it goes:

            Code:
            package com.ajaxelements.gwt.client;
            
            import com.google.gwt.core.client.EntryPoint;
            import com.google.gwt.core.client.GWT;
            import com.google.gwt.user.client.ui.Label;
            import com.google.gwt.user.client.ui.RootPanel;
            import com.smartgwt.client.data.DataSource;
            import com.smartgwt.client.data.ResultSet;
            import com.smartgwt.client.data.events.DataArrivedEvent;
            import com.smartgwt.client.data.events.DataArrivedHandler;
            import com.smartgwt.client.data.events.DataChangedEvent;
            import com.smartgwt.client.data.events.DataChangedHandler;
            import com.smartgwt.client.data.fields.DataSourceDateField;
            import com.smartgwt.client.data.fields.DataSourceSequenceField;
            import com.smartgwt.client.data.fields.DataSourceTextField;
            import com.smartgwt.client.widgets.grid.ListGridRecord;
            import com.smartgwt.client.widgets.calendar.CalendarEvent;
            
            import java.util.Date;
            import java.util.HashMap;
            
            
            public class SampleEntryPoint implements EntryPoint {
            
                @Override
                public void onModuleLoad() {
                    DataSource eventDS = new DataSource();
                    DataSourceSequenceField eventIdField = new DataSourceSequenceField("eventId");
                    eventIdField.setPrimaryKey(true);
            
                    DataSourceTextField nameField = new DataSourceTextField("name");
                    DataSourceTextField descField = new DataSourceTextField("description");
                    DataSourceDateField startDateField = new DataSourceDateField("startDate");
                    DataSourceDateField endDateField = new DataSourceDateField("endDate");
            
                    eventDS.setFields(eventIdField, nameField, descField, startDateField, endDateField);
                    eventDS.setClientOnly(true);
                    eventDS.setTestData(CalendarData.getRecords());
            
                    final ResultSet entityAttributeSetRS = new ResultSet(eventDS);
                    entityAttributeSetRS.addDataChangedHandler(new DataChangedHandler() {
                        @Override
                        public void onDataChanged(DataChangedEvent dataChangedEvent) {
                            GWT.log("data changed event...");
                        }
                    });
            
                    entityAttributeSetRS.addDataArrivedHandler(new DataArrivedHandler() {
                        @Override
                        public void onDataArrived(DataArrivedEvent dataArrivedEvent) {
                            GWT.log("data arrived event");
                        }
                    });
            
            
                    entityAttributeSetRS.find(new HashMap());
                }
            }
            
            
            
            
            class CalendarData {
            
                private static CalendarEvent[] records;
                private static Date today = new Date();
                private static int year = today.getYear();
                private static int month = today.getMonth();
                private static int start = today.getDate() - today.getDay();
            
                public static CalendarEvent[] getRecords() {
                    if (records == null) {
                        records = getNewRecords();
                    }
                    return records;
                }
            
                public static CalendarEvent[] getNewRecords() {
                    return new CalendarEvent[]{
                            new CalendarEvent(1, "Meeting", "Shareholders meeting: monthly forecast report", new Date(year, month, start + 2, 9, 0, 0), new Date(year, month, start + 2, 14, 0, 0)),
                            new CalendarEvent(2, "Realtor", "Breakfast with realtor to discuss moving plans", new Date(year, month, start + 3, 8, 0, 0), new Date(year, month, start + 3, 10, 0, 0)),
                            new CalendarEvent(3, "Soccer", "Little league soccer finals", new Date(year, month, start + 4, 13, 0, 0), new Date(year, month, start + 4, 16, 0, 0)),
                            new CalendarEvent(4, "Sleep", "Catch up on sleep", new Date(year, month, start + 4, 5, 0, 0), new Date(year, month, start + 4, 9, 0, 0)),
                            new CalendarEvent(5, "Inspection", "Home inspector coming", new Date(year, month, start + 4, 10, 0, 0), new Date(year, month, start + 4, 12, 0, 0), false, "testStyle"),
                            new CalendarEvent(6, "Airport run", "Pick James up from the airport", new Date(year, month, start + 4, 1, 0, 0), new Date(year, month, start + 4, 3, 0, 0)),
                            new CalendarEvent(7, "Dinner Party", "Prepare elaborate meal for friends", new Date(year, month, start + 4, 17, 0, 0), new Date(year, month, start + 4, 20, 0, 0)),
                            new CalendarEvent(8, "Poker", "Poker at Steve's house", new Date(year, month, start + 4, 21, 0, 0), new Date(year, month, start + 4, 23, 0, 0)),
                            new CalendarEvent(9, "Meeting", "Board of directors meeting: discussion of next months strategy", new Date(year, month, start + 5, 11, 0, 0), new Date(year, month, start + 5, 15, 0, 0))
                    };
                }
            }
            onDataChanged is being called instead of onDataArrived - is that intended? I need to do some additional filtering on the result set in the onDataChanged event, and if I call any of the find(...) methods, I end up in an endless recursion. Ideas?

            regards,
            Andrius J.

            Comment


              #7
              Do you guys need any more information to test it? I am heavily relying on this functionality, so if it's not a bug or an issue, I'll have to reconsider the architecture. Any help would be appreciated!

              regards,
              Andrius J.

              Comment


                #8
                OK, I think I found a workaround. Instead of trying to call ResultSet.find() in the onDataChanged() event handler, which was causing the endless recursion, I refactored the code to use EventBus to publish the metadata change event and deferring it's execution using the Timer() {...}.schedule(1);
                Once the onDataChanged() handler completes, it is no longer invoked when calling ResultSet.find() methods.

                Comment


                  #9
                  When using these listeners I made heavy use of this kind of pattern.

                  Code:
                   Handler
                    onSomethingHappened(){
                       markDoSomething();
                    }
                  
                    markDoSomething(){
                      marked=true;
                      Scheduler.get().scheduleDeferred(new ScheduledCommand() {
                         @Override
                         public void execute() {
                  	  if (marked){
                               marked=false;
                               //things to do...
                            }
                         }})
                    }
                  Of course, it is crucial that nothing in execute fire more events, else loopy.

                  I really do not like using the Timer - it should be used only for efficiency reasons, not to defer commands that *rely* on a delay (fine if they don't care about a delay at all). Otherwise users on slow computers/connections will hate you.

                  Comment


                    #10
                    Good point. It's been 3 months since I used the APIs, so I forgot about Scheduler. Thanks!

                    regards,
                    Andrius J.

                    Comment


                      #11
                      Chances are your timer did exactly the same thing. It's only if you were relying on that delay that it causes problems (like, "hmm, these events will stop firing in 100ms, sure...")

                      Comment

                      Working...
                      X