Thanks John,
I think I am tackling this in the correct way and indeed your post backs up my thinking.
So far i have pretty much done what you suggest. I have a date last synced field and then a date modified on both servers.
Working on Local Offline → Server first. My local solution finds all records changed since the last sync and then can loop through them to work out if they are more up to date than the server.
I was thinking that this was more efficiently done by not using a form and trying to run it using the database and RawSQL functions.
Where I am stuck is having go a local record that i now know need updating, but sitting in a dataset, i need to try and push that to the server.
Trying to create an “UPDATE so_appointments set …” doesnt seem to be working.
Can anyone see an easy way to do this, or am i being stupid by not doing a find for this record on a layout and then looping through the allproviders in order to update it. The reason for avoiding a relationship is that when i use my solution in offline, then if their are relationships to the remote server then they come up with an error on startup, which i have failed as yet to catch and therefore looks a bit messy for my users.
//First identify all local records that have been modified since the last sync date
//Use the local server
var maxReturnedRows = 999;//useful to limit number of rows
var query = 'select * from so_appointments where date_modified > ?'
var args = new Array();
args[0] = login_to_so_customer.date_lastsync
var dataset_local = databaseManager.getDataSetByQuery("reportwriter", query, args, maxReturnedRows);
application.output(dataset_local.getMaxRowIndex())
//Need to get the column id of the date modified
// var local_columns=new Array()
for (var x = 1; x <= dataset_local.getMaxColumnIndex() ; x++ )
{
if (dataset_local.getColumnName(x)=='date_modified')
var dm_col=x
}
//We now have a dataset with all the local records that have changed since the last syncronisation
//Rule one if local date_modified ID>remote date_modified then overright remote.
//Never overright a remote field with a blank or null local field
//Loop through all the modified records locally
for( var i = 1 ; i <= dataset_local.getMaxRowIndex() ; i++ )
{
//Need to deal with new records first
//>10,000,000
//if not new
//Check the make sure the remote date_modified is less than the local one.
//Lets Get the remote Date_modified dataset_local.getValue(i,1)
var query = 'select date_modified from so_appointments where id = ?'
var dataset_remote = databaseManager.getDataSetByQuery("reportwriter_server", query, [dataset_local.getValue(i,1)], 1);
//Verify that the local record has in fact been modified after the remote one
if (dataset_local.getValue(i,dm_col)>dataset_remote.getValue(1,1))
{
//This local record has beend modified after the remote one
application.output (dataset_local.getValue(i,dm_col)+' - '+dataset_remote.getValue(1,1))
//Now need to create a rawsql statement
//Execute any SQL, returns true if successful
//DOESNT WORK I THINK DUE TO quotes etc. must be an easier way to do this.
var update='update so_appointments set'
for (var x = 2; x <= dataset_local.getMaxColumnIndex() ; x++ )
{
update += dataset_local.getColumnName(x)+'='+ dataset_local.getValue(i,x)
if (x !=dataset_local.getMaxColumnIndex())
update +=','
}
update +=' where id='+dataset_local.getValue(i,1)
application.output (update)
var done = plugins.rawSQL.executeSQL("reportwriter_server","so_appointments",update)
if (done)
{
//flush is required when changes are made in db
plugins.rawSQL.flushAllClientsCache("reportwriter_server","so_appointments")
}
else
{
var msg = plugins.rawSQL.getException().getMessage(); //see exception node for more info about the exception obj
plugins.dialogs.showErrorDialog('Error', 'SQL exception: '+msg, 'Ok')
}
}
}
Answers to my stupidity gratefully received. I am sure a seasoned SQL servoyan will do this in a line or two!
David