Insert / Locate in Cache DataSet
Insert / Locate in Cache DataSet
Hello,
I do some evaluation, comparison of IbDac features and it raises some questions.
My app have a lot of forms that display data. Most of them have a grid on all area. I call them browsers. Beside browsers there are forms that edit data, a lot of inputs with ok/cancel buttons. I call them editors. Scenario is that browsers / editors are completely independent/standalone. You can insert a new record directly by opening an editor, you can invoke an editor or more editors from browser, later close browsers, or open separately two browser instances.
Each editor/browser have their standalone dataset for displaying/editing data.
The big question is how to synchronize inserted/edited records between editors and browsers.
I already have some similar implementation using FibPlus components. I build a Notifier component that signal to subscribed browsers: hey, one record with pk=val has been inserted/updated. So browser do a fake insert (in case of insert) in cache or locate in cache of fetched records and refresh this record, asking from server just one row, instead refreshing/reopening entire dataset.
How can I do this using IbDac? Is this approach "compatible" with IbDac logic?
I do some evaluation, comparison of IbDac features and it raises some questions.
My app have a lot of forms that display data. Most of them have a grid on all area. I call them browsers. Beside browsers there are forms that edit data, a lot of inputs with ok/cancel buttons. I call them editors. Scenario is that browsers / editors are completely independent/standalone. You can insert a new record directly by opening an editor, you can invoke an editor or more editors from browser, later close browsers, or open separately two browser instances.
Each editor/browser have their standalone dataset for displaying/editing data.
The big question is how to synchronize inserted/edited records between editors and browsers.
I already have some similar implementation using FibPlus components. I build a Notifier component that signal to subscribed browsers: hey, one record with pk=val has been inserted/updated. So browser do a fake insert (in case of insert) in cache or locate in cache of fetched records and refresh this record, asking from server just one row, instead refreshing/reopening entire dataset.
How can I do this using IbDac? Is this approach "compatible" with IbDac logic?
Re: Insert / Locate in Cache DataSet
Hello,
You can use your notifier component with IBDAC. To refresh only one record, you should use the RefreshRecord method, it refreshes only the current record without refreshing of the whole dataset. So, you can use the primary key value obtained from the notifier to locate to the correct record and call the RefreshRecord method. If you want to save the position in the dataset, we suggest to use bookmarks for this.
You can use your notifier component with IBDAC. To refresh only one record, you should use the RefreshRecord method, it refreshes only the current record without refreshing of the whole dataset. So, you can use the primary key value obtained from the notifier to locate to the correct record and call the RefreshRecord method. If you want to save the position in the dataset, we suggest to use bookmarks for this.
Re: Insert / Locate in Cache DataSet
Hello mr. Andrey,
Thanks for prompt and quick answer!
Yeah, I understand and saw before RefreshRecord method (although TDataSet.Refresh already is built to refresh just current record), but the problem is with newly inserted records.
First I need to do a fake insert with PK (that does not interact with server, just a mark), something like CacheInsert('PK', 'Value'), and later to call RefreshRecord. Is it possible?
Also, if dataset is very large, in a new opened Browser, is a nonsense to call Locate and fetch all records until found and later to call RefreshRecord for it. The best method is to Locate/change if it is already fetched, or update it when fetched in next batch (ok this can be implemented at Notifier level, not at IbDac), but i need something like CacheLocate.
Any ideas?
Thanks for prompt and quick answer!
Yeah, I understand and saw before RefreshRecord method (although TDataSet.Refresh already is built to refresh just current record), but the problem is with newly inserted records.
First I need to do a fake insert with PK (that does not interact with server, just a mark), something like CacheInsert('PK', 'Value'), and later to call RefreshRecord. Is it possible?
Also, if dataset is very large, in a new opened Browser, is a nonsense to call Locate and fetch all records until found and later to call RefreshRecord for it. The best method is to Locate/change if it is already fetched, or update it when fetched in next batch (ok this can be implemented at Notifier level, not at IbDac), but i need something like CacheLocate.
Any ideas?
Re: Insert / Locate in Cache DataSet
The TDataSet.Refresh method serves to refresh all records in the dataset by re-fetching data from the database server. You can find more information at http://docwiki.embarcadero.com/Librarie ... et.Refresh . To refresh only the current record, you should use the RefreshRecord method.
Please describe in details the way you performed cached insert and cached locating using fibplus.
Please describe in details the way you performed cached insert and cached locating using fibplus.
Re: Insert / Locate in Cache DataSet
About Refresh method, sorry, I was wrong. Probably used too long time Fib approach.
Take a look here, page 23: http://www.devrace.com/files/files/devguide1.pdf
Also I found this feature is not requested just by me, see last chapter: http://www.codenewsfast.com/cnf/article ... ng1701q424
In fact CacheInsert just insert a record in dataset buffers, internal cache of records like in CachedUpdates mode, on client side, without sending any statements to the server.
More info in russian: http://www.devrace.com/ru/fibplus/articles/3513.php
Take a look here, page 23: http://www.devrace.com/files/files/devguide1.pdf
Also I found this feature is not requested just by me, see last chapter: http://www.codenewsfast.com/cnf/article ... ng1701q424
In fact CacheInsert just insert a record in dataset buffers, internal cache of records like in CachedUpdates mode, on client side, without sending any statements to the server.
More info in russian: http://www.devrace.com/ru/fibplus/articles/3513.php
Re: Insert / Locate in Cache DataSet
We have fixed a bug with RefreshRecord in the CachedUpdates mode. It is now possible to add a new record (cached on the client) and call the RefreshRecord method for it. This fix will be included in the next IBDAC build. It means that in the CachedUpdates mode you can add a new record (using the Append or Insert dataset methods), post it (using the Post dataset method), and then call the RefreshRecord method after this. If there is such a record on the server, you will obtain all new values for it. In this case, there is no need to call the Locate method because after adding a new record it becomes the current record.
You can use the CachedUpdates mode to prevent IBDAC from sending SQL statements to the server when you add, modify, or delete records in the dataset. But make sure you do not call the ApplyUpdates method, as it sends all cached changes to the server.
You can use the CachedUpdates mode to prevent IBDAC from sending SQL statements to the server when you add, modify, or delete records in the dataset. But make sure you do not call the ApplyUpdates method, as it sends all cached changes to the server.
Re: Insert / Locate in Cache DataSet
Andrey,
CachedUpdates mode build a delta set of changes scheduled to be sent to server on ApplyUpdates. I don't need them. It's more a workaround than a solution. Beside Edit and Inserts user can Delete records, and they should be deleted immediately. Implementing Cache functions Insert/Edit/Delete it's relatively an easy task, just update local data, record buffers without touching the server.
Or let's say we have two datasets with the same exact set of data. When I delete one record from first dataset, I can do CacheDelete from second without Refreshing whole set. I am sure that record already are deleted from the server, so I can safe delete it from second cache.
I'll be very thankful if this functionality will be someday implemented in AnyDac components set.
CachedUpdates mode build a delta set of changes scheduled to be sent to server on ApplyUpdates. I don't need them. It's more a workaround than a solution. Beside Edit and Inserts user can Delete records, and they should be deleted immediately. Implementing Cache functions Insert/Edit/Delete it's relatively an easy task, just update local data, record buffers without touching the server.
Or let's say we have two datasets with the same exact set of data. When I delete one record from first dataset, I can do CacheDelete from second without Refreshing whole set. I am sure that record already are deleted from the server, so I can safe delete it from second cache.
I'll be very thankful if this functionality will be someday implemented in AnyDac components set.
Re: Insert / Locate in Cache DataSet
For the time being IBDAC does not have such functionality. You can leave your suggestion at our UserVoice page at http://devart.uservoice.com/forums/1046 ... components . Suggestions with many votes will be implemented faster.
Re: Insert / Locate in Cache DataSet
Ok, I added one entry related to this feature at uservoice:
http://devart.uservoice.com/forums/1046 ... t-cachedel
Interested developers are welcome to vote/discuss this feature!
http://devart.uservoice.com/forums/1046 ... t-cachedel
Interested developers are welcome to vote/discuss this feature!
Re: Insert / Locate in Cache DataSet
We have investigated this question. There is the way to achieve the same functionality using IBDAC. All dataset components in IBDAC have the LocalUpdate property ( http://www.devart.com/ibdac/docs/devart ... update.htm ). When LocalUpdate is set to True, dataset does not send any data changes to the server, they are stored in the client memory. This way is actually more flexible than in FIBPlus, because you can add, delete, or modify records with the choice of sending these changes to the server or not. Here is a code example:
Code: Select all
IBCQuery1.SQL.Text := 'select * from tablename';
IBCQuery1.Open;
// this record will be sent to the server
IBCQuery1.Append;
IBCQuery1.FieldByName('id').AsInteger := 1;
IBCQuery1.Post;
IBCQuery1.LocalUpdate := True;
// this record will not be sent to the server
IBCQuery1.Append;
IBCQuery1.FieldByName('id').AsInteger := 2;
IBCQuery1.Post;
Re: Insert / Locate in Cache DataSet
Hello Andrey,
Big thanks for the hint!
Really nice feature & good architecture design.
Big thanks for the hint!
Really nice feature & good architecture design.
Re: Insert / Locate in Cache DataSet
You are welcome. Does this functionality fully cover your needs? If yes, we will close your suggestion at UserVoice.
Re: Insert / Locate in Cache DataSet
> Does this functionality fully cover your needs?
> If yes, we will close your suggestion at UserVoice.
Yeah, it seems to completely solve my needs. Will test it in work tonight.
> If yes, we will close your suggestion at UserVoice.
Yeah, it seems to completely solve my needs. Will test it in work tonight.
Re: Insert / Locate in Cache DataSet
We will wait for your confirmation. Thank you in advance.
Re: Insert / Locate in Cache DataSet
Thank you so much for this hint