EODatabaseDataSource

Inherits From:
EODataSource : NSObject

Conforms To: NSObject (NSObject)

Declared in: EOAccess/EODatabaseDataSource.h

Class Description

EODatabaseDataSource is a concrete subclass of EODataSource that fetches objects based on an EOModel, using an EODatabaseContext that services the data source's EOEditingContext. An EODatabaseDataSource can be set up to fetch all objects for its root entity, to fetch objects matching a particular EOFetchSpecification, and to further filter its fetching with an auxiliary EOQualifier.

EODatabaseDataSource implements all the functionality defined by EODataSource: In addition to fetching objects, it can insert and delete them (provided the entity isn't read-only). See the EODataSource class specification for more information on these topics.

As with other data sources, EODatabaseDataSource can also provide a detail data source. The most significant consequence of using an master-detail configuration is that the detail operates directly on the master's object graph. The EODetailDataSource has a master object and a detail key through which the detail data source accesses the its objects. The master object is simply the object that's selected in the master display group, and the detail key is the name of a relationship property in the master object. When the detail display group asks its data source to fetch, the EODetailDataSource simply gets the value for the relationship property named detail key from its master object and returns it. When you add and remove objects from the detail, you're directly modifying the master's relationship array. In fact, you can think EODetailDataSource an interface to its master object's relationship property.

Master-Peer Configurations

EODatabaseDataSources can be used in master-peer configurations. In a master-peer configuration, instead of using an EODatabaseDataSource with the master display group and an EODetailDataSource with the detail display group, both display groups use EODatabaseDataSources.

The peer in a master-peer configuration-an EODatabaseDataSource-operates independently of its master. It goes to the database to fetch its objects and maintains those objects in its own array. Because the peer data source acts independently, if you add or remove objects from the peer, the changes aren't automatically reflected in the master. The database is updated correctly, but the master's relationship array (if it exists) isn't. Consequently, if you're using master-peer and the master has a to-many relationship as a class property, you're responsible for modifying the master's relationship array to keep it in sync with the peer.

When to Use Master-Peer

You might want to use a master-peer configuration instead of a master-detail if the master doesn't have a class property that represents a relationship to the peer. With master-detail, the master must have a class property that represents a relationship to the detail, but because a peer does its own fetching, the master in a master-detail doesn't have this restriction.

Another scenario in which you might want to use a master-peer configuration is when you need to further qualify the set of objects related to the master's selected object. For example, instead of displaying all of a studio's movies, you want to display only the movies whose revenues are greater than $5,000,000. You can accomplish this by assigning an in-memory qualifier to the detail display group, but if the number of records in the unfiltered set is prohibitively large, the filtering is better performed in the database. Using a master-peer configuration, you can further qualify the peer's set of objects in the database by assigning an auxiliary qualifier. You must also use this auxiliary qualifier approach if the qualifier can't be executed in memory (for example, because it uses custom SQL or accesses properties not in the object graph). For an example of applying an auxiliary qualifier, see "Creating a Master-Peer Configuration."

Creating a Master-Peer Configuration

To set up a master-peer configuration, follow these basic steps:

  1. Create the master display group and EODatabaseDataSource.
  2. Create the peer display group and EODatabaseDataSource.
  3. Connect the display groups.
  4. Optionally, apply an auxiliary qualifier to the peer's data source.
For an OpenStep application, the easiest way to create a display group and its data source is to drag a model file (or an entity from EOModeler) into a nib in Interface Builder. This action creates an EODisplayGroup and a corresponding EODatabaseDataSource. Using this approach, you can then connect your two display groups as you would for a master-detail configuration, but create an EOMasterPeerAssociation instead of an EOMasterDetailAssociation. For more information on this topic, see Using Enterprise Objects Framework with OPENSTEP.

For a WebObjects application, start out similarly by dragging a model file (or an entity from EOModeler) into a component in WebObjects Builder to create a WODisplayGroup and a corresponding EODatabaseDataSource. Do this twice, once to create a master display group and again to create the peer. Don't configure your peer display group to have a detail data source as you would for a master-peer configuration. Instead, you must establish the master-peer relationship in code, using the EODataSource method qualifyWithRelationshipKey:ofObject: . The following method demonstrates the procedure:

- (void)selectObject {

WODisplayGroup *studioDisplayGroup; // Assume this exists.

WODisplayGroup *movieDisplayGroup;  // Assume this exists. 

Studio *studio;                     // Assume this exists.

EODatabaseDataSource *movieDataSource =

(EODatabaseDataSource *)[movieDisplayGroup dataSource];

[studioDisplayGroup selectObject:studio];

[movieDataSource qualifyWithRelationshipKey:@"movies" ofObject:studio];

[movieDisplayGroup fetch];

}

In this example, the selectObject method is invoked when a user selects a new master object (studio ). It updates the selection of the master display group (studioDisplayGroup ) and requalifies the peer data source (movieDataSource ) to match. The final step is to send a fetch message to the peer display group (movieDisplayGroup ), causing movieDataSource to refetch its objects from the database using a newly formed qualifier.

For both OpenStep and WebObjects applications, to apply an auxiliary qualifier, use EODatabaseDataSource's setAuxiliaryQualifier: method. The following method demonstrates the procedure:

- (void)requalifyMovies {

NSDecimalNumber *revenue;          // Assume this exists.

id movieDisplayGroup;              // Assume this exists.

EOQualifier *auxiliaryQualifier = nil;

EODatabaseDataSource *movieDataSource;

/* Construct qualifier. */

auxiliaryQualifier = [EOQualifier

qualifierWithQualifierFormat:@"%@ > %@", @"revenue", revenue];

/* Apply qualifier to peer data source. */

movieDataSource = (EODatabaseDataSource *)[movieDisplayGroup dataSource];

[movieDataSource setAuxiliaryQualifier:auxiliaryQualifier];

/* Tell peer controller to fetch. */

[movieDisplayGroup fetch];

}

This method constructs a qualifier that selects movies whose revenues are greater than revenue , assigns that qualifier as the auxiliary qualifier for the peer data source (movieDataSource ), and then directs the peer display group to fetch. Because the peer display group uses an EODatabaseDataSource instead of an EODetailDataSource, the refetch performs a fetch with the qualifier in the database.

Creating instances
- initWithEditingContext:entityName:
Setting selection criteria
- setFetchSpecification:
- fetchSpecification
- setAuxiliaryQualifier:
- auxiliaryQualifier
- fetchSpecificationForFetch
Getting objects used for fetching
- entity
- databaseContext
Enabling fetching
- setFetchEnabled:
- isFetchEnabled

Instance Methods

auxiliaryQualifier

- (EOQualifier *)auxiliaryQualifier

Returns the EOQualifier used to further filter the objects fetched by the receiver's EOFetchSpecification.

See also: - setAuxiliaryQualifier: , - fetchSpecificationForFetch , - fetchSpecification

databaseContext

- (EODatabaseContext *)databaseContext

Returns the EODatabaseContext that the receiver uses to access the external database. This is either the root EOObjectStore for the receiver's EOEditingContext, or if the root is an EOCooperatingObjectStore, it's the EODatabaseContext under that EOCooperatingObjectStore that services the EOModel containing the EOEntity for the receiver.

entity

- (EOEntity *)entity

Returns the EOEntity from which the receiver fetches objects.

fetchSpecification

- (EOFetchSpecification *)fetchSpecification

Returns the receiver's basic EOFetchSpecification. Its EOQualifier is conjoined with the receiver's auxiliary EOQualifier when the receiver fetches objects. The sender of this message can alter the EOFetchSpecification directly, or replace it using setFetchSpecification: .

See also: - fetchSpecificationForFetch , - auxiliaryQualifier

fetchSpecificationForFetch

- (EOFetchSpecification *)fetchSpecificationForFetch

Returns a copy of the EOFetchSpecification that the receiver uses to fetch. This is constructed by conjoining the EOQualifier of the receiver's EOFetchSpecification with its auxiliary EOQualifier. Modifying the returned EOFetchSpecification doesn't affect the receiver's fetching behavior; use setFetchSpecification: and setAuxiliaryQualifier: for that purpose.

See also: - fetchSpecification , - auxiliaryQualifier

initWithEditingContext:entityName:

- (id)initWithEditingContext: (EOEditingContext *)anEditingContext entityName: (NSString *)anEntityName

Initializes a newly allocated EODatabaseDataSource to fetch objects into anEditingContext for the EOEntity named by anEntityName. This method checks anEditingContext's EOObjectStoreCoordinator for an EODatabaseChannel that services the EOModel containing the named EOEntity. If none exists, this method creates one. This is the designated initializer for the EODatabaseDataSource class. Returns self .

isFetchEnabled

- (BOOL)isFetchEnabled

Returns YES if the receiver's fetchObjects method actually fetches objects, NO if it returns an empty array without fetching. Fetching is typically disabled in a master-peer configuration when no object is selected in the master.

See also: - setFetchEnabled:

setAuxiliaryQualifier:

- (void)setAuxiliaryQualifier: (EOQualifier *)aQualifier

Sets the receiver's auxiliary qualifier to aQualifier. The auxiliary qualifier usually adds conditions to the primary qualifier and is useful for narrowing the scope of a data source without altering its primary qualifier. This is especially useful for setting a qualifier on a qualified peer data source, since a peer's primary qualifiers specifies the matching criteria for the relationship it fetches for. For more information on auxiliary qualifiers, see "Creating a Master-Peer Configuration" in the class description.

See also: - fetchSpecificationForFetch , - fetchSpecification , - auxiliaryQualifier

setFetchEnabled:

- (void)setFetchEnabled: (BOOL)flag

Controls whether the receiver can fetch. If flag is YES the receiver's fetchObjects method actually fetches objects, if NO it returns an empty array without fetching. Fetching is typically disabled in a master-peer configuration when no object is selected in the master. For example, EODatabaseDataSource's implementation of qualifyWithRelationshipKey:ofObject: invokes this method to enable or disable fetching based on whether a master object is provided.

See also: - setFetchEnabled:

setFetchSpecification:

- (void)setFetchSpecification: (EOFetchSpecification *)aFetchSpecification

Sets the receiver's basic EOFetchSpecification to aFetchSpecification. Its EOQualifier is conjoined with the receiver's auxiliary EOQualifier when the receiver fetches objects.

See also: - setAuxiliaryQualifier: , - fetchSpecificationForFetch , - fetchSpecification

Copyright © 1997, Apple Computer, Inc. All rights reserved.