001package org.apache.fulcrum.security.torque.om;
002
003import java.sql.Connection;
004import java.util.ArrayList;
005import java.util.Collection;
006import java.util.List;
007import java.util.Map;
008import java.util.Set;
009import java.util.HashSet;
010import java.util.Objects;
011import java.util.stream.Collectors;
012
013import org.apache.torque.NoRowsException;
014import org.apache.torque.TooManyRowsException;
015import org.apache.torque.TorqueException;
016import org.apache.torque.criteria.Criteria;
017import org.apache.torque.criteria.Criterion;
018import org.apache.torque.om.mapper.RecordMapper;
019import org.apache.torque.om.ObjectKey;
020import org.apache.torque.om.SimpleKey;
021import org.apache.torque.map.TableMap;
022import org.apache.torque.util.TorqueConnection;
023import org.apache.torque.util.Transaction;
024import org.apache.torque.util.ColumnValues;
025import org.apache.torque.util.JdbcTypedValue;
026
027
028
029/**
030 * The skeleton for this class was autogenerated by Torque on:
031 *
032 * [Thu Nov 04 13:34:23 CET 2021]
033 *
034 * You should not use this class directly.  It should not even be
035 * extended; all references should be to TurbineRolePeer
036 */
037
038@SuppressWarnings("unused")
039public abstract class BaseTurbineRolePeerImpl
040    extends org.apache.torque.util.AbstractPeerImpl<TurbineRole>
041{
042    /** Serial version */
043    private static final long serialVersionUID = 1636029263364L;
044
045
046
047    /**
048     * Constructor.
049     * The recordMapper, tableMap and databaseName fields are correctly
050     * initialized.
051     */
052    public BaseTurbineRolePeerImpl()
053    {
054        this(new TurbineRoleRecordMapper(),
055            TurbineRolePeer.TABLE,
056            TurbineRolePeer.DATABASE_NAME);
057    }
058
059    /**
060     * Constructor providing the objects to be injected as parameters.
061     *
062     * @param recordMapper a record mapper to map JDBC result sets to objects
063     * @param tableMap the default table map
064     * @param databaseName the name of the database
065     */
066    public BaseTurbineRolePeerImpl(
067            RecordMapper<TurbineRole> recordMapper, 
068            TableMap tableMap,
069            String databaseName)
070    {
071        super(recordMapper, tableMap, databaseName);
072    }
073
074
075    /**
076     * Returns a new instance of the Data object class
077     */
078    public TurbineRole getDbObjectInstance()
079    {
080        return new TurbineRole();
081    }
082
083
084    /**
085     * Method to do updates.  This method is to be used during a transaction,
086     * otherwise use the doUpdate(Criteria) method.
087     *
088     * @param columnValues the values to update plus the primary key
089     *        identifying the row to update.
090     * @param con the connection to use, not null.
091     *
092     * @return the number of affected rows.
093     *
094     * @throws TorqueException Any exceptions caught during processing will be
095     *         rethrown wrapped into a TorqueException.
096     */
097    public int doUpdate(ColumnValues columnValues, Connection con)
098        throws TorqueException
099    {
100        Criteria selectCriteria = new Criteria(getDatabaseName());
101        correctBooleans(columnValues);
102
103        {
104            JdbcTypedValue pkValue
105                = columnValues.remove(TurbineRolePeer.ROLE_ID);
106            if (pkValue == null)
107            {
108                throw new TorqueException(
109                        "The value for the primary key column "
110                        + "TurbineRolePeer.ROLE_ID"
111                        + " must be set");
112            }
113            if (pkValue.getSqlExpression() == null)
114            {
115                selectCriteria.where(
116                        TurbineRolePeer.ROLE_ID,
117                        pkValue.getValue());
118            }
119            else
120            {
121                selectCriteria.where(
122                        TurbineRolePeer.ROLE_ID,
123                        pkValue.getSqlExpression());
124            }
125        }
126
127
128        int rowCount = doUpdate(selectCriteria, columnValues, con);
129        return rowCount;
130    }
131
132    /**
133     * Deletes a data object, i.e. a row in a table, in the database.
134     *
135     * @param obj the data object to delete in the database, not null.
136     *
137     * @return the number of deleted rows.
138     *
139     * @throws TorqueException Any exceptions caught during processing will be
140     *         rethrown wrapped into a TorqueException.
141     */
142    public int doDelete(TurbineRole obj) throws TorqueException
143    {
144        int result = doDelete(buildCriteria(obj.getPrimaryKey()));
145        obj.setDeleted(true);
146        return result;
147    }
148
149    /**
150     * Deletes a data object, i.e. a row in a table, in the database.
151     * This method is to be used during a transaction, otherwise use the
152     * doDelete(TurbineRole) method.
153     *
154     * @param obj the data object to delete in the database, not null.
155     * @param con the connection to use, not null.
156     *
157     * @return the number of deleted rows.
158     *
159     * @throws TorqueException Any exceptions caught during processing will be
160     *         rethrown wrapped into a TorqueException.
161     */
162    public int doDelete(TurbineRole obj, Connection con)
163        throws TorqueException
164    {
165        int result = doDelete(buildCriteria(obj.getPrimaryKey()), con);
166        obj.setDeleted(true);
167        return result;
168    }
169
170    /**
171     * Deletes data objects, i.e. rows in a table, in the database.
172     *
173     * @param objects the data object to delete in the database, not null,
174     *        may not contain null.
175     *
176     * @return the number of deleted rows.
177     *
178     * @throws TorqueException Any exceptions caught during processing will be
179     *         rethrown wrapped into a TorqueException.
180     */
181    public int doDelete(Collection<TurbineRole> objects)
182            throws TorqueException
183    {
184        int result = doDelete(buildPkCriteria(objects));
185        objects.forEach(object -> object.setDeleted(true));
186        return result;
187    }
188
189    /**
190     * Deletes data objects, i.e. rows in a table, in the database.
191     * This method uses the passed connection to delete the rows;
192     * if a transaction is open in the connection, the deletion happens inside
193     * this transaction.
194     *
195     * @param objects the data objects to delete in the database, not null,
196     *        may not contain null.
197     * @param con the connection to use for deleting, not null.
198     *
199     * @return the number of deleted rows.
200     *
201     * @throws TorqueException Any exceptions caught during processing will be
202     *         rethrown wrapped into a TorqueException.
203     */
204    public int doDelete(
205            Collection<TurbineRole> objects,
206            Connection con)
207        throws TorqueException
208    {
209        int result = doDelete(buildPkCriteria(objects), con);
210        objects.forEach(object -> object.setDeleted(true));
211        return result;
212    }
213
214    /** 
215     * Build a Criteria object which selects all objects which have a given
216     * primary key.
217     *
218     * @param pk the primary key value to build the criteria from, not null.
219     */
220    public Criteria buildCriteria(ObjectKey<?> pk)
221    {
222        Criteria criteria = new Criteria();
223        criteria.and(TurbineRolePeer.ROLE_ID, pk);
224        return criteria;
225     }
226
227    /** 
228     * Build a Criteria object which selects all objects which primary keys
229     * are contained in the passed collection.
230     *
231     * @param pks the primary key values to build the criteria from, not null,
232     *        may not contain null.
233     */
234    public Criteria buildCriteria(Collection<ObjectKey<?>> pks)
235    {
236        Criteria criteria = new Criteria();
237        criteria.andIn(TurbineRolePeer.ROLE_ID, pks);
238        return criteria;
239     }
240
241
242    /** 
243     * Build a Criteria object which selects all passed objects using their
244     * primary key. Objects which do not yet have a primary key are ignored.
245     *
246     * @param objects the objects to build the criteria from, not null,
247     *        may not contain null.
248     */
249    public Criteria buildPkCriteria(
250            Collection<TurbineRole> objects)
251    {
252        return buildCriteria(objects.stream()
253                .map(object -> object.getPrimaryKey())
254                .collect(Collectors.toList()));
255    }
256
257    /** 
258     * Build a Criteria object from the data object for this peer.
259     * The primary key columns are only added if the object is not new.
260     *
261     * @param obj the object to build the criteria from, not null.
262     */
263    public Criteria buildCriteria(TurbineRole obj)
264    {
265        Criteria criteria = new Criteria(getDatabaseName());
266        if (!obj.isNew())
267        {
268            criteria.and(TurbineRolePeer.ROLE_ID, obj.getEntityId());
269        }
270        criteria.and(TurbineRolePeer.ROLE_NAME, obj.getEntityName());
271        return criteria;
272    }
273
274    /** 
275     * Build a Criteria object from the data object for this peer,
276     * skipping all binary columns.
277     *
278     * @param obj the object to build the criteria from, not null.
279     */
280    public Criteria buildSelectCriteria(TurbineRole obj)
281    {
282        Criteria criteria = new Criteria(getDatabaseName());
283        if (!obj.isNew())
284        {
285            criteria.and(TurbineRolePeer.ROLE_ID, obj.getEntityId());
286        }
287        criteria.and(TurbineRolePeer.ROLE_NAME, obj.getEntityName());
288        return criteria;
289    }
290
291    /** 
292     * Returns the contents of the object as ColumnValues object.
293     * Primary key columns which are generated on insertion are not
294     * added to the returned object if they still have their initial
295     * value. Also, columns which have the useDatabaseDefaultValue
296     * flag set to true are also not added to the returned object
297     * if they still have their initial value.
298     *
299     * @throws TorqueException if the table map cannot be retrieved
300     *         (should not happen).
301     */
302    public ColumnValues buildColumnValues(TurbineRole turbineRole)
303            throws TorqueException
304    {
305        ColumnValues columnValues = new ColumnValues();
306        if (!turbineRole.isNew() 
307            || turbineRole.getEntityId() != null)
308        {
309            columnValues.put(
310                    TurbineRolePeer.ROLE_ID,
311                    new JdbcTypedValue(
312                        turbineRole.getEntityId(),
313                        4));
314        }
315        columnValues.put(
316                TurbineRolePeer.ROLE_NAME,
317                new JdbcTypedValue(
318                    turbineRole.getEntityName(),
319                    12));
320        return columnValues;
321    }
322
323    /**
324     * Retrieve a single object by pk
325     *
326     * @param pk the primary key
327     * @throws TorqueException Any exceptions caught during processing will be
328     *         rethrown wrapped into a TorqueException.
329     * @throws NoRowsException Primary key was not found in database.
330     * @throws TooManyRowsException Primary key was not found in database.
331     */
332    public TurbineRole retrieveByPK(Integer pk)
333        throws TorqueException, NoRowsException, TooManyRowsException
334    {
335        return retrieveByPK(SimpleKey.keyFor(pk));
336    }
337
338    /**
339     * Retrieve a single object by pk
340     *
341     * @param pk the primary key
342     * @param con the connection to use
343     * @throws TorqueException Any exceptions caught during processing will be
344     *         rethrown wrapped into a TorqueException.
345     * @throws NoRowsException Primary key was not found in database.
346     * @throws TooManyRowsException Primary key was not found in database.
347     */
348    public TurbineRole retrieveByPK(Integer pk, Connection con)
349        throws TorqueException, NoRowsException, TooManyRowsException
350    {
351        return retrieveByPK(SimpleKey.keyFor(pk), con);
352    }
353    
354    
355    
356
357    /**
358     * Retrieve a single object by pk
359     *
360     * @param pk the primary key
361     * @throws TorqueException Any exceptions caught during processing will be
362     *         rethrown wrapped into a TorqueException.
363     * @throws NoRowsException Primary key was not found in database.
364     * @throws TooManyRowsException Primary key was not found in database.
365     */
366    public TurbineRole retrieveByPK(ObjectKey<?> pk)
367        throws TorqueException, NoRowsException, TooManyRowsException
368    {
369        try (TorqueConnection connection = Transaction.begin(getDatabaseName()))
370        {
371            TurbineRole result = retrieveByPK(pk, connection);
372            Transaction.commit(connection);
373            return result;
374        }
375    }
376
377    /**
378     * Retrieve a single object by pk
379     *
380     * @param pk the primary key
381     * @param con the connection to use
382     * @throws TorqueException Any exceptions caught during processing will be
383     *         rethrown wrapped into a TorqueException.
384     * @throws NoRowsException Primary key was not found in database.
385     * @throws TooManyRowsException Primary key was not found in database.
386     */
387    public TurbineRole retrieveByPK(ObjectKey<?> pk, Connection con)
388        throws TorqueException, NoRowsException, TooManyRowsException
389    {
390        Criteria criteria = buildCriteria(pk);
391        TurbineRole v = doSelectSingleRecord(criteria, con);
392        if (v == null)
393        {
394            throw new NoRowsException("Failed to select a row.");
395        }
396
397        return v;
398    }
399
400
401    /**
402     * Retrieve multiple objects by pk.
403     *
404     * @param pks List of primary keys.
405     *        Entries in pks which do not match entries in the database are ignored.
406     *
407     * @return the list of matching objects, not null.
408     *
409     * @throws TorqueException Any exceptions caught during processing will be
410     *         rethrown wrapped into a TorqueException.
411     */
412    public List<TurbineRole> retrieveByTypedPKs(Collection<Integer> pks)
413        throws TorqueException
414    {
415        try (TorqueConnection connection = Transaction.begin(getDatabaseName()))
416        {
417            List<TurbineRole> result = retrieveByTypedPKs(pks, connection);
418            Transaction.commit(connection);
419            return result;
420        }
421    }
422
423    /**
424     * Retrieve multiple objects by pk.
425     *
426     * @param pks List of primary keys.
427     *        Entries in pks which do not match entries in the database are ignored.
428     * @param dbcon the connection to use
429     *
430     * @return the list of matching objects, not null.
431     *
432     * @throws TorqueException Any exceptions caught during processing will be
433     *         rethrown wrapped into a TorqueException.
434     */
435    public List<TurbineRole> retrieveByTypedPKs(
436                Collection<Integer> pks,
437                Connection dbcon)
438            throws TorqueException
439    {
440        if (pks == null || pks.size() == 0)
441        {
442            return new ArrayList<TurbineRole>();
443        }
444        List<ObjectKey<?>> objectKeyList = new ArrayList<ObjectKey<?>>();
445        for (Integer pk : pks)
446        {
447            objectKeyList.add(SimpleKey.keyFor(pk));
448        }
449        Criteria criteria = buildCriteria(objectKeyList);
450        List<TurbineRole> result = doSelect(criteria, dbcon);
451        return result;
452    }
453
454    /**
455     * Retrieve multiple objects by pk.
456     *
457     * @param pks List of primary keys.
458     *        Entries in pks which do not match entries in the database are ignored.
459     *
460     * @return the list of matching objects, not null.
461     *
462     * @throws TorqueException Any exceptions caught during processing will be
463     *         rethrown wrapped into a TorqueException.
464     */
465    public List<TurbineRole> retrieveByObjectKeys(Collection<ObjectKey<?>> pks)
466        throws TorqueException
467    {
468        try (TorqueConnection connection = Transaction.begin(getDatabaseName()))
469        {
470            List<TurbineRole> result = retrieveByObjectKeys(pks, connection);
471            Transaction.commit(connection);
472            return result;
473        }
474    }
475
476    /**
477     * Retrieve multiple objects by pk.
478     *
479     * @param pks List of primary keys.
480     *        Entries in pks which do not match entries in the database are ignored.
481     * @param dbcon the connection to use
482     *
483     * @return the list of matching objects, not null.
484     *
485     * @throws TorqueException Any exceptions caught during processing will be
486     *         rethrown wrapped into a TorqueException.
487     */
488    public List<TurbineRole> retrieveByObjectKeys(
489                Collection<ObjectKey<?>> pks,
490                Connection dbcon)
491            throws TorqueException
492    {
493        if (pks == null || pks.size() == 0)
494        {
495            return new ArrayList<TurbineRole>();
496        }
497        Criteria criteria = buildCriteria(pks);
498        List<TurbineRole> result = doSelect(criteria, dbcon);
499        return result;
500    }
501
502
503
504
505    /** 
506     * Saves the passed collection as linked objects.
507     * This means the following is done:
508     * <ul>
509     *  <li>
510     *    The current collection of objects which are linked to toLinkTo
511     *    and which are also in the list toSave is read from the database
512     *    into the list intersection.
513     *  </li>
514     *  <li>
515     *    All objects in toSave which are not in intersection are inserted.
516     *  </li>
517     *  <li>
518     *    All objects in intersection are updated with the 
519     *    corresponding values in toSave and saved.
520     *  </li>
521     *  <li>
522     *    All objects in the database which are linked to toLinkTo but are 
523     *    not in toSave are deleted from the database.
524     *  </li>
525     * </ul>
526     *
527     * @param toLinkTo the object which collections should be set with the
528     *        values in toSave.
529     * @param toSave Contains the objects to save, not null, 
530     *        may not contain null.
531     *
532     * @throws TorqueException if an error accessing the database occurs.
533     * @throws NullPointerException if toSave is null or contains null elements.
534     */
535    public void setAndSaveTurbineRolePermissions(
536            TurbineRole toLinkTo,
537            Collection<TurbineRolePermission> toSave) 
538        throws TorqueException
539    {
540        try (TorqueConnection connection = Transaction.begin(getDatabaseName()))
541        {
542            setAndSaveTurbineRolePermissions(toLinkTo, toSave, connection);
543            Transaction.commit(connection);
544        }
545    }
546
547    /** 
548     * Saves the passed collection as linked objects.
549     * This means the following is done:
550     * <ul>
551     *  <li>
552     *    The current collection of objects which are linked to toLinkTo
553     *    and which are also in the list toSave is read from the database
554     *    into the list intersection.
555     *  </li>
556     *  <li>
557     *    All objects in toSave which are not in intersection are inserted.
558     *  </li>
559     *  <li>
560     *    All objects in intersection are updated with the 
561     *    corresponding values in toSave and saved.
562     *  </li>
563     *  <li>
564     *    All objects in the database which are linked to toLinkTo but are 
565     *    not in toSave are deleted from the database.
566     *  </li>
567     * </ul>
568     *
569     * @param toLinkTo the object which collections should be set with the
570     *        values in toSave.
571     * @param toSave Contains the objects to save, not null, 
572     *        may not contain null.
573     * @param connection the database connection to use.
574     *
575     * @throws TorqueException if an error accessing the database occurs.
576     * @throws NullPointerException if toSave is null or contains null elements.
577     */
578    public void setAndSaveTurbineRolePermissions(
579            TurbineRole toLinkTo,
580            Collection<TurbineRolePermission> toSave,
581            Connection connection) 
582        throws TorqueException
583    {
584        // make sure the collection cache in toLinkTo represents the current
585        // database state
586        toLinkTo.resetTurbineRolePermission();
587        toLinkTo.getTurbineRolePermissions(connection);
588        ObjectKey<?> localKey = toLinkTo.getPrimaryKey();
589
590        Criteria criteria = new Criteria();
591        Criterion onlyReferencingCriterion = new Criterion(
592                TurbineRolePermissionPeer.ROLE_ID, 
593                localKey);
594        criteria.where(onlyReferencingCriterion);
595        Set<ObjectKey<?>> toSaveKeys = new HashSet<ObjectKey<?>>();
596        for (TurbineRolePermission toSaveElement : toSave)
597        {
598            ObjectKey<?> toSaveKey = toSaveElement.getPrimaryKey();
599            if (toSaveKey.getValue() != null)
600            {
601                toSaveKeys.add(toSaveKey);
602            }
603        }
604        
605        // calculate intersection between objects in the database
606        // and objects in the list
607        List<TurbineRolePermission> intersection;
608        if (toSaveKeys.isEmpty())
609        {
610            intersection = new ArrayList<TurbineRolePermission>();
611        }
612        else
613        {
614            Criterion toSaveKeyCriterion = null;
615            for (ObjectKey<?> toSaveKey : toSaveKeys)
616            {
617                SimpleKey<?>[] toSavePrimaryKeys = (SimpleKey[]) toSaveKey.getValue();
618                 Criterion p0 = new Criterion(
619                        TurbineRolePermissionPeer.ROLE_ID,
620                        toSavePrimaryKeys[0]);
621                 Criterion p1 = new Criterion(
622                        TurbineRolePermissionPeer.PERMISSION_ID,
623                        toSavePrimaryKeys[1]);
624                p0.and(p1);
625                if (toSaveKeyCriterion == null)
626                {
627                    toSaveKeyCriterion = p0;
628                }
629                else
630                {
631                    toSaveKeyCriterion.or(p0);
632                }
633            }
634            criteria.and(toSaveKeyCriterion);
635            intersection = TurbineRolePermissionPeer.doSelect(
636                    criteria,
637                    connection);
638        }
639        if (toLinkTo.isTurbineRolePermissionsInitialized())
640        {
641            toLinkTo.getTurbineRolePermissions().clear();
642        }
643        else
644        {
645           toLinkTo.initTurbineRolePermissions();
646        }
647        for (TurbineRolePermission toSaveElement : toSave)
648        {
649            int listIndex = intersection.indexOf(toSaveElement);
650            if (listIndex == -1)
651            {
652                toLinkTo.addTurbineRolePermission(toSaveElement);
653                toSaveElement.save(connection);
654            }
655            else
656            {
657                toLinkTo.addTurbineRolePermission(toSaveElement);
658                toSaveElement.setNew(false);
659                if (!toSaveElement.valueEquals(intersection.get(listIndex)))
660                {
661                    //force saving if content differs
662                    toSaveElement.setModified(true);
663                }
664                toSaveElement.save(connection);
665            }
666            toSaveKeys.add(toSaveElement.getPrimaryKey());
667        }
668        
669        // delete elements not in intersection
670        Criteria deleteCriteria = new Criteria();
671        deleteCriteria.where(onlyReferencingCriterion);
672        if (!toSaveKeys.isEmpty())
673        {
674            Criterion toSaveKeyCriterion = null;
675            for (ObjectKey<?> toSaveKey : toSaveKeys)
676            {
677                SimpleKey<?>[] toSavePrimaryKeys = (SimpleKey[]) toSaveKey.getValue();
678                  Criterion p0 = new Criterion(
679                         TurbineRolePermissionPeer.ROLE_ID,
680                         toSavePrimaryKeys[0],
681                         Criteria.NOT_EQUAL);
682                  Criterion p1 = new Criterion(
683                         TurbineRolePermissionPeer.PERMISSION_ID,
684                         toSavePrimaryKeys[1],
685                         Criteria.NOT_EQUAL);
686                p0.or(p1);
687                if (toSaveKeyCriterion == null)
688                {
689                    toSaveKeyCriterion = p0;
690                }
691                else
692                {
693                    toSaveKeyCriterion.and(p0);
694                }
695            }
696            deleteCriteria.and(toSaveKeyCriterion);
697        }
698        TurbineRolePermissionPeer.doDelete(deleteCriteria, connection);
699    }
700    /** 
701     * Saves the passed collection as linked objects.
702     * This means the following is done:
703     * <ul>
704     *  <li>
705     *    The current collection of objects which are linked to toLinkTo
706     *    and which are also in the list toSave is read from the database
707     *    into the list intersection.
708     *  </li>
709     *  <li>
710     *    All objects in toSave which are not in intersection are inserted.
711     *  </li>
712     *  <li>
713     *    All objects in intersection are updated with the 
714     *    corresponding values in toSave and saved.
715     *  </li>
716     *  <li>
717     *    All objects in the database which are linked to toLinkTo but are 
718     *    not in toSave are deleted from the database.
719     *  </li>
720     * </ul>
721     *
722     * @param toLinkTo the object which collections should be set with the
723     *        values in toSave.
724     * @param toSave Contains the objects to save, not null, 
725     *        may not contain null.
726     *
727     * @throws TorqueException if an error accessing the database occurs.
728     * @throws NullPointerException if toSave is null or contains null elements.
729     */
730    public void setAndSaveTurbineUserGroupRoles(
731            TurbineRole toLinkTo,
732            Collection<TurbineUserGroupRole> toSave) 
733        throws TorqueException
734    {
735        try (TorqueConnection connection = Transaction.begin(getDatabaseName()))
736        {
737            setAndSaveTurbineUserGroupRoles(toLinkTo, toSave, connection);
738            Transaction.commit(connection);
739        }
740    }
741
742    /** 
743     * Saves the passed collection as linked objects.
744     * This means the following is done:
745     * <ul>
746     *  <li>
747     *    The current collection of objects which are linked to toLinkTo
748     *    and which are also in the list toSave is read from the database
749     *    into the list intersection.
750     *  </li>
751     *  <li>
752     *    All objects in toSave which are not in intersection are inserted.
753     *  </li>
754     *  <li>
755     *    All objects in intersection are updated with the 
756     *    corresponding values in toSave and saved.
757     *  </li>
758     *  <li>
759     *    All objects in the database which are linked to toLinkTo but are 
760     *    not in toSave are deleted from the database.
761     *  </li>
762     * </ul>
763     *
764     * @param toLinkTo the object which collections should be set with the
765     *        values in toSave.
766     * @param toSave Contains the objects to save, not null, 
767     *        may not contain null.
768     * @param connection the database connection to use.
769     *
770     * @throws TorqueException if an error accessing the database occurs.
771     * @throws NullPointerException if toSave is null or contains null elements.
772     */
773    public void setAndSaveTurbineUserGroupRoles(
774            TurbineRole toLinkTo,
775            Collection<TurbineUserGroupRole> toSave,
776            Connection connection) 
777        throws TorqueException
778    {
779        // make sure the collection cache in toLinkTo represents the current
780        // database state
781        toLinkTo.resetTurbineUserGroupRole();
782        toLinkTo.getTurbineUserGroupRoles(connection);
783        ObjectKey<?> localKey = toLinkTo.getPrimaryKey();
784
785        Criteria criteria = new Criteria();
786        Criterion onlyReferencingCriterion = new Criterion(
787                TurbineUserGroupRolePeer.ROLE_ID, 
788                localKey);
789        criteria.where(onlyReferencingCriterion);
790        Set<ObjectKey<?>> toSaveKeys = new HashSet<ObjectKey<?>>();
791        for (TurbineUserGroupRole toSaveElement : toSave)
792        {
793            ObjectKey<?> toSaveKey = toSaveElement.getPrimaryKey();
794            if (toSaveKey.getValue() != null)
795            {
796                toSaveKeys.add(toSaveKey);
797            }
798        }
799        
800        // calculate intersection between objects in the database
801        // and objects in the list
802        List<TurbineUserGroupRole> intersection;
803        if (toSaveKeys.isEmpty())
804        {
805            intersection = new ArrayList<TurbineUserGroupRole>();
806        }
807        else
808        {
809            Criterion toSaveKeyCriterion = null;
810            for (ObjectKey<?> toSaveKey : toSaveKeys)
811            {
812                SimpleKey<?>[] toSavePrimaryKeys = (SimpleKey[]) toSaveKey.getValue();
813                 Criterion p0 = new Criterion(
814                        TurbineUserGroupRolePeer.USER_ID,
815                        toSavePrimaryKeys[0]);
816                 Criterion p1 = new Criterion(
817                        TurbineUserGroupRolePeer.GROUP_ID,
818                        toSavePrimaryKeys[1]);
819                p0.and(p1);
820                 Criterion p2 = new Criterion(
821                        TurbineUserGroupRolePeer.ROLE_ID,
822                        toSavePrimaryKeys[2]);
823                p1.and(p2);
824                if (toSaveKeyCriterion == null)
825                {
826                    toSaveKeyCriterion = p0;
827                }
828                else
829                {
830                    toSaveKeyCriterion.or(p0);
831                }
832            }
833            criteria.and(toSaveKeyCriterion);
834            intersection = TurbineUserGroupRolePeer.doSelect(
835                    criteria,
836                    connection);
837        }
838        if (toLinkTo.isTurbineUserGroupRolesInitialized())
839        {
840            toLinkTo.getTurbineUserGroupRoles().clear();
841        }
842        else
843        {
844           toLinkTo.initTurbineUserGroupRoles();
845        }
846        for (TurbineUserGroupRole toSaveElement : toSave)
847        {
848            int listIndex = intersection.indexOf(toSaveElement);
849            if (listIndex == -1)
850            {
851                toLinkTo.addTurbineUserGroupRole(toSaveElement);
852                toSaveElement.save(connection);
853            }
854            else
855            {
856                toLinkTo.addTurbineUserGroupRole(toSaveElement);
857                toSaveElement.setNew(false);
858                if (!toSaveElement.valueEquals(intersection.get(listIndex)))
859                {
860                    //force saving if content differs
861                    toSaveElement.setModified(true);
862                }
863                toSaveElement.save(connection);
864            }
865            toSaveKeys.add(toSaveElement.getPrimaryKey());
866        }
867        
868        // delete elements not in intersection
869        Criteria deleteCriteria = new Criteria();
870        deleteCriteria.where(onlyReferencingCriterion);
871        if (!toSaveKeys.isEmpty())
872        {
873            Criterion toSaveKeyCriterion = null;
874            for (ObjectKey<?> toSaveKey : toSaveKeys)
875            {
876                SimpleKey<?>[] toSavePrimaryKeys = (SimpleKey[]) toSaveKey.getValue();
877                  Criterion p0 = new Criterion(
878                         TurbineUserGroupRolePeer.USER_ID,
879                         toSavePrimaryKeys[0],
880                         Criteria.NOT_EQUAL);
881                  Criterion p1 = new Criterion(
882                         TurbineUserGroupRolePeer.GROUP_ID,
883                         toSavePrimaryKeys[1],
884                         Criteria.NOT_EQUAL);
885                p0.or(p1);
886                  Criterion p2 = new Criterion(
887                         TurbineUserGroupRolePeer.ROLE_ID,
888                         toSavePrimaryKeys[2],
889                         Criteria.NOT_EQUAL);
890                p1.or(p2);
891                if (toSaveKeyCriterion == null)
892                {
893                    toSaveKeyCriterion = p0;
894                }
895                else
896                {
897                    toSaveKeyCriterion.and(p0);
898                }
899            }
900            deleteCriteria.and(toSaveKeyCriterion);
901        }
902        TurbineUserGroupRolePeer.doDelete(deleteCriteria, connection);
903    }
904
905
906}