Release 3.0 Copyright ã1992 by NeXT Computer, Inc.  All Rights Reserved.
(Preliminary draft, Thurs Apr 16 13:14:46 PDT 1992)

DBBasicAdaptor

Inherits From:	Object

Protocols:	DBTransactions

Declared In:	dbkit/DBBasicAdaptor.h

Class Description

DBBasicAdaptor is the abstract superclass for all adaptors.  Many of  the default behaviors provided by this superclass will be adequate for simple adaptors.  Implementors who need to generate their own special query dialects, or who want to do complex runtime resource management, will find that they need to override most of the methods in DBBasicAdaptor.

There are two support classes that lend additional flexability to the adaptor mechanisam of the DBKit.  By overriding one or both of these classes, different query languages and complex context management schemes (such as multiple database "cursors") can be supported.

The expressionClass method returns a class that is used to generate query language. The default expressionClass is a private class that produces SQL; this class implements the DBExpressionValues protocol, which is what the DBKit uses to get at the resulting SQL.  In order to implement a different query language, the expressionClass method should return a class that can convert the contents of a DBBinder into an expression in some query language.  This expression should take the form of an object that conforms to the DBExpressionValues protocol.

The contextClass method returns the class used by contextForObject:  The default is nil -- which results in messages being sent directly to the adaptor.  If the class is method is overridden to return a factory object, then the default behavior will send the fetchData: and evaluateString:using: messages to contexts produced from that factory, rather than to the adaptor.  This is extremely useful when the underlying datasource expects its users to keep some identifying data structure handy to manage interactions, such as a cursor or a connection identifier.  See the specification sheet for DBBasicAdaptorContext for more details.

Instance Variables

Inherited from Object	Class	isa;
Declared in DBBasicAdaptor	id	bundle;

Adopted Protocols

DBTransactions	- beginTransaction
- rollbackTransaction
	- commitTransaction

Method Types

Creating and freeing an adaptor	- free
- initForDatabase:
- bundle
Connection management	- connectUsingString:
	- disconnectUsingString:
	- isConnected
- connectionName
- currentLoginString
Moving data to and fro	- evaluateString:using:
- fetchData:
- fetchDone:
- insertData:
- updateData:
- selectData:
- deleteData:
Transaction management	- areTransactionsEnabled
	- enableTransactions:
	- isTransactionInProgress
Data dictionary	- enumerateEntities:
- enumerateProperties:forEntity:
Support classes	- contextClass
- expressionClass
Special support for relational databases
	- outerJoinIsDefault
- recordIdentityProperty
Context management	- maintainContexts:
- contextForObject:
- releaseContextForObject:

Instance Methods

			bundle
- (NXBundle*)bundle

This method returns the bundle used to store all of the resources for this adaptor.

			contextForObject:
- contextForObject:anObject

This method returns an object of the class returned by contextClass, which is "owned" by anObject.  This object will be either nil, or a subclass of DBBasicAdaptorContext.  In adaptors that manage multiple contexts per adaptor, there is typically a single context that is shared for all data modifying operations (the "shared context"), and any number of contexts that are used for data retrieval.

			maintainContexts:
- (BOOL)maintainContexts:(BOOL)yn

Use this method to set whether the adaptor needs to manage multiple contexts.

			releaseContextForObject:
- releaseContextForObject:anObject

This method will free up the resources associated with anObject.

Methods to be Re-Defined in a Subclass of DBBasicAdaptor

The following methods are included in the DBBasicAdaptor class as stubs: although they are defined in the class, they do nothing and generally return nil or NO. These methods are usually invoked from a DBBinder.  Many of the methods in this section are optional; if they are not overridden, the default behavior will be adequate.  Minimally, a subclass of DBBasicAdaptor must implement evaluateString:using: and fetchData:.

			areTransactionsEnabled
- (BOOL)areTransactionsEnabled

This method should return the whether or not transactions are enabled for the adaptor.  The default case returns NO.

			beginTransaction
- (BOOL)beginTransaction

This method should begin a transaction in the adaptor's datasource, and return whether this beginning succeeded.  The default case returns NO.

			commitTransaction
- (BOOL)commitTransaction

This method should commit the current transaction, if one exists.  The default case returns NO.

			connectionName
- (const unsigned char*)connectionName

This method should return a display name for the adaptor's datasource.  The default case returns "No Database".

			connectUsingString
- (BOOL)connectUsingString:(const unsigned char*)aString

This method should attempt to connect to the datasource for the adaptor, and return whether the connection succeeded.  The string can be used for whatever purpose the adaptor wishes; if login information is necessary, this is a good place to put it.  The default case does nothing and returns NO.

			contextClass
- contextClass

This method should return the class object to be used by the adaptors context maintenance mechanism.  The default is nil.

			currentLoginString
- (const unsigned char*)currentLoginString

If the adaptor uses the string passed as a parameter to connectUsingString: as a part of its connection logic, then this method should return the publically readable part of the string that was passed to a connected adaptor.  The default case returns "".

Remember that this method could consitute a security risk if its implementation returns too much information.

			deleteData:
- (BOOL)deleteData:(DBBinder*)aBinder

This method is called to delete the values in the adaptor's datasource for the properties and qualifier in aBinder.  The default implementation creates a new object using expressionClass, and calls deleteExpressionForBinder: on this object.  It then aquires the shared context for the adaptor, and calls evaluateString:using: on the context, passing the expressionValue of the expression object as the string argument.

			disconnectUsingString
- (BOOL)disconnectUsingString:(const unsigned char*)aString

This method should disconnect a connected adaptor, or return NO.  The default case does nothing and returns NO.

			enableTransactions
- (BOOL)enableTransactions:(BOOL)yn

Calling this method with YES should enable the use of transactional protection within the adaptor, while a NO creates an environment where changes take effect immediately, and are not protected from failure.  If switching transactions on and off cannot be supported, this should return NO.  The default case returns NO.

			enumerateEntities:
- (List*)enumerateEntities:(List*)aList

This method should fill aList with the entities for the adaptor's current datasource.  The default is to return the list empty.

			enumerateProperties:forEntity:
- (List*)enumerateProperties:(List*)aList forEntity:(id<DBEntities>)anEntity

This method should fill aList with the attributes and relationships for anEntity.  The default is to return the list empty.

			evaluateString:using:
- (BOOL)evaluateString:(const unsigned char*)aString using:(DBBinder*)aBinder

This method should evaluate aString and return the success status of the evaluation.  If the adaptor doesn't support a query language, then this should just return NO.  The default case aquires either the context object for aBinder or the shared context, if appropriate, and calls evaluateString:using: on that context object.

This method should almost always be overridden.

			expressionClass
- expressionClass

This method should return the class object to be used when generating query expressions, if a query language is supported by the adaptor.  The default case returns a private class which conforms to the DBExpressionValues protocol, and which responds to insertExpressionForBinder:, updateExpressionForBinder:, selectExpressionForBinder:, and deleteExpressionForBinder:.  If a class is returned as the expressionClass, and it is used with the default DBBasicAdaptor implementations of insertData:, updateData:, selectData: and deleteData:, it should implement these four methods.

			fetchData:
- (BOOL)fetchData:(DBBinder*)aBinder

This method is called after a data-producing operation such as selectData: or evaluateString:using:.  It should inject the next available "row" of data into aBinder using the valueForProperty: method for every property returned.  The default implementation acquires either the context for aBinder or the shared context, if appropriate, and calls fetchData: on the context.  Finally, if the call to the context's fetchData: failed, the adaptor calls fetchDone: on itself.

			fetchDone:
- (void)fetchDone:(DBBinder*)aBinder

This method is called whenever the end of a fetch cycle has been detected.  It's purpose is to allow adaptors to reap expensive runtime resources such as network connections or database cursors.  The default implementation releases the context object for aBinder, if there is one.

			free
- free

				This method should close and free any resources associated with the adaptor.  The default returns [super free].

			initForDatabase
- initForDatabase:(DBDatabase*)aDatabase

This method should prepare any data structures that the adaptor will need to be useful.  The default case does nothing and returns nil.

			insertData:
- (BOOL)insertData:(DBBinder*)aBinder

This method is called to insert new values into the adaptor's datasource for the properties in aBinder.  The default implementation creates a new object using expressionClass, and calls insertExpressionForBinder: on this object.  It then aquires the shared context for the adaptor, and calls evaluateString:using: on the context, passing the expressionValue of the expression object as the string argument.

			isConnected
- (BOOL)isConnected

This method should return the connection state of  the adaptor.  The default case returns NO.

			isTransactionInProgress
- (BOOL)isTransactionInProgress

This method returns whether a transaction has already been started with beginTransaction.  Transactions may not be nested.

			outerJoinIsDefault
- (BOOL)outerJoinIsDefault

This method is specifically for relational databases.  The method should return YES if the underlying database fully supports outer joins.  This will result in the default use of outer joins in the higher level DBKit objects.  The default case returns NO.

			recordIdentityProperty
- (id<DBProperties>)recordIdentityProperty

This method is a specific optimization for relational databases which support the ANSI notion of ROWID.  Adaptors for this kind of database can dedicate a static property named "ROWID" to acting as a unique identifier for individual rows of data; this will result in faster updating and sometimes in better concurrency, depending on the database implementation.  The default case returns nil.

			rollbackTransaction
- (BOOL)rollbackTransaction

This method should rollback the current transaction, if one exists.  The default case returns NO.

			selectData:
- (BOOL)selectData:(DBBinder*)aBinder

This method is called to extract the values contained in the adaptor's datasource for the properties in aBinder.  The default implementation creates a new object using expressionClass, and calls selectExpressionForBinder: on this object.  It then aquires either the context for aBinder or the shared context for the adaptor, if appropriate, and calls evaluateString:using: on this context, passing the expressionValue of the expression object as the string argument.

			updateData:
- (BOOL)updateData:(DBBinder*)aBinder

This method is called to update the values contained in the adaptor's datasource for the properties in aBinder.  The default implementation creates a new object using expressionClass, and calls updateExpressionForBinder: on this object.  It then aquires the shared context for the adaptor, and calls evaluateString:using: on the context, passing the expressionValue of the expression object as the string argument.