# Backup of edited records

**URL:** <https://forum.servoy.com/t/backup-of-edited-records/17507>\
**Category:** Classic Servoy\
**Created:** [October 2, 2013, 11:08am UTC](https://forum.servoy.com/t/backup-of-edited-records/17507 "2013-10-02T11:08:06Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![deezzub](https://avatars.discourse-cdn.com/v4/letter/d/dec6dc/32.png) [@deezzub](https://forum.servoy.com/u/deezzub)\
**Post date:** [October 2, 2013, 11:08am UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/1 "2013-10-02T11:08:06Z")

</div>

I need backup edited records, so I do:

```auto
var editedRecs = databaseManager.getEditedRecords( foundset[relation] );

```

After that I call:

```auto
databaseManager.revertEditedRecords( foundset[relation] );

```

The problem is, that also the contents of the backup array editedRecs is reverted. This also occurs if I copy the array to another array. Cause the array contains jsrecords, it seems that the jsrecord has a reference to the original edited records.

Why has this a reference to the original? How can I copy the edited records and unrelate them from the original records?

---

<div class="post-metadata">

**Author:** ![jcompagner](https://yyz2.discourse-cdn.com/flex010/user_avatar/forum.servoy.com/jcompagner/32/4889_2.png) [@jcompagner](https://forum.servoy.com/u/jcompagner)\
**Post date:** [October 2, 2013, 3:25pm UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/2 "2013-10-02T15:25:16Z")

</div>

this is logical, the records you hold on to are exactly the same record that gets reverted (if you do record.value = x you want that it really will change the actual value of the ‘real’ record)  
If you really want to keep the data you have to loop over the records  
and copy the record.getChangedData() into an array instead of the record itself.

---

<div class="post-metadata">

**Author:** ![david](https://avatars.discourse-cdn.com/v4/letter/d/aeb1de/32.png) [@david](https://forum.servoy.com/u/david)\
**Post date:** [October 2, 2013, 4:22pm UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/3 "2013-10-02T16:22:59Z")

</div>

Easy way to duplicate a record:

```auto
// get foundset of source record
var serverName = srcRecord.foundset.getServerName()
var tableName = srcRecord.foundset.getTableName()
var fsThis = databaseManager.getFoundSet(serverName,tableName)

// create duplicate record and copy data
var destRecord = fsThis.getRecord(fsThis.newRecord(false,true))
databaseManager.copyMatchingFields(srcRecord,destRecord,overwriteOK[0] || false)

```

Use a different destination foundset (with identical fields) to archive records.

[http://community.data-sutra.com/project … s.js#L4279](http://community.data-sutra.com/projects/datasutra/repository/entry/trunk/_ds_CODE_resources/globals.js#L4279) for a utility function that copies a record and all related records (Servoy 3 to 5 era code but it still works).

---

<div class="post-metadata">

**Author:** ![deezzub](https://avatars.discourse-cdn.com/v4/letter/d/dec6dc/32.png) [@deezzub](https://forum.servoy.com/u/deezzub)\
**Post date:** [October 4, 2013, 2:16pm UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/4 "2013-10-04T14:16:22Z")

</div>

> jcompagner:  
> this is logical, the records you hold on to are exactly the same record that gets reverted (if you do record.value = x you want that it really will change the actual value of the ‘real’ record)

Why is there no ‘virtual’ record, that has no binding to the database / memory or to the record stored in the database / memory. I think it is really useful, if this would be possible and the possibility to override the record in the database with the ‘virtual’ record (only for values that can not cause data inconsistencies).

> jcompagner:  
> If you really want to keep the data you have to loop over the records  
> and copy the record.getChangedData() into an array instead of the record itself.

I found this solution, but it would be great if Servoy has a built in function for this.

```auto
/**
 * Backup record changes for later reusing if they needed.
 * 
 * @param {String} formName , the name of the form to get the foundset for backup the record changes.
 * @param {String} foundSet , the foundset or relation name to backup its changes.
 * @param {String} uid , a column name as unique record identifier in the context of the record in the foundset.
 * 
 * @return {Array<Array<Array<Object>>>} the array with the changed values for the records and "null" if there are no changed record values.
 *
 * @public
 * @since 02.10.2013
 * @version 04.10.2013 14:11:36
 *
 * @author deezzub
 */
function backupRecordChanges( formName, foundSet, uid ) {
	var changedData,
		changedRow,
		editedRec,
		editedRecs,
		/** @type {JSFoundSet} */
		fs = forms[formName][foundSet],
		recBackup,
		recsBackup = [],
		recUid;

	if ( databaseManager.hasRecordChanges( fs ) ) {

		editedRecs = databaseManager.getEditedRecords( fs );

		for ( var recIndex = 0; recIndex < editedRecs.length; recIndex++ ) {
			/** @type {JSRecord} */
			editedRec = editedRecs [recIndex],
			changedData = editedRec.getChangedData( ),
			recBackup = [],
			recUid = editedRecs [recIndex][uid];

			for ( var rowIndex = 1; rowIndex <= changedData.getMaxRowIndex( ); rowIndex++ ) {
				changedRow = [];
                                for ( var columnIndex = 1; columnIndex <= 3; columnIndex++ ) {

					changedRow[columnIndex - 1] = changedData.getValue( rowIndex, columnIndex );
				}
				recBackup[0] = recUid;
				recBackup[rowIndex] = changedRow
			}
			recsBackup[recIndex] = recBackup;
		}
	} else {
		recsBackup = null;
	}
	return recsBackup;
}

```

> david:  
> Easy way to duplicate a record:
> 
> ```auto
> // get foundset of source record
> 
> ```

var serverName = srcRecord.foundset.getServerName()  
var tableName = srcRecord.foundset.getTableName()  
var fsThis = databaseManager.getFoundSet(serverName,tableName)

// create duplicate record and copy data  
var destRecord = fsThis.getRecord(fsThis.newRecord(false,true))  
databaseManager.copyMatchingFields(srcRecord,destRecord,overwriteOK[0] || false)

> ```auto
> 
> Use a different destination foundset (with identical fields) to archive records.
> 
> <a class="postlink" href="http://community.data-sutra.com/projects/datasutra/repository/entry/trunk/_ds_CODE_resources/globals.js#L4279">http://community.data-sutra.com/project ... s.js#L4279</a> for a utility function that copies a record and all related records (Servoy 3 to 5 era code but it still works).
> 
> ```

Can I use the following to get a foundset, that has the edited records, but it’s not changed if I changed the source foundset?

```auto
var fsCopy = foundset[relation].duplicateFoundSet();
fsCopy.unrelate();

```

---

<div class="post-metadata">

**Author:** ![david](https://avatars.discourse-cdn.com/v4/letter/d/aeb1de/32.png) [@david](https://forum.servoy.com/u/david)\
**Post date:** [October 4, 2013, 5:59pm UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/5 "2013-10-04T17:59:20Z")

</div>

> deezzub:  
> Can I use the following to get a foundset, that has the edited records, but it’s not changed if I changed the source foundset?
> 
> ```auto
> var fsCopy = foundset[relation].duplicateFoundSet();
> 
> ```

fsCopy.unrelate();

> ```auto
> 
> ```

I think you are getting confused with what “duplicate” at the foundset level means. Foundsets are their own scriptable objects that just so happen to have records in them. So foundset.duplicateFoundSet() and foundset.unrelate() do not do anything to the actual records in the foundset record collection – they just give you a “new” foundset object with potentially different record collection characteristics (ie. total number) and selected index.

The most common usage for duplicateFoundset() is to duplicate a foundset just prior to doing a search on a foundset. If the search returns no records, you can restore the visible foundset (that now contains zero records because of the search operation) with the previously duplicated foundset (which has the original record set). ([https://wiki.servoy.com/display/DOCS/JS … teFoundSet](https://wiki.servoy.com/display/DOCS/JSFoundSet#JSFoundSet-duplicateFoundSet).)

If you want to duplicated the records in a foundset, you have to iterate over those records and copy/duplicate individually. All of this follows javascript object duplication rules so it’s standard stuff.

---

<div class="post-metadata">

**Author:** ![amcgilly](https://avatars.discourse-cdn.com/v4/letter/a/e0b2c6/32.png) [@amcgilly](https://forum.servoy.com/u/amcgilly)\
**Post date:** [December 19, 2013, 7:49am UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/6 "2013-12-19T07:49:53Z")

</div>

I have a related question. Let’s say I have a related foundset of unpaid invoices that looks like this:

customerRecord.customers\_to\_unpaid\_invoices

And now I want to do a 2-phase process on those invoice records.

Phase 1: mark the invoices as ‘paid’  
Phase 2: print the invoice numbers in a log file.

If I work directly that foundset, I won’t be able to do phase 2 because the records will fall out of the foundset as I mark them ‘paid’.

So I want to create an unrelated foundset that contains the same records, and work with that foundset.

I have tried

```auto
var newFoundset = customerRecord.customers_to_unpaid_invoices.duplicateFoundset()
newFoundset.unrelate()

```

but newFoundset still loses records as I mark invoices ‘paid’. I am wondering if unrelate() only works on form foundsets. and not on foundset objects held in javascript vars.

So I ended up doing this:

```auto
	var ds = databaseManager.convertToDataSet(customerRecord.customers_to_unpaid_invoices,['invoice_id'])
	var newFoundset = databaseManager.getFoundSet('myServer','invoices')
	newFoundset.loadRecords(ds)

```

which works fine. Was there a way of doing this using duplication and/or unrelate that I just haven’t figured out?

---

<div class="post-metadata">

**Author:** ![jcompagner](https://yyz2.discourse-cdn.com/flex010/user_avatar/forum.servoy.com/jcompagner/32/4889_2.png) [@jcompagner](https://forum.servoy.com/u/jcompagner)\
**Post date:** [December 23, 2013, 9:30am UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/7 "2013-12-23T09:30:56Z")

</div>

try this:

var newFoundset = customerRecord.customers\_to\_unpaid\_invoices.unrelate();

---

<div class="post-metadata">

**Author:** ![amcgilly](https://avatars.discourse-cdn.com/v4/letter/a/e0b2c6/32.png) [@amcgilly](https://forum.servoy.com/u/amcgilly)\
**Post date:** [December 23, 2013, 5:05pm UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/8 "2013-12-23T17:05:06Z")

</div>

Thanks Johan that worked.

In the Wiki, the sample code shown for how to use unrelate() is this:

```auto
forms.customer.foundset.unrelate()

```

In the Serclipse IDE the sample code is:

```auto
foundset.unrelate()

```

These examples make it seem like unrelate() ACTS ON the foundset, converting it to an unrelated foundset. It would be a bit clearer if the examples were more like this:

```auto
var newFoundset = forms.customer.foundset.unrelate();

```

I’ve added this suggestion in the support system.

---

<div class="post-metadata">

**Author:** ![amcgilly](https://avatars.discourse-cdn.com/v4/letter/a/e0b2c6/32.png) [@amcgilly](https://forum.servoy.com/u/amcgilly)\
**Post date:** [February 28, 2014, 11:56pm UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/9 "2014-02-28T23:56:47Z")

</div>

Talking to Johan Compagner at ServoyCamp last month I learned a bit more about the .unrelate() method that I thought I’d share what I learned.

when you do this:

var newFoundset = relatedFoundset.unrelate();

your newFoundset will stop behaving like a related foundset, and will start behaving like a foundset that was created using find/search. What does this mean?

**Related foundsets** are of course based on relations. Servoy ensures that a related foundset always contains EXACTLY the records that match the relation. After you’ve created a related foundset, Servoy monitors the db and if it sees new records that meet the relation’s criteria, it will automatically add them to the foundset. Similarly, records that started out in the related foundset will drop out of it automatically if they are modified in such a way that they no longer meet the criteria set out in the relation.

But for **UNrelated foundsets** , Servoy does not do that management. If you modify a record in an UNrelated foundset such that it no longer matches the find/search criteria, it won’t automatically drop out of the foundset. If after creating an UNrelated foundset you create new records that match the find/search criteria, they will not be added to the UNrelated foundset automatically. If you modify existing records such that they now match the find/search criteria where they didn’t before, they will NOT be automatically added to the foundset. To refresh your UNrelated foundset to take all such changes into account, you would need to do a loadRecords(). Servoy remembers the query that it used to build the foundset in the first place, so it just re-runs that query.

You can see a foundset’s query anytime by doing databaseManager.getSQL(foundset)

Finally, on an UNrelated foundset, loadAllRecords() will load ALL records in the source table, whereas on a related foundset, loadAllRecords() loads all the related records as defined in the relation. This is useful if you’ve reduced your related foundset by performing a find/search on it, and now want to get back all your related records.

I hope some people find this helpful. And if you see any errors in what I’ve said please let me know!

---

<div class="post-metadata">

**Author:** ![Harjo](https://yyz2.discourse-cdn.com/flex010/user_avatar/forum.servoy.com/harjo/32/4873_2.png) [@Harjo](https://forum.servoy.com/u/Harjo)\
**Post date:** [March 1, 2014, 10:46am UTC](https://forum.servoy.com/t/backup-of-edited-records/17507/10 "2014-03-01T10:46:38Z")

</div>

Totally correct! ![:-)]( "Smile")
