How to update QTableView when database updated? - database

I use QSqlRelationalTableModel to extract data from database, and use tableView to show it. Now, when I update my database, how to update tableView automatically to show it? I know i need to use function dataChanged() to make this automatically, but i do not know how to use it? Any suggestion will be appreciated.
The main code is as follows:
QSqlRelationalTableModel *model = new QSqlRelationalTableModel(NULL, db);
model->setTable(tableName);
model->select();
tableView->setModel(model);
tableView->show();

No, there is no need to use dataChanged().
You just need to call QSqlRelationalTableModel::select() whenever the database gets updated. This will re-populate the model from the database, and update the views that are using it automatically.
If the database is updated from within you application, you can just call model->select() after the update queries get executed in your application.
If the database is updated from another application, you'll have to use something like PostgreSQL's event notification system, subscribe to the notification from your application using QSqlDriver::subscribeToNotification() and call model->select() in a slot connected to the notification() signal.
You can use QSqlDriver::hasFeature(QSqlDriver::EventNotifications) to check if notifications from your database are supported.

Related

How do I make a form refresh whenever Database is updated?

I have a database (table) on Microsoft Access that's constantly updating from python and I have a form displaying Fields from that table. How do I make a form update (refresh) automatically when data is added to the table it's reading from?
I've set a button that runs Me.Requery when pressed thus refreshing the Form and getting the new data, but I want for to update/refresh automatically. On Data change (Form_datachange) doesn't work (don't know why).
I don’t think you can run a macro to requery your form when the table updates due to the restrictions on data macros.
However, you can put your requery logic in the form’s OnTimer event and set it to run at a desired interval (e.g. 5000 ms which is 5 seconds)

Oracle ADF: Refresh Form data

I am developing a web app using Oracle ADF. I have a bounded task flow. In that I have a search page like below.
I have created the above two forms using view object data controls.
Searching is performing well. But my problem is when I go some where else in my application using menus provided left side and come back to the search page , the page is not getting refreshed. I am getting a search page that contains old search results. At this point of time if I am trying to make any changes am getting some error called "Another user with this id already modifed data ....". After this error my app is not running. Means what ever am trying to do its showing the same error.
So I need to make this: "When ever the user come to this form, He should get fresh form. It should not contain old search results.
Please help me. How do I achieve this.
Thank you.
There are 2 ways of doing it:
1) Set your task flow as ISOLATED, from Task Flow Overview tab -> Behaviour -> Share Data Control with calling task flow -> unchecked (or isolated, if you are using JDev 12c)
This will ensure you always start FRESH when accessing the page, but it will potentially create a performance overhead because entire View Object cache will be recreated (requeried) on page load. Nevertheless, it is the quickest solution.
2) You may create a default Method Call Activity in your task flow from where you may call a AM's custom method that resets the view criteria. The method will be placed on application module's implementation class and it may look like this:
public void initTaskFlow() {
this.getViewObject1().executeEmptyRowSet();
}
This will clean the result data. If you want to reset the querying parameters as well, you can use this example:
http://www.jobinesh.com/2011/04/programmatically-resetting-and-search.html
When you made any changes to any viewObject then excute this viewObject to match entity state and viewState , i think excuting viewObject will solve your issue
Ashish

Salesforce Trigger workflow on record delete

I want to listen change in my legacy system whenever there is any change in SF object (add/update/delete). So I have created outbound message and workflow. But in workflow I don't see any way to fire if object is deleted.
Is there anyway I can trigger outbound message on record delete? I know have heard that it can be done by trigger. But I don't want to write apex code for this.
To the best of my knowledge it cannot be done, the workflow actions are decoupled from the workflow rule (you can even reuse them) so they probably do not receive the transaction scope and when they execute the record is already gone and any reference inside action would point to a non-existing data. Thus the only way I know how to do it is via trigger.
Here is a workaround. However this will only be able to capture deletion made via std. Salesforce UI.
1.Create a custom checkbox field "Is Deleted"
2.Override the Del link with a custom VF page, that first updates the record status to "Is Deleted", and deletes the record.
3.Write workflow rule using the "Is Deleted" field.
Perhaps a compromise architecture would be to write an extremely small and simple after delete trigger that simply copies the deleted records in question to some new custom object. That new custom object fires your workflow rule and thus sends the outbound message you're looking for. The only issue with this would be to periodically clean up your custom object data that would grow in size as you deleted records from your other object. In other words, your "scratch" object would just need periodic cleaning - which could be done on a nightly schedule with batch Apex.
Here's a delete trigger that would do the trick using Opportunity as an example:
trigger AfterDelete on Opportunity (after delete)
{
List<CustObj__c> co = new List<CustObj__c>();
for(Opportunity o : Trigger.old)
{
CustObj__c c = new CustObj__c();
c.Name = o.Name;
c.Amount__c = o.Amount;
c.CloseDate__c = o.CloseDate;
c.Description__c = o.Description;
// etc.
co.add(c);
}
insert co;
}
It's not ideal but at least this would save you from having to code your own trigger-based outbound messages. These can only be done using the #Future annotation, btw, since callouts directly from triggers are forbidden. Hope that helps.
write a single email send in the trigger delete event. You have it in less than 1 hour.

How to update a TClientDataSet with changes made to the DB without it knowing?

I have a simple TClientDataSet component that I use to populate some data-aware components. However, if I insert data into my database using this dataset, I can't seem to find a proper way to sync it back into my TClientDataSet component.
How do I achieve this?
The TClientDataSet component has a Refresh method that does exactly that. Took some time for me to find this out in the docs, though. :)
From the docs:
From DB.pas
procedure Refresh;
Re-fetches data from the database to update a dataset's view of data.
Call Refresh to ensure that an application has the latest data from a database. For example, when an application turns off filtering for a dataset, it should immediately call Refresh to display all records in the dataset, not just those that used to meet the filter condition.
Note: The Refresh method does not work for all TDataSet descendants. In particular, TQuery components do not support the Refresh method if the query is not "live". To refresh a static TQuery, close and reopen the dataset.
TDataSet generates a BeforeRefresh event before refreshing the records and an AfterRefresh event afterwards.
Note: Most datasets try to maintain the current record position when you call refresh. However, this is not always possible. For example, the current record may have been deleted from the server by another user. Unidirectional datasets have no mechanism for locating the current record after a refresh, and always move back to the first record.
Warning: Unidirectional datasets refresh the data by closing and reopening the cursor. This can have unintended side effects if, for example, you have code in the BeforeClose, AfterClose, BeforeOpen, or AfterOpen event handlers.
Closing and opening the CDS didn't work for me. I'm using Delphi XE2, Update 3, with ADO tables connecting to an Access 2007 database. The only way I could refresh the data in my CDS was this:
procedure TForm1.PeopleRefreshButtonClick(Sender: TObject);
// this actually re-loads the data from the table!
begin
DM1.PeopleTable.Close;
DM1.PeopleTable.Open;
DM1.PeopleCDS.Refresh;
end;
A refresh button on the form closes, then opens the table. Then I refresh the ClientDataSet.
Basically, you must close the TClientDataset and then open it, loading the data from the database the same way you did originally. If the TClientDataset is connected to a TDataSetProvider, which is connected to a TDataset/TQuery descendant, all you have to do is close TClientDataset then open it.

CakePHP afterSave Timing

I have a situation where, in a model's afterSave callback, I'm trying to access data from a distant association (it's a legacy data model with a very wonky association linkage). What I'm finding is that within the callback I can execute a find call on the model, but if I exit right then, the record is never inserted into the database. The lack of a record means that I can't execute a find on the related model using data that was just inserted into the current.
I haven't found any mention of when data is actually committed with respect to when the afterSave callback is engaged. I'm working with legacy code, but I see no indication that we're specifically engaging transactions, so I'm trying to figure out what my options might be.
Thanks.
UPDATE
The gist of the scenario is this: We're taking event registrations, but folks can be wait listed. A user can register (or be registered) for a given Date. After a registration is complete, I need to check the wait list for the existence of a record for the registering user (WaitList.user_id) on the date being registered for (WaitList.date_id). If such a record exists, it can be deleted because it's become an active registration.
The legacy schema puts me in a place where the registration isn't directly tied to a date so I can't get the Date.id easily. Instead, Registration->Registrant->Ticket->Date. Unintuitive, I know, but it is what it is for now. Even better (sarcasm included), we have a view named attendees that rolls all of this info up and from which I would be able to use the newly created Registration->id to return Attendee.date_id. Since the record doesn't exist, it's not available in the view.
Hopefully that provides a little more context.
What's the purpose of the find query inside of your afterSave?
Update
Is it at all possible to properly associate the records? Or are we talking about way too much refactoring for it to be worth it? You could move the check to the controller if it's not possible to modify the associations between the records.
Something like (in psuedo code)
if (save->isSuccessful) {
if (onWaitList) {
// delete record
}
}
It's not best practice, but it will get you around your issue.

Resources