Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

dbRelSet Class Reference
[OOFILE Database package]

#include <oofrel.h>

Inheritance diagram for dbRelSet:

Inheritance graph
[legend]
Collaboration diagram for dbRelSet:

Collaboration graph
[legend]
List of all members.

Detailed Description

Relationship field to set of 0..N instances.


mandatory dbField overrides

virtual OOF_fieldTypes fieldType () const
virtual unsigned long fieldStorageLen () const

reflective operations

virtual bool fieldIsSameTypeAs (const dbField *) const
virtual const OOF_StringfieldName () const
 Override to return related table name as sensible default.

virtual void describe (std::ostream &) const
 Provide human-readable information about object.

virtual void extract (std::ostream &) const
virtual OOF_fieldTypes nativeType () const
virtual bool fieldIsVirtual () const
dbRelRefBaseinverse () const
dbTablerelatedTable ()
tableNumT relatedTableNumber () const
bool isRef () const
 Is "ref" to just one instance.

virtual bool pointsToCorrectTableType () const
 Default base method.


simple user-level queries as to type of relationship

bool isOneToMany () const
bool isManyToOne () const
bool isOneToOne () const
bool isManyToMany () const
bool isJoin () const
 If we don't have mJoinField then we are a pointer relationship.

bool isRelBackToParent () const
 Do we point left or right? ie: in Patients->Visits is this relationship field pointing back from Visits to Patients (the inverse relationship).


perform the relationship traversal

unsigned long countAllRelated ()
bool relateRecord (bool broadcastChange=true)
bool selectAllRelated (bool broadcastChange=true)
bool relateFromRecord (bool broadcastChange=true)
 Used to load a related selection.


relationship manipulation

void updateRelValue ()
 Propagate values to maintain a relationship.

void setOID (oidT)
void breakRelLink ()
 Break the link from another table pointing at us.

void changeRelationshipTo (dbRelRefBase &newRhs)
 Change an existing relationship to point to a different field.


Public Types

enum  FieldIsStandaloneT { eFieldIsStandalone }
enum  { kKeyLengthAutoCalculated = USHRT_MAX }

Public Member Functions

 dbRelSet (const char *inFieldName=0)
 ctor allowing you to pass field name for relationship.

virtual dbFieldclone () const
virtual void postCloneTableCleanup ()
void completeCloneOfInverse (dbRelRefBase *cloner)
void completeCloneOfInverse (dbTable *clonerTable)
void setMNlink (OOF_RelMN *)
 Point this relationship at the object which maintains the link.

OOF_RelMNgetMNlink () const
void relatesTo (dbRelRefBase &)
 Called by dbRelationship to tie two instances of dbRelRefBase together.

void joinField (dbField &)
dbFieldjoinField () const
bool propagatesDeletes () const
void propagateRelatedDeletes (bool prop=true)
 Set relationship to propagate deletes, ie: owns related records.

virtual bool receiveMsg (OOFmsgT msg, unsigned long senderDefined)
 The default receiveMsg behaviour is to delete yourself when the broadcaster closes.

virtual oofString name () const
void index (const OOF_IndexOptions=kIndexed)
void indexPartialKeyLen (unsigned short)
void setName (const char *name)
bool hasDefaultCalculator () const
void useCalculatorOnlyForDefaults ()
bool storesCalculatedValues () const
void storeCalculatedValues ()
bool usingCalculator () const
const char * tableName () const
bool fieldIsStandalone () const
virtual unsigned long fieldMinWrapWidth () const
virtual unsigned long fieldUsualWrapWidth () const
dbTablefieldTable () const
unsigned long fieldDataLen () const
virtual bool isEmpty () const
bool isDirty () const
fieldNumT fieldNumber () const
OOF_IndexOptions fieldIndexOptions () const
bool fieldIndexIgnoresNulls () const
bool fieldIndexIsCompressLeading () const
bool fieldIndexIsCompressPadding () const
virtual bool fieldIsIndexed () const
bool fieldIsPartiallyIndexed () const
virtual bool fieldIsKeywordIndexed () const
virtual bool fieldIsUniqueIndexed () const
unsigned short fieldNumIndexes () const
unsigned short fieldKeyLen () const
bool caseSensitive () const
virtual bool fieldIsBlob () const
virtual bool fieldIsBinary () const
dbFieldequivalentFieldFromTable (dbTable *) const
bool valueIsDuplicate () const
virtual dbQueryClausevalueAsQueryLiteral () const
bool fieldIsJoinKey () const
 Checks if any relationships in field's table use field as join key.

virtual void clear ()
virtual void setString (const char *)
virtual void setNumber (long)
virtual oofString copyString () const
virtual void getChars (char *ioBuff, unsigned long &outLen) const
virtual const char * asChars () const
virtual bool insert (std::istream &, char fieldSep, char recSep)
virtual void copyValueFrom (const dbField *)
virtual void copyValueIfDifferent (const dbField *)
virtual bool validateContents ()
virtual oofWordParserwords () const
void saveDefaultCalculatedValue ()
void saveStoredCalculatedValue ()
virtual void generateTestData (bool, unsigned long)
bool hidden () const
void hide (bool hideIt=true)
virtual void subscribeTo (oofBroadcaster *)
virtual void unsubscribe (oofBroadcaster *from=0)
void suspendListening ()
void resumeListening ()

Protected Member Functions

unsigned long CountAllRelatedIn (dbTable *)
void BuildRelatedTable ()
bool CompletelySpecified () const
void SetCommonRelationshipFields (dbRelRefBase &)
oidT OID () const
void OID (oidT)
void CalculateWith (dbCalculator *adoptedCalculator, bool useOnlyForDefaults)
virtual void CopyCalculatedValueToBuffer ()

Protected Attributes

unsigned long mMinLinks
unsigned long mMaxLinks
dbTablemRelatedTableProto
dbTablemActualRelatedTable
fieldNumT mInverseFieldNumber
dbFieldmJoinField
bool mPropagatesDeletes
dbRelRefBasemInverseField
OOF_RelMNmMNlink
OOF_tableBackendmBackend
dbTablemTable
fieldNumT mFieldNumber
dbCalculatormCalculator
bool mHidden
oofBroadcastermListensTo
oofBroadcastermSuspendedListensTo
unsigned short mSuspendCount


Member Enumeration Documentation

anonymous enum [inherited]
 

Enumeration values:
kKeyLengthAutoCalculated 

enum dbField::FieldIsStandaloneT [inherited]
 

Enumeration values:
eFieldIsStandalone 


Constructor & Destructor Documentation

dbRelSet::dbRelSet const char *  inFieldName = 0  )  [inline]
 

ctor allowing you to pass field name for relationship.


Member Function Documentation

const char * dbField::asChars  )  const [virtual, inherited]
 

Reimplemented in dbChar, and dbText.

void dbRelRefBase::breakRelLink  )  [inherited]
 

Break the link from another table pointing at us.

Doesn't need to do anything for join relationships as we deem it too dangerous to go and blithely clear key fields which may have multiple uses.

Called when update record on rhs OR when reassign link

Todo:
if save type of rhs is requireExplicitAndBuffer then need to cache some kind of undo comand in case need to cancel delete.

reassess need to clear join key fields - maybe that is needed in some cases to retain referential integrity

void dbRelRefBase::BuildRelatedTable  )  [protected, inherited]
 

void dbField::CalculateWith dbCalculator adoptedCalculator,
bool  useOnlyForDefaults
[protected, inherited]
 

bool dbField::caseSensitive  )  const [inline, inherited]
 

virtual void dbField::clear  )  [inline, virtual, inherited]
 

Reimplemented in dbChar, dbText, dbFixedBinary, and dbNumericField.

dbField * dbRelRefBase::clone  )  const [virtual, inherited]
 

Implements dbField.

void dbRelRefBase::completeCloneOfInverse dbTable clonerTable  )  [inherited]
 

void dbRelRefBase::completeCloneOfInverse dbRelRefBase cloner  )  [inherited]
 

bool dbRelRefBase::CompletelySpecified  )  const [inline, protected, inherited]
 

void dbField::CopyCalculatedValueToBuffer  )  [protected, virtual, inherited]
 

Reimplemented in dbChar, dbText, dbShort, dbUshort, dbBool, dbLong, dbUlong, dbReal, dbDate, dbTime, and dbDateTime.

oofString dbField::copyString  )  const [virtual, inherited]
 

Reimplemented in dbChar, and dbText.

virtual void dbField::copyValueFrom const dbField  )  [inline, virtual, inherited]
 

Reimplemented in dbChar, dbText, dbShort, dbUshort, dbBool, dbLong, dbUlong, dbReal, dbDate, dbTime, and dbDateTime.

virtual void dbField::copyValueIfDifferent const dbField  )  [inline, virtual, inherited]
 

Reimplemented in dbChar, dbText, dbShort, dbUshort, dbBool, dbLong, dbUlong, dbReal, dbDate, dbTime, and dbDateTime.

unsigned long dbRelRefBase::countAllRelated  )  [inherited]
 

unsigned long dbRelRefBase::CountAllRelatedIn dbTable  )  [protected, inherited]
 

void dbRelRefBase::describe std::ostream &  os  )  const [virtual, inherited]
 

Provide human-readable information about object.

Overriden to provide much more detail particularly for dbTable::describe() which provides full schema.

Reimplemented from dbField.

dbField * dbField::equivalentFieldFromTable dbTable  )  const [inherited]
 

void dbRelRefBase::extract std::ostream &   )  const [virtual, inherited]
 

Reimplemented from dbField.

unsigned long dbField::fieldDataLen  )  const [inline, inherited]
 

bool dbField::fieldIndexIgnoresNulls  )  const [inline, inherited]
 

bool dbField::fieldIndexIsCompressLeading  )  const [inline, inherited]
 

bool dbField::fieldIndexIsCompressPadding  )  const [inline, inherited]
 

OOF_IndexOptions dbField::fieldIndexOptions  )  const [inline, inherited]
 

bool dbField::fieldIsBinary  )  const [virtual, inherited]
 

Reimplemented in dbChar, and dbText.

bool dbField::fieldIsBlob  )  const [virtual, inherited]
 

Reimplemented in dbBLOB.

bool dbField::fieldIsIndexed  )  const [virtual, inherited]
 

bool dbField::fieldIsJoinKey  )  const [inherited]
 

Checks if any relationships in field's table use field as join key.

Relatively expensive because it's iterating over all fields but all the function calls below are inline queries so will compile down well in release mode.

WARNING Doesn't fan out - if any other tables use this field as a join key then they are doing really weird stuff and the application programmer must add their own checks.

This feature originally added to support OOF_repEditSetupVisitor::VisitViewBandBody

bool dbField::fieldIsKeywordIndexed  )  const [virtual, inherited]
 

Reimplemented in dbChar, and dbText.

bool dbField::fieldIsPartiallyIndexed  )  const [inline, inherited]
 

bool dbRelRefBase::fieldIsSameTypeAs const dbField  )  const [virtual, inherited]
 

Reimplemented from dbField.

bool dbField::fieldIsStandalone  )  const [inline, inherited]
 

bool dbField::fieldIsUniqueIndexed  )  const [virtual, inherited]
 

bool dbRelRefBase::fieldIsVirtual  )  const [virtual, inherited]
 

Reimplemented from dbField.

unsigned short dbField::fieldKeyLen  )  const [inherited]
 

unsigned long dbField::fieldMinWrapWidth  )  const [virtual, inherited]
 

Reimplemented in dbNumericField.

const OOF_String & dbRelRefBase::fieldName  )  const [virtual, inherited]
 

Override to return related table name as sensible default.

Usually we don't bother naming individual relationships however you are able to call setName or pass in a name to the ctor. When modelling more than one relationship between the same classes we recommend naming the relationship variables.

Returns:
specified name or name of related table.

Reimplemented from dbField.

fieldNumT dbField::fieldNumber  )  const [inline, inherited]
 

unsigned short dbField::fieldNumIndexes  )  const [inline, inherited]
 

unsigned long dbRelRefBase::fieldStorageLen  )  const [virtual, inherited]
 

Implements dbField.

dbTable * dbField::fieldTable  )  const [inherited]
 

OOF_fieldTypes dbRelRefBase::fieldType  )  const [virtual, inherited]
 

Implements dbField.

unsigned long dbField::fieldUsualWrapWidth  )  const [virtual, inherited]
 

Reimplemented in dbChar, and dbText.

virtual void dbField::generateTestData bool  ,
unsigned  long
[inline, virtual, inherited]
 

Reimplemented in dbChar, dbBLOB, dbText, dbFixedBinary, dbShort, dbUshort, dbBool, dbLong, dbUlong, dbReal, dbDate, dbTime, and dbDateTime.

void dbField::getChars char *  ioBuff,
unsigned long &  outLen
const [virtual, inherited]
 

Reimplemented in dbChar, and dbText.

OOF_RelMN * dbRelRefBase::getMNlink  )  const [inline, inherited]
 

bool dbField::hasDefaultCalculator  )  const [inline, inherited]
 

bool OOF_PublicBase::hidden  )  const [inline, inherited]
 

void OOF_PublicBase::hide bool  hideIt = true  )  [inline, inherited]
 

void dbField::index const  OOF_IndexOptions = kIndexed  )  [inherited]
 

void dbField::indexPartialKeyLen unsigned  short  )  [inline, inherited]
 

bool dbField::insert std::istream &  ,
char  fieldSep,
char  recSep
[virtual, inherited]
 

Reimplemented in dbChar, dbText, dbShort, dbUshort, dbBool, dbLong, dbUlong, dbReal, dbDate, dbTime, and dbDateTime.

dbRelRefBase * dbRelRefBase::inverse  )  const [inline, inherited]
 

bool dbField::isDirty  )  const [inherited]
 

Reimplemented in dbBLOB.

bool dbField::isEmpty  )  const [virtual, inherited]
 

Reimplemented in dbChar, dbBLOB, dbDate, and dbDateTime.

bool dbRelRefBase::isJoin  )  const [inline, inherited]
 

If we don't have mJoinField then we are a pointer relationship.

(or some other kind added later than OOFILE 1.4)

bool dbRelRefBase::isManyToMany  )  const [inline, inherited]
 

bool dbRelRefBase::isManyToOne  )  const [inline, inherited]
 

bool dbRelRefBase::isOneToMany  )  const [inline, inherited]
 

bool dbRelRefBase::isOneToOne  )  const [inline, inherited]
 

bool dbRelRefBase::isRef  )  const [inline, inherited]
 

Is "ref" to just one instance.

Returns:
false if can relate to multiple records

bool dbRelRefBase::isRelBackToParent  )  const [inline, inherited]
 

Do we point left or right? ie: in Patients->Visits is this relationship field pointing back from Visits to Patients (the inverse relationship).

This is important to know if you are following a relationship chain back from a related table to the source. So we test if the table which contains this field actually points back to the LHS via this field.

dbField * dbRelRefBase::joinField  )  const [inline, inherited]
 

void dbRelRefBase::joinField dbField  )  [inherited]
 

oofString dbField::name  )  const [virtual, inherited]
 

Reimplemented from OOF_PublicBase.

OOF_fieldTypes dbRelRefBase::nativeType  )  const [virtual, inherited]
 

Reimplemented from dbField.

void dbRelRefBase::OID oidT   )  [protected, inherited]
 

oidT dbRelRefBase::OID  )  const [protected, inherited]
 

bool dbRelRefBase::pointsToCorrectTableType  )  const [virtual, inherited]
 

Default base method.

Macro REL_REF_BODY in oofmacro.h defines virtual overrides for each subclass that do an actual test using the macro-generated dbTable::defaultName() override.

Note:
it is possible for people to create relationships other than through the declarative macros so we need to keep the base dbRelRef and dbRelSet usable, which is why this method isn't a pure virtual.
Returns:
true always, macro-generated override returns true OR false

void dbRelRefBase::postCloneTableCleanup  )  [virtual, inherited]
 

Reimplemented from dbField.

void dbRelRefBase::propagateRelatedDeletes bool  prop = true  )  [inherited]
 

Set relationship to propagate deletes, ie: owns related records.

Warning:
It is tempting to only allow this if (mTable->inDeclarativePhase()) but that check is not sufficient - during cloning of a table it is possible and legal to call propagateRelatedDeletes, as happens in ooftst42 with the MN link.
Todo:
see if we can add back the commented out test below safely

propagate deletes for N:1 with pointer relationships.

bool dbRelRefBase::propagatesDeletes  )  const [inline, inherited]
 

bool dbRelRefBase::receiveMsg OOFmsgT  msg,
unsigned long  senderDefined
[virtual, inherited]
 

The default receiveMsg behaviour is to delete yourself when the broadcaster closes.

In many user subclasses oofSingleListener is a mixin and you have a class owned elsewhere, not self-deleting.

Warning:
If a subclass is not self-deleting it MUST override receiveMsg handling of the msg OOFmsg_BroadcasterClosing to prevent runtime error.
However it is still important to set mListensTo=0 otherwise when you finally get around to deleting your oofSingleListener, it will try to update a deleted oofBroadcaster and cause a crash.

Reimplemented from oofSingleListener.

dbTable * dbRelRefBase::relatedTable  )  [inherited]
 

tableNumT dbRelRefBase::relatedTableNumber  )  const [inherited]
 

bool dbRelRefBase::relateFromRecord bool  broadcastChange = true  )  [inherited]
 

Used to load a related selection.

Mainly called from dbTable::ensureRecordLoaded and dbTable::MakeTableValid.

It may seem a little backwards but think of the normal context of using this method. We have already loaded a current record in the LHS of a relationship and now want the related record or selection. Remember that OOFILE allows you to iterate a table without forcing instantiation of relationships. Only when you refer to a related selection or specific fields in a related record is the relationship instantiated.

There are three distinct cases dealt with by this method:

  1. an M:N relationship, which is implemented by our member mMNlink.
  2. a 1:1, 1:N or N:1 join relationship which is handled by OOF_simpleRecordBackend::loadRelatedContextJoiningFromTo (normally via a search)
  3. a 1:1, 1:N or N:1 pointer relationship using record OID's in a search or direct lookup

If mInverseField (ie: other side of relationship pointing to us) isRef() then it contains a copy of the OID of a record in our table and we have a direct lookup (not caring if this is 1:1 or N:1 situation).

Otherwise it is 1:N and the OID on the other side is its record's OID, used as a key to search our relationship fields.

Todo:
explore using virtual overrides of relateFromRecord for user-defined relationships

bool dbRelRefBase::relateRecord bool  broadcastChange = true  )  [inherited]
 

void dbRelRefBase::relatesTo dbRelRefBase rhs  )  [inherited]
 

Called by dbRelationship to tie two instances of dbRelRefBase together.

Makes an actual relationship occur between the known tables in a dbConnection, finishing the work of declaring dbRelRef or dbRelSet members in the tables.

Sets the relational integrity up by default to make sense for Western users. The left table owns the right table unless the relationship is back to front. ie: an N:1 doesn't propagate deletes. Assumes ctor initialises mPropagatesDeletes false. If you have explicitly set mPropagatesDeletes true already it will retain that setting.

At this level we are working with the virtual and base methods of the dbRelRefBase

Note:
After this is called (ie: after dbRelationship functor) you can call propagateRelatedDeletes explicitly. eg: if you had a 1:1 relationship just to avoid loading large records, you would want to propagate deletes. We err on the side of caution in not propagating by default when it is hard to tell.

void oofSingleListener::resumeListening  )  [inherited]
 

void dbField::saveDefaultCalculatedValue  )  [inherited]
 

void dbField::saveStoredCalculatedValue  )  [inherited]
 

bool dbRelRefBase::selectAllRelated bool  broadcastChange = true  )  [inherited]
 

void dbRelRefBase::SetCommonRelationshipFields dbRelRefBase  )  [protected, inherited]
 

void dbRelRefBase::setMNlink OOF_RelMN inLink  )  [inherited]
 

Point this relationship at the object which maintains the link.

Calling setMNlink completes specifying the relationship - we assume the OOF_RelMN class manages the other relationships used to provide the 1:N N:1 that implement the M:N.

Note:
doesn't propagateRelatedDeletes because the other relationships that implement the link take care of propagation. However we could call propagateRelatedDeletes(true) if we wanted deleting one side to delete the other automatically.

void dbField::setName const char *  name  )  [inherited]
 

virtual void dbField::setNumber long   )  [inline, virtual, inherited]
 

Reimplemented in dbChar, dbText, dbShort, dbUshort, dbBool, dbLong, dbUlong, dbReal, dbDate, and dbDateTime.

void dbRelRefBase::setOID oidT   )  [inherited]
 

virtual void dbField::setString const char *   )  [inline, virtual, inherited]
 

Reimplemented in dbChar, dbText, dbFixedBinary, dbShort, dbUshort, dbBool, dbLong, dbUlong, dbReal, dbDate, and dbDateTime.

void dbField::storeCalculatedValues  )  [inline, inherited]
 

bool dbField::storesCalculatedValues  )  const [inline, inherited]
 

void oofSingleListener::subscribeTo oofBroadcaster  )  [virtual, inherited]
 

Reimplemented from oofReceiver.

void oofSingleListener::suspendListening  )  [inherited]
 

const char * dbField::tableName  )  const [inherited]