Announcement

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

    Updating a DataSource

    Hi.

    I am evaluating the SmartGwt EE. I have already built the UI and am trying to populate my ListGrid table with data from an Oracle 10g database. After having used the visual builder and defined the ds.xml it all works fine and I can see the data in a ListGrid in my UI (Thanks for the examples). I have the following question:

    There is another application that writes new records in the database every minute. That is why I want to update my DataSource (and ListGrid) in short intervals. What is the best way to achieve that?

    Thanks

    #2
    Hello kissev,

    Calling invalidateCache() will cause automatic reloading of data.

    This will show a loading message which in some cases is undesirable. To avoid this, call DataSource.fetchData() directly, construct a ResultSet with initialData set to dsResponse.getData(), and pass this to setData() on the grid.

    Comment


      #3
      thanks for the reply. Does this mean that I will load the whole DB Table each time? Also I want to know which records are new, so I can show them in the ListGrid lets say in another color.

      The next problem is that i have user rights, some users can see all the records from the DB and other just a part of them. I will have 4 or 5 different user rights. I am not quite sure how i can implement this using only smartgwt functionality, because of the CRUD operations. For each user right i need to have a different "where clause" when i get the data from the DB. That's why I am planing now to create a custom DS on the server, and implement the DB connection alone. Then it will be easier to refresh the DS every minute. So the next 2 questions:

      Is there a possibility to achieve that only with the smartgwtee functionality?

      If i create a custom DS that extends DataSource is it possible to use updateCaches() every time new records are added? Which showcase should I use?

      Thanks
      kissev
      Last edited by kissev; 31 Aug 2010, 23:44.

      Comment


        #4
        You can use dsRequest.startRow and dsRequest.endRow to load a subset of the data, and create the ResultSet with initialData and initialLength.

        Different where clauses for different users is straightforward. Consider SQL Templating and also Declarative Security for the actual enforcement.

        Comment


          #5
          On updateCaches(), this API probably does not apply to your usage. See the ResultSet documentation on automatic cache synchronization.

          Comment


            #6
            Hi,

            as You proposed I am now creating a ResultSet, which i pass to the setData() on the Grid. I have just a little problem when i try to use a filter. I am making a filter with a filterBuilder and using it on the grid. So far no problem and when i get the new Records(that corresponds to the filter Criteria) from the DB they are displayed. The Problem comes when i am using a filter on the Grid and also type something in one of the search fields. The first time i try to get the new Records from the DB everything is alright, but after that it seems that the Criterias are lost. Do you have any idea how to fix that?

            Thanks

            Comment


              #7
              There was a bug along these lines that was recently fixed. If you're seeing a problem, first check the Developer Console for warnings, then try creating a standalone test case that we can look at.

              Comment


                #8
                Hi,

                I think i found the problem. In my fetch method in the DMI class i have some specific criteria that i apply on the dsRequest before i call execute(). In the console i can see following line:
                Code:
                criteria: {operator:"and",_constructor:"AdvancedCriteria",criteria:[{operator:"contains",fieldName:"ASA",value:"5_ASA"},{USERTEXT:"9"}]}
                ASA = 5_ASA is a criteria that i manually create in the DMI.
                {USERTEXT:"9"} is the value in the filter editor. How can i transform it to an AdvancedCriteria except from parsing simple Criteria Objects on the server an put it into an AdvancedCriteria-Map??

                Working with AdvancedCriteria on the server side works pretty good for us. "Simple" Criteria is added from the text added into the filter editor. Is there a way to force the filter editor to use AdvancedCriteria, other than specifying a date/datetime field, that users can't hide?


                thanks
                Last edited by kissev; 5 Oct 2010, 08:41.

                Comment


                  #9
                  Using SmartGWT 2.4.

                  We also need to reload for realtime data into ListGrid but the only way we found are invalidatingCache() to the DataSource. And then fetch again.

                  The added problem is that we need to filter the server results by an IPickTreeItem that decides which subset of data is needed to show.
                  The ListGrid permit to change the sort and filtering its own data.

                  The TTDS is defined with the following parameters:
                  Code:
                  setClientOnly(false);
                  setDataURL(url);
                  setDropExtraFields(true);
                  setCacheMaxAge(120);
                  setPreventHTTPCaching(true);
                  We created a timer to refresh the data using invalidateCache.
                  Code:
                  //in a Timer.run() schedule every 120s
                  TTDS.getInstance().invalidateCache();
                  ttGrid.fetchData(new Criteria("z", zone));
                  After this code is executed the ListGrid lost all sorting and filters done by the user.

                  Thats why we tried to save/load them in different situations:
                  Code:
                  public void loadConfig() {
                  	String cc = Cookies.getCookie("ttGridViewState");
                  	if (cc != null)
                  		ttGrid.setViewState(cc);
                  	cc = Cookies.getCookie("ttGridSortState");
                  	if (cc != null)
                  		ttGrid.setSortState(cc);
                  }
                  
                  @SuppressWarnings("deprecation")
                  public void saveConfig() {
                  	Date now = new Date();
                  	Date exp = new Date(now.getYear() + 1, now.getMonth(), now.getDay());
                  	Cookies.setCookie("ttGridViewState", ttGrid.getViewState(), exp);
                  	Cookies.setCookie("ttGridSortState", ttGrid.getSortState(), exp);
                  }
                  But this method does not solve filtering and that's why we tried a sophisticated fetch method (simplified here):
                  Code:
                  TTDS.getInstance().invalidateCache();
                  Criteria c = new Criteria();
                  c.addCriteria(ttGrid.getCriteria());
                  c.addCriteria("z", zone);
                  ttGrid.fetchData(c);
                  But when users resets the criteria using the UI the SmartGWT don't re-fetch from the server, resulting the same data or re-filtered by the browser client part the already shown data.

                  To summarize:
                  -We need an external specified filtering: fetchData(new Criteria("z", zone));
                  -We need to conserve trough refreshes the sorting and the filtering introduced by the user to the Web UI.
                  -It doesn't matter if the user filtering is done by the client, but the "z" filtering must be done by the server.

                  Comment


                    #10
                    All you need to do to preserve sort and filter when reloading data is to simply remove your call to fetchData(). The call to invalidateCache() is sufficient, and reloads the data with the current criteria and sort.

                    Comment


                      #11
                      Ok, reload is now fine doing ListGrid.invalidateCache().

                      But there is another case that makes me dubt the way it should be solved. Sometimes we also need to change the filtering, we are currently doing:
                      Code:
                      MyDataSource.getInstance().invalidateCache();
                      lsGrid.fetchData(new Criteria("z", zone));
                      Is this a better way?
                      Code:
                      lsGrid.invalidateCache();
                      lsGrid.fetchData(new Criteria("z", zone));
                      Or both are equally correct?

                      Or do we need to specify the criteria simply by modifying "z" from getCriteria and returning it to setCriteria.

                      What we are interested is not to fetch from the server more than once the same information, and I'm worried if lsGrid.invalidateCache(); could we eventually fetch the data before the following call to fetchData();.
                      Thats why initially we invalidate only the cache from the DS, but we want to ensure if this is the correct way or is preferable the second or another one.

                      Thanks in advance.

                      Comment


                        #12
                        invalidateCache at the DataSource level invalidates cache for all components, invalidateCache at the ListGrid level only does it for the ListGrid. Taking just the grid into account, there is no difference unless you have also set cacheAllData:true on this DataSource.

                        Comment

                        Working...
                        X