Problem with databaseManager.hasRecordChanges()

Hi,

I am having trouble with the hasRecordChanges() method. If data in the foundset has not changed, the following code snippet executes properly (test_rec_change is false). However, if I change data on the form, hasRecordChanges() also returns a false (I expected a true).

Can anyone see what is wrong with my code block? I have checked the state of Autosave (set globally off and confirmed with my debug() routine) but I can’t seem to see what I am doing wrong.

/************************
	
	method name:	DCM_Obj_Rollback
	
	usage:			globals.DCM_Obj_Rollback();
	
	input:			fired by the Rollback icon within the common/shared icons in the nav_ctl icon set
	
	output:			brokers the transaction rollback and coordinates enabling of other previously disabled objects
	
	description:	controls all rollback requests of a given table/record available through the Services object
	
	change _history:

************************/
var test_rec_change = databaseManager.hasRecordChanges(forms[globals.dcmg_curr_form].foundset);
	// debug comment:  globals.dcmg_curr_form string content confirmed ( = 'name_profile')

if (test_rec_change == false)
	 // intentional premature exit of this rollback process if no changes in the underlying foundset ...
{
	globals.dcm_debug('autosave is - ' + databaseManager.getAutoSave());  // added for debugging
	globals.dcm_debug('no record changes on foundset: ' + globals.dcmg_curr_form); // added for debugging

	forms.Main.elements.btn_ViewStats.text = 'No changes made ...'
	application.sleep(500) // only a brief advice to the user of this as this is a fairly routine activity

	databaseManager.commitTransaction();  // set globally by the Edit Request Handler foundation method - close this trans block
	globals.DCM_ContainerMode('Record_Select');  // re-set back to Record Selection mode - set container object to default
	globals.DCM_Set_Button_Access('true');  // re-enable custom button bar controls

	forms.Main.elements.btn_ViewStats.text = ''	
	return 1;
}


var response = plugins.dialogs.showQuestionDialog( 'Database Manager',  'Undo (rollback) your changes to this record?',  'Yes', 'No')

if (response == 'Yes')

Appreciate any assistance on this topic,

Michael

Have you run this through debugger allready, to see the content of vars and which path the code follows whent ehre are changes?

Paul

Not yet, Paul. I have checked (visually and via my mental-debugger-tracer :) ) any other possible events that could fire that might cause the state of the record buffer to change (e.g. - index pointer moves, autosave states varied, controller readonly state etc).

When I enter Edit-Mode I change the state of the controller from readonly=true to readonly=false. Other than that I am only touching screen objects (like setting control buttons to Editable=false and that sort of thing).

There is not a lot going on between entering Edit Mode and the triggering the Rollback event. Specifically:

  1. Enter Edit Mode (Edit button fires this event) - controller.readonly=false and I can see that edit fields are now available
  2. I change one field with one character and tab out of that field (to make sure the field level buffer fires into the foundset buffer)
  3. I click on the Rollback button - the code you are viewing

Michael

Just run it in debugger and see what the result of the call to hasRecordChanges is…

What is the value of var test_rec_change?

Paul,

The value of the test variable (test_rec_change) is equal to false. Confirmed via debugger and via a quick call to my debug dialog.

Do you also need me to run an evaluation on databaseManager.hasRecordChanges() in the debugger? i.e. - check both the function call (Editor: Evaluate) and the local form variable (test_rec_change) that is storing this?

The code block after the if(…) does execute, but it shouldn’t: if the buffer has changes then I am thinking that this should variable should evaluate to true and then move along to whatever else needs doing.

Michael

you say that “test_rec_change” is false after the call to databaseManager.hasRecordChanges?

That means there are no record changes.

so, then servoy gets to the if statement. The equation for the if statement should evaluate to true (false == false), so the code block inbetween the brackets of the If statement should execute, right?

You say this doesn;t happen? I can hardly believe that…

Have you continued stepping through the code, to see exactly what is executed?

Paul

Paul,

The problem is that changes to the foundset HAVE taken place through me typing something into the record and editing an existing record. So, I am expecting an if(…) test where a “true=false” condition arises and the code block would not execute. I understand that false==false and that 2 logical boolean negatives = a true.

It is the return value from the db node.hasRecordChanges() that I am concerned about, not the evaluation of the logical if(…) test itself.

I don’t understand why hasRecordChanges is returning a false and not a true (ie - data HAS changed).

Michael

Ah, ok, was looking at it from the wrong angle.

The only thing I can think about is that “globals.dcmg_curr_form” does not contain the name of the form that has the foundset that has the change.

What happens if you do an:
application.output(globals.dcmg_curr_form)
application.output(forms[globals.dcmg_curr_form])
application.output(forms[globals.dcmg_curr_form].foundset)
application.output(databaseManager.hasRecordChanges(forms[globals.dcmg_curr_form].foundset))

What do you get in the logs/output console?

Paul

Paul:

I am going to set up a simple test form to see if I can emulate this condition (either something screwy in my code/logic or something else going on) … this app wouldn’t be straight forward to bundle up and send ( I know you haven’t asked for it …).

In the meantime, here’s the dump to the Editor dialog of the 4 requested Application.output things:

name_profile

FormController[form: name_profile, fs size:200, selected record: Record[DATA:Row[DATA:name_id=320,parent_name_id=null,event_id=null,integration_profile_id=null,status=ACTIVE,is_active=null,tenant_id=null,name_type=null,inactive_date=null,inactive_notes=null,reinstatement_ts=null,reinstatement_by_user=null,name_role=null,primary_contact_id=null,purge_date=null,read_lname1=xxxxxxx,read_fname1=xxxxx 2,read_other1=null,read_lname2=,read_fname2=,read_other2=null,read_orgname=,name_prefix=null,primaryname=,data_trimmed=null,name_suffix=null,formal_salutation=null,salutation=null,mail_label=null,name_extend=null,data_extend=null,charforeignkey1=null,charforeignkey2=null,intforeignkey1=null,intforeignkey2=null,user_classify1=Investor,user_classify2=,user_classify3=null,classify1_fk1=null,classify1_fk2=null,classify1_fk3=null,read1_mailing_line1=,read1_address1=xxxxxxxx Court,read1_address2=,read1_address3=,read1_city=Sherwood Park,read1_subregion=Alberta,read1_country=38,read1_postal_code=xxx,rec1_city_id=null,rec1_subregion_id=null,rec1_country_id=null,read2_address1=,read2_address2=,read2_address3=,read2_city=,read2_subregion=null,read2_country=,read2_postal_code=,reader_trimmed=null,reader_buffer=null,rec2_city_id=null,rec2_subregion_id=null,rec2_country_id=null,mailer_contact_name=null,mailer_organization=null,mailer_add1=null,mailer_add2=null,mailer_city=null,mailer_subregion=null,mailer_country=null,mailer_postal_code=null,mailer_line5=null,phone1_type=Direct,phone1=(604) xxxxx,phone2_type=Home,phone2=(250) xxxxxxx,phone3_type=Direct,phone3=(250) xxxxxxxx,phone4_type=Satphone,phone4=(413) xxxxxxxxxxx,phone5_type=null,phone5=null,phone6_type=null,phone6=null,phone7_type=null,phone7=null,email1=mrc22@test.com,email2=Third rec,email3=First_rec@somewhere.com,email4=some@goolge.ca,website=,flag_is_primary=null,flag_potential_dupe_sys=null,sys_dupe_rational=null,flag_potential_dupe_user=null,flag_delete_ok=0,flag_mailable=1,flag_commercial_mailable=null,flag_is_person=null,flag_address_ok=1,flag_phones_ok=null,flag_emails_ok=0,flag_do_not_call=null,flag_do_not_mail=null,flag_user1=null,flag_user2=null,core_gender=null,core_dob=null,core_anniversary=null,core_marital=null,notes_general=null,notes_phone=null,ts_added=2007-07-11 13:56:37.0,ts_modified=null,user_added=0,user_modified=null, CALCULATIONS: {dcm_row_bgcolor=java.lang.Object@7b0aef}]]

COLUMS: name_id,parent_name_id,event_id,integration_profile_id,status,is_active,tenant_id,name_type,inactive_date,inactive_notes,reinstatement_ts,reinstatement_by_user,name_role,primary_contact_id,purge_date,read_lname1,read_fname1,read_other1,read_lname2,read_fname2,read_other2,read_orgname,name_prefix,primaryname,data_trimmed,name_suffix,formal_salutation,salutation,mail_label,name_extend,data_extend,charforeignkey1,charforeignkey2,intforeignkey1,intforeignkey2,user_classify1,user_classify2,user_classify3,classify1_fk1,classify1_fk2,classify1_fk3,read1_mailing_line1,read1_address1,read1_address2,read1_address3,read1_city,read1_subregion,read1_country,read1_postal_code,rec1_city_id,rec1_subregion_id,rec1_country_id,read2_address1,read2_address2,read2_address3,read2_city,read2_subregion,read2_country,read2_postal_code,reader_trimmed,reader_buffer,rec2_city_id,rec2_subregion_id,rec2_country_id,mailer_contact_name,mailer_organization,mailer_add1,mailer_add2,mailer_city,mailer_subregion,mailer_country,mailer_postal_code,mailer_line5,phone1_type,phone1,phone2_type,phone2,phone3_type,phone3,phone4_type,phone4,phone5_type,phone5,phone6_type,phone6,phone7_type,phone7,email1,email2,email3,email4,website,flag_is_primary,flag_potential_dupe_sys,sys_dupe_rational,flag_potential_dupe_user,flag_delete_ok,flag_mailable,flag_commercial_mailable,flag_is_person,flag_address_ok,flag_phones_ok,flag_emails_ok,flag_do_not_call,flag_do_not_mail,flag_user1,flag_user2,core_gender,core_dob,core_anniversary,core_marital,notes_general,notes_phone,ts_added,ts_modified,user_added,user_modified,dcm_row_bgcolor,]

FoundSet[Table:dcm_name,Size: 200,CachedRecords: 30,SELECTED INDEX: 0]

false

Paul,

This condition is replicable as follows (at least on this end against against a Postgres database and PG repository … which I am thinking has no bearing on the foundset buffer tests):

  1. Create a simple form with 5 or so fields on an existing table using the native navigator and with all the default methods active (add rec, save etc)

  2. Add the following buttons:
    a) Set Controller Read Only On
    b) Set Controller Read Only Off
    c) View Has Changes
    d) View Autosave
    e) Toggle Autosave

  3. Add simple methods as follows:
    a) controller.readOnly = true
    b) controller.readOnly = false
    c) view with whatever: databaseManager.hasRecordChanges(foundset)
    d) view with whatever: databaseManager.getAutoSave()
    e) databaseManager.setAutoSave( ! databaseManager.getAutoSave());

  4. I can’t get button 2(c) to show TRUE - no matter what combo I try. I take an existing record and edit it and all I get is FALSE with button 2(c)

What does your screen show with the above test?

Michael

Michael,

Made a small sample solution myself. Indeed, when checking if a foundset has recordChanged, the function returns false, even when there are changes.

Forwarded it to our engineering department.

Paul

databaseManager.hasRecordChanges(foundset)
with only the foundset is currently not supported
you have to give an index:

databaseManager.hasRecordChanges(foundset,0)

and then 0 mean check the whole foundset.

i changed this (3.5.1) so that 0 is the default thing when you only give the foundset.

Thanks Paul, Johan … will roll with the second argument for the call,

Michael