Commits

Tuukka Norri committed 9901f0e

Refactoring (references #197)
- Replaced various methods that required error parameters with ones that don't.
- Marked the previous versions as deprecated.
- Made deprecation warnings more informative.
- Fixed a bug in -[NSError BXExceptionWithName:] which caused the name to be always kBXExceptionUnhandledError.

  • Participants
  • Parent commits e468cb6

Comments (0)

Files changed (25)

File BaseTen.xcodeproj/project.pbxproj

 		538334DB0F0405F50040368E /* BXDatabaseObject+PGTSResultRowProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 538334D90F0405F50040368E /* BXDatabaseObject+PGTSResultRowProtocol.m */; };
 		53857894119213AB00426CEA /* NSPredicate+BaseTenAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 535661CF0F025DD800920008 /* NSPredicate+BaseTenAdditions.m */; };
 		538578A0119213F500426CEA /* NSArray+BaseTenAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 535661CE0F025DD800920008 /* NSArray+BaseTenAdditions.m */; };
-		538578A91192143F00426CEA /* BXDeprecationWarning.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B934DD0F98BDFA006BD87D /* BXDeprecationWarning.m */; };
 		538578AD1192144500426CEA /* BXError.m in Sources */ = {isa = PBXBuildFile; fileRef = 53BFE53C0FAF2EFA0004533F /* BXError.m */; };
 		538578C61192155B00426CEA /* PGTSValuePlaceholder.m in Sources */ = {isa = PBXBuildFile; fileRef = 536206510FB87DDA00ACAE57 /* PGTSValuePlaceholder.m */; };
 		538578D6119215B100426CEA /* NSRelationshipDescription+BXPGAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 53877EEA0E2773E30097C35F /* NSRelationshipDescription+BXPGAdditions.m */; };
 		538579D0119219BD00426CEA /* PGTSOids.h in Headers */ = {isa = PBXBuildFile; fileRef = 5354F8810F004F9300422613 /* PGTSOids.h */; };
 		538579D1119219BF00426CEA /* PGTSInvocationRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 53937B650EFD097700510DBD /* PGTSInvocationRecorder.h */; };
 		538579D2119219C000426CEA /* PGTSHOM.h in Headers */ = {isa = PBXBuildFile; fileRef = 53666CC20E1CD8D20028DBEA /* PGTSHOM.h */; };
-		538579D3119219C100426CEA /* BXDeprecationWarning.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B934DC0F98BDFA006BD87D /* BXDeprecationWarning.h */; };
 		538579D4119219C200426CEA /* BXException.h in Headers */ = {isa = PBXBuildFile; fileRef = 5339AB910A7542EC00994B1A /* BXException.h */; };
 		538579D5119219C200426CEA /* BXError.h in Headers */ = {isa = PBXBuildFile; fileRef = 53BFE53B0FAF2EFA0004533F /* BXError.h */; };
 		538579D6119219C400426CEA /* BXURLEncoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 5354F7DC0F00417400422613 /* BXURLEncoding.h */; };
 		53B24CF50E223A14007AED76 /* BXPGDatabaseDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B24CF30E223A14007AED76 /* BXPGDatabaseDescription.m */; };
 		53B24CFA0E223C8C007AED76 /* BXPGTableDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B24CF80E223C8C007AED76 /* BXPGTableDescription.h */; };
 		53B24CFB0E223C8C007AED76 /* BXPGTableDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B24CF90E223C8C007AED76 /* BXPGTableDescription.m */; };
-		53B934DE0F98BDFA006BD87D /* BXDeprecationWarning.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B934DC0F98BDFA006BD87D /* BXDeprecationWarning.h */; };
-		53B934DF0F98BDFA006BD87D /* BXDeprecationWarning.m in Sources */ = {isa = PBXBuildFile; fileRef = 53B934DD0F98BDFA006BD87D /* BXDeprecationWarning.m */; };
 		53BFE53D0FAF2EFA0004533F /* BXError.h in Headers */ = {isa = PBXBuildFile; fileRef = 53BFE53B0FAF2EFA0004533F /* BXError.h */; };
 		53BFE53E0FAF2EFA0004533F /* BXError.m in Sources */ = {isa = PBXBuildFile; fileRef = 53BFE53C0FAF2EFA0004533F /* BXError.m */; };
 		53C4C3F41192EC10003FB842 /* BXCFHostCompatibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 53C4C3F31192EC10003FB842 /* BXCFHostCompatibility.h */; };
 		53B872800A0A4CEC007315BC /* BXAbstractDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BXAbstractDescription.h; path = Sources/BXAbstractDescription.h; sourceTree = "<group>"; };
 		53B872810A0A4CEC007315BC /* BXAbstractDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BXAbstractDescription.m; path = Sources/BXAbstractDescription.m; sourceTree = "<group>"; };
 		53B90C250BA6AE7600D982C4 /* BXPropertyDescriptionPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = BXPropertyDescriptionPrivate.h; path = Sources/BXPropertyDescriptionPrivate.h; sourceTree = "<group>"; };
-		53B934DC0F98BDFA006BD87D /* BXDeprecationWarning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXDeprecationWarning.h; path = Sources/BXDeprecationWarning.h; sourceTree = "<group>"; };
-		53B934DD0F98BDFA006BD87D /* BXDeprecationWarning.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BXDeprecationWarning.m; path = Sources/BXDeprecationWarning.m; sourceTree = "<group>"; };
 		53BDBBFC0C306DA6007F63A1 /* BXConstantsPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXConstantsPrivate.h; path = Sources/BXConstantsPrivate.h; sourceTree = "<group>"; };
 		53BFE53B0FAF2EFA0004533F /* BXError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BXError.h; path = Sources/BXError.h; sourceTree = "<group>"; };
 		53BFE53C0FAF2EFA0004533F /* BXError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BXError.m; path = Sources/BXError.m; sourceTree = "<group>"; };
 				53BFE53C0FAF2EFA0004533F /* BXError.m */,
 				5339AB910A7542EC00994B1A /* BXException.h */,
 				5339AB920A7542EC00994B1A /* BXException.m */,
-				53B934DC0F98BDFA006BD87D /* BXDeprecationWarning.h */,
-				53B934DD0F98BDFA006BD87D /* BXDeprecationWarning.m */,
 				53666CC20E1CD8D20028DBEA /* PGTSHOM.h */,
 				53666CC30E1CD8D20028DBEA /* PGTSHOM.m */,
 				53937B650EFD097700510DBD /* PGTSInvocationRecorder.h */,
 				535736CB0F333CCD00DB3D0B /* BXDatabaseObjectModelStorage.h in Headers */,
 				534BE4680F34F7130098951C /* BXForeignKey.h in Headers */,
 				538FA0250F576278005EBFAC /* BXOpenSSLCompatibility.h in Headers */,
-				53B934DE0F98BDFA006BD87D /* BXDeprecationWarning.h in Headers */,
 				53671B4B0FABAC5F002FD0B4 /* BXDatabaseObjectModelXMLSerialization.h in Headers */,
 				53BFE53D0FAF2EFA0004533F /* BXError.h in Headers */,
 				536206360FB87AB700ACAE57 /* PGTSValueTypes.h in Headers */,
 				538579D0119219BD00426CEA /* PGTSOids.h in Headers */,
 				538579D1119219BF00426CEA /* PGTSInvocationRecorder.h in Headers */,
 				538579D2119219C000426CEA /* PGTSHOM.h in Headers */,
-				538579D3119219C100426CEA /* BXDeprecationWarning.h in Headers */,
 				538579D4119219C200426CEA /* BXException.h in Headers */,
 				538579D5119219C200426CEA /* BXError.h in Headers */,
 				538579D6119219C400426CEA /* BXURLEncoding.h in Headers */,
 				5348B84A0F575EE100B2655E /* BXDatabaseObjectModelStorage.m in Sources */,
 				53857894119213AB00426CEA /* NSPredicate+BaseTenAdditions.m in Sources */,
 				538578A0119213F500426CEA /* NSArray+BaseTenAdditions.m in Sources */,
-				538578A91192143F00426CEA /* BXDeprecationWarning.m in Sources */,
 				538578AD1192144500426CEA /* BXError.m in Sources */,
 				538578C61192155B00426CEA /* PGTSValuePlaceholder.m in Sources */,
 				538578D6119215B100426CEA /* NSRelationshipDescription+BXPGAdditions.m in Sources */,
 				535736C60F3283C200DB3D0B /* BXDatabaseObjectModel.m in Sources */,
 				535736CC0F333CCD00DB3D0B /* BXDatabaseObjectModelStorage.m in Sources */,
 				533F88410F35482000041C02 /* BXForeignKey.m in Sources */,
-				53B934DF0F98BDFA006BD87D /* BXDeprecationWarning.m in Sources */,
 				53671B4C0FABAC5F002FD0B4 /* BXDatabaseObjectModelXMLSerialization.m in Sources */,
 				53BFE53E0FAF2EFA0004533F /* BXError.m in Sources */,
 				5362062A0FB87A0300ACAE57 /* PGTSDates.m in Sources */,

File BaseTenAppKit/Sources/BXSynchronizedArrayController.m

 {
 	BXAssertVoidReturn (databaseContext, @"Expected databaseContext not to be nil. Was it set or bound in Interface Builder?");
 	
-	NSError* error = nil;
 	[self setEntityDescription: nil];
-	BXEntityDescription* entityDescription = [databaseContext entityForTable: [self tableName]
-																	inSchema: [self schemaName]
-																	   error: &error];
-	if (nil != error)
-		[self BXHandleError: error];
-	else
+	BXDatabaseObjectModel *objectModel = [databaseContext databaseObjectModel];
+	BXEntityDescription* entityDescription = [objectModel entityForTable: [self tableName] inSchema: [self schemaName]];
+
+	if (entityDescription)
 	{
 		[entityDescription setDatabaseObjectClass: NSClassFromString ([self databaseObjectClassName])];                
 		[self setEntityDescription: entityDescription];
-	}	
+	}
+	else
+	{
+		[self BXHandleError: [BXDatabaseObjectModel errorForMissingEntity: [self tableName] inSchema: [self schemaName]]];
+	}
 }
 
 /**

File BaseTenAssistant/Sources/BXAController.m

 	[connection executeQuery: @"DROP TABLE IF EXISTS baseten_view_pkey"];
 	[connection executeQuery: @"DROP TABLE IF EXISTS baseten_enabled_oids"];
 	
-	NSDictionary* entities = [mContext entitiesBySchemaAndName: YES error: NULL];
+	NSDictionary *entities = [[mContext databaseObjectModel] entitiesBySchemaAndName: mContext reload: YES error: NULL];
 	[mEntitiesBySchema setContent: entities];
 }
 
 	[self hideProgressPanel];
 	//End patch
 
-	NSDictionary* entities = [mContext entitiesBySchemaAndName: YES error: NULL];
+	NSDictionary *entities = [[mContext databaseObjectModel] entitiesBySchemaAndName: mContext reload: YES error: NULL];
 	[mEntitiesBySchema setContent: entities];
 	
 	BXPGInterface* interface = (id) [mContext databaseInterface];
 	
 	NSModalSession session = [NSApp beginModalSessionForWindow: mMainWindow];
 	
-	NSDictionary* entities = [mContext entitiesBySchemaAndName: YES error: &error];
+	NSDictionary *entities = [[mContext databaseObjectModel] entitiesBySchemaAndName: mContext reload: YES error: NULL];
 	[self setProgressMin: 1.0 max: 1.0];
 	
 	[NSApp endModalSession: session];

File BaseTenAssistant/Sources/BXAImportController.m

 	
 	for (NSEntityDescription* entity in [mEntities arrangedObjects])
 	{
-		BXEntityDescription* bxEntity = [mContext matchingEntity: entity inSchema: schemaName error: NULL];
+		BXEntityDescription* bxEntity = [[mContext databaseObjectModel] matchingEntity: entity inSchema: schemaName];
 		if (bxEntity)
 		{
 			if (! conflictingEntities)

File Sources/BXDatabaseContext.h

 
 
 @interface BXDatabaseContext (HelperMethods)
-- (BOOL) canGiveEntities;
 - (NSArray *) objectIDsForEntity: (BXEntityDescription *) anEntity error: (NSError **) error;
 - (NSArray *) objectIDsForEntity: (BXEntityDescription *) anEntity predicate: (NSPredicate *) predicate error: (NSError **) error;
-- (BXEntityDescription *) entityForTable: (NSString *) tableName inSchema: (NSString *) schemaName error: (NSError **) error;
-- (BXEntityDescription *) entityForTable: (NSString *) tableName error: (NSError **) error;
-- (NSDictionary *) entitiesBySchemaAndName: (BOOL) reload error: (NSError **) error;
-- (BOOL) entity: (NSEntityDescription *) entity existsInSchema: (NSString *) schemaName error: (NSError **) error;
-- (BXEntityDescription *) matchingEntity: (NSEntityDescription *) entity inSchema: (NSString *) schemaName error: (NSError **) error;
+
+- (BOOL) canGiveEntities BX_DEPRECATED;
+- (BXEntityDescription *) entityForTable: (NSString *) tableName inSchema: (NSString *) schemaName error: (NSError **) error BX_DEPRECATED;
+- (BXEntityDescription *) entityForTable: (NSString *) tableName error: (NSError **) error BX_DEPRECATED;
+- (NSDictionary *) entitiesBySchemaAndName: (BOOL) reload error: (NSError **) error BX_DEPRECATED;
+
+- (BOOL) entity: (NSEntityDescription *) entity existsInSchema: (NSString *) schemaName error: (NSError **) error BX_DEPRECATED;
+- (BXEntityDescription *) matchingEntity: (NSEntityDescription *) entity inSchema: (NSString *) schemaName error: (NSError **) error BX_DEPRECATED;
 @end
 
 

File Sources/BXDatabaseContext.m

 
 #define BXHandleError( ERROR, LOCAL_ERROR ) BXHandleError2( self, mDelegateProxy, ERROR, LOCAL_ERROR )
 
-static void
-BXHandleError2 (id ctx, id <BXDatabaseContextDelegate> delegateProxy, NSError **error, NSError *localError)
+void
+BXHandleError2 (BXDatabaseContext *ctx, id <BXDatabaseContextDelegate> delegateProxy, NSError **error, NSError *localError)
 {
     if (nil != localError)
     {
  */
 - (BXEntityDescription *) entityForTable: (NSString *) name inSchema: (NSString *) schemaName error: (NSError **) outError
 {
-	NSError* localError = nil;
+	BXDeprecationLog ();
 	if (! schemaName) schemaName = @"public";
-	id retval = [mObjectModel entityForTable: name inSchema: schemaName error: &localError];
-	
-	//FIXME: should this be here or in the object model?
-	if (! retval && ! localError)
-	{
-		NSString* title = BXLocalizedString (@"databaseError", @"Database error", @"Title for a sheet");
-		NSString* errorFormat = BXLocalizedString (@"relationNotFound", @"Relation %@ was not found in schema %@.", @"Error message for getting or using an entity description.");
-		NSString* reason = [NSString stringWithFormat: errorFormat, name, schemaName];
-		NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
-								  title, NSLocalizedDescriptionKey,
-								  title, NSLocalizedFailureReasonErrorKey, 
-								  reason, NSLocalizedRecoverySuggestionErrorKey, 
-								  self, kBXDatabaseContextKey,
-								  nil];
-		localError = [BXError errorWithDomain: kBXErrorDomain code: kBXErrorNoTableForEntity userInfo: userInfo];
-	}
-	
-	BXHandleError (outError, localError);
-	
+	id retval = [mObjectModel entityForTable: name inSchema: schemaName];
+	if (! retval)
+		BXHandleError (outError, [BXDatabaseObjectModel errorForMissingEntity: name inSchema: schemaName]);
 	return retval;
 }
 
  */
 - (BXEntityDescription *) entityForTable: (NSString *) name error: (NSError **) outError
 {
-	return [self entityForTable: name inSchema: nil error: outError];
+	BXDeprecationLog ();
+	return [mObjectModel entityForTable: name inSchema: @"public"];
 }
 
 /**
  */
 - (NSDictionary *) entitiesBySchemaAndName: (BOOL) reload error: (NSError **) outError
 {
+	BXDeprecationLog ();
 	NSError* localError = nil;
 	NSDictionary* retval = [mObjectModel entitiesBySchemaAndName: mDatabaseInterface reload: reload error: &localError];
 	[mObjectModel setCanCreateEntityDescriptions: NO];
 }
 //@}
 
+
 - (BOOL) entity: (NSEntityDescription *) entity existsInSchema: (NSString *) schemaName error: (NSError **) error
 {
-	return ([self matchingEntity: entity inSchema: schemaName error: error] ? YES : NO);
+	BXDeprecationLog ();
+	return [mObjectModel entity: entity existsInSchema: schemaName];
 }
 
+
 - (BXEntityDescription *) matchingEntity: (NSEntityDescription *) entity inSchema: (NSString *) schemaName error: (NSError **) error
 {
-	NSDictionary* entities = [self entitiesBySchemaAndName: NO error: error];
-	return [[entities objectForKey: schemaName] objectForKey: [entity name]];
+	BXDeprecationLog ();
+	return [mObjectModel entityForTable: [entity name] inSchema: schemaName];
 }
 
+
 - (BOOL) canGiveEntities
 {
+	BXDeprecationLog ();
 	NSError* localError = nil;
 	return ([self checkDatabaseURI: &localError] && [mDatabaseURI host] && [mDatabaseURI path]);
 }
 		}
 	}
 }
+
+
+- (void) handleError: (NSError *) error outError: (NSError **) outError
+{
+	BXHandleError (outError, error);
+}
 @end
 
 

File Sources/BXDatabaseContextPrivate.h

 - (struct update_kvo_ctx) handleWillChangeForUpdate: (NSArray *) objects newValues: (NSDictionary *) newValues;
 - (void) handleDidChangeForUpdate: (struct update_kvo_ctx *) ctx newValues: (NSDictionary *) newValues 
 				sendNotifications: (BOOL) shouldSend targetEntity: (BXEntityDescription *) entity;
+- (void) handleError: (NSError *) error outError: (NSError **) outError;
 @end
 
 

File Sources/BXDatabaseObjectID.h

            schema: (NSString **) outSchemaName
  primaryKeyFields: (NSDictionary **) outPkeyDict;
 
-- (id) initWithURI: (NSURL *) anURI context: (BXDatabaseContext *) context error: (NSError **) error;
+- (id) initWithURI: (NSURL *) anURI context: (BXDatabaseContext *) context;
+- (id) initWithURI: (NSURL *) anURI context: (BXDatabaseContext *) context error: (NSError **) error BX_DEPRECATED;
 - (NSURL *) URIRepresentation;
 
 - (BXEntityDescription *) entity;

File Sources/BXDatabaseObjectID.m

 // $Id$
 //
 
+#import "BXDatabaseObjectModel.h"
 #import "BXDatabaseObjectID.h"
 #import "BXDatabaseObjectIDPrivate.h"
 #import "BXEntityDescription.h"
 #import "BXLogger.h"
 #import "BXEnumerate.h"
 #import "BXURLEncoding.h"
+#import "BXException.h"
 #import "NSURL+BaseTenAdditions.h"
 
 
  * \brief Create an object identifier from an NSURL.
  * \note This is not the designated initializer.
  */
-- (id) initWithURI: (NSURL *) anURI context: (BXDatabaseContext *) context error: (NSError **) error
+- (id) initWithURI: (NSURL *) anURI context: (BXDatabaseContext *) context
 {
     NSString* entityName = nil;
     NSString* schemaName = nil;
     if ([[self class] parseURI: anURI entity: &entityName
                         schema: &schemaName primaryKeyFields: &pkeyDict])
     {
-        BXEntityDescription* entity = [context entityForTable: entityName inSchema: schemaName error: error];
+		BXEntityDescription *entity = [[context databaseObjectModel] entityForTable: entityName inSchema: schemaName];
+		if (! entity)
+		{
+			NSError *error = [BXDatabaseObjectModel errorForMissingEntity: entityName inSchema: schemaName];
+			@throw [error BXExceptionWithName: NSInvalidArgumentException];
+		}
+		
         [[self class] verifyPkey: pkeyDict entity: entity];
         self = [self initWithEntity: entity objectURI: anURI];
     }
     return self;
 }
 
+- (id) initWithURI: (NSURL *) anURI context: (BXDatabaseContext *) context error: (NSError **) error
+{
+	BXDeprecationLog ();
+	return [self initWithURI: anURI context: context];
+}
+
 - (NSString *) description
 {
     return [NSString stringWithFormat: @"<%@ (%p) %@>", [self class], self, [self URIRepresentation]];

File Sources/BXDatabaseObjectModel.h

 
 #import <Foundation/Foundation.h>
 
+@class BXDatabaseObjectModelStorage;
+@class BXDatabaseContext;
 @class BXEntityDescription;
-@class BXDatabaseObjectModelStorage;
-@protocol BXInterface;
+@class NSEntityDescription;
 
 
 @interface BXDatabaseObjectModel : NSObject 
 	NSMutableDictionary* mEntitiesBySchemaAndName;
 	BOOL mCanCreateEntities;
 }
-- (BXEntityDescription *) entityForTable: (NSString *) tableName inSchema: (NSString *) schemaName error: (NSError **) outError;
-- (BXEntityDescription *) entityForTable: (NSString *) tableName error: (NSError **) outError;
-- (NSArray *) entities: (NSError **) outError;
-- (NSDictionary *) entitiesBySchemaAndName: (id <BXInterface>) interface reload: (BOOL) shouldReload error: (NSError **) outError;
++ (NSError *) errorForMissingEntity: (NSString *) name inSchema: (NSString *) schemaName;
+
+- (BOOL) canCreateEntityDescriptions;
+
+- (NSArray *) entities;
+- (BXEntityDescription *) entityForTable: (NSString *) tableName;
+- (BXEntityDescription *) entityForTable: (NSString *) tableName inSchema: (NSString *) schemaName;
+- (NSDictionary *) entitiesBySchemaAndName: (BXDatabaseContext *) context reload: (BOOL) shouldReload error: (NSError **) outError;
+
+- (BOOL) entity: (NSEntityDescription *) entity existsInSchema: (NSString *) schemaName;
+- (BXEntityDescription *) matchingEntity: (NSEntityDescription *) entity inSchema: (NSString *) schemaName;
 @end

File Sources/BXDatabaseObjectModel.m

 // $Id$
 //
 
+#import "BXDatabaseContextPrivate.h"
 #import "BXDatabaseObjectModel.h"
 #import "BXDatabaseObjectModelStorage.h"
 #import "BXDatabaseObjectModelStoragePrivate.h"
 #import "BXEntityDescriptionPrivate.h"
 #import "BXInterface.h"
 #import "BXLogger.h"
+#import "BXLocalizedString.h"
+#import "BXError.h"
 
 
 /** 
 }
 
 
++ (NSError *) errorForMissingEntity: (NSString *) name inSchema: (NSString *) schemaName
+{
+	NSString* title = BXLocalizedString (@"databaseError", @"Database error", @"Title for a sheet");
+	NSString* errorFormat = BXLocalizedString (@"relationNotFound", @"Relation %@ was not found in schema %@.", @"Error message for getting or using an entity description.");
+	NSString* reason = [NSString stringWithFormat: errorFormat, name, schemaName];
+	NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+							  title, NSLocalizedDescriptionKey,
+							  title, NSLocalizedFailureReasonErrorKey, 
+							  reason, NSLocalizedRecoverySuggestionErrorKey, 
+							  self, kBXDatabaseContextKey,
+							  nil];
+	NSError *retval = [BXError errorWithDomain: kBXErrorDomain code: kBXErrorNoTableForEntity userInfo: userInfo];
+	return retval;
+}
+
+
+- (BOOL) canCreateEntityDescriptions
+{
+	BOOL retval = NO;
+	@synchronized (mEntitiesBySchemaAndName)
+	{
+		retval = mCanCreateEntities;
+	}
+	return retval;
+}
+
+
 /** 
  * \brief Entity for a table in the schema \em public
  */
-- (BXEntityDescription *) entityForTable: (NSString *) name error: (NSError **) outError
+- (BXEntityDescription *) entityForTable: (NSString *) name
 {
-	return [self entityForTable: name inSchema: @"public" error: outError];
+	return [self entityForTable: name inSchema: @"public"];
 }
 
 
  * \note Unlike PostgreSQL, leaving \em schemaName unspecified does not cause the search path to be used but 
  *       instead will search the \em public schema.
  */
-- (BXEntityDescription *) entityForTable: (NSString *) name inSchema: (NSString *) schemaName error: (NSError **) outError
+- (BXEntityDescription *) entityForTable: (NSString *) name inSchema: (NSString *) schemaName
 {
 	NSMutableDictionary* schemaDict = nil;
 	BXEntityDescription* retval = nil;
  * \param outError If an error occurs, this pointer is set to an NSError instance. May be NULL.
  * \return An NSArray containing BXEntityDescriptions.
  */
-- (NSArray *) entities: (NSError **) outError
+- (NSArray *) entities
 {
 	NSMutableArray* retval = [NSMutableArray array];
 	NSDictionary* schemas = nil;
  *         Each of them will have NSStrings corresponding to relation names as keys and BXEntityDescriptions
  *         as objects.
  */
-- (NSDictionary *) entitiesBySchemaAndName: (id <BXInterface>) interface reload: (BOOL) shouldReload error: (NSError **) outError
+- (NSDictionary *) entitiesBySchemaAndName: (BXDatabaseContext *) context reload: (BOOL) shouldReload error: (NSError **) outError
 {
 	id retval = nil;
+	NSError *localError = nil;
 	if (shouldReload)
 	{
+		id <BXInterface> interface = [context databaseInterface];
 		[interface reloadDatabaseMetadata];
 		@synchronized (mEntitiesBySchemaAndName)
 		{			
 			mCanCreateEntities = YES;
 			[interface prepareForEntityValidation];
-			NSArray* entities = [self entities: outError];
+			NSArray* entities = [self entities];
 			if (entities)
 			{
 				BXEnumerate (currentEntity, e, [entities objectEnumerator])
 					[currentEntity removeValidation];
 				
-				if ([interface validateEntities: entities error: outError])
+				if ([interface validateEntities: entities error: &localError])
 					retval = [[mEntitiesBySchemaAndName copy] autorelease];
+				else
+					[context handleError: localError outError: outError];
 			}
 		}
 	}
 	}
 	return retval;
 }
+
+
+- (BOOL) entity: (NSEntityDescription *) entity existsInSchema: (NSString *) schemaName
+{
+	return ([self matchingEntity: entity inSchema: schemaName] ? YES : NO);
+}
+
+
+- (BXEntityDescription *) matchingEntity: (NSEntityDescription *) entity inSchema: (NSString *) schemaName
+{
+	BXEntityDescription *retval = [self entityForTable: [entity name] inSchema: schemaName];
+	return retval;
+}
 @end
 
 
 	BOOL retval = NO;
 	[interface prepareForEntityValidation];
 	
-	NSArray* entities = [self entities: outError];
+	NSArray* entities = [self entities];
 	if (entities)
 		retval = [interface validateEntities: entities error: outError];
 	return retval;

File Sources/BXDatabaseObjectModelMOMSerialization.mm

 	const BOOL excludeFkeyAttrs           = options & kBXDatabaseObjectModelSerializationOptionExcludeForeignKeyAttributes;
 	const BOOL relationshipsAsOptional    = options & kBXDatabaseObjectModelSerializationOptionCreateRelationshipsAsOptional;
 	
-	NSArray* bxEntities = [objectModel entities: outError];
+	NSArray* bxEntities = [objectModel entities];
 	NSMutableArray* entities = [NSMutableArray arrayWithCapacity: [bxEntities count]];
 	NSMutableSet* entityNames = [NSMutableSet setWithCapacity: [bxEntities count]];
 	NSMutableDictionary* entitiesBySchema = [NSMutableDictionary dictionary];

File Sources/BXDatabaseObjectModelPrivate.h

 //
 
 #import <BaseTen/BXDatabaseObjectModel.h>
+@protocol BXInterface;
 
 
 @interface BXDatabaseObjectModel (PrivateMethods)

File Sources/BXDatabaseObjectModelXMLSerialization.m

 	NSXMLElement* root = [NSXMLElement elementWithName: @"objectModel"];
 	NSXMLDocument* retval = [NSXMLDocument documentWithRootElement: root];
 	
-	NSArray* entities = [objectModel entities: outError];
+	NSArray* entities = [objectModel entities];
 	BXEnumerate (currentEntity, e, [entities objectEnumerator])
 	{
 		NSXMLElement* entity = [NSXMLElement elementWithName: @"entity"];

File Sources/BXDeprecationWarning.h

-//
-// BXDeprecationWarning.h
-// BaseTen
-//
-// Copyright (C) 2009 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import <Foundation/Foundation.h>
-#import <BaseTen/BXExport.h>
-
-BX_EXPORT void BXDeprecationWarning ();

File Sources/BXDeprecationWarning.m

-//
-// BXDeprecationWarning.m
-// BaseTen
-//
-// Copyright (C) 2009 Marko Karppinen & Co. LLC.
-//
-// Before using this software, please review the available licensing options
-// by visiting http://basetenframework.org/licensing/ or by contacting
-// us at sales@karppinen.fi. Without an additional license, this software
-// may be distributed only in compliance with the GNU General Public License.
-//
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License, version 2.0,
-// as published by the Free Software Foundation.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-//
-// $Id$
-//
-
-#import "BXDeprecationWarning.h"
-
-/** 
- * \file 
- * This file contains only one function, BXDeprecationWarning.
- */
-
-
-/**
- * \brief A debugging helper.
- *
- * This function provides a convenient breakpoint. It will be called when
- * deprecated functionality is invoked, presently when relationships with
- * deprecated names are used.
- */
-void
-BXDeprecationWarning ()
-{
-}

File Sources/BXException.m

 
 
 @implementation NSError (BXDatabaseAdditions)
-- (NSException *) BXExceptionWithName: (NSString *) aName
+- (NSException *) BXExceptionWithName: (NSString *) name
 {
     NSMutableDictionary* userInfo = [NSMutableDictionary dictionaryWithDictionary: [self userInfo]];
     [userInfo setObject: self forKey: kBXErrorKey];
-    return [BXException exceptionWithName: kBXExceptionUnhandledError 
+    return [BXException exceptionWithName: name 
 								   reason: [self localizedFailureReason]
 								 userInfo: userInfo];
 }

File Sources/BXExport.h

 #define BX_EXPORT extern
 #endif
 #endif
+
+
+#define BX_DEPRECATED DEPRECATED_ATTRIBUTE

File Sources/BXLogger.h

 // BXLogger.h
 // BaseTen
 //
-// Copyright (C) 2006-2008 Marko Karppinen & Co. LLC.
+// Copyright (C) 2006-2010 Marko Karppinen & Co. LLC.
 //
 // Before using this software, please review the available licensing options
 // by visiting http://basetenframework.org/licensing/ or by contacting
 #define BXLogFatal(message, ...)   do { if (BXLogLevel >= kBXLogLevelFatal)   BXLog (BX_LOG_ARGS, kBXLogLevelFatal,   message , ##__VA_ARGS__); } while (0)
 
 #define BXAssertLog(assertion, message, ...) \
-	do { if (! (assertion)) { BXLog (BX_LOG_ARGS, kBXLogLevelError, message , ##__VA_ARGS__); BXAssertionDebug (); }} while (0)
+	do { if (! (assertion)) { BXLogError (message , ##__VA_ARGS__); BXAssertionDebug (); }} while (0)
 #define BXAssertVoidReturn(assertion, message, ...) \
-	do { if (! (assertion)) { BXLog (BX_LOG_ARGS, kBXLogLevelError, message , ##__VA_ARGS__); BXAssertionDebug (); return; }} while (0)
+	do { if (! (assertion)) { BXLogError (message , ##__VA_ARGS__); BXAssertionDebug (); return; }} while (0)
 #define BXAssertValueReturn(assertion, retval, message, ...) \
-	do { if (! (assertion)) { BXLog (BX_LOG_ARGS, kBXLogLevelError, message , ##__VA_ARGS__); BXAssertionDebug (); return (retval); }} while (0)
+	do { if (! (assertion)) { BXLogError (message , ##__VA_ARGS__); BXAssertionDebug (); return (retval); }} while (0)
+
+#define BXDeprecationLogSpecific(...) \
+	do { BXLogWarning (__VA_ARGS__); BXDeprecationWarning (); } while (0)
+#define BXDeprecationLog() BXDeprecationLogSpecific(@"This method or function has been deprecated.");
+
+
 //C function variants.
-#define BXCAssertLog(...) BXCAssertLog(__VA_ARGS__)
+#define BXCAssertLog(...) BXAssertLog(__VA_ARGS__)
 #define BXCAssertValueReturn(...) BXAssertValueReturn(__VA_ARGS__)
 #define BXCAssertVoidReturn(...) BXAssertVoidReturn(__VA_ARGS__)
+#define BXCDeprecationLogSpecific(...) BXDeprecationLogSpecific(__VA_ARGS__)
+#define BXCDeprecationLog() BXDeprecationLog()
 
 
 #define Expect( X )	BXAssertValueReturn( X, nil, @"Expected " #X " to evaluate to true.");
  * \warning This function is not thread-safe.
  */
 BX_EXPORT void BXSetLogLevel (enum BXLogLevel level);
-BX_EXPORT void BXLog (const char* fileName, const char* functionName, void* functionAddress, int line, enum BXLogLevel level, id messageFmt, ...);
-BX_EXPORT void BXLog_v (const char* fileName, const char* functionName, void* functionAddress, int line, enum BXLogLevel level, id messageFmt, va_list args);
+
 
 /**
  * \brief A debugging helper.
  * user code.
  */
 BX_EXPORT void BXAssertionDebug ();
+
+
+/**
+ * \brief A debugging helper.
+ *
+ * This function provides a convenient breakpoint. It will be called when
+ * deprecated functionality is invoked, presently when relationships with
+ * deprecated names are used.
+ */
+BX_EXPORT void BXDeprecationWarning ();
+
+
+BX_EXPORT void BXLog (const char* fileName, const char* functionName, void* functionAddress, int line, enum BXLogLevel level, id messageFmt, ...);
+BX_EXPORT void BXLog_v (const char* fileName, const char* functionName, void* functionAddress, int line, enum BXLogLevel level, id messageFmt, va_list args);

File Sources/BXLogger.m

 
 void BXAssertionDebug ()
 {
-	BXLogInfo (@"Break on BXAssertionDebug to inspect.");
+	BXLogError (@"Break on BXAssertionDebug to inspect.");
+}
+
+void
+BXDeprecationWarning ()
+{
+	BXLogError (@"Break on BXDeprecationWarning to inspect.");
 }
 
 void BXLog (const char* fileName, const char* functionName, void* functionAddress, int line, enum BXLogLevel level, id messageFmt, ...)

File Sources/BXManyToManyRelationshipDescription.m

 #import "BXLogger.h"
 #import "BXDatabaseObjectPrivate.h"
 #import "BXEnumerate.h"
-#import "BXDeprecationWarning.h"
 
 
 @implementation BXManyToManyRelationshipDescription

File Sources/BXPGClearLocksHandler.m

 			//Get the entity.
 			NSString* tableName = [table name];
 			NSString* schemaName = [table schemaName];
-			BXEntityDescription* entity = [ctx entityForTable: tableName inSchema: schemaName error: &error];
+			BXEntityDescription* entity = [[ctx databaseObjectModel] entityForTable: tableName inSchema: schemaName];
 			if (! entity) goto error;
 			
 			while ([unlockedRows advanceRow])

File Sources/BXPGEntityImporter.m

 								 inSchema: (NSString *) schemaName
 									error: (NSError **) outError
 {
-	return [mContext matchingEntity: importedEntity inSchema: schemaName error: outError];
+	return [[mContext databaseObjectModel] matchingEntity: importedEntity inSchema: schemaName];
 }
 
 

File Sources/BXPGInterface.m

 {
 	//Warm-up the cache by ensuring that an entity exists for each table.
 	BXDatabaseObjectModel* objectModel = [mContext databaseObjectModel];
+	ExpectV ([objectModel canCreateEntityDescriptions]);
 	BXEnumerate (schema, e, [[[mTransactionHandler databaseDescription] schemasByName] objectEnumerator])
 	{
 		BXEnumerate (table, e, [[schema allTables] objectEnumerator])
 		{
-			[objectModel entityForTable: [table name] inSchema: [table schemaName] error: NULL];
+			[objectModel entityForTable: [table name] inSchema: [table schemaName]];
 		}
 	}
 }
 {
 	struct table_inheritance_st* ctx = (struct table_inheritance_st *) ctxPointer;
 	BXPGTableDescription* table = [ctx->ti_database_description tableWithOid: currentOid];
-	BXEntityDescription* entity = [ctx->ti_object_model entityForTable: [table name] inSchema: [table schemaName] error: NULL];
+	BXEntityDescription* entity = [ctx->ti_object_model entityForTable: [table name] inSchema: [table schemaName]];
 	[ctx->ti_super_entities addObject: entity];
 }
 
 					NSString* name = [currentRel objectForKey: @"name"];
 					NSString* dstrelname = [currentRel objectForKey: @"dstrelname"];
 					NSString* dstnspname = [currentRel objectForKey: @"dstnspname"];
-					BXEntityDescription* dstEntity = [objectModel entityForTable: dstrelname inSchema: dstnspname error: NULL];
+					BXEntityDescription* dstEntity = [objectModel entityForTable: dstrelname inSchema: dstnspname];
 					switch (kind)
 					{
 						case 't':
 						
 						NSString* helperrelname = [currentRel objectForKey: @"helperrelname"];
 						NSString* helpernspname = [currentRel objectForKey: @"helpernspname"];
-						BXEntityDescription* helper = [objectModel entityForTable: helperrelname inSchema: helpernspname error: NULL];
+						BXEntityDescription* helper = [objectModel entityForTable: helperrelname inSchema: helpernspname];
 						
 						//The helper entity may get changed by trigger if rows are deleted from source
 						//and destination entities.

File Sources/BXRelationshipDescription.m

 #import "BXProbes.h"
 #import "BXAttributeDescriptionPrivate.h"
 #import "BXEnumerate.h"
-#import "BXDeprecationWarning.h"
 
 
 /**
     BXAssertValueReturn ([[self entity] isEqual: [databaseObject entity]], nil, 
 						 @"Expected object's entity to match. Self: %@ aDatabaseObject: %@", self, databaseObject);
 	
-	if (mIsDeprecated) BXDeprecationWarning ();
+	if (mIsDeprecated) 
+	{
+		BXDeprecationLogSpecific (@"The relationship name %@ in %@.%@ has been deprecated.",
+								  mName, [mEntity schemaName], [mEntity name]);
+	}
 	
 	id retval = nil;
 	//If we can determine an object ID, fetch the target object from the context's cache.
 	ExpectR (databaseObject, NO);
 	ExpectR ([[self entity] isEqual: [databaseObject entity]], NO);
 	
-	if (mIsDeprecated) BXDeprecationWarning ();
+	if (mIsDeprecated) 
+	{
+		BXDeprecationLogSpecific (@"The relationship name %@ in %@.%@ has been deprecated.",
+								  mName, [mEntity schemaName], [mEntity name]);
+	}
 	
 	BOOL retval = NO;
 	BXRelationshipDescription* inverse = [self inverseRelationship];