From: helge Date: Fri, 20 Aug 2004 17:27:20 +0000 (+0000) Subject: more directory hierarchy reorganisations, X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=854ec8f6329431a7d5b12e6c265f1a6c2f014e8a;p=sope more directory hierarchy reorganisations, moved in our GDL fork git-svn-id: http://svn.opengroupware.org/SOPE/trunk@5 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- diff --git a/GNUmakefile b/GNUmakefile index 668c6bd5..8244c86b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,13 +1,15 @@ -# $Id$ - # Note: could be that it may not fully compile 'inline' include $(GNUSTEP_MAKEFILES)/common.make SUBPROJECTS += \ - skyrix-xml \ - skyrix-core \ - skyrix-sope + sope-xml \ + sope-core \ + sope-mime \ + sope-appserver \ + sope-ldap \ + sope-ical \ + sope-gdl1 \ -include $(GNUSTEP_MAKEFILES)/GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/aggregate.make diff --git a/sope-xml/CFXMLSaxDriver/CFXMLSaxDriver-Info.plist b/Recycler/CFXMLSaxDriver/CFXMLSaxDriver-Info.plist similarity index 100% rename from sope-xml/CFXMLSaxDriver/CFXMLSaxDriver-Info.plist rename to Recycler/CFXMLSaxDriver/CFXMLSaxDriver-Info.plist diff --git a/sope-xml/CFXMLSaxDriver/CFXMLSaxDriver.h b/Recycler/CFXMLSaxDriver/CFXMLSaxDriver.h similarity index 100% rename from sope-xml/CFXMLSaxDriver/CFXMLSaxDriver.h rename to Recycler/CFXMLSaxDriver/CFXMLSaxDriver.h diff --git a/sope-xml/CFXMLSaxDriver/CFXMLSaxDriver.m b/Recycler/CFXMLSaxDriver/CFXMLSaxDriver.m similarity index 100% rename from sope-xml/CFXMLSaxDriver/CFXMLSaxDriver.m rename to Recycler/CFXMLSaxDriver/CFXMLSaxDriver.m diff --git a/sope-appserver/NGJavaScript/COPYING b/Recycler/CFXMLSaxDriver/COPYING similarity index 100% rename from sope-appserver/NGJavaScript/COPYING rename to Recycler/CFXMLSaxDriver/COPYING diff --git a/sope-xml/CFXMLSaxDriver/ChangeLog b/Recycler/CFXMLSaxDriver/ChangeLog similarity index 100% rename from sope-xml/CFXMLSaxDriver/ChangeLog rename to Recycler/CFXMLSaxDriver/ChangeLog diff --git a/sope-xml/CFXMLSaxDriver/README b/Recycler/CFXMLSaxDriver/README similarity index 100% rename from sope-xml/CFXMLSaxDriver/README rename to Recycler/CFXMLSaxDriver/README diff --git a/sope-xml/CFXMLSaxDriver/bundle-info.plist b/Recycler/CFXMLSaxDriver/bundle-info.plist similarity index 100% rename from sope-xml/CFXMLSaxDriver/bundle-info.plist rename to Recycler/CFXMLSaxDriver/bundle-info.plist diff --git a/sope-appserver/NGObjDOM/COPYING b/Recycler/ExpatSaxDriver/COPYING similarity index 100% rename from sope-appserver/NGObjDOM/COPYING rename to Recycler/ExpatSaxDriver/COPYING diff --git a/sope-xml/ExpatSaxDriver/ExpatSaxDriver.m b/Recycler/ExpatSaxDriver/ExpatSaxDriver.m similarity index 100% rename from sope-xml/ExpatSaxDriver/ExpatSaxDriver.m rename to Recycler/ExpatSaxDriver/ExpatSaxDriver.m diff --git a/sope-xml/ExpatSaxDriver/GNUmakefile b/Recycler/ExpatSaxDriver/GNUmakefile similarity index 100% rename from sope-xml/ExpatSaxDriver/GNUmakefile rename to Recycler/ExpatSaxDriver/GNUmakefile diff --git a/sope-xml/ExpatSaxDriver/README b/Recycler/ExpatSaxDriver/README similarity index 100% rename from sope-xml/ExpatSaxDriver/README rename to Recycler/ExpatSaxDriver/README diff --git a/sope-xml/ExpatSaxDriver/bundle-info.plist b/Recycler/ExpatSaxDriver/bundle-info.plist similarity index 100% rename from sope-xml/ExpatSaxDriver/bundle-info.plist rename to Recycler/ExpatSaxDriver/bundle-info.plist diff --git a/sope-xml/ExpatSaxDriver/common.h b/Recycler/ExpatSaxDriver/common.h similarity index 100% rename from sope-xml/ExpatSaxDriver/common.h rename to Recycler/ExpatSaxDriver/common.h diff --git a/sope-xml/ExpatSaxDriver/unicode.h b/Recycler/ExpatSaxDriver/unicode.h similarity index 100% rename from sope-xml/ExpatSaxDriver/unicode.h rename to Recycler/ExpatSaxDriver/unicode.h diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/COPYING b/Recycler/NGJavaScript/COPYING similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/COPYING rename to Recycler/NGJavaScript/COPYING diff --git a/sope-appserver/NGJavaScript/ChangeLog b/Recycler/NGJavaScript/ChangeLog similarity index 99% rename from sope-appserver/NGJavaScript/ChangeLog rename to Recycler/NGJavaScript/ChangeLog index 9c262b86..8323683c 100644 --- a/sope-appserver/NGJavaScript/ChangeLog +++ b/Recycler/NGJavaScript/ChangeLog @@ -1,5 +1,7 @@ 2004-08-20 Helge Hess + * deprecated and moved to Recycler + * moved to SOPE 4.3 (v4.3.31) 2004-08-17 Helge Hess diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/EODataSource+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/EODataSource+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/EODataSource+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/EODataSource+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.h b/Recycler/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.h similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.h rename to Recycler/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.h diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.m b/Recycler/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.m rename to Recycler/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/EONull+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/EONull+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/EONull+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/EONull+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/GNUmakefile b/Recycler/NGJavaScript/Core+JS.subproj/GNUmakefile similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/GNUmakefile rename to Recycler/NGJavaScript/Core+JS.subproj/GNUmakefile diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/GNUmakefile.preamble b/Recycler/NGJavaScript/Core+JS.subproj/GNUmakefile.preamble similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/GNUmakefile.preamble rename to Recycler/NGJavaScript/Core+JS.subproj/GNUmakefile.preamble diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NGFileManager+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NGFileManager+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NGFileManager+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NGFileManager+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSArray+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NSArray+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSArray+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NSArray+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSDate+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NSDate+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSDate+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NSDate+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSDictionary+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NSDictionary+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSDictionary+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NSDictionary+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSNumber+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NSNumber+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSNumber+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NSNumber+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSObject+JS.h b/Recycler/NGJavaScript/Core+JS.subproj/NSObject+JS.h similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSObject+JS.h rename to Recycler/NGJavaScript/Core+JS.subproj/NSObject+JS.h diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSObject+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NSObject+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSObject+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NSObject+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSString+JS.h b/Recycler/NGJavaScript/Core+JS.subproj/NSString+JS.h similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSString+JS.h rename to Recycler/NGJavaScript/Core+JS.subproj/NSString+JS.h diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSString+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NSString+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSString+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NSString+JS.m diff --git a/sope-appserver/NGJavaScript/Core+JS.subproj/NSUserDefaults+JS.m b/Recycler/NGJavaScript/Core+JS.subproj/NSUserDefaults+JS.m similarity index 100% rename from sope-appserver/NGJavaScript/Core+JS.subproj/NSUserDefaults+JS.m rename to Recycler/NGJavaScript/Core+JS.subproj/NSUserDefaults+JS.m diff --git a/sope-appserver/NGJavaScript/GNUmakefile b/Recycler/NGJavaScript/GNUmakefile similarity index 100% rename from sope-appserver/NGJavaScript/GNUmakefile rename to Recycler/NGJavaScript/GNUmakefile diff --git a/sope-appserver/NGJavaScript/GNUmakefile.preamble b/Recycler/NGJavaScript/GNUmakefile.preamble similarity index 100% rename from sope-appserver/NGJavaScript/GNUmakefile.preamble rename to Recycler/NGJavaScript/GNUmakefile.preamble diff --git a/sope-appserver/NGJavaScript/JSObjectOps.m b/Recycler/NGJavaScript/JSObjectOps.m similarity index 100% rename from sope-appserver/NGJavaScript/JSObjectOps.m rename to Recycler/NGJavaScript/JSObjectOps.m diff --git a/sope-appserver/NGJavaScript/NGJavaScript-Info.plist b/Recycler/NGJavaScript/NGJavaScript-Info.plist similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScript-Info.plist rename to Recycler/NGJavaScript/NGJavaScript-Info.plist diff --git a/sope-appserver/NGJavaScript/NGJavaScript.h b/Recycler/NGJavaScript/NGJavaScript.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScript.h rename to Recycler/NGJavaScript/NGJavaScript.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptArray.m b/Recycler/NGJavaScript/NGJavaScriptArray.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptArray.m rename to Recycler/NGJavaScript/NGJavaScriptArray.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptCallable.h b/Recycler/NGJavaScript/NGJavaScriptCallable.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptCallable.h rename to Recycler/NGJavaScript/NGJavaScriptCallable.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptCallable.m b/Recycler/NGJavaScript/NGJavaScriptCallable.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptCallable.m rename to Recycler/NGJavaScript/NGJavaScriptCallable.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptContext.h b/Recycler/NGJavaScript/NGJavaScriptContext.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptContext.h rename to Recycler/NGJavaScript/NGJavaScriptContext.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptContext.m b/Recycler/NGJavaScript/NGJavaScriptContext.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptContext.m rename to Recycler/NGJavaScript/NGJavaScriptContext.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptDecls.h b/Recycler/NGJavaScript/NGJavaScriptDecls.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptDecls.h rename to Recycler/NGJavaScript/NGJavaScriptDecls.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptError.h b/Recycler/NGJavaScript/NGJavaScriptError.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptError.h rename to Recycler/NGJavaScript/NGJavaScriptError.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptError.m b/Recycler/NGJavaScript/NGJavaScriptError.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptError.m rename to Recycler/NGJavaScript/NGJavaScriptError.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptFunction.h b/Recycler/NGJavaScript/NGJavaScriptFunction.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptFunction.h rename to Recycler/NGJavaScript/NGJavaScriptFunction.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptFunction.m b/Recycler/NGJavaScript/NGJavaScriptFunction.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptFunction.m rename to Recycler/NGJavaScript/NGJavaScriptFunction.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptLanguage.m b/Recycler/NGJavaScript/NGJavaScriptLanguage.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptLanguage.m rename to Recycler/NGJavaScript/NGJavaScriptLanguage.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObjCClassInfo.h b/Recycler/NGJavaScript/NGJavaScriptObjCClassInfo.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObjCClassInfo.h rename to Recycler/NGJavaScript/NGJavaScriptObjCClassInfo.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObjCClassInfo.m b/Recycler/NGJavaScript/NGJavaScriptObjCClassInfo.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObjCClassInfo.m rename to Recycler/NGJavaScript/NGJavaScriptObjCClassInfo.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObject.h b/Recycler/NGJavaScript/NGJavaScriptObject.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObject.h rename to Recycler/NGJavaScript/NGJavaScriptObject.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObject.m b/Recycler/NGJavaScript/NGJavaScriptObject.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObject.m rename to Recycler/NGJavaScript/NGJavaScriptObject.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObjectHandler.h b/Recycler/NGJavaScript/NGJavaScriptObjectHandler.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObjectHandler.h rename to Recycler/NGJavaScript/NGJavaScriptObjectHandler.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObjectHandler.m b/Recycler/NGJavaScript/NGJavaScriptObjectHandler.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObjectHandler.m rename to Recycler/NGJavaScript/NGJavaScriptObjectHandler.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObjectMappingContext.h b/Recycler/NGJavaScript/NGJavaScriptObjectMappingContext.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObjectMappingContext.h rename to Recycler/NGJavaScript/NGJavaScriptObjectMappingContext.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptObjectMappingContext.m b/Recycler/NGJavaScript/NGJavaScriptObjectMappingContext.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptObjectMappingContext.m rename to Recycler/NGJavaScript/NGJavaScriptObjectMappingContext.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptRuntime.h b/Recycler/NGJavaScript/NGJavaScriptRuntime.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptRuntime.h rename to Recycler/NGJavaScript/NGJavaScriptRuntime.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptRuntime.m b/Recycler/NGJavaScript/NGJavaScriptRuntime.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptRuntime.m rename to Recycler/NGJavaScript/NGJavaScriptRuntime.m diff --git a/sope-appserver/NGJavaScript/NGJavaScriptShadow.h b/Recycler/NGJavaScript/NGJavaScriptShadow.h similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptShadow.h rename to Recycler/NGJavaScript/NGJavaScriptShadow.h diff --git a/sope-appserver/NGJavaScript/NGJavaScriptShadow.m b/Recycler/NGJavaScript/NGJavaScriptShadow.m similarity index 100% rename from sope-appserver/NGJavaScript/NGJavaScriptShadow.m rename to Recycler/NGJavaScript/NGJavaScriptShadow.m diff --git a/sope-appserver/NGJavaScript/README b/Recycler/NGJavaScript/README similarity index 100% rename from sope-appserver/NGJavaScript/README rename to Recycler/NGJavaScript/README diff --git a/sope-appserver/NGJavaScript/ScriptLanguages.plist b/Recycler/NGJavaScript/ScriptLanguages.plist similarity index 100% rename from sope-appserver/NGJavaScript/ScriptLanguages.plist rename to Recycler/NGJavaScript/ScriptLanguages.plist diff --git a/sope-appserver/NGJavaScript/TODO b/Recycler/NGJavaScript/TODO similarity index 100% rename from sope-appserver/NGJavaScript/TODO rename to Recycler/NGJavaScript/TODO diff --git a/sope-appserver/NGJavaScript/Version b/Recycler/NGJavaScript/Version similarity index 100% rename from sope-appserver/NGJavaScript/Version rename to Recycler/NGJavaScript/Version diff --git a/sope-appserver/NGJavaScript/common.h b/Recycler/NGJavaScript/common.h similarity index 100% rename from sope-appserver/NGJavaScript/common.h rename to Recycler/NGJavaScript/common.h diff --git a/sope-appserver/NGJavaScript/dummy.m b/Recycler/NGJavaScript/dummy.m similarity index 100% rename from sope-appserver/NGJavaScript/dummy.m rename to Recycler/NGJavaScript/dummy.m diff --git a/sope-appserver/NGJavaScript/globals.h b/Recycler/NGJavaScript/globals.h similarity index 100% rename from sope-appserver/NGJavaScript/globals.h rename to Recycler/NGJavaScript/globals.h diff --git a/sope-appserver/NGJavaScript/globals.m b/Recycler/NGJavaScript/globals.m similarity index 100% rename from sope-appserver/NGJavaScript/globals.m rename to Recycler/NGJavaScript/globals.m diff --git a/sope-appserver/NGJavaScript/jsobjops.m b/Recycler/NGJavaScript/jsobjops.m similarity index 100% rename from sope-appserver/NGJavaScript/jsobjops.m rename to Recycler/NGJavaScript/jsobjops.m diff --git a/sope-appserver/NGJavaScript/testjs.m b/Recycler/NGJavaScript/testjs.m similarity index 100% rename from sope-appserver/NGJavaScript/testjs.m rename to Recycler/NGJavaScript/testjs.m diff --git a/sope-appserver/NGJavaScript/tests/Blah.h b/Recycler/NGJavaScript/tests/Blah.h similarity index 100% rename from sope-appserver/NGJavaScript/tests/Blah.h rename to Recycler/NGJavaScript/tests/Blah.h diff --git a/sope-appserver/NGJavaScript/tests/Blah.m b/Recycler/NGJavaScript/tests/Blah.m similarity index 100% rename from sope-appserver/NGJavaScript/tests/Blah.m rename to Recycler/NGJavaScript/tests/Blah.m diff --git a/sope-appserver/NGJavaScript/tests/Combined.h b/Recycler/NGJavaScript/tests/Combined.h similarity index 100% rename from sope-appserver/NGJavaScript/tests/Combined.h rename to Recycler/NGJavaScript/tests/Combined.h diff --git a/sope-appserver/NGJavaScript/tests/Combined.m b/Recycler/NGJavaScript/tests/Combined.m similarity index 100% rename from sope-appserver/NGJavaScript/tests/Combined.m rename to Recycler/NGJavaScript/tests/Combined.m diff --git a/sope-appserver/NGJavaScript/tests/GNUmakefile b/Recycler/NGJavaScript/tests/GNUmakefile similarity index 100% rename from sope-appserver/NGJavaScript/tests/GNUmakefile rename to Recycler/NGJavaScript/tests/GNUmakefile diff --git a/sope-appserver/NGJavaScript/tests/JSArchivingTests.h b/Recycler/NGJavaScript/tests/JSArchivingTests.h similarity index 100% rename from sope-appserver/NGJavaScript/tests/JSArchivingTests.h rename to Recycler/NGJavaScript/tests/JSArchivingTests.h diff --git a/sope-appserver/NGJavaScript/tests/JSArchivingTests.m b/Recycler/NGJavaScript/tests/JSArchivingTests.m similarity index 100% rename from sope-appserver/NGJavaScript/tests/JSArchivingTests.m rename to Recycler/NGJavaScript/tests/JSArchivingTests.m diff --git a/sope-appserver/NGJavaScript/tests/JSBridgeTests.h b/Recycler/NGJavaScript/tests/JSBridgeTests.h similarity index 100% rename from sope-appserver/NGJavaScript/tests/JSBridgeTests.h rename to Recycler/NGJavaScript/tests/JSBridgeTests.h diff --git a/sope-appserver/NGJavaScript/tests/JSBridgeTests.m b/Recycler/NGJavaScript/tests/JSBridgeTests.m similarity index 100% rename from sope-appserver/NGJavaScript/tests/JSBridgeTests.m rename to Recycler/NGJavaScript/tests/JSBridgeTests.m diff --git a/sope-appserver/NGJavaScript/tests/JSTest.h b/Recycler/NGJavaScript/tests/JSTest.h similarity index 100% rename from sope-appserver/NGJavaScript/tests/JSTest.h rename to Recycler/NGJavaScript/tests/JSTest.h diff --git a/sope-appserver/NGJavaScript/tests/JSTest.m b/Recycler/NGJavaScript/tests/JSTest.m similarity index 100% rename from sope-appserver/NGJavaScript/tests/JSTest.m rename to Recycler/NGJavaScript/tests/JSTest.m diff --git a/sope-appserver/NGJavaScript/tests/MyNum.h b/Recycler/NGJavaScript/tests/MyNum.h similarity index 100% rename from sope-appserver/NGJavaScript/tests/MyNum.h rename to Recycler/NGJavaScript/tests/MyNum.h diff --git a/sope-appserver/NGJavaScript/tests/MyNum.m b/Recycler/NGJavaScript/tests/MyNum.m similarity index 100% rename from sope-appserver/NGJavaScript/tests/MyNum.m rename to Recycler/NGJavaScript/tests/MyNum.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/COPYING b/Recycler/NGObjDOM/COPYING similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/COPYING rename to Recycler/NGObjDOM/COPYING diff --git a/mod_ngobjweb/COPYRIGHT b/Recycler/NGObjDOM/COPYRIGHT similarity index 100% rename from mod_ngobjweb/COPYRIGHT rename to Recycler/NGObjDOM/COPYRIGHT diff --git a/sope-appserver/NGObjDOM/ChangeLog b/Recycler/NGObjDOM/ChangeLog similarity index 99% rename from sope-appserver/NGObjDOM/ChangeLog rename to Recycler/NGObjDOM/ChangeLog index e11735c9..1d96ab36 100644 --- a/sope-appserver/NGObjDOM/ChangeLog +++ b/Recycler/NGObjDOM/ChangeLog @@ -1,5 +1,7 @@ 2004-08-20 Helge Hess + * deprecated and moved to Recycler + * moved to SOPE 4.3 (v4.3.25) 2004-07-19 Helge Hess diff --git a/sope-appserver/NGObjDOM/XUL.subproj/COPYING b/Recycler/NGObjDOM/Dynamic.subproj/COPYING similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/COPYING rename to Recycler/NGObjDOM/Dynamic.subproj/COPYING diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ChangeLog b/Recycler/NGObjDOM/Dynamic.subproj/ChangeLog similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ChangeLog rename to Recycler/NGObjDOM/Dynamic.subproj/ChangeLog diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/GNUmakefile b/Recycler/NGObjDOM/Dynamic.subproj/GNUmakefile similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/GNUmakefile rename to Recycler/NGObjDOM/Dynamic.subproj/GNUmakefile diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.h b/Recycler/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.h similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.h rename to Recycler/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.h diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.m b/Recycler/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_checkbox.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_checkbox.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_checkbox.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_checkbox.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_collapsible.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_collapsible.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_collapsible.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_collapsible.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_datefield.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_datefield.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_datefield.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_datefield.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_fieldset.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_fieldset.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_fieldset.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_fieldset.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_foreach.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_foreach.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_foreach.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_foreach.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_form.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_form.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_form.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_form.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.h b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.h similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.h rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.h diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_if.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_if.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_if.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_if.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_multiselection.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_multiselection.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_multiselection.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_multiselection.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_nbsp.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_nbsp.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_nbsp.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_nbsp.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_popupbutton.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_popupbutton.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_popupbutton.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_popupbutton.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_radiobutton.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_radiobutton.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_radiobutton.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_radiobutton.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.h b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.h similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.h rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.h diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_string.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_string.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_string.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_string.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_switch.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_switch.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_switch.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_switch.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.h b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.h similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.h rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.h diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tabledata.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tabledata.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tabledata.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tabledata.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableheader.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableheader.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableheader.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableheader.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.h b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.h similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.h rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.h diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tabview.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tabview.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tabview.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tabview.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_viewertitle.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_viewertitle.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_viewertitle.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_viewertitle.m diff --git a/sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_with.m b/Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_with.m similarity index 100% rename from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_with.m rename to Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_with.m diff --git a/sope-appserver/NGObjDOM/GNUmakefile b/Recycler/NGObjDOM/GNUmakefile similarity index 100% rename from sope-appserver/NGObjDOM/GNUmakefile rename to Recycler/NGObjDOM/GNUmakefile diff --git a/sope-appserver/NGObjDOM/GNUmakefile.postamble b/Recycler/NGObjDOM/GNUmakefile.postamble similarity index 100% rename from sope-appserver/NGObjDOM/GNUmakefile.postamble rename to Recycler/NGObjDOM/GNUmakefile.postamble diff --git a/sope-appserver/NGObjDOM/GNUmakefile.preamble b/Recycler/NGObjDOM/GNUmakefile.preamble similarity index 100% rename from sope-appserver/NGObjDOM/GNUmakefile.preamble rename to Recycler/NGObjDOM/GNUmakefile.preamble diff --git a/sope-appserver/NGObjDOM/NGObjDOM-Info.plist b/Recycler/NGObjDOM/NGObjDOM-Info.plist similarity index 100% rename from sope-appserver/NGObjDOM/NGObjDOM-Info.plist rename to Recycler/NGObjDOM/NGObjDOM-Info.plist diff --git a/sope-appserver/NGObjDOM/NGObjDOM.h b/Recycler/NGObjDOM/NGObjDOM.h similarity index 100% rename from sope-appserver/NGObjDOM/NGObjDOM.h rename to Recycler/NGObjDOM/NGObjDOM.h diff --git a/sope-appserver/NGObjDOM/NGObjDOMModule.m b/Recycler/NGObjDOM/NGObjDOMModule.m similarity index 100% rename from sope-appserver/NGObjDOM/NGObjDOMModule.m rename to Recycler/NGObjDOM/NGObjDOMModule.m diff --git a/sope-appserver/NGObjDOM/ODNamespaces.h b/Recycler/NGObjDOM/ODNamespaces.h similarity index 100% rename from sope-appserver/NGObjDOM/ODNamespaces.h rename to Recycler/NGObjDOM/ODNamespaces.h diff --git a/sope-appserver/NGObjDOM/ODNodeRenderer+attributes.h b/Recycler/NGObjDOM/ODNodeRenderer+attributes.h similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRenderer+attributes.h rename to Recycler/NGObjDOM/ODNodeRenderer+attributes.h diff --git a/sope-appserver/NGObjDOM/ODNodeRenderer+attributes.m b/Recycler/NGObjDOM/ODNodeRenderer+attributes.m similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRenderer+attributes.m rename to Recycler/NGObjDOM/ODNodeRenderer+attributes.m diff --git a/sope-appserver/NGObjDOM/ODNodeRenderer.h b/Recycler/NGObjDOM/ODNodeRenderer.h similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRenderer.h rename to Recycler/NGObjDOM/ODNodeRenderer.h diff --git a/sope-appserver/NGObjDOM/ODNodeRenderer.m b/Recycler/NGObjDOM/ODNodeRenderer.m similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRenderer.m rename to Recycler/NGObjDOM/ODNodeRenderer.m diff --git a/sope-appserver/NGObjDOM/ODNodeRendererFactory.h b/Recycler/NGObjDOM/ODNodeRendererFactory.h similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRendererFactory.h rename to Recycler/NGObjDOM/ODNodeRendererFactory.h diff --git a/sope-appserver/NGObjDOM/ODNodeRendererFactory.m b/Recycler/NGObjDOM/ODNodeRendererFactory.m similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRendererFactory.m rename to Recycler/NGObjDOM/ODNodeRendererFactory.m diff --git a/sope-appserver/NGObjDOM/ODNodeRendererFactorySet.h b/Recycler/NGObjDOM/ODNodeRendererFactorySet.h similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRendererFactorySet.h rename to Recycler/NGObjDOM/ODNodeRendererFactorySet.h diff --git a/sope-appserver/NGObjDOM/ODNodeRendererFactorySet.m b/Recycler/NGObjDOM/ODNodeRendererFactorySet.m similarity index 100% rename from sope-appserver/NGObjDOM/ODNodeRendererFactorySet.m rename to Recycler/NGObjDOM/ODNodeRendererFactorySet.m diff --git a/sope-appserver/NGObjDOM/ODREmbedComponent.h b/Recycler/NGObjDOM/ODREmbedComponent.h similarity index 100% rename from sope-appserver/NGObjDOM/ODREmbedComponent.h rename to Recycler/NGObjDOM/ODREmbedComponent.h diff --git a/sope-appserver/NGObjDOM/ODREmbedComponent.m b/Recycler/NGObjDOM/ODREmbedComponent.m similarity index 100% rename from sope-appserver/NGObjDOM/ODREmbedComponent.m rename to Recycler/NGObjDOM/ODREmbedComponent.m diff --git a/sope-appserver/NGObjDOM/ODRGenericTag.h b/Recycler/NGObjDOM/ODRGenericTag.h similarity index 100% rename from sope-appserver/NGObjDOM/ODRGenericTag.h rename to Recycler/NGObjDOM/ODRGenericTag.h diff --git a/sope-appserver/NGObjDOM/ODRGenericTag.m b/Recycler/NGObjDOM/ODRGenericTag.m similarity index 100% rename from sope-appserver/NGObjDOM/ODRGenericTag.m rename to Recycler/NGObjDOM/ODRGenericTag.m diff --git a/sope-appserver/NGObjDOM/ODRNodeText.h b/Recycler/NGObjDOM/ODRNodeText.h similarity index 100% rename from sope-appserver/NGObjDOM/ODRNodeText.h rename to Recycler/NGObjDOM/ODRNodeText.h diff --git a/sope-appserver/NGObjDOM/ODRNodeText.m b/Recycler/NGObjDOM/ODRNodeText.m similarity index 100% rename from sope-appserver/NGObjDOM/ODRNodeText.m rename to Recycler/NGObjDOM/ODRNodeText.m diff --git a/sope-appserver/NGObjDOM/ODRWebObject.h b/Recycler/NGObjDOM/ODRWebObject.h similarity index 100% rename from sope-appserver/NGObjDOM/ODRWebObject.h rename to Recycler/NGObjDOM/ODRWebObject.h diff --git a/sope-appserver/NGObjDOM/ODRWebObject.m b/Recycler/NGObjDOM/ODRWebObject.m similarity index 100% rename from sope-appserver/NGObjDOM/ODRWebObject.m rename to Recycler/NGObjDOM/ODRWebObject.m diff --git a/sope-appserver/NGObjDOM/ODR_bind_collapsible.h b/Recycler/NGObjDOM/ODR_bind_collapsible.h similarity index 100% rename from sope-appserver/NGObjDOM/ODR_bind_collapsible.h rename to Recycler/NGObjDOM/ODR_bind_collapsible.h diff --git a/sope-appserver/NGObjDOM/ODR_bind_fieldset.h b/Recycler/NGObjDOM/ODR_bind_fieldset.h similarity index 100% rename from sope-appserver/NGObjDOM/ODR_bind_fieldset.h rename to Recycler/NGObjDOM/ODR_bind_fieldset.h diff --git a/sope-appserver/NGObjDOM/ODR_bind_tableview.h b/Recycler/NGObjDOM/ODR_bind_tableview.h similarity index 100% rename from sope-appserver/NGObjDOM/ODR_bind_tableview.h rename to Recycler/NGObjDOM/ODR_bind_tableview.h diff --git a/sope-appserver/NGObjDOM/ODR_bind_tabview.h b/Recycler/NGObjDOM/ODR_bind_tabview.h similarity index 100% rename from sope-appserver/NGObjDOM/ODR_bind_tabview.h rename to Recycler/NGObjDOM/ODR_bind_tabview.h diff --git a/sope-appserver/NGObjDOM/ODR_bind_viewertitle.h b/Recycler/NGObjDOM/ODR_bind_viewertitle.h similarity index 100% rename from sope-appserver/NGObjDOM/ODR_bind_viewertitle.h rename to Recycler/NGObjDOM/ODR_bind_viewertitle.h diff --git a/sope-appserver/NGObjDOM/ODResourceManager.h b/Recycler/NGObjDOM/ODResourceManager.h similarity index 100% rename from sope-appserver/NGObjDOM/ODResourceManager.h rename to Recycler/NGObjDOM/ODResourceManager.h diff --git a/sope-appserver/NGObjDOM/ODResourceManager.m b/Recycler/NGObjDOM/ODResourceManager.m similarity index 100% rename from sope-appserver/NGObjDOM/ODResourceManager.m rename to Recycler/NGObjDOM/ODResourceManager.m diff --git a/sope-appserver/NGObjDOM/ODWONodeRenderFactory.m b/Recycler/NGObjDOM/ODWONodeRenderFactory.m similarity index 100% rename from sope-appserver/NGObjDOM/ODWONodeRenderFactory.m rename to Recycler/NGObjDOM/ODWONodeRenderFactory.m diff --git a/sope-appserver/NGObjDOM/README b/Recycler/NGObjDOM/README similarity index 100% rename from sope-appserver/NGObjDOM/README rename to Recycler/NGObjDOM/README diff --git a/sope-appserver/NGObjDOM/Version b/Recycler/NGObjDOM/Version similarity index 100% rename from sope-appserver/NGObjDOM/Version rename to Recycler/NGObjDOM/Version diff --git a/sope-appserver/NGObjDOM/WOContext+Cursor.h b/Recycler/NGObjDOM/WOContext+Cursor.h similarity index 100% rename from sope-appserver/NGObjDOM/WOContext+Cursor.h rename to Recycler/NGObjDOM/WOContext+Cursor.h diff --git a/sope-appserver/NGObjDOM/WORenderDOM.h b/Recycler/NGObjDOM/WORenderDOM.h similarity index 100% rename from sope-appserver/NGObjDOM/WORenderDOM.h rename to Recycler/NGObjDOM/WORenderDOM.h diff --git a/sope-appserver/NGObjDOM/WORenderDOM.m b/Recycler/NGObjDOM/WORenderDOM.m similarity index 100% rename from sope-appserver/NGObjDOM/WORenderDOM.m rename to Recycler/NGObjDOM/WORenderDOM.m diff --git a/sope-core/NGLdap/COPYING b/Recycler/NGObjDOM/XHTML.subproj/COPYING similarity index 100% rename from sope-core/NGLdap/COPYING rename to Recycler/NGObjDOM/XHTML.subproj/COPYING diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ChangeLog b/Recycler/NGObjDOM/XHTML.subproj/ChangeLog similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ChangeLog rename to Recycler/NGObjDOM/XHTML.subproj/ChangeLog diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/GNUmakefile b/Recycler/NGObjDOM/XHTML.subproj/GNUmakefile similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/GNUmakefile rename to Recycler/NGObjDOM/XHTML.subproj/GNUmakefile diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/GNUmakefile.preamble b/Recycler/NGObjDOM/XHTML.subproj/GNUmakefile.preamble similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/GNUmakefile.preamble rename to Recycler/NGObjDOM/XHTML.subproj/GNUmakefile.preamble diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.h b/Recycler/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.h similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.h rename to Recycler/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.h diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.m b/Recycler/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.m rename to Recycler/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_a.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_a.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_a.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_a.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_button.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_button.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_button.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_button.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_form.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_form.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_form.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_form.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_img.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_img.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_img.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_img.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_input.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_input.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_input.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_input.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_option.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_option.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_option.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_option.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_select.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_select.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_select.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_select.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_textarea.m b/Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_textarea.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_textarea.m rename to Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_textarea.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.h b/Recycler/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.h similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.h rename to Recycler/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.h diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.m b/Recycler/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.m similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.m rename to Recycler/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.m diff --git a/sope-appserver/NGObjDOM/XHTML.subproj/bundle-info.plist b/Recycler/NGObjDOM/XHTML.subproj/bundle-info.plist similarity index 100% rename from sope-appserver/NGObjDOM/XHTML.subproj/bundle-info.plist rename to Recycler/NGObjDOM/XHTML.subproj/bundle-info.plist diff --git a/sope-core/NGMime/COPYING b/Recycler/NGObjDOM/XUL.subproj/COPYING similarity index 100% rename from sope-core/NGMime/COPYING rename to Recycler/NGObjDOM/XUL.subproj/COPYING diff --git a/sope-appserver/NGObjDOM/XUL.subproj/GNUmakefile b/Recycler/NGObjDOM/XUL.subproj/GNUmakefile similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/GNUmakefile rename to Recycler/NGObjDOM/XUL.subproj/GNUmakefile diff --git a/sope-appserver/NGObjDOM/XUL.subproj/GNUmakefile.preamble b/Recycler/NGObjDOM/XUL.subproj/GNUmakefile.preamble similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/GNUmakefile.preamble rename to Recycler/NGObjDOM/XUL.subproj/GNUmakefile.preamble diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODRDynamicXULTag.h b/Recycler/NGObjDOM/XUL.subproj/ODRDynamicXULTag.h similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODRDynamicXULTag.h rename to Recycler/NGObjDOM/XUL.subproj/ODRDynamicXULTag.h diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODRDynamicXULTag.m b/Recycler/NGObjDOM/XUL.subproj/ODRDynamicXULTag.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODRDynamicXULTag.m rename to Recycler/NGObjDOM/XUL.subproj/ODRDynamicXULTag.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_box.h b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_box.h similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_box.h rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_box.h diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_box.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_box.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_box.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_box.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_button.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_button.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_button.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_button.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_column.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_column.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_column.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_column.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_columns.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_columns.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_columns.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_columns.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_grid.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_grid.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_grid.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_grid.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_image.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_image.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_image.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_image.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_spring.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_spring.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_spring.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_spring.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_tab.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_tab.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_tab.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_tab.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_text.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_text.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_text.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_text.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_textfield.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_textfield.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_textfield.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_textfield.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_title.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_title.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_title.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_title.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_titledbox.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_titledbox.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_titledbox.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_titledbox.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_window.m b/Recycler/NGObjDOM/XUL.subproj/ODR_XUL_window.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_window.m rename to Recycler/NGObjDOM/XUL.subproj/ODR_XUL_window.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.h b/Recycler/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.h similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.h rename to Recycler/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.h diff --git a/sope-appserver/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.m b/Recycler/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.m similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.m rename to Recycler/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.m diff --git a/sope-appserver/NGObjDOM/XUL.subproj/bundle-info.plist b/Recycler/NGObjDOM/XUL.subproj/bundle-info.plist similarity index 100% rename from sope-appserver/NGObjDOM/XUL.subproj/bundle-info.plist rename to Recycler/NGObjDOM/XUL.subproj/bundle-info.plist diff --git a/sope-appserver/NGObjDOM/bundle-info.plist b/Recycler/NGObjDOM/bundle-info.plist similarity index 100% rename from sope-appserver/NGObjDOM/bundle-info.plist rename to Recycler/NGObjDOM/bundle-info.plist diff --git a/sope-appserver/NGObjDOM/common.h b/Recycler/NGObjDOM/common.h similarity index 100% rename from sope-appserver/NGObjDOM/common.h rename to Recycler/NGObjDOM/common.h diff --git a/sope-appserver/NGObjDOM/dummy.m b/Recycler/NGObjDOM/dummy.m similarity index 100% rename from sope-appserver/NGObjDOM/dummy.m rename to Recycler/NGObjDOM/dummy.m diff --git a/sope-appserver/NGObjDOM/used_privates.h b/Recycler/NGObjDOM/used_privates.h similarity index 100% rename from sope-appserver/NGObjDOM/used_privates.h rename to Recycler/NGObjDOM/used_privates.h diff --git a/mod_ngobjweb/CHANGES b/sope-appserver/mod_ngobjweb/CHANGES similarity index 100% rename from mod_ngobjweb/CHANGES rename to sope-appserver/mod_ngobjweb/CHANGES diff --git a/sope-appserver/NGObjDOM/COPYRIGHT b/sope-appserver/mod_ngobjweb/COPYRIGHT similarity index 100% rename from sope-appserver/NGObjDOM/COPYRIGHT rename to sope-appserver/mod_ngobjweb/COPYRIGHT diff --git a/mod_ngobjweb/ChangeLog b/sope-appserver/mod_ngobjweb/ChangeLog similarity index 100% rename from mod_ngobjweb/ChangeLog rename to sope-appserver/mod_ngobjweb/ChangeLog diff --git a/mod_ngobjweb/GNUmakefile b/sope-appserver/mod_ngobjweb/GNUmakefile similarity index 100% rename from mod_ngobjweb/GNUmakefile rename to sope-appserver/mod_ngobjweb/GNUmakefile diff --git a/mod_ngobjweb/NGBufferedDescriptor.c b/sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c similarity index 100% rename from mod_ngobjweb/NGBufferedDescriptor.c rename to sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c diff --git a/mod_ngobjweb/NGBufferedDescriptor.h b/sope-appserver/mod_ngobjweb/NGBufferedDescriptor.h similarity index 100% rename from mod_ngobjweb/NGBufferedDescriptor.h rename to sope-appserver/mod_ngobjweb/NGBufferedDescriptor.h diff --git a/mod_ngobjweb/README b/sope-appserver/mod_ngobjweb/README similarity index 100% rename from mod_ngobjweb/README rename to sope-appserver/mod_ngobjweb/README diff --git a/mod_ngobjweb/apversion.sh b/sope-appserver/mod_ngobjweb/apversion.sh similarity index 100% rename from mod_ngobjweb/apversion.sh rename to sope-appserver/mod_ngobjweb/apversion.sh diff --git a/mod_ngobjweb/common.h b/sope-appserver/mod_ngobjweb/common.h similarity index 100% rename from mod_ngobjweb/common.h rename to sope-appserver/mod_ngobjweb/common.h diff --git a/mod_ngobjweb/config.c b/sope-appserver/mod_ngobjweb/config.c similarity index 100% rename from mod_ngobjweb/config.c rename to sope-appserver/mod_ngobjweb/config.c diff --git a/mod_ngobjweb/globals.c b/sope-appserver/mod_ngobjweb/globals.c similarity index 100% rename from mod_ngobjweb/globals.c rename to sope-appserver/mod_ngobjweb/globals.c diff --git a/mod_ngobjweb/handler.c b/sope-appserver/mod_ngobjweb/handler.c similarity index 100% rename from mod_ngobjweb/handler.c rename to sope-appserver/mod_ngobjweb/handler.c diff --git a/mod_ngobjweb/httpd.conf b/sope-appserver/mod_ngobjweb/httpd.conf similarity index 100% rename from mod_ngobjweb/httpd.conf rename to sope-appserver/mod_ngobjweb/httpd.conf diff --git a/mod_ngobjweb/ngobjweb_module.c b/sope-appserver/mod_ngobjweb/ngobjweb_module.c similarity index 100% rename from mod_ngobjweb/ngobjweb_module.c rename to sope-appserver/mod_ngobjweb/ngobjweb_module.c diff --git a/mod_ngobjweb/scanhttp.c b/sope-appserver/mod_ngobjweb/scanhttp.c similarity index 100% rename from mod_ngobjweb/scanhttp.c rename to sope-appserver/mod_ngobjweb/scanhttp.c diff --git a/mod_ngobjweb/skyrix.conf b/sope-appserver/mod_ngobjweb/skyrix.conf similarity index 100% rename from mod_ngobjweb/skyrix.conf rename to sope-appserver/mod_ngobjweb/skyrix.conf diff --git a/mod_ngobjweb/sns.c b/sope-appserver/mod_ngobjweb/sns.c similarity index 100% rename from mod_ngobjweb/sns.c rename to sope-appserver/mod_ngobjweb/sns.c diff --git a/sope-appserver/samples/WOxExtTest/WOxExtTest.pbproj/project.pbxproj b/sope-appserver/samples/WOxExtTest/WOxExtTest.pbproj/project.pbxproj deleted file mode 100644 index e2748585..00000000 --- a/sope-appserver/samples/WOxExtTest/WOxExtTest.pbproj/project.pbxproj +++ /dev/null @@ -1,1796 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 38; - objects = { - 6904BAA001EB9B4900A8007E = { - isa = PBXFileReference; - path = CalendarField.wox; - refType = 4; - }; - 6904BAA101EB9B4900A8007E = { - isa = PBXFileReference; - path = CheckBoxMatrix.wox; - refType = 4; - }; - 6904BAA201EB9B4900A8007E = { - isa = PBXFileReference; - path = CollapsibleContent.wox; - refType = 4; - }; - 6904BAA301EB9B4900A8007E = { - isa = PBXFileReference; - path = CollapsibleContentExt.wox; - refType = 4; - }; - 6904BAA401EB9B4900A8007E = { - isa = PBXFileReference; - path = DictionaryRepetition.wox; - refType = 4; - }; - 6904BAA501EB9B4900A8007E = { - isa = PBXFileReference; - path = DnD.wox; - refType = 4; - }; - 6904BAA601EB9B4900A8007E = { - isa = PBXFileReference; - path = KeyValueConditional.wox; - refType = 4; - }; - 6904BAA701EB9B4900A8007E = { - isa = PBXFileReference; - path = ModalWindow.wox; - refType = 4; - }; - 6904BAA801EB9B4900A8007E = { - isa = PBXFileReference; - path = MonthOverview.wox; - refType = 4; - }; - 6904BAA901EB9B4900A8007E = { - isa = PBXFileReference; - path = PageView.wox; - refType = 4; - }; - 6904BAAA01EB9B4900A8007E = { - isa = PBXFileReference; - path = PanelContent.wox; - refType = 4; - }; - 6904BAAB01EB9B4900A8007E = { - isa = PBXFileReference; - path = RadioButtonMatrix.wox; - refType = 4; - }; - 6904BAAC01EB9B4900A8007E = { - isa = PBXFileReference; - path = Switch.wox; - refType = 4; - }; - 6904BAAD01EB9B4900A8007E = { - isa = PBXFileReference; - path = Table.wox; - refType = 4; - }; - 6904BAAE01EB9B4900A8007E = { - isa = PBXFileReference; - path = TableMatrix.wox; - refType = 4; - }; - 6904BAAF01EB9B4900A8007E = { - isa = PBXFileReference; - path = TableView.wox; - refType = 4; - }; - 6904BAB001EB9B4900A8007E = { - isa = PBXFileReference; - path = TabPanel.wox; - refType = 4; - }; - 6904BAB101EB9B4900A8007E = { - isa = PBXFileReference; - path = TabView.wox; - refType = 4; - }; - 6904BAB201EB9B4900A8007E = { - isa = PBXFileReference; - path = TextFlyover.wox; - refType = 4; - }; - 6904BAB301EB9B4900A8007E = { - isa = PBXFileReference; - path = ThresholdColoredNumber.wox; - refType = 4; - }; - 6904BAB401EB9B4900A8007E = { - isa = PBXFileReference; - path = TimeField.wox; - refType = 4; - }; - 6904BAB501EB9B4900A8007E = { - isa = PBXFileReference; - path = TreeView.wox; - refType = 4; - }; - 6904BAB601EB9B4900A8007E = { - isa = PBXFileReference; - path = ValidatedField.wox; - refType = 4; - }; - 6904BAB701EB9B4900A8007E = { - isa = PBXFileReference; - path = WeekColumnView.wox; - refType = 4; - }; - 6904BAB801EB9B4900A8007E = { - isa = PBXFileReference; - path = WeekOverview.wox; - refType = 4; - }; - 6905B77501CE9CDB006474DE = { - buildStyles = ( - 6905B77701CE9CDB006474DE, - 6905B77801CE9CDB006474DE, - ); - isa = PBXProject; - mainGroup = 6905B77601CE9CDB006474DE; - productRefGroup = 6941F0270242A10C00A8007E; - projectDirPath = ""; - targets = ( - 6918B0C201CE9E590053A783, - 6941F0290242A10C00A8007E, - ); - }; - 6905B77601CE9CDB006474DE = { - children = ( - 6918B09801CE9DFF0053A783, - 691DC05601F6197E00A8007E, - 69AC2E89031D8E3200A8CBE9, - 6918B09901CE9DFF0053A783, - 6918B09A01CE9DFF0053A783, - 6905B77901CE9D13006474DE, - 6941F0830242A2FE00A8007E, - 6941F0270242A10C00A8007E, - ); - isa = PBXGroup; - refType = 4; - }; - 6905B77701CE9CDB006474DE = { - buildRules = ( - ); - buildSettings = { - COPY_PHASE_STRIP = NO; - }; - isa = PBXBuildStyle; - name = Development; - }; - 6905B77801CE9CDB006474DE = { - buildRules = ( - ); - buildSettings = { - COPY_PHASE_STRIP = YES; - }; - isa = PBXBuildStyle; - name = Deployment; - }; - 6905B77901CE9D13006474DE = { - children = ( - 6918B09C01CE9DFF0053A783, - 6918B09D01CE9DFF0053A783, - 6918B09E01CE9DFF0053A783, - 691DC04401F4D3CB00A8007E, - 6918B09F01CE9DFF0053A783, - 6904BAA001EB9B4900A8007E, - 6918B0A001CE9DFF0053A783, - 6904BAA101EB9B4900A8007E, - 6918B0A101CE9DFF0053A783, - 6904BAA201EB9B4900A8007E, - 6918B0A201CE9DFF0053A783, - 6904BAA301EB9B4900A8007E, - 6918B0A301CE9DFF0053A783, - 6918B0F701CEA8DF0053A783, - 6918B0A401CE9DFF0053A783, - 6918B0F801CEAA3F0053A783, - 6918B0A501CE9DFF0053A783, - 6904BAA401EB9B4900A8007E, - 6918B0A601CE9DFF0053A783, - 6918B0A701CE9DFF0053A783, - 6904BAA501EB9B4900A8007E, - 6918B0A801CE9DFF0053A783, - 6918B0A901CE9DFF0053A783, - 6918B0AA01CE9DFF0053A783, - 6918B0F901CEAB5E0053A783, - 6918B0AB01CE9DFF0053A783, - 6904BAA601EB9B4900A8007E, - 6918B0AC01CE9DFF0053A783, - 6918B0AD01CE9DFF0053A783, - 6918B0AE01CE9DFF0053A783, - 6904BAA701EB9B4900A8007E, - 6918B0AF01CE9DFF0053A783, - 6904BAA801EB9B4900A8007E, - 6918B0B001CE9DFF0053A783, - 6904BAA901EB9B4900A8007E, - 6918B0B101CE9DFF0053A783, - 6904BAAA01EB9B4900A8007E, - 6918B0B201CE9DFF0053A783, - 6904BAAB01EB9B4900A8007E, - 6918B0B301CE9DFF0053A783, - 6918B0F301CEA4C20053A783, - 6918B0B401CE9DFF0053A783, - 6918B0F101CEA2F40053A783, - 6918B0B501CE9DFF0053A783, - 6904BAAC01EB9B4900A8007E, - 6918B0B601CE9DFF0053A783, - 6904BAAD01EB9B4900A8007E, - 6918B0B701CE9DFF0053A783, - 6904BAAE01EB9B4900A8007E, - 6918B0B801CE9DFF0053A783, - 6904BAAF01EB9B4900A8007E, - 6918B0B901CE9DFF0053A783, - 6904BAB001EB9B4900A8007E, - 6918B0BA01CE9DFF0053A783, - 6904BAB101EB9B4900A8007E, - 6918B0BB01CE9DFF0053A783, - 6904BAB201EB9B4900A8007E, - 6918B0BC01CE9DFF0053A783, - 6904BAB301EB9B4900A8007E, - 6918B0BD01CE9DFF0053A783, - 6904BAB401EB9B4900A8007E, - 6918B0BE01CE9DFF0053A783, - 6904BAB501EB9B4900A8007E, - 6918B0BF01CE9DFF0053A783, - 6904BAB601EB9B4900A8007E, - 6918B0C001CE9DFF0053A783, - 6904BAB701EB9B4900A8007E, - 6918B0C101CE9DFF0053A783, - 6904BAB801EB9B4900A8007E, - ); - isa = PBXGroup; - name = Components; - refType = 4; - }; - 6918B09601CE9DFF0053A783 = { - isa = PBXFileReference; - path = GNUmakefile; - refType = 4; - }; - 6918B09701CE9DFF0053A783 = { - isa = PBXFileReference; - path = GNUmakefile.preamble; - refType = 4; - }; - 6918B09801CE9DFF0053A783 = { - isa = PBXFileReference; - path = WOxExtTest.m; - refType = 4; - }; - 6918B09901CE9DFF0053A783 = { - children = ( - 6918B0C301CE9EEE0053A783, - 6918B0C401CE9EEE0053A783, - 6918B0C501CE9EEE0053A783, - 6918B0C601CE9EEE0053A783, - ); - isa = PBXGroup; - name = Resources; - refType = 4; - }; - 6918B09A01CE9DFF0053A783 = { - children = ( - 6918B09B01CE9DFF0053A783, - 6918B0C701CE9EEE0053A783, - 6918B0C801CE9EEE0053A783, - 6918B0C901CE9EEE0053A783, - 6918B0CA01CE9EEE0053A783, - 6918B0CB01CE9EEE0053A783, - 6918B0CC01CE9EEE0053A783, - 6918B0CD01CE9EEE0053A783, - 6918B0CE01CE9EEE0053A783, - 6918B0CF01CE9EEE0053A783, - 6918B0D001CE9EEE0053A783, - 6918B0D101CE9EEE0053A783, - 6918B0D201CE9EEE0053A783, - 6918B0D301CE9EEE0053A783, - 6918B0D401CE9EEE0053A783, - 6918B0D501CE9EEE0053A783, - 6918B0D601CE9EEE0053A783, - 6918B0D701CE9EEE0053A783, - 6918B0D801CE9EEE0053A783, - 6918B0D901CE9EEE0053A783, - 6918B0DA01CE9EEE0053A783, - 6918B0DB01CE9EEE0053A783, - 6918B0DC01CE9EEE0053A783, - 6918B0DD01CE9EEE0053A783, - 6918B0DE01CE9EEE0053A783, - 6918B0DF01CE9EEE0053A783, - 6918B0E001CE9EEE0053A783, - 6918B0E101CE9EEE0053A783, - 6918B0E201CE9EEE0053A783, - 6918B0E301CE9EEE0053A783, - 6918B0E401CE9EEE0053A783, - 6918B0E501CE9EEE0053A783, - 6918B0E601CE9EEE0053A783, - 6918B0E701CE9EEE0053A783, - 6918B0E801CE9EEE0053A783, - 6918B0E901CE9EEE0053A783, - 6918B0EA01CE9EEE0053A783, - 6918B0EB01CE9EEE0053A783, - 6918B0EC01CE9EEE0053A783, - ); - isa = PBXGroup; - name = WebServerResources; - refType = 4; - }; - 6918B09B01CE9DFF0053A783 = { - isa = PBXFileReference; - path = favicon.ico; - refType = 4; - }; - 6918B09C01CE9DFF0053A783 = { - isa = PBXFileReference; - path = AlertPanel.m; - refType = 4; - }; - 6918B09D01CE9DFF0053A783 = { - isa = PBXFileReference; - path = AlertPanel.wox; - refType = 4; - }; - 6918B09E01CE9DFF0053A783 = { - isa = PBXFileReference; - path = Browser.m; - refType = 4; - }; - 6918B09F01CE9DFF0053A783 = { - isa = PBXFileReference; - path = CalendarField.m; - refType = 4; - }; - 6918B0A001CE9DFF0053A783 = { - isa = PBXFileReference; - path = CheckBoxMatrix.m; - refType = 4; - }; - 6918B0A101CE9DFF0053A783 = { - isa = PBXFileReference; - path = CollapsibleContent.m; - refType = 4; - }; - 6918B0A201CE9DFF0053A783 = { - isa = PBXFileReference; - path = CollapsibleContentExt.m; - refType = 4; - }; - 6918B0A301CE9DFF0053A783 = { - isa = PBXFileReference; - path = ConfirmPanel.m; - refType = 4; - }; - 6918B0A401CE9DFF0053A783 = { - isa = PBXFileReference; - path = DateField.m; - refType = 4; - }; - 6918B0A501CE9DFF0053A783 = { - isa = PBXFileReference; - path = DictionaryRepetition.m; - refType = 4; - }; - 6918B0A601CE9DFF0053A783 = { - isa = PBXFileReference; - path = DirectAction.m; - refType = 4; - }; - 6918B0A701CE9DFF0053A783 = { - isa = PBXFileReference; - path = DnD.m; - refType = 4; - }; - 6918B0A801CE9DFF0053A783 = { - isa = PBXFileReference; - path = Frame.m; - refType = 4; - }; - 6918B0A901CE9DFF0053A783 = { - isa = PBXFileReference; - path = Frame.wox; - refType = 4; - }; - 6918B0AA01CE9DFF0053A783 = { - isa = PBXFileReference; - path = ImageFlyover.m; - refType = 4; - }; - 6918B0AB01CE9DFF0053A783 = { - isa = PBXFileReference; - path = KeyValueConditional.m; - refType = 4; - }; - 6918B0AC01CE9DFF0053A783 = { - isa = PBXFileReference; - path = Main.m; - refType = 4; - }; - 6918B0AD01CE9DFF0053A783 = { - isa = PBXFileReference; - path = Main.wox; - refType = 4; - }; - 6918B0AE01CE9DFF0053A783 = { - isa = PBXFileReference; - path = ModalWindow.m; - refType = 4; - }; - 6918B0AF01CE9DFF0053A783 = { - isa = PBXFileReference; - path = MonthOverview.m; - refType = 4; - }; - 6918B0B001CE9DFF0053A783 = { - isa = PBXFileReference; - path = PageView.m; - refType = 4; - }; - 6918B0B101CE9DFF0053A783 = { - isa = PBXFileReference; - path = PanelContent.m; - refType = 4; - }; - 6918B0B201CE9DFF0053A783 = { - isa = PBXFileReference; - path = RadioButtonMatrix.m; - refType = 4; - }; - 6918B0B301CE9DFF0053A783 = { - isa = PBXFileReference; - path = RichString.m; - refType = 4; - }; - 6918B0B401CE9DFF0053A783 = { - isa = PBXFileReference; - path = ShiftClick.m; - refType = 4; - }; - 6918B0B501CE9DFF0053A783 = { - isa = PBXFileReference; - path = Switch.m; - refType = 4; - }; - 6918B0B601CE9DFF0053A783 = { - isa = PBXFileReference; - path = Table.m; - refType = 4; - }; - 6918B0B701CE9DFF0053A783 = { - isa = PBXFileReference; - path = TableMatrix.m; - refType = 4; - }; - 6918B0B801CE9DFF0053A783 = { - isa = PBXFileReference; - path = TableView.m; - refType = 4; - }; - 6918B0B901CE9DFF0053A783 = { - isa = PBXFileReference; - path = TabPanel.m; - refType = 4; - }; - 6918B0BA01CE9DFF0053A783 = { - isa = PBXFileReference; - path = TabView.m; - refType = 4; - }; - 6918B0BB01CE9DFF0053A783 = { - isa = PBXFileReference; - path = TextFlyover.m; - refType = 4; - }; - 6918B0BC01CE9DFF0053A783 = { - isa = PBXFileReference; - path = ThresholdColoredNumber.m; - refType = 4; - }; - 6918B0BD01CE9DFF0053A783 = { - isa = PBXFileReference; - path = TimeField.m; - refType = 4; - }; - 6918B0BE01CE9DFF0053A783 = { - isa = PBXFileReference; - path = TreeView.m; - refType = 4; - }; - 6918B0BF01CE9DFF0053A783 = { - isa = PBXFileReference; - path = ValidatedField.m; - refType = 4; - }; - 6918B0C001CE9DFF0053A783 = { - isa = PBXFileReference; - path = WeekColumnView.m; - refType = 4; - }; - 6918B0C101CE9DFF0053A783 = { - isa = PBXFileReference; - path = WeekOverview.m; - refType = 4; - }; - 6918B0C201CE9E590053A783 = { - buildArgumentsString = $ACTION; - buildPhases = ( - ); - buildSettings = { - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = "gs-WOxExtTest"; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; - debug = yes; - shared = yes; - }; - buildToolPath = /usr/bin/gnumake; - dependencies = ( - ); - isa = PBXLegacyTarget; - name = "gs-WOxExtTest"; - productName = "gs-WOxExtTest"; - settingsToExpand = 6; - settingsToPassInEnvironment = 287; - settingsToPassOnCommandLine = 280; - shouldUseHeadermap = 0; - }; - 6918B0C301CE9EEE0053A783 = { - isa = PBXFileReference; - name = appointments.plist; - path = Resources/appointments.plist; - refType = 4; - }; - 6918B0C401CE9EEE0053A783 = { - isa = PBXFileReference; - name = Dictionary.plist; - path = Resources/Dictionary.plist; - refType = 4; - }; - 6918B0C501CE9EEE0053A783 = { - isa = PBXFileReference; - name = TableView.plist; - path = Resources/TableView.plist; - refType = 4; - }; - 6918B0C601CE9EEE0053A783 = { - isa = PBXFileReference; - name = TreeView.plist; - path = Resources/TreeView.plist; - refType = 4; - }; - 6918B0C701CE9EEE0053A783 = { - isa = PBXFileReference; - name = collapsed.gif; - path = WebServerResources/collapsed.gif; - refType = 4; - }; - 6918B0C801CE9EEE0053A783 = { - isa = PBXFileReference; - name = corner_left.gif; - path = WebServerResources/corner_left.gif; - refType = 4; - }; - 6918B0C901CE9EEE0053A783 = { - isa = PBXFileReference; - name = corner_right.gif; - path = WebServerResources/corner_right.gif; - refType = 4; - }; - 6918B0CA01CE9EEE0053A783 = { - isa = PBXFileReference; - name = downward_sorted.gif; - path = WebServerResources/downward_sorted.gif; - refType = 4; - }; - 6918B0CB01CE9EEE0053A783 = { - isa = PBXFileReference; - name = expanded.gif; - path = WebServerResources/expanded.gif; - refType = 4; - }; - 6918B0CC01CE9EEE0053A783 = { - isa = PBXFileReference; - name = first_blind.gif; - path = WebServerResources/first_blind.gif; - refType = 4; - }; - 6918B0CD01CE9EEE0053A783 = { - isa = PBXFileReference; - name = first.gif; - path = WebServerResources/first.gif; - refType = 4; - }; - 6918B0CE01CE9EEE0053A783 = { - isa = PBXFileReference; - name = folder_closed.gif; - path = WebServerResources/folder_closed.gif; - refType = 4; - }; - 6918B0CF01CE9EEE0053A783 = { - isa = PBXFileReference; - name = folder_opened.gif; - path = WebServerResources/folder_opened.gif; - refType = 4; - }; - 6918B0D001CE9EEE0053A783 = { - isa = PBXFileReference; - name = last_blind.gif; - path = WebServerResources/last_blind.gif; - refType = 4; - }; - 6918B0D101CE9EEE0053A783 = { - isa = PBXFileReference; - name = last.gif; - path = WebServerResources/last.gif; - refType = 4; - }; - 6918B0D201CE9EEE0053A783 = { - isa = PBXFileReference; - name = menu_email_inactive.gif; - path = WebServerResources/menu_email_inactive.gif; - refType = 4; - }; - 6918B0D301CE9EEE0053A783 = { - isa = PBXFileReference; - name = menu_email.gif; - path = WebServerResources/menu_email.gif; - refType = 4; - }; - 6918B0D401CE9EEE0053A783 = { - isa = PBXFileReference; - name = next_blind.gif; - path = WebServerResources/next_blind.gif; - refType = 4; - }; - 6918B0D501CE9EEE0053A783 = { - isa = PBXFileReference; - name = next.gif; - path = WebServerResources/next.gif; - refType = 4; - }; - 6918B0D601CE9EEE0053A783 = { - isa = PBXFileReference; - name = non_sorted.gif; - path = WebServerResources/non_sorted.gif; - refType = 4; - }; - 6918B0D701CE9EEE0053A783 = { - isa = PBXFileReference; - name = previous_blind.gif; - path = WebServerResources/previous_blind.gif; - refType = 4; - }; - 6918B0D801CE9EEE0053A783 = { - isa = PBXFileReference; - name = previous.gif; - path = WebServerResources/previous.gif; - refType = 4; - }; - 6918B0D901CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_news_left.gif; - path = WebServerResources/tab_news_left.gif; - refType = 4; - }; - 6918B0DA01CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_news_selected.gif; - path = WebServerResources/tab_news_selected.gif; - refType = 4; - }; - 6918B0DB01CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_news.gif; - path = WebServerResources/tab_news.gif; - refType = 4; - }; - 6918B0DC01CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_persons_left.gif; - path = WebServerResources/tab_persons_left.gif; - refType = 4; - }; - 6918B0DD01CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_persons_selected.gif; - path = WebServerResources/tab_persons_selected.gif; - refType = 4; - }; - 6918B0DE01CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_persons.gif; - path = WebServerResources/tab_persons.gif; - refType = 4; - }; - 6918B0DF01CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_projects_left.gif; - path = WebServerResources/tab_projects_left.gif; - refType = 4; - }; - 6918B0E001CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_projects_selected.gif; - path = WebServerResources/tab_projects_selected.gif; - refType = 4; - }; - 6918B0E101CE9EEE0053A783 = { - isa = PBXFileReference; - name = tab_projects.gif; - path = WebServerResources/tab_projects.gif; - refType = 4; - }; - 6918B0E201CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_corner_minus.gif; - path = WebServerResources/treeview_corner_minus.gif; - refType = 4; - }; - 6918B0E301CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_corner_plus.gif; - path = WebServerResources/treeview_corner_plus.gif; - refType = 4; - }; - 6918B0E401CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_corner.gif; - path = WebServerResources/treeview_corner.gif; - refType = 4; - }; - 6918B0E501CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_junction.gif; - path = WebServerResources/treeview_junction.gif; - refType = 4; - }; - 6918B0E601CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_leaf_corner.gif; - path = WebServerResources/treeview_leaf_corner.gif; - refType = 4; - }; - 6918B0E701CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_leaf.gif; - path = WebServerResources/treeview_leaf.gif; - refType = 4; - }; - 6918B0E801CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_line.gif; - path = WebServerResources/treeview_line.gif; - refType = 4; - }; - 6918B0E901CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_minus.gif; - path = WebServerResources/treeview_minus.gif; - refType = 4; - }; - 6918B0EA01CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_plus.gif; - path = WebServerResources/treeview_plus.gif; - refType = 4; - }; - 6918B0EB01CE9EEE0053A783 = { - isa = PBXFileReference; - name = treeview_space.gif; - path = WebServerResources/treeview_space.gif; - refType = 4; - }; - 6918B0EC01CE9EEE0053A783 = { - isa = PBXFileReference; - name = upward_sorted.gif; - path = WebServerResources/upward_sorted.gif; - refType = 4; - }; - 6918B0F101CEA2F40053A783 = { - isa = PBXFileReference; - path = ShiftClick.wox; - refType = 4; - }; - 6918B0F301CEA4C20053A783 = { - isa = PBXFileReference; - path = RichString.wox; - refType = 4; - }; - 6918B0F701CEA8DF0053A783 = { - isa = PBXFileReference; - path = ConfirmPanel.wox; - refType = 4; - }; - 6918B0F801CEAA3F0053A783 = { - isa = PBXFileReference; - path = DateField.wox; - refType = 4; - }; - 6918B0F901CEAB5E0053A783 = { - isa = PBXFileReference; - path = ImageFlyover.wox; - refType = 4; - }; - 691DC04401F4D3CB00A8007E = { - isa = PBXFileReference; - path = Browser.wox; - refType = 4; - }; - 691DC05601F6197E00A8007E = { - isa = PBXFileReference; - path = common.h; - refType = 4; - }; - 6941F0270242A10C00A8007E = { - children = ( - 6941F0280242A10C00A8007E, - ); - isa = PBXGroup; - name = Products; - refType = 4; - }; - 6941F0280242A10C00A8007E = { - isa = PBXApplicationReference; - path = WOxExtTest.woa; - refType = 3; - }; - 6941F0290242A10C00A8007E = { - buildPhases = ( - 6941F02A0242A10C00A8007E, - 6941F02B0242A10C00A8007E, - 6941F04A0242A10C00A8007E, - 6941F06C0242A10C00A8007E, - 6941F06D0242A10C00A8007E, - ); - buildSettings = { - FRAMEWORK_SEARCH_PATHS = /Users/helge/build; - OTHER_CFLAGS = "-DCOCOA_Foundation_LIBRARY=1 -DNeXT_Foundation_LIBRARY=1 -DNeXT_RUNTIME=1"; - OTHER_LDFLAGS = ""; - OTHER_REZFLAGS = ""; - PRODUCT_NAME = WOxExtTest; - SECTORDER_FLAGS = ""; - WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; - WRAPPER_EXTENSION = woa; - }; - dependencies = ( - ); - isa = PBXApplicationTarget; - name = WOxExtTest; - productInstallPath = "$(USER_APPS_DIR)"; - productName = WOxExtTest; - productReference = 6941F0280242A10C00A8007E; - productSettingsXML = " - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - - CFBundleGetInfoString - - CFBundleIconFile - - CFBundleIdentifier - com.skyrix.WOxExtTest - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - - CFBundlePackageType - BDNL - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - 4.2 - - -"; - shouldUseHeadermap = 0; - }; - 6941F02A0242A10C00A8007E = { - buildActionMask = 2147483647; - files = ( - 6941F0760242A19200A8007E, - ); - isa = PBXHeadersBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 6941F02B0242A10C00A8007E = { - buildActionMask = 2147483647; - files = ( - 6941F02C0242A10C00A8007E, - 6941F02D0242A10C00A8007E, - 6941F02E0242A10C00A8007E, - 6941F02F0242A10C00A8007E, - 6941F0300242A10C00A8007E, - 6941F0310242A10C00A8007E, - 6941F0320242A10C00A8007E, - 6941F0330242A10C00A8007E, - 6941F0340242A10C00A8007E, - 6941F0350242A10C00A8007E, - 6941F0360242A10C00A8007E, - 6941F0370242A10C00A8007E, - 6941F0380242A10C00A8007E, - 6941F0390242A10C00A8007E, - 6941F03A0242A10C00A8007E, - 6941F03B0242A10C00A8007E, - 6941F03C0242A10C00A8007E, - 6941F03D0242A10C00A8007E, - 6941F03E0242A10C00A8007E, - 6941F03F0242A10C00A8007E, - 6941F0400242A10C00A8007E, - 6941F0410242A10C00A8007E, - 6941F0420242A10C00A8007E, - 6941F0430242A10C00A8007E, - 6941F0440242A10C00A8007E, - 6941F0450242A10C00A8007E, - 6941F0460242A10C00A8007E, - 6941F0470242A10C00A8007E, - 6941F0480242A10C00A8007E, - 6941F0490242A10C00A8007E, - 6941F06F0242A18300A8007E, - 6941F0700242A18300A8007E, - 6941F0710242A18300A8007E, - 6941F0720242A18300A8007E, - 6941F0770242A19200A8007E, - 6941F0780242A19200A8007E, - 6941F0790242A19200A8007E, - 6941F07A0242A19200A8007E, - 69FC79A902983FB40083626D, - 69FC79AA02983FB50083626D, - 69FC79AB02983FB60083626D, - 69FC79AC02983FB60083626D, - 69FC79AD02983FB70083626D, - 69FC79AE02983FB70083626D, - 69FC79AF02983FB80083626D, - 69FC79B002983FB80083626D, - 69FC79B202983FBA0083626D, - 69FC79B302983FBA0083626D, - 69FC79B402983FBB0083626D, - 69FC79B502983FBC0083626D, - 69FC79B602983FBD0083626D, - 69FC79B702983FBD0083626D, - 69FC79B802983FBE0083626D, - 69FC79B902983FBE0083626D, - 69FC79BA02983FBF0083626D, - 69FC79BB02983FC00083626D, - 69FC79BC02983FC00083626D, - 69FC79BD02983FC10083626D, - 69FC79BE02983FC10083626D, - 69FC79BF02983FC40083626D, - 69FC79C002983FC40083626D, - 69FC79C102983FC50083626D, - 69FC79C202983FC50083626D, - 69FC79C302983FC60083626D, - 69FC79C402983FC60083626D, - 69FC79C502983FCC0083626D, - 69FC79C602983FCD0083626D, - 69FC79C702983FCD0083626D, - 69FC79C802983FCE0083626D, - 69FC79C902983FCE0083626D, - 69FC79CA02983FCF0083626D, - 69FC79CB02983FCF0083626D, - 69FC79CC02983FD00083626D, - 69FC79CD02983FD00083626D, - 69FC79CE02983FD40083626D, - 69FC79CF02983FD70083626D, - 69FC79D002983FD80083626D, - ); - isa = PBXResourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 6941F02C0242A10C00A8007E = { - fileRef = 6918B09D01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F02D0242A10C00A8007E = { - fileRef = 691DC04401F4D3CB00A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F02E0242A10C00A8007E = { - fileRef = 6904BAA001EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F02F0242A10C00A8007E = { - fileRef = 6904BAA101EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0300242A10C00A8007E = { - fileRef = 6904BAA201EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0310242A10C00A8007E = { - fileRef = 6904BAA301EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0320242A10C00A8007E = { - fileRef = 6918B0F701CEA8DF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0330242A10C00A8007E = { - fileRef = 6918B0F801CEAA3F0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0340242A10C00A8007E = { - fileRef = 6904BAA401EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0350242A10C00A8007E = { - fileRef = 6904BAA501EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0360242A10C00A8007E = { - fileRef = 6918B0A901CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0370242A10C00A8007E = { - fileRef = 6918B0F901CEAB5E0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0380242A10C00A8007E = { - fileRef = 6904BAA601EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0390242A10C00A8007E = { - fileRef = 6918B0AD01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F03A0242A10C00A8007E = { - fileRef = 6904BAA701EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F03B0242A10C00A8007E = { - fileRef = 6904BAA801EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F03C0242A10C00A8007E = { - fileRef = 6904BAA901EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F03D0242A10C00A8007E = { - fileRef = 6904BAAA01EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F03E0242A10C00A8007E = { - fileRef = 6904BAAB01EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F03F0242A10C00A8007E = { - fileRef = 6918B0F301CEA4C20053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0400242A10C00A8007E = { - fileRef = 6918B0F101CEA2F40053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0410242A10C00A8007E = { - fileRef = 6904BAAC01EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0420242A10C00A8007E = { - fileRef = 6904BAAD01EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0430242A10C00A8007E = { - fileRef = 6904BAAE01EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0440242A10C00A8007E = { - fileRef = 6904BAAF01EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0450242A10C00A8007E = { - fileRef = 6904BAB001EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0460242A10C00A8007E = { - fileRef = 6904BAB101EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0470242A10C00A8007E = { - fileRef = 6904BAB201EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0480242A10C00A8007E = { - fileRef = 6904BAB301EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0490242A10C00A8007E = { - fileRef = 6904BAB401EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F04A0242A10C00A8007E = { - buildActionMask = 2147483647; - files = ( - 6941F04B0242A10C00A8007E, - 6941F04C0242A10C00A8007E, - 6941F04D0242A10C00A8007E, - 6941F04E0242A10C00A8007E, - 6941F04F0242A10C00A8007E, - 6941F0500242A10C00A8007E, - 6941F0510242A10C00A8007E, - 6941F0520242A10C00A8007E, - 6941F0530242A10C00A8007E, - 6941F0540242A10C00A8007E, - 6941F0550242A10C00A8007E, - 6941F0560242A10C00A8007E, - 6941F0570242A10C00A8007E, - 6941F0580242A10C00A8007E, - 6941F0590242A10C00A8007E, - 6941F05A0242A10C00A8007E, - 6941F05B0242A10C00A8007E, - 6941F05C0242A10C00A8007E, - 6941F05D0242A10C00A8007E, - 6941F05E0242A10C00A8007E, - 6941F05F0242A10C00A8007E, - 6941F0600242A10C00A8007E, - 6941F0610242A10C00A8007E, - 6941F0620242A10C00A8007E, - 6941F0630242A10C00A8007E, - 6941F0640242A10C00A8007E, - 6941F0650242A10C00A8007E, - 6941F0660242A10C00A8007E, - 6941F0670242A10C00A8007E, - 6941F0680242A10C00A8007E, - 6941F0690242A10C00A8007E, - 6941F06A0242A10C00A8007E, - 6941F06B0242A10C00A8007E, - 6941F0730242A18300A8007E, - 6941F0740242A18300A8007E, - 6941F0750242A18300A8007E, - ); - isa = PBXSourcesBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 6941F04B0242A10C00A8007E = { - fileRef = 6918B09801CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F04C0242A10C00A8007E = { - fileRef = 6918B09C01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F04D0242A10C00A8007E = { - fileRef = 6918B09E01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F04E0242A10C00A8007E = { - fileRef = 6918B09F01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F04F0242A10C00A8007E = { - fileRef = 6918B0A001CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0500242A10C00A8007E = { - fileRef = 6918B0A101CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0510242A10C00A8007E = { - fileRef = 6918B0A201CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0520242A10C00A8007E = { - fileRef = 6918B0A301CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0530242A10C00A8007E = { - fileRef = 6918B0A401CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0540242A10C00A8007E = { - fileRef = 6918B0A501CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0550242A10C00A8007E = { - fileRef = 6918B0A601CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0560242A10C00A8007E = { - fileRef = 6918B0A701CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0570242A10C00A8007E = { - fileRef = 6918B0A801CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0580242A10C00A8007E = { - fileRef = 6918B0AA01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0590242A10C00A8007E = { - fileRef = 6918B0AB01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F05A0242A10C00A8007E = { - fileRef = 6918B0AC01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F05B0242A10C00A8007E = { - fileRef = 6918B0AE01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F05C0242A10C00A8007E = { - fileRef = 6918B0AF01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F05D0242A10C00A8007E = { - fileRef = 6918B0B001CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F05E0242A10C00A8007E = { - fileRef = 6918B0B101CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F05F0242A10C00A8007E = { - fileRef = 6918B0B201CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0600242A10C00A8007E = { - fileRef = 6918B0B301CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0610242A10C00A8007E = { - fileRef = 6918B0B401CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0620242A10C00A8007E = { - fileRef = 6918B0B501CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0630242A10C00A8007E = { - fileRef = 6918B0B601CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0640242A10C00A8007E = { - fileRef = 6918B0B701CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0650242A10C00A8007E = { - fileRef = 6918B0B801CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0660242A10C00A8007E = { - fileRef = 6918B0B901CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0670242A10C00A8007E = { - fileRef = 6918B0BA01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0680242A10C00A8007E = { - fileRef = 6918B0BB01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0690242A10C00A8007E = { - fileRef = 6918B0BC01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F06A0242A10C00A8007E = { - fileRef = 6918B0BD01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F06B0242A10C00A8007E = { - fileRef = 6918B0BE01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F06C0242A10C00A8007E = { - buildActionMask = 2147483647; - files = ( - 6941F07F0242A1F300A8007E, - 6941F0800242A1F300A8007E, - 6941F0850242A2FE00A8007E, - ); - isa = PBXFrameworksBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 6941F06D0242A10C00A8007E = { - buildActionMask = 2147483647; - files = ( - ); - isa = PBXRezBuildPhase; - runOnlyForDeploymentPostprocessing = 0; - }; - 6941F06F0242A18300A8007E = { - fileRef = 6904BAB501EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0700242A18300A8007E = { - fileRef = 6904BAB601EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0710242A18300A8007E = { - fileRef = 6904BAB701EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0720242A18300A8007E = { - fileRef = 6904BAB801EB9B4900A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0730242A18300A8007E = { - fileRef = 6918B0BF01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0740242A18300A8007E = { - fileRef = 6918B0C001CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0750242A18300A8007E = { - fileRef = 6918B0C101CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0760242A19200A8007E = { - fileRef = 691DC05601F6197E00A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0770242A19200A8007E = { - fileRef = 6918B0C301CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0780242A19200A8007E = { - fileRef = 6918B0C401CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0790242A19200A8007E = { - fileRef = 6918B0C501CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F07A0242A19200A8007E = { - fileRef = 6918B0C601CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F07B0242A1F300A8007E = { - isa = PBXFrameworkReference; - name = FoundationExt.framework; - path = /Users/helge/build/FoundationExt.framework; - refType = 0; - }; - 6941F07C0242A1F300A8007E = { - isa = PBXFrameworkReference; - name = NGObjWeb.framework; - path = /Users/helge/build/NGObjWeb.framework; - refType = 0; - }; - 6941F07F0242A1F300A8007E = { - fileRef = 6941F07B0242A1F300A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0800242A1F300A8007E = { - fileRef = 6941F07C0242A1F300A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 6941F0830242A2FE00A8007E = { - children = ( - 6941F07C0242A1F300A8007E, - 6941F07B0242A1F300A8007E, - 6941F0840242A2FE00A8007E, - ); - isa = PBXGroup; - name = "Linked Frameworks"; - refType = 4; - }; - 6941F0840242A2FE00A8007E = { - isa = PBXFrameworkReference; - name = Foundation.framework; - path = /System/Library/Frameworks/Foundation.framework; - refType = 0; - }; - 6941F0850242A2FE00A8007E = { - fileRef = 6941F0840242A2FE00A8007E; - isa = PBXBuildFile; - settings = { - }; - }; - 69AC2E89031D8E3200A8CBE9 = { - children = ( - 6918B09601CE9DFF0053A783, - 6918B09701CE9DFF0053A783, - ); - isa = PBXGroup; - name = Makefiles; - refType = 4; - }; - 69FC79A902983FB40083626D = { - fileRef = 6918B09B01CE9DFF0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79AA02983FB50083626D = { - fileRef = 6918B0C701CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79AB02983FB60083626D = { - fileRef = 6918B0C801CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79AC02983FB60083626D = { - fileRef = 6918B0C901CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79AD02983FB70083626D = { - fileRef = 6918B0CA01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79AE02983FB70083626D = { - fileRef = 6918B0CB01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79AF02983FB80083626D = { - fileRef = 6918B0CC01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B002983FB80083626D = { - fileRef = 6918B0CD01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B202983FBA0083626D = { - fileRef = 6918B0D001CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B302983FBA0083626D = { - fileRef = 6918B0CF01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B402983FBB0083626D = { - fileRef = 6918B0CE01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B502983FBC0083626D = { - fileRef = 6918B0D101CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B602983FBD0083626D = { - fileRef = 6918B0D201CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B702983FBD0083626D = { - fileRef = 6918B0D301CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B802983FBE0083626D = { - fileRef = 6918B0D401CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79B902983FBE0083626D = { - fileRef = 6918B0D501CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79BA02983FBF0083626D = { - fileRef = 6918B0D701CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79BB02983FC00083626D = { - fileRef = 6918B0D601CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79BC02983FC00083626D = { - fileRef = 6918B0D801CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79BD02983FC10083626D = { - fileRef = 6918B0D901CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79BE02983FC10083626D = { - fileRef = 6918B0DA01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79BF02983FC40083626D = { - fileRef = 6918B0DB01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C002983FC40083626D = { - fileRef = 6918B0DC01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C102983FC50083626D = { - fileRef = 6918B0DD01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C202983FC50083626D = { - fileRef = 6918B0DE01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C302983FC60083626D = { - fileRef = 6918B0DF01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C402983FC60083626D = { - fileRef = 6918B0E001CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C502983FCC0083626D = { - fileRef = 6918B0E101CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C602983FCD0083626D = { - fileRef = 6918B0E201CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C702983FCD0083626D = { - fileRef = 6918B0E301CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C802983FCE0083626D = { - fileRef = 6918B0E401CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79C902983FCE0083626D = { - fileRef = 6918B0E501CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79CA02983FCF0083626D = { - fileRef = 6918B0E601CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79CB02983FCF0083626D = { - fileRef = 6918B0E701CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79CC02983FD00083626D = { - fileRef = 6918B0E801CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79CD02983FD00083626D = { - fileRef = 6918B0E901CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79CE02983FD40083626D = { - fileRef = 6918B0EA01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79CF02983FD70083626D = { - fileRef = 6918B0EC01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - 69FC79D002983FD80083626D = { - fileRef = 6918B0EB01CE9EEE0053A783; - isa = PBXBuildFile; - settings = { - }; - }; - }; - rootObject = 6905B77501CE9CDB006474DE; -} diff --git a/sope-core/GNUmakefile b/sope-core/GNUmakefile index 2de42883..7f58da2c 100644 --- a/sope-core/GNUmakefile +++ b/sope-core/GNUmakefile @@ -1,23 +1,11 @@ -# $Id$ - include $(GNUSTEP_MAKEFILES)/common.make -PACKAGE_NAME=skyrix-core -VERSION=4.2.0 +PACKAGE_NAME=sope-core +VERSION=4.3.0 SUBPROJECTS = \ EOControl \ NGExtensions \ NGStreams \ - NGMime \ - NGLdap \ - NGiCal \ include $(GNUSTEP_MAKEFILES)/aggregate.make - -autodoc : - (cd EOControl; $(MAKE) autodoc) - (cd NGExtensions; $(MAKE) autodoc) - (cd NGStreams; $(MAKE) autodoc) - (cd NGMime; $(MAKE) autodoc) - (cd NGLdap; $(MAKE) autodoc) diff --git a/sope-core/README-OSX.txt b/sope-core/README-OSX.txt index c722ff36..8119c4df 100644 --- a/sope-core/README-OSX.txt +++ b/sope-core/README-OSX.txt @@ -5,7 +5,7 @@ Building Notes Prerequisites: - Apple Developer Tools -- skyrix-xml +- sope-xml There are two ways to build SOPE on MacOSX, either using the gnustep-make package or as native Xcode projects. The first option is usually used when @@ -132,9 +132,4 @@ SxCore: 0xC1000000 - 0xC2FFFFFF 0xC1000000 EOControl 0xC1200000 NGExtensions 0xC1400000 NGStreams -0xC1600000 NGImap4 [not available with gstep-make] -0xC1800000 NGMail [not available with gstep-make] -0xC1A00000 NGMime [used as base in gstep-make] -0xC1C00000 NGLdap -0xC1E00000 NGiCal 0xC2FF0000 SxCore diff --git a/sope-core/NGMime/NGImap4/COPYING b/sope-gdl1/COPYING.LIB similarity index 100% rename from sope-core/NGMime/NGImap4/COPYING rename to sope-gdl1/COPYING.LIB diff --git a/sope-gdl1/FrontBase2/COPYING.LIB b/sope-gdl1/FrontBase2/COPYING.LIB new file mode 100644 index 00000000..eb685a5e --- /dev/null +++ b/sope-gdl1/FrontBase2/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/sope-gdl1/FrontBase2/ChangeLog b/sope-gdl1/FrontBase2/ChangeLog new file mode 100644 index 00000000..61d528d4 --- /dev/null +++ b/sope-gdl1/FrontBase2/ChangeLog @@ -0,0 +1,109 @@ +2004-08-20 Helge Hess + + * moved from ThirdParty to SOPE/sope-gdl1 (v1.0.2) + +2003-05-07 Helge Hess + + * v1.0.1 + + * replaced all THROW macros with -raise calls, this was necessary with + the new gcc 3.3 preprocessor for compilation + + * GNUmakefile (FrontBase2_RESOURCE_FILES): added a Version file + +Mon May 5 16:08:07 2003 Jan Reichmann + + * FBValues.m: code cleanups, fixed retain bug (NSData valueFromBytes) + +Wed Mar 26 10:23:53 2003 Jan Reichmann + + * FBChannel.m: add debugging-logs if channel will be closed + +Mon Dec 23 18:22:18 2002 Helge Hess + + * FBChannel.m: fixed a gcc 3.2 warning + +Fri Nov 29 15:17:04 2002 + + * FBChannel.m: from 4.1 + +Tue Sep 3 15:32:24 2002 Jan Reichmann + + * FBChannel.m: values comes now from self->selectedAttributes + * FBValues.m: add missing Frontbase type to NSNumber -valueFromBytes + (FB_VCharacter) + +2002-08-30 Helge Hess + + * GNUmakefile.preamble (FrontBase2_BUNDLE_LIBS): fixed a bug in the + Makefile (did compile without prior installation of GDLAccess) + +Wed Aug 21 17:55:25 2002 Jan Reichmann + + * FBChannel.m: (from 4.1) + -use _attributes-var (model) for creating attr-row + -fixed '\0' bug (empty password must be set to '\0') + -fixed login with passwd bug (pwd will be only accepted, + if it isn`t crypted with fbcDigestPassword + +Fri Jul 27 10:22:18 2001 Helge Hess + + * FBChannel.m: close channel on -dealloc + +Wed Jan 3 19:15:59 2001 Jan Reichmann + + * FBChannel.m, FBChannel+Model.m: cache table informations + +Wed Jan 3 18:51:28 2001 Jan Reichmann + + * FBAdaptor+Types.m, EOAttribute+FB.m: INT -> INTEGER + +Tue Jan 2 14:42:20 2001 Jan Reichmann + + * FBChannel.m: fixed core dump if password is wrong + +Wed Dec 6 12:48:58 2000 Helge Hess + + * renamed file FBAdaptor to FrontBase2Adaptor, renamed FrontBaseAdaptor + class to FrontBase2Adaptor + +Mon Dec 4 13:31:07 2000 Helge Hess + + * GNUmakefile: added cancompile.sh script and support + +Fri Nov 17 15:46:43 2000 Helge Hess + + * created FB2 adaptor out of FB1 adaptor .. + +Wed Aug 23 16:56:28 2000 Joerg Grimm + + * FBAdaptor.m: formatting for text attributes added + +Mon May 29 15:56:58 2000 Helge Hess + + * FBChannel.m: automagically add sort-ordering attributes to query set + +Mon Apr 10 17:54:39 2000 Helge Hess + + * FBValues.m ([NSCalendarDate -stringValueForFrontBaseType:attribute:]): + removed a NSLog + +Mon Apr 10 12:25:38 2000 Helge Hess + + * FBChannel.m: fixed memory free bug + +Tue Feb 29 19:30:46 2000 Helge Hess + + * MOF3 import + +Fri Nov 12 14:35:05 1999 Helge Hess + + * added support for user and database authentication + +Tue Nov 2 16:52:47 1999 Helge Hess + + * FBAdaptor.m: fixed -charConvertExpression.. + +Thu Oct 7 13:50:48 1999 Helge Hess + + * created ChangeLog for FrontBase adaptor diff --git a/sope-gdl1/FrontBase2/EOAttribute+FB.h b/sope-gdl1/FrontBase2/EOAttribute+FB.h new file mode 100644 index 00000000..7594bcd7 --- /dev/null +++ b/sope-gdl1/FrontBase2/EOAttribute+FB.h @@ -0,0 +1,42 @@ +/* + EOAttribute+FB.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAttribute+FB.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_EOAttribute_H___ +#define ___FB_EOAttribute_H___ + +#import + +@class NSString; + +@interface EOAttribute(FBAttributeAdditions) + +- (void)loadValueClassForExternalFrontBaseType:(NSString *)_type; +- (void)loadValueClassAndTypeFromFrontBaseType:(int)_type; +//- (void)loadValueClassAndTypeFromSybaseDataFmt:(CS_DATAFMT *)_type; + +@end + +#endif diff --git a/sope-gdl1/FrontBase2/EOAttribute+FB.m b/sope-gdl1/FrontBase2/EOAttribute+FB.m new file mode 100644 index 00000000..8f9ef969 --- /dev/null +++ b/sope-gdl1/FrontBase2/EOAttribute+FB.m @@ -0,0 +1,212 @@ +/* + EOAttribute+FB.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAttribute+FB.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import "EOAttribute+FB.h" +#import + +// Frontbase Date: Oct 21 1997 21:52:26+08:00 +static NSString *FRONTBASE_DATE_FORMAT = @"%Y-%m-%d %H:%M:%S"; + +@implementation EOAttribute(FBAttributeAdditions) + +- (void)loadValueClassForExternalFrontBaseType:(NSString *)_type { + _type = [_type lowercaseString]; + + if ([_type isEqualToString:@"tinyint"] || + [_type isEqualToString:@"bit"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + } + else if ([_type isEqualToString:@"smallint"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + } + else if ([_type isEqualToString:@"int"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + } + else if ([_type isEqualToString:@"char"] || + [_type isEqualToString:@"varchar"]) { + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"date"] || + [_type isEqualToString:@"timestamp"] || + [_type isEqualToString:@"timestamp with time zone"]) { + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:FRONTBASE_DATE_FORMAT]; + } + else if ([_type isEqualToString:@"float"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"f"]; + } + else if ([_type isEqualToString:@"time"] || + [_type isEqualToString:@"time with time zone"]) { + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"real"] || + [_type isEqualToString:@"money"] || + [_type isEqualToString:@"money4"] || + [_type isEqualToString:@"decimal"] || + [_type isEqualToString:@"numeric"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + } + else if ([_type isEqualToString:@"BLOB"]) { + [self setValueClassName:@"NSData"]; + } + else if ([_type isEqualToString:@"CLOB"]) { + [self setValueClassName:@"NSString"]; + } + else { + NSLog(@"invalid argument %@", _type); + + [InvalidArgumentException raise:@"InvalidArgumentException" + format: + @"invalid FrontBase type %@ passed to -%@", + _type, NSStringFromSelector(_cmd)]; + } +} + +- (void)loadValueClassAndTypeFromFrontBaseType:(int)_type { + switch (_type) { + case FB_Boolean: + [self setExternalType:@"BOOLEAN"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + break; + + case FB_Integer: + [self setExternalType:@"INTEGER"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + break; + case FB_SmallInteger: + [self setExternalType:@"SMALLINT"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + break; + + case FB_Float: + [self setExternalType:@"FLOAT"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + break; + case FB_Real: + [self setExternalType:@"REAL"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + break; + case FB_Double: + [self setExternalType:@"DOUBLE"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + break; + case FB_Numeric: + [self setExternalType:@"NUMERIC"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + break; + case FB_Decimal: + [self setExternalType:@"DECIMAL"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + break; + + case FB_Character: + [self setExternalType:@"CHAR"]; + [self setValueClassName:@"NSString"]; + break; + case FB_VCharacter: + [self setExternalType:@"VARCHAR"]; + [self setValueClassName:@"NSString"]; + break; + + case FB_Bit: + [self setExternalType:@"BIT"]; + [self setValueClassName:@"NSData"]; + break; + case FB_VBit: + [self setExternalType:@"VARBIT"]; + [self setValueClassName:@"NSData"]; + break; + + case FB_Date: + [self setExternalType:@"DATE"]; + [self setValueClassName:@"NSCalendarDate"]; + break; + + case FB_Time: + [self setExternalType:@"TIME"]; + [self setValueClassName:@"NSString"]; + break; + case FB_TimeTZ: + [self setExternalType:@"TIME WITH TIME ZONE"]; + [self setValueClassName:@"NSString"]; + break; + + case FB_Timestamp: + [self setExternalType:@"TIMESTAMP"]; + [self setValueClassName:@"NSCalendarDate"]; + break; + case FB_TimestampTZ: + [self setExternalType:@"TIMESTAMP WITH TIME ZONE"]; + [self setValueClassName:@"NSCalendarDate"]; + break; + + case FB_YearMonth: + [self setExternalType:@"INTERVAL YEAR TO MONTH"]; + [self setValueClassName:@"NSNumber"]; + break; + case FB_DayTime: /* NSDecimalNumber */ + [self setExternalType:@"INTERVAL DAY TO SECOND"]; + [self setValueClassName:@"NSNumber"]; + break; + + case FB_CLOB: + [self setExternalType:@"CLOB"]; + [self setValueClassName:@"NSString"]; + break; + case FB_BLOB: + [self setExternalType:@"BLOB"]; + [self setValueClassName:@"NSData"]; + break; + + default: + [InvalidArgumentException raise:@"InvalidArgumentException" + format: + @"invalid frontbase type %d passed to -%s", + _type, NSStringFromSelector(_cmd)]; + break; + } +} + +@end + +void __link_EOAttributeFB() { + // used to force linking of object file + __link_EOAttributeFB(); +} diff --git a/sope-gdl1/FrontBase2/English.lproj/InfoPlist.strings b/sope-gdl1/FrontBase2/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..97e09354 Binary files /dev/null and b/sope-gdl1/FrontBase2/English.lproj/InfoPlist.strings differ diff --git a/sope-gdl1/FrontBase2/FBAdaptor+Types.m b/sope-gdl1/FrontBase2/FBAdaptor+Types.m new file mode 100644 index 00000000..5ffb21de --- /dev/null +++ b/sope-gdl1/FrontBase2/FBAdaptor+Types.m @@ -0,0 +1,289 @@ +/* + FBAdaptor+Types.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBAdaptor+Types.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#include "FrontBase2Adaptor.h" +#include "FBChannel.h" +#include "FBContext.h" + +@interface FrontBase2Adaptor(DomainResolver) +- (BOOL)fetchDomainInfo; +@end + +@implementation FrontBase2Adaptor(DomainResolver) + +typedef struct _InternalTypeMapping { + int code; + NSString *name; +} InternalTypeMapping; + +static InternalTypeMapping internalTypeMappings[] = { + { FB_PrimaryKey, @"PRIMARYKEY" }, + { FB_Boolean, @"BOOLEAN" }, + { FB_Integer, @"INTEGER" }, + { FB_SmallInteger, @"SMALLINT" }, + { FB_Float, @"FLOAT" }, + { FB_Real, @"REAL" }, + { FB_Double, @"DOUBLE" }, + { FB_Numeric, @"NUMERIC" }, + { FB_Decimal, @"DECIMAL" }, + { FB_Character, @"CHAR" }, + { FB_VCharacter, @"VARCHAR" }, + { FB_Bit, @"BIT" }, + { FB_VBit, @"VARBIT" }, + { FB_Date, @"DATE" }, + { FB_Time, @"TIME" }, + { FB_TimeTZ, @"TIME WITH TIME ZONE" }, + { FB_Timestamp, @"TIMESTAMP" }, + { FB_TimestampTZ, @"TIMESTAMP WITH TIME ZONE" }, + { FB_YearMonth, @"INTERVAL YEAR TO MONTH" }, + { FB_DayTime, @"INTERVAL DAY TO SECOND" }, + { FB_CLOB, @"CLOB" }, + { FB_BLOB, @"BLOB" }, + { -1, nil } // end marker +}; + +static NSString *DomainQuery = + @"SELECT \"DOMAIN_NAME\" FROM INFORMATION_SCHEMA.domains"; + +- (void)_resetTypeMapping { + if (self->typeNameToCode) { + NSFreeMapTable(self->typeNameToCode); + self->typeNameToCode = NULL; + } + if (self->typeCodeToName) { + NSFreeMapTable(self->typeCodeToName); + self->typeCodeToName = NULL; + } +} + +- (void)_loadStandardTypes { + register InternalTypeMapping *mapping; + + if (self->typeNameToCode == NULL) { + self->typeNameToCode = NSCreateMapTable(NSObjectMapKeyCallBacks, + NSIntMapValueCallBacks, + 64); + } + if (self->typeCodeToName == NULL) { + self->typeCodeToName = NSCreateMapTable(NSIntMapKeyCallBacks, + NSObjectMapValueCallBacks, + 64); + } + + mapping = &(internalTypeMappings[1]); + + while (mapping->name != nil) { + NSMapInsert(self->typeCodeToName, + (void *)(mapping->code), + (void *)mapping->name); + NSMapInsert(self->typeNameToCode, + (void *)mapping->name, + (void *)(mapping->code)); + mapping++; + } +} + +- (BOOL)fetchDomainInfo { + FrontBaseContext *ctx; + FrontBaseChannel *channel; + BOOL result; + + if (self->typeNameToCode == NULL) + [self _loadStandardTypes]; + + result = NO; + ctx = (FrontBaseContext *)[self createAdaptorContext]; + channel = (FrontBaseChannel *)[ctx createAdaptorChannel]; + + if ([channel openChannel]) { + if ([ctx beginTransaction]) { + if ([channel evaluateExpression:DomainQuery]) { + NSArray *attributes; + NSDictionary *record; + NSMutableArray *domains; + + attributes = [channel describeResults]; + domains = nil; + + while ((record = [channel fetchAttributes:attributes withZone:NULL])) { + NSString *domainName; + + if ((domainName = [record objectForKey:@"domainName"])) { + if (![domainName hasPrefix:@"T_"]) + continue; + + if (domains == nil) + domains = [NSMutableArray arrayWithCapacity:32]; + [domains addObject:domainName]; + } + else + NSLog(@"no domain name in record %@ ?", record); + } + + /* no get the meta-info of the domains */ + + if ([domains count] > 0) { + /* we need to resolve domains, construct a VALUES expression .. */ + NSMutableString *expr; + NSEnumerator *e; + NSString *domainName; + BOOL isFirst = YES; + + expr = [NSMutableString stringWithCapacity:512]; + [expr appendString:@"VALUES("]; + + e = [domains objectEnumerator]; + while ((domainName = [e nextObject])) { + if (isFirst) isFirst = NO; + else [expr appendString:@","]; + + [expr appendString:@"CAST(NULL AS \""]; + [expr appendString:domainName]; + [expr appendString:@"\")"]; + } + + [expr appendString:@")"]; + + //NSLog(@"expr: %@", expr); + + /* now execute expression */ + + if ([channel evaluateExpression:expr]) { + int *dc = channel->datatypeCodes; + int i; + + for (i = 0; i < channel->numberOfColumns; i++) { + if (dc[i] > 0) { + NSString *domainName; + + domainName = [[domains objectAtIndex:i] uppercaseString]; + + //NSMapInsert(self->typeCodeToName, (void *)dc[i], domainName); + NSMapInsert(self->typeNameToCode, domainName, (void *)dc[i]); +#if 0 + NSLog(@"domain %@ is code %i type %@", + domainName, + dc[i], + NSMapGet(self->typeCodeToName, (void*)dc[i])); +#endif + } + } + + [channel cancelFetch]; + + result = YES; + if (![ctx commitTransaction]) + NSLog(@"couldn't common tx for domain-resolver .."); + } + else + NSLog(@"couldn't evaluate expression: %@", expr); + } + } + else + NSLog(@"couldn't evaluate expression: %@", DomainQuery); + if (!result) [ctx rollbackTransaction]; + } + else + NSLog(@"couldn't begin tx for domain-resolver .."); + + [channel closeChannel]; + } + else + NSLog(@"couldn't open channel for domain-resolver .."); + + return result; +} + +@end + +@implementation FrontBase2Adaptor(ExternalTyping) + +- (int)typeCodeForExternalName:(NSString *)_typeName { + int code; + + _typeName = [_typeName uppercaseString]; + + if (self->typeNameToCode == NULL) + [self fetchDomainInfo]; + + if (self->typeNameToCode == NULL) + return FB_VCharacter; + + if ((code = (int)NSMapGet(self->typeNameToCode, _typeName))) + return code; + + return FB_VCharacter; +} + +- (NSString *)externalNameForTypeCode:(int)_typeCode { + if (_typeCode == 0) + return nil; + + if (self->typeCodeToName == NULL) + [self fetchDomainInfo]; + + return NSMapGet(self->typeCodeToName, (void *)_typeCode); +} + +- (BOOL)isInternalBlobType:(int)_type { + switch (_type) { + case FB_BLOB: + case FB_CLOB: + return YES; + + default: + return NO; + } +} + +- (BOOL)isBlobAttribute:(EOAttribute *)_attr { + int fbType; + + NSAssert(_attr, @"missing attribute parameter"); + + fbType = [self typeCodeForExternalName:[_attr externalType]]; + + return [self isInternalBlobType:fbType]; +} + +- (BOOL)isValidQualifierType:(NSString *)_typeName { + switch ([self typeCodeForExternalName:_typeName]) { + case FB_BLOB: + case FB_CLOB: + return NO; + + default: + return YES; + } +} + +- (BOOL)attributeAllowedInDistinctSelects:(EOAttribute *)_attr { + NSAssert(_attr, @"missing attribute parameter"); + return YES; +} + +@end diff --git a/sope-gdl1/FrontBase2/FBBlobHandle.h b/sope-gdl1/FrontBase2/FBBlobHandle.h new file mode 100644 index 00000000..f182da11 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBBlobHandle.h @@ -0,0 +1,44 @@ +/* + FBBlobHandle.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FrontBase Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBBlobHandle.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_FBBlobHandle_H___ +#define ___FB_FBBlobHandle_H___ + +#import +#import "FBValues.h" + +@interface FBBlobHandle : NSObject < FBValues > +{ +@private + NSString *bid; +} + +- (id)initWithBlobID:(NSString *)_bid; +- (NSString *)blobID; + +@end + +#endif /* ___FB_FBBlobHandle_H___ */ diff --git a/sope-gdl1/FrontBase2/FBBlobHandle.m b/sope-gdl1/FrontBase2/FBBlobHandle.m new file mode 100644 index 00000000..e6e7dcee --- /dev/null +++ b/sope-gdl1/FrontBase2/FBBlobHandle.m @@ -0,0 +1,62 @@ +// $Id: FBBlobHandle.m 1 2004-08-20 10:38:46Z znek $ + +#include "FBBlobHandle.h" +#include "FBValues.h" +#include "common.h" + +@implementation FBBlobHandle + +- (id)initWithBlobID:(NSString *)_bid { + self->bid = [_bid copyWithZone:[self zone]]; + return self; +} + +- (void)dealloc { + RELEASE(self->bid); + [super dealloc]; +} + +/* accessors */ + +- (NSString *)blobID { + return self->bid; +} + +/* data */ + ++ (id)valueFromBytes:(const char *)_bytes length:(unsigned)_length + frontBaseType:(int)_fb attribute:(EOAttribute *)_attribute + adaptorChannel:(FrontBaseChannel *)_channel +{ + NSLog(@"called %@ on BLOB handle %@", NSStringFromSelector(_cmd), self); + return nil; +} + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + NSLog(@"called %@ on BLOB handle %@", NSStringFromSelector(_cmd), self); + return nil; +} + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + switch (_type) { + case FB_Character: + case FB_VCharacter: + case FB_CLOB: + case FB_BLOB: + return self->bid; + //return [NSString stringWithFormat:@"@'%s'", [self->bid cString]]; + } + return nil; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@[0x%08X]: id=%@>", + NSStringFromClass([self class]), self, + [self blobID]]; +} + +@end /* FBBlobHandle */ diff --git a/sope-gdl1/FrontBase2/FBChannel+Model.h b/sope-gdl1/FrontBase2/FBChannel+Model.h new file mode 100644 index 00000000..eb138f75 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBChannel+Model.h @@ -0,0 +1,42 @@ +/* + FBChannel+Model.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBChannel+Model.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_ModelFetching_H___ +#define ___FB_ModelFetching_H___ + +#import "FBChannel.h" + +@class NSArray; +@class EOModel; + +@interface FrontBaseChannel(ModelFetching) + +- (EOModel *)describeModelWithTableNames:(NSArray *)_tableNames; +- (NSArray *)describeTableNames; + +@end + +#endif diff --git a/sope-gdl1/FrontBase2/FBChannel+Model.m b/sope-gdl1/FrontBase2/FBChannel+Model.m new file mode 100644 index 00000000..98c8c407 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBChannel+Model.m @@ -0,0 +1,316 @@ +/* + FBChannel+Model.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBChannel+Model.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import + +@interface EORelationship(Private) +- (void)addJoin:(EOJoin *)_join; +@end + +@implementation FrontBaseChannel(ModelFetching) + +- (NSArray *)_attributesForTableName:(NSString *)_tableName { + NSArray *attrForTableName = nil; + + if ((attrForTableName = + [self->_attributesForTableName objectForKey:_tableName]) == nil) { + NSMutableArray *attributes = nil; + NSArray *resultDescription = nil; + NSString *selectExpression = nil; + NSString *columnNameKey = nil; + NSString *externalTypeKey = nil; + NSDictionary *row = nil; + unsigned cnt = 0; + + selectExpression = [NSString stringWithFormat: + @"SELECT C1.\"COLUMN_NAME\", DTD1.\"DATA_TYPE\" FROM INFORMATION_SCHEMA." + @"COLUMNS C1, INFORMATION_SCHEMA.TABLES T1, INFORMATION_SCHEMA.DATA_" + @"TYPE_DESCRIPTOR DTD1 WHERE T1.\"TABLE_NAME\" = '%s' AND T1.\"" + @"TABLE_PK\" = DTD1.\"TABLE_OR_DOMAIN_PK\" AND C1.\"TABLE_PK\" = T1." + @"\"TABLE_PK\" AND C1.\"COLUMN_PK\" = DTD1.\"COLUMN_NAME_PK\"", + [[_tableName uppercaseString] cString]]; + + if (![self evaluateExpression:selectExpression]) { + fprintf(stderr, "Couldn`t evaluate expression %s\n", + [selectExpression cString]); + return nil; + } + resultDescription = [self describeResults]; + columnNameKey = [(EOAttribute *)[resultDescription objectAtIndex:0] name]; + externalTypeKey = [(EOAttribute *)[resultDescription objectAtIndex:1] name]; + attributes = [NSMutableArray arrayWithCapacity:16]; + + while ((row = [self fetchAttributes:resultDescription withZone:NULL])) { + EOAttribute *attribute = nil; + NSString *columnName = nil; + NSString *externalType = nil; + NSString *attrName = nil; + int fbType = 0; + + attribute = [[EOAttribute alloc] init]; + columnName = [row objectForKey:columnNameKey]; + externalType = [row objectForKey:externalTypeKey]; + attrName = [columnName _sybModelMakeInstanceVarName]; + fbType = [(id)[adaptorContext adaptor] + typeCodeForExternalName:externalType]; + + [attribute setName:attrName]; + [attribute setColumnName:columnName]; + [attribute loadValueClassAndTypeFromFrontBaseType:fbType]; + [attribute setExternalType:externalType]; + + [attributes addObject:attribute]; + RELEASE(attribute); attribute = nil; + } + + // fetch external types + + for (cnt = 0; cnt < [attributes count]; cnt++) { + EOAttribute *attribute = nil; + NSString *externalType = nil; + int fbType = 0; + + attribute = [attributes objectAtIndex:cnt]; + externalType = [attribute externalType]; + fbType = [(id)[adaptorContext adaptor] + typeCodeForExternalName:externalType]; + [attribute loadValueClassAndTypeFromFrontBaseType:fbType]; + [attribute setExternalType:externalType]; + } + attrForTableName = attributes; + [self->_attributesForTableName setObject:attrForTableName forKey:_tableName]; + } + return attrForTableName; +} + +- (NSArray *)_primaryKeysNamesForTableName:(NSString *)_tableName { + NSArray *pkNameForTable = nil; + + if (_tableName == nil) + return nil; + + if ((pkNameForTable = + [self->_primaryKeysNamesForTableName objectForKey:_tableName]) == nil) { + NSMutableArray *primaryKeys = nil; + NSString *selectExpression = nil; + NSArray *resultDescription = nil; + NSString *columnNameKey = nil; + NSDictionary *row = nil; + + selectExpression = [NSString stringWithFormat: + @"SELECT C1.\"COLUMN_NAME\" FROM INFORMATION_SCHEMA.COLUMNS C1, " + @"INFORMATION_SCHEMA.TABLES T1, INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC1, " + @"INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1 WHERE T1.\"TABLE_NAME\" = " + @"'%s' AND TC1.\"TABLE_PK\" = T1.\"TABLE_PK\" AND TC1.\"CONSTRAINT" + @"_TYPE\" = 'PRIMARY KEY' AND KCU1.\"TABLE_PK\" = T1.\"TABLE_PK\" AND " + @"KCU1.\"CONSTRAINT_NAME_PK\" = TC1.\"CONSTRAINT_NAME_PK\" AND C1.\"" + @"COLUMN_PK\" = KCU1.\"COLUMN_PK\"", + [[_tableName uppercaseString] cString]]; + + if (![self evaluateExpression:selectExpression]) { + fprintf(stderr, "Couldn`t evaluate expression %s\n", + [selectExpression cString]); + return nil; + } + resultDescription = [self describeResults]; + columnNameKey = [(EOAttribute *)[resultDescription objectAtIndex:0] + name]; + primaryKeys = [NSMutableArray arrayWithCapacity:4]; + + while ((row = [self fetchAttributes:resultDescription withZone:NULL])) + [primaryKeys addObject:[row objectForKey:columnNameKey]]; + + pkNameForTable = primaryKeys; + [self->_primaryKeysNamesForTableName setObject:pkNameForTable + forKey:_tableName]; + } + return pkNameForTable; +} + +- (NSArray *)_foreignKeysForTableName:(NSString *)_tableName { + return [NSArray array]; +} + +- (EOModel *)describeModelWithTableNames:(NSArray *)_tableNames { + NSMutableArray *buildRelShips = nil; + EOModel *model = nil; + int cnt = 0; + int tc = 0; + + buildRelShips = [NSMutableArray arrayWithCapacity:64]; + model = [[EOModel alloc] init]; + tc = [_tableNames count]; + AUTORELEASE(model); + + for (cnt = 0; cnt < tc; cnt++) { + NSMutableDictionary *relNamesUsed = nil; + NSMutableArray *classProperties = nil; + NSMutableArray *primaryKeyAttributes = nil; + NSString *tableName = nil; + NSArray *attributes = nil; + NSArray *pkeys = nil; + NSArray *fkeys = nil; + EOEntity *entity = nil; + int cnt2 = 0; + int ac = 0; + int fkc = 0; + + relNamesUsed = [NSMutableDictionary dictionary]; + classProperties = [NSMutableArray array]; + primaryKeyAttributes = [NSMutableArray array]; + tableName = [_tableNames objectAtIndex:cnt]; + attributes = [self _attributesForTableName:tableName]; + pkeys = [self _primaryKeysNamesForTableName:tableName]; + fkeys = [self _foreignKeysForTableName:tableName]; + entity = [[EOEntity alloc] init]; + ac = [attributes count]; + fkc = [fkeys count]; + AUTORELEASE(entity); + + [entity setName:[tableName _sybModelMakeClassName]]; + [entity setClassName: + [@"EO" stringByAppendingString:[tableName _sybModelMakeClassName]]]; + [entity setExternalName:tableName]; + [classProperties addObjectsFromArray:[entity classProperties]]; + [primaryKeyAttributes addObjectsFromArray:[entity primaryKeyAttributes]]; + [model addEntity:entity]; + + for (cnt2 = 0; cnt2 < ac; cnt2++) { + EOAttribute *attribute = [attributes objectAtIndex:cnt2]; + NSString *columnName = [attribute columnName]; + + [entity addAttribute:attribute]; + [classProperties addObject:attribute]; + + if ([pkeys containsObject:columnName]) + [primaryKeyAttributes addObject:attribute]; + } + [entity setClassProperties:classProperties]; + [entity setPrimaryKeyAttributes:primaryKeyAttributes]; + + for (cnt2 = 0; cnt2 < fkc; cnt2++) { + NSDictionary *fkey = nil; + NSMutableArray *classProperties = nil; + NSString *sa = nil; + NSString *da = nil; + NSString *dt = nil; + EORelationship *rel = nil; + EOJoin *join = nil; + NSString *relName = nil; + + fkey = [fkeys objectAtIndex:cnt2]; + classProperties = [NSMutableArray array]; + sa = [fkey objectForKey:@"sourceAttr"]; + da = [fkey objectForKey:@"targetAttr"]; + dt = [fkey objectForKey:@"targetTable"]; + rel = [[EORelationship alloc] init]; + join = [[EOJoin alloc] init]; + AUTORELEASE(rel); + AUTORELEASE((id)join); + + if ([pkeys containsObject:sa]) + relName = [@"to" stringByAppendingString:[dt _sybModelMakeClassName]]; + else { + relName = [@"to" stringByAppendingString: + [[sa _sybModelMakeInstanceVarName] + _sybStringWithCapitalizedFirstChar]]; + if ([relName hasSuffix:@"Id"]) { + int cLength = [relName cStringLength]; + + relName = [relName substringToIndex:cLength - 2]; + } + } + if ([relNamesUsed objectForKey:relName]) { + int useCount = [[relNamesUsed objectForKey:relName] intValue]; + + [relNamesUsed setObject:[NSNumber numberWithInt:(useCount++)] + forKey:relName]; + relName = [NSString stringWithFormat:@"%s%d", + [relName cString], useCount]; + } + else + [relNamesUsed setObject:[NSNumber numberWithInt:0] forKey:relName]; + + [rel setName:relName]; + //[rel setDestinationEntity:(EOEntity *)[dt _sybModelMakeClassName]]; + [rel setToMany:NO]; + + [(id)join setSourceAttribute: + (EOAttribute *)[sa _sybModelMakeInstanceVarName]]; + [(id)join setDestinationAttribute: + (EOAttribute *)[da _sybModelMakeInstanceVarName]]; + [rel addJoin:join]; + + [entity addRelationship:rel]; + [classProperties addObjectsFromArray:[entity classProperties]]; + [classProperties addObject:rel]; + [entity setClassProperties:classProperties]; + [buildRelShips addObject:rel]; + } + + [entity setAttributesUsedForLocking:[[entity attributes] copy]]; + } + + [buildRelShips makeObjectsPerformSelector:@selector(replaceStringsWithObjects)]; + + [model setAdaptorName:@"FrontBase2"]; + [model setAdaptorClassName:@"FrontBase2Adaptor"]; + [model setConnectionDictionary:[[adaptorContext adaptor] connectionDictionary]]; + return model; +} + +- (NSArray *)describeTableNames { + NSMutableArray *tableNames = nil; + NSArray *resultDescription = nil; + NSString *attributeName = nil; + NSDictionary *row = nil; + NSString *selectExpression = nil; + + selectExpression = @"SELECT T1.\"TABLE_NAME\" FROM " + @"INFORMATION_SCHEMA.TABLES T1"; + + if (![self evaluateExpression:selectExpression]) { + fprintf(stderr, "Couldn`t evaluate expression %s\n", + [selectExpression cString]); + return nil; + } + resultDescription = [self describeResults]; + attributeName = [(EOAttribute *)[resultDescription objectAtIndex:0] name]; + tableNames = [NSMutableArray arrayWithCapacity:16]; + + while ((row = [self fetchAttributes:resultDescription withZone:NULL])) + [tableNames addObject:[row objectForKey:attributeName]]; + + return tableNames; +} + +@end + +void __link_FBChannelModel() { + // used to force linking of object file + __link_FBChannelModel(); +} diff --git a/sope-gdl1/FrontBase2/FBChannel.h b/sope-gdl1/FrontBase2/FBChannel.h new file mode 100644 index 00000000..c7463bba --- /dev/null +++ b/sope-gdl1/FrontBase2/FBChannel.h @@ -0,0 +1,88 @@ +/* + FBChannel.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBChannel.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_Channel_H___ +#define ___FB_Channel_H___ + +#import +#import "FBHeaders.h" + +@class NSArray, NSString, NSMutableDictionary; + +struct _FBColumnData; + +@interface FrontBaseChannel : EOAdaptorChannel +{ +@public + /* connection is valid after an openChannel call */ + FBCDatabaseConnection *fbdc; + void **rawRows; + FBCRowHandler *rowHandler; + FBCMetaData *cmdMetaData; + char *fetchHandle; + BOOL isFirstInBatch; + + /* these variables are valid only during an evaluation */ + int currentRow; + int numberOfColumns; // number of columns in result set + int *datatypeCodes; + int rowsAffected; + unsigned txVersion; + NSArray *selectedAttributes; // contains the real select order + + /* turns on/off channel debugging */ + BOOL isDebuggingEnabled; + NSString *sqlLogFile; + + /* caching */ + NSMutableDictionary *_primaryKeysNamesForTableName; + NSMutableDictionary *_attributesForTableName; +} + +- (void)setDebugEnabled:(BOOL)_flag; +- (BOOL)isDebugEnabled; + +- (BOOL)isOpen; +- (BOOL)openChannel; +- (void)closeChannel; +- (void)primaryCloseChannel; // private + +- (NSMutableDictionary *)primaryFetchAttributes:(NSArray *)_attributes + withZone:(NSZone *)_zone; + +- (BOOL)evaluateExpression:(NSString *)_expression; + +// cancelFetch is always called to terminate a fetch +// (even by primaryFetchAttributes) +// it frees all fetch-local variables +- (void)cancelFetch; + +// uses type information to create EOAttribute objects +- (NSArray *)describeResults; + +@end + +#endif diff --git a/sope-gdl1/FrontBase2/FBChannel.m b/sope-gdl1/FrontBase2/FBChannel.m new file mode 100644 index 00000000..f1f54616 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBChannel.m @@ -0,0 +1,1302 @@ +/* + FBChannel.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBChannel.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include +#if HAVE_STRINGS_H +#include +#endif +#import "common.h" +#include "FBBlobHandle.h" +#include + +#include +#include +#import + +//#define BLOB_DEBUG 1 + +@implementation FrontBaseChannel + +static EONull *null = nil; + ++ (void)initialize { + if (null == NULL) null = [[EONull null] retain]; +} + +#ifdef __MINGW32__ +extern __declspec(import) void fbcInitialize(void); +#endif + +- (id)initWithAdaptorContext:(EOAdaptorContext*)_adaptorContext { + static BOOL didInit = NO; + if (!didInit) { + didInit = YES; +#ifdef __MINGW32__ + fbcInitialize(); +#endif +#ifdef __APPLE__ + fbcInitialize(); +#endif + } + + if ((self = [super initWithAdaptorContext:_adaptorContext])) { + [self setDebugEnabled:[[NSUserDefaults standardUserDefaults] + boolForKey:@"FBDebugEnabled"]]; + sqlLogFile = [[[NSUserDefaults standardUserDefaults] + stringForKey:@"FBLogFile"] + copyWithZone:[self zone]]; + self->_primaryKeysNamesForTableName = [[NSMutableDictionary alloc] init]; + self->_attributesForTableName = [[NSMutableDictionary alloc] init]; + } + return self; +} + +#if !LIB_FOUNDATION_BOEHM_GC +- (void)dealloc { + if ([self isOpen]) { + [self cancelFetch]; + [self closeChannel]; + } + RELEASE(self->sqlLogFile); + RELEASE(self->_primaryKeysNamesForTableName); + RELEASE(self->_attributesForTableName); + [super dealloc]; +} +#endif + +// NSCopying methods + +- (id)copyWithZone:(NSZone *)zone { + return RETAIN(self);// copy is needed during creation of NSNotification object +} + +// debugging + +- (void)setDebugEnabled:(BOOL)_flag { + self->isDebuggingEnabled = _flag; +} +- (BOOL)isDebugEnabled { + return self->isDebuggingEnabled; +} + +// open/close + +- (BOOL)isOpen { + return self->fbdc != NULL ? YES : NO; +} + +- (BOOL)openChannel { + FrontBase2Adaptor *adaptor; + FBCMetaData *md; + BOOL result = NO; + NSString *txIsoLevel; + NSString *locking; + NSString *expr; + const char *password; + char pwdDigest[17]; + + // [self setDebugEnabled:YES]; + + adaptor = (FrontBase2Adaptor *)[[self adaptorContext] adaptor]; + + if (![super openChannel]) + return NO; + + /* digest the database password */ + + if ((password = [[adaptor databasePassword] cString])) { + if (fbcDigestPassword("_SYSTEM", (char *)password, pwdDigest) == NULL) { + NSLog(@"%@: Couldn't digest password !", self); + pwdDigest[0] = '\0'; + } + } + else + pwdDigest[0] = '\0'; + + /* connect to database */ + + if (isDebuggingEnabled) + NSLog(@"Open fb-channel[%p]: db=%@, server=%@", self, + [adaptor databaseName], [adaptor serverName]); + + self->fbdc = + fbcdcConnectToDatabase((char *)[[adaptor databaseName] cString], + (char *)[[adaptor serverName] cString], + (char *)pwdDigest); + if (self->fbdc == NULL) { + if (isDebuggingEnabled) { + NSLog(@"FrontBase channel 0x%08X (db=%@, server=%@, digest=%s) " + @"could not be opened: %s ..", self, + [adaptor databaseName], [adaptor serverName], + pwdDigest /* ? "yes" : "no"*/, + fbcdcClassErrorMessage()); + } + return NO; + } + + fbcdcSetRollbackAfterError(self->fbdc, True); + + /* digest the user password */ +#if 0 + if ((password = [[adaptor loginPassword] cString])) { + if (fbcDigestPassword((char *)[[adaptor loginName] cString], + (char *)password, pwdDigest) == NULL) { + NSLog(@"%@: Couldn't digest password !", self); + pwdDigest[0] = '\0'; + } + } + else + pwdDigest[0] = '\0'; +#else + if (!(password = [[adaptor loginPassword] cString])) + password = "\0"; +#endif + + /* create session */ + + md = fbcdcCreateSession(self->fbdc, + (char *)[[NSString stringWithFormat: + @"GDL<0x%08X>", self] + cString], + (char *)[[adaptor loginName] cString], + // pwdDigest, + (char *)password, + (char *)[NSUserName() cString]); + if (md == NULL) { + if (isDebuggingEnabled) { + NSLog(@"FrontBase session (channel=0x%08X) couldn't be created, " + @" login=%@ password=%s user=%@: %s.", + self, + [adaptor loginName], [adaptor loginPassword], + [adaptor loginName], + fbcdcClassErrorMessage()); + } + fbcdcClose(self->fbdc); self->fbdc = NULL; + return NO; + } + + if (fbcmdErrorCount(md) > 0) { + if (isDebuggingEnabled) { + FBCErrorMetaData *emd; + int i, count; + + emd = fbcdcErrorMetaData(self->fbdc, md); + + NSLog(@"FrontBase session (channel=0x%08X) couldn't be created:", self); + + for (i = 0, count = fbcemdErrorCount(emd); i < count; i++) { + unsigned code; + const char *errorKind; + const char *emsg; + + code = fbcemdErrorCodeAtIndex(emd, i); + errorKind = fbcemdErrorKindAtIndex(emd, i); + emsg = fbcemdErrorMessageAtIndex(emd, i); + + NSLog(@" code=%i", code); + NSLog(@" kind=%s", errorKind); + NSLog(@" msdg=%s", emsg); +#if 0 + free((void *)errorKind); +#endif + free((void *)emsg); + } + fbcemdRelease(emd); emd = NULL; + } + fbcdcClose(self->fbdc); self->fbdc = NULL; + fbcmdRelease(md); md = NULL; + return NO; + } + + fbcmdRelease(md); md = NULL; + + result = YES; + + /* apply session level setting (locking & tx levels) */ + + if ((txIsoLevel = [adaptor transactionIsolationLevel]) == nil) + txIsoLevel = @"READ COMMITTED"; + if ((locking = [adaptor lockingDiscipline]) == nil) + locking = @"OPTIMISTIC"; + + expr = [NSString stringWithFormat: + @"SET TRANSACTION ISOLATION LEVEL %s, LOCKING %s", + [txIsoLevel cString], [locking cString]]; + if (![self evaluateExpression:expr]) { + if (isDebuggingEnabled) + NSLog(@"%@: couldn't apply tx iso level '%@' and locking '%@'..", + self, txIsoLevel, locking); + } + +#if LIB_FOUNDATION_BOEHM_GC + [GarbageCollector registerForFinalizationObserver:self + selector:@selector(_adaptorWillFinalize:) + object:[[self adaptorContext] adaptor]]; +#endif + + if (isDebuggingEnabled) + NSLog(@"FrontBase channel 0x%08X opened ..", self); + + return result; +} + +- (void)primaryCloseChannel { + /* release all resources */ + + if (self->fbdc) { + if (isDebuggingEnabled) { + id ad; + + ad = [[self adaptorContext] adaptor]; + NSLog(@"Close fb-channel[%p]: db=%@, server=%@", self, + ad, [ad serverName]); + } + + fbcdcClose(self->fbdc); + self->fbdc = NULL; + } + + RELEASE(self->selectedAttributes); self->selectedAttributes = nil; +} + +- (void)closeChannel { + [super closeChannel]; + [self primaryCloseChannel]; +} + +// fetching rows + +- (void)cancelFetch { + if (![self isOpen]) { + [FrontBaseException raise:@"ChannelNotOpenException" + format:@"No fetch in progress, fb connection is not" + @" open (channel=%@)", self]; + } + + if (self->fetchHandle) { + FBCMetaData *md; + if ((md = fbcdcCancelFetch(self->fbdc, self->fetchHandle))) { + fbcmdRelease(md); md = NULL; + } + self->fetchHandle = NULL; + } + + if (self->datatypeCodes) { + free(self->datatypeCodes); + self->datatypeCodes = NULL; + } + + if (self->rowHandler) { + fbcrhRelease(self->rowHandler); + self->rowHandler = NULL; + self->rawRows = NULL; + } + else { + NSAssert(self->rawRows == NULL, @"raw rows set, but no row handler ! .."); + } + + if (self->cmdMetaData) { + fbcmdRelease(self->cmdMetaData); + self->cmdMetaData = NULL; + } + + NSAssert(self->rowHandler == NULL, @"row handler still set .."); + NSAssert(self->rawRows == NULL, @"raw row still set .."); + + [super cancelFetch]; + + self->currentRow = 0; + self->numberOfColumns = 0; + RELEASE(self->selectedAttributes); self->selectedAttributes = nil; +} + +- (NSArray *)describeResults { + int cnt; + NSMutableArray *result = nil; + NSMutableDictionary *usedNames = nil; + NSNumber *yesObj = [NSNumber numberWithBool:YES]; + + if (![self isFetchInProgress]) { + [FrontBaseException raise:@"NoFetchInProgress" + format:@"No fetch in progress (channel=%@)", self]; + } + + NSAssert(self->cmdMetaData, @"no cmd-meta-data .."); + + result = + [[NSMutableArray alloc] initWithCapacity:self->numberOfColumns + 1]; + usedNames = + [[NSMutableDictionary alloc] initWithCapacity:self->numberOfColumns + 1]; + + for (cnt = 0; cnt < self->numberOfColumns; cnt++) { + const FBCColumnMetaData *cmd; + EOAttribute *attribute = nil; + NSString *columnName = nil; + NSString *attrName = nil; + + cmd = fbcmdColumnMetaDataAtIndex(self->cmdMetaData, cnt); + + if (cmd) { + const char *s; + + if ((s = fbccmdLabelName(cmd))) + columnName = [NSString stringWithCString:s]; + else if ((s = fbccmdColumnName(cmd))) + columnName = [NSString stringWithCString:s]; + } + + if ([columnName length] == 0) { + columnName = [NSString stringWithFormat:@"column%i", cnt]; + attrName = [NSString stringWithFormat:@"column%i", cnt]; + } + else + attrName = [columnName _sybModelMakeInstanceVarName]; + + if ([[usedNames objectForKey:attrName] boolValue]) { + int cnt2 = 0; + char buf[64]; + NSString *newAttrName = nil; + + for (cnt2 = 2; cnt2 < 100; cnt2++) { + sprintf(buf, "%i", cnt2); + + newAttrName = [attrName stringByAppendingString: + [NSString stringWithCString:buf]]; + + if (![[usedNames objectForKey:newAttrName] boolValue]) { + attrName = newAttrName; + break; + } + } + } + [usedNames setObject:yesObj forKey:attrName]; + + attribute = [[EOAttribute alloc] init]; + [attribute setName:attrName]; + [attribute setColumnName:columnName]; + [attribute loadValueClassAndTypeFromFrontBaseType:self->datatypeCodes[cnt]]; + [result addObject:attribute]; + RELEASE(attribute); attribute = nil; + } + + RELEASE(usedNames); + usedNames = nil; + + return AUTORELEASE(result); +} + +- (int)batchSize { + return 1000; +} + +- (BOOL)_nextBatch { + if (self->rowHandler) { + fbcrhRelease(self->rowHandler); + self->rowHandler = NULL; + self->rawRows = NULL; + } + + //NSLog(@"fetching new batch .."); + NSAssert(self->fetchHandle, @"missing fetch handle .."); + self->rawRows = fbcdcFetch(self->fbdc, [self batchSize], self->fetchHandle); + + if (self->rawRows) { + self->rowHandler = fbcrhInitWith(self->rawRows, self->cmdMetaData); + self->isFirstInBatch = YES; + //NSLog(@"fetched new batch %i rows ..", fbcrhRowCount(self->rowHandler)); + } + else { + /* no more fetch data, finish fetch op */ + [self cancelFetch]; + self->isFetchInProgress = NO; + return NO; + } + + return YES; +} + +- (NSMutableDictionary *)primaryFetchAttributes:(NSArray *)_attributes + withZone:(NSZone *)_zone +{ + NSMutableDictionary *record; + void **rawRow; + int i; + + record = nil; + + if (!self->isFetchInProgress) + return nil; + + if (self->rawRows == NULL) { + if (![self _nextBatch]) + return nil; + } + + if (self->selectedAttributes == nil) { + self->selectedAttributes = RETAIN([self describeResults]); + } + + if ([_attributes count] < [self->selectedAttributes count]) + _attributes = self->selectedAttributes; + + NSAssert(self->rowHandler, @"missing row handler .."); + + rawRow = self->isFirstInBatch + ? fbcrhFirstRow(self->rowHandler) + : fbcrhNextRow(self->rowHandler); + + if (rawRow == NULL) { + /* no more rows available in fetch-buffer, get next batch */ + if (![self _nextBatch]) + return nil; + + rawRow = self->isFirstInBatch + ? fbcrhFirstRow(self->rowHandler) + : fbcrhNextRow(self->rowHandler); + } + self->isFirstInBatch = NO; + + if (rawRow == NULL) { + /* no rows were in batch and no new batch could be fetched, so we finished */ + [self cancelFetch]; + self->isFetchInProgress = NO; + return nil; + } + + /* deconstruct raw row */ + + { + id objects[self->numberOfColumns]; + id keys[self->numberOfColumns]; + + for (i = 0; i < self->numberOfColumns; i++) { + EOAttribute *attribute; + register void *rawValue; + Class valueClass; + NSString *attrName; + id value; + + objects[i] = NULL; + keys[i] = NULL; + + if (self->datatypeCodes[i] < 1) + continue; + +#if 1 + if (!(attribute = [_attributes objectAtIndex:i])) { + attribute = [self->selectedAttributes objectAtIndex:i]; + } +#endif + + attrName = [attribute name]; + valueClass = NSClassFromString([attribute valueClassName]); + +#if DEBUG + NSAssert3(valueClass, + @"no valueClass for attribute %@ entity %@ name %@ ..", + attribute, [attribute entity], [attribute valueClassName]); +#endif + + if (attrName == nil) + attrName = [NSString stringWithFormat:@"column%i", i]; + + rawValue = rawRow[i]; + if (rawValue == NULL) { + value = null; + } + else { + FBCBlobHandle *handle = NULL; + unsigned int len = 4; + + switch (self->datatypeCodes[i]) { + case FB_Boolean: + len = sizeof(unsigned char); + break; + + case FB_Character: + len = strlen(rawValue); + break; + case FB_VCharacter: + len = strlen(rawValue); + break; + case FB_Date: + NSLog(@"handling date .."); + len = strlen(rawValue); + break; + case FB_Timestamp: + NSLog(@"handling timestamp .."); + len = strlen(rawValue); + break; + case FB_TimestampTZ: + len = strlen(rawValue); + if (len != 25) { + NSLog(@"handling timestamp with TZ with length=%i ..", len); + } + break; + + case FB_SmallInteger: + len = sizeof(short); + break; + + case FB_Integer: + case FB_YearMonth: + len = sizeof(int); + break; + + case FB_Double: + case FB_Real: + case FB_Numeric: + case FB_Decimal: + case FB_DayTime: + len = sizeof(double); + break; + + case FB_Float: + len = sizeof(float); + break; + + case FB_CLOB: + case FB_BLOB: + /* + CLOB/BLOB are a bit more tricky, mainly because values of up to a + given size are inlined in the fetch result, i.e. no need for a + round trip to the server. + */ + if ((*(unsigned char *)rawValue) == 0) { + /* blob via handle */ +#if BLOB_DEBUG + NSLog(@"blob via handle %s", + ((FBCBlobIndirect *)rawValue)->handleAsString); +#endif + + handle = + fbcbhInitWithHandle(((FBCBlobIndirect *)rawValue)->handleAsString); + len = fbcbhBlobSize(handle); + + rawValue = fbcdcReadBLOB(self->fbdc, handle); + } + else { + /* blob inline */ + FBCBlobDirect *blob; + +#if BLOB_DEBUG + NSLog(@"blob inline"); +#endif + blob = rawValue; + rawValue = blob->blobData; + len = blob->blobSize; + } +#if BLOB_DEBUG + NSLog(@" size=%d", len); +#endif + break; + } + + /* make an object value from the data */ + +#if DEBUG + NSAssert3(valueClass, + @"lost valueClass for attribute %@ entity %@ name %@ ..", + attribute, [attribute entity], [attribute valueClassName]); +#endif + + value = [valueClass valueFromBytes:rawValue length:len + frontBaseType:self->datatypeCodes[i] + attribute:attribute + adaptorChannel:self]; + +#if DEBUG + if (value == nil) { + NSAssert4(value, + @"no value for attribute %@ entity %@ " + @"valueClass %@, record %@ ..", + attribute, [attribute entity], + NSStringFromClass(valueClass), record); + } +#endif + + /* free BLOB handle if one was allocated */ + + if (handle) { + fbcbhRelease(handle); + handle = NULL; + } + } + +#if DEBUG + NSAssert2(value, @"no value for attribute %@ entity %@ ..", + attribute, [attribute entity]); +#endif + + objects[i] = value; + keys[i] = [attribute name]; + } + { + static Class EORecordDictionaryClass = nil; + + if (EORecordDictionaryClass == nil) + EORecordDictionaryClass = [EORecordDictionary class]; + + record = (id)NSAllocateObject(EORecordDictionaryClass, + sizeof(EORecordDictionary) * + self->numberOfColumns, nil); + record = [record initWithObjects:objects forKeys:keys + count:self->numberOfColumns]; + AUTORELEASE(record); + } + } + return record; +} + +/* sending sql to server */ + +- (BOOL)evaluateExpression:(NSString *)_expression { + BOOL result; +#if DEBUG + static Class NSDateClass = Nil; + NSDate *startDate; +#endif + + *(&result) = YES; + NSAssert(self->rowHandler == NULL, @"raw handler still available .."); + NSAssert(self->rawRows == NULL, @"raw rows still available .."); + NSAssert(self->fetchHandle == NULL, @"fetch handle still available .."); + + if (_expression == nil) { + [InvalidArgumentException raise:@"InvalidArgumentException" + format:@"parameter for evaluateExpression: " + @"must not be null (channel=%@)", self]; + } + + *(&_expression) = AUTORELEASE([_expression mutableCopy]); + + if (delegateRespondsTo.willEvaluateExpression) { + EODelegateResponse response = + [delegate adaptorChannel:self + willEvaluateExpression:(NSMutableString *)_expression]; + + if (response == EODelegateRejects) + return NO; + else if (response == EODelegateOverrides) + return YES; + } + + if (isDebuggingEnabled) + NSLog(@"SQL[%p]: %@", self, _expression); + + + if (![self isOpen]) { + [FrontBaseException raise:@"ChannelNotOpenException" + format:@"FrontBase connection is not open (channel=%@)", + self]; + } + if (self->cmdMetaData != NULL) { + [FrontBaseException raise:@"CommandInProgressException" + format:@"command data already set up" + @" (channel=%@)", self]; + } + + _expression = [_expression stringByAppendingString:@";"]; + + if (self->sqlLogFile) { + FILE *fh; + if ((fh = fopen([self->sqlLogFile cString], "a"))) { + fprintf(fh, "%s\n", [_expression cString]); + fflush(fh); + fclose(fh); + } + } + + /* execute expression */ + +#if DEBUG + if (NSDateClass == Nil) NSDateClass = [NSDate class]; + startDate = [NSDateClass date]; +#endif + + self->cmdMetaData = fbcdcExecuteDirectSQL(self->fbdc, + (char *)[_expression cString]); + if (self->cmdMetaData == NULL) { + NSLog(@"%@: could not execute SQL: %@", self, _expression); + return NO; + } + + /* check for errors */ + + if (fbcmdErrorCount(self->cmdMetaData) > 0) { + FBCErrorMetaData *emd; + char *msg; + NSString *error; + int i, count; + + emd = fbcdcErrorMetaData(self->fbdc, self->cmdMetaData); + + for (i = 0, count = fbcemdErrorCount(emd); i < count; i++) { + unsigned code; + const char *errorKind; + const char *emsg; + + code = fbcemdErrorCodeAtIndex(emd, i); + errorKind = fbcemdErrorKindAtIndex(emd, i); + emsg = fbcemdErrorMessageAtIndex(emd, i); + + NSLog(@" code=%i", code); + NSLog(@" kind=%s", errorKind); + NSLog(@" msdg=%s", emsg); +#if 0 + free((void *)errorKind); +#endif + free((void *)emsg); + } + + if ((msg = fbcemdAllErrorMessages(emd))) + error = [NSString stringWithCString:msg]; + else + error = @"unknown"; + free(msg); msg = NULL; + fbcemdRelease(emd); emd = NULL; + fbcmdRelease(self->cmdMetaData); self->cmdMetaData = NULL; + + if (self->sqlLogFile) { + FILE *fh; + if ((fh = fopen([self->sqlLogFile cString], "a"))) { + fprintf(fh, "# failed: %s\n", + [[error stringByApplyingCEscaping] cString]); + fflush(fh); + fclose(fh); + } + } + + NSLog(@"%@: could not execute SQL: %@\n reason: %@", + self, _expression, + error); + return NO; + } + + /* init common results */ + + NSAssert(self->cmdMetaData, @"missing command-meta-data"); + self->numberOfColumns = fbcmdColumnCount(self->cmdMetaData); + self->rowsAffected = fbcmdRowCount(self->cmdMetaData); + self->txVersion = fbcmdTransactionVersion(self->cmdMetaData); + self->isFetchInProgress = NO; + + if ((self->fetchHandle = fbcmdFetchHandle(self->cmdMetaData))) + self->isFetchInProgress = YES; + + if (self->numberOfColumns > 0) { + int i; + + self->datatypeCodes = calloc(self->numberOfColumns, sizeof(int)); + for (i = 0; i < self->numberOfColumns; i++) { + const FBCDatatypeMetaData *dmd; + + if ((dmd = fbcmdDatatypeMetaDataAtIndex(self->cmdMetaData, i))) + self->datatypeCodes[i] = fbcdmdDatatypeCode(dmd); + else + self->datatypeCodes[i] = FB_VCharacter; + } + } + + if (!self->isFetchInProgress) { + fbcmdRelease(self->cmdMetaData); + self->cmdMetaData = NULL; + } +#if DEBUG + else { + /* some constraints */ + if ([_expression hasPrefix:@"INSERT"]) { + NSLog(@"an insert shouldn't start a fetch ! .."); + } + else if ([_expression hasPrefix:@"DELETE"]) { + NSLog(@"a delete shouldn't start a fetch ! .."); + } + else if ([_expression hasPrefix:@"UPDATE"]) { + NSLog(@"an update shouldn't start a fetch ! .."); + } + } +#endif + + /* setup row handler */ + + if (result) { + if (delegateRespondsTo.didEvaluateExpression) + [delegate adaptorChannel:self didEvaluateExpression:_expression]; + } + else { + [self cancelFetch]; + } + + if (self->sqlLogFile) { + FILE *fh; + if ((fh = fopen([self->sqlLogFile cString], "a"))) { +#if DEBUG + fprintf(fh, "# %s %3.3g\n", result ? "yes" : "no", + -[startDate timeIntervalSinceNow]); +#else + fprintf(fh, "# %s\n", result ? "yes" : "no"); +#endif + fflush(fh); + fclose(fh); + } + } + + return result; +} + +/* description */ + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@[0x%08X]: open=%s fetching=%s>", + NSStringFromClass([self class]), + self, + [self isOpen] ? "yes" : "no", + [self isFetchInProgress] ? "yes" : "no"]; +} + +@end /* FrontBaseChannel */ + +@implementation FrontBaseChannel(PrimaryKeyGeneration) + +- (NSDictionary *)primaryKeyForNewRowWithEntity:(EOEntity *)_entity { + NSArray *pkeys; + FrontBase2Adaptor *adaptor; + NSString *newKeyExpr; + NSDictionary *pkey; + + pkeys = [_entity primaryKeyAttributeNames]; + adaptor = (id)[[self adaptorContext] adaptor]; + newKeyExpr = [adaptor newKeyExpression]; + + if (newKeyExpr == nil) { + NSLog(@"ERROR: missing newkey expression, can't gen pkey for %@", + [_entity name]); + return nil; + } + + if ([pkeys count] != 1) { + NSLog(@"no pkeys configured for entity %@", [_entity name]); + return nil; + } + + *(&pkey) = nil; + + NS_DURING { + if ([self evaluateExpression:newKeyExpr]) { + NSDictionary *row; + NSArray *attrs; + id key; + + attrs = [self describeResults]; + row = [self fetchAttributes:attrs withZone:NULL]; + [self cancelFetch]; + + if ((key = [[row objectEnumerator] nextObject])) { + pkey = [NSDictionary dictionaryWithObject: + [NSNumber numberWithInt:[key intValue]] + forKey:[pkeys objectAtIndex:0]]; + } + } + else { + NSLog(@"could not evaluate newkey expression: %@", newKeyExpr); + } + } + NS_HANDLER { + fprintf(stderr, "newkey failed: %s\n", + [[localException description] cString]); + fflush(stderr); + pkey = nil; + } + NS_ENDHANDLER; + + return pkey; +} + +@end /* FrontBaseChannel(PrimaryKeyGeneration) */ + +@implementation FrontBaseChannel(BlobHandling) + +- (NSDictionary *)_extractBlobsFromRow:(NSMutableDictionary *)_mrow + entity:(EOEntity *)_entity +{ + /* + Search for BLOB attributes. + If a BLOB attribute is found, remove it from mrow and add it's data to + blobRow. + */ + FrontBase2Adaptor *adaptor; + NSMutableDictionary *blobRow; + NSEnumerator *keys; + NSString *key; + + adaptor = (FrontBase2Adaptor *)[[self adaptorContext] adaptor]; +#if DEBUG + NSAssert(adaptor, @"missing adaptor .."); +#endif + + /* must use allKeys since we are going to modify mrow */ + keys = [[_mrow allKeys] objectEnumerator]; + blobRow = nil; + + while ((key = [keys nextObject])) { + EOAttribute *attribute; + int fbType; + + attribute = [_entity attributeNamed:key]; + fbType = [adaptor typeCodeForExternalName:[attribute externalType]]; + + if ((fbType == FB_BLOB) || (fbType == FB_CLOB)) { + NSData *data; + id value; + + value = [_mrow objectForKey:key]; + data = [value dataValueForFrontBaseType:fbType + attribute:attribute]; + if (data == nil) // EONull + continue; + + if (blobRow == nil) + blobRow = [NSMutableDictionary dictionaryWithCapacity:4]; + + [blobRow setObject:data forKey:key]; + [_mrow removeObjectForKey:key]; + } + else if (fbType == FB_VCharacter) { + /* check for large VARCHARs and handle them like BLOBs.. */ + id value; + + value = [_mrow objectForKey:key]; + + if ([value isKindOfClass:[NSString class]]) { + if ([value length] > 2000) { + NSData *data; + + data = [value dataValueForFrontBaseType:fbType + attribute:attribute]; + if (data == nil) + continue; + + if (blobRow == nil) + blobRow = [NSMutableDictionary dictionaryWithCapacity:4]; + + [blobRow setObject:data forKey:key]; + [_mrow removeObjectForKey:key]; + } + } + else if ([value isKindOfClass:[NSData class]]) { + if ([value length] > 60) { + NSData *data; + + data = [value dataValueForFrontBaseType:fbType + attribute:attribute]; + if (data == nil) + continue; + + if (blobRow == nil) + blobRow = [NSMutableDictionary dictionaryWithCapacity:4]; + + [blobRow setObject:data forKey:key]; + [_mrow removeObjectForKey:key]; + } + } + } +#if 0 + else { + NSLog(@"%@ is *not* a BLOB attribute (type=%i) ..", attribute, fbType); + } +#endif + } + return blobRow; +} + +- (BOOL)_writeBlobs:(NSDictionary *)_blobs ofRow:(NSMutableDictionary *)_mrow { + /* + This method writes the blobs and set's the appropriate handle-keys in + the row. + */ + if (_blobs) { + NSEnumerator *keyEnum; + NSString *key; + + keyEnum = [_blobs keyEnumerator]; + while ((key = [keyEnum nextObject])) { + NSData *value; + FBCBlobHandle *blob; + + value = [_blobs objectForKey:key]; + +#if BLOB_DEBUG + NSLog(@"writing blob %@ of size %i ...", key, [value length]); +#endif + + if ((blob = fbcdcWriteBLOB(self->fbdc, + (char*)[value bytes], + [value length]))) { + char blobid[FBBlobHandleByteSize + 4]; + NSString *blobKey; + FBBlobHandle *handle; + + fbcbhGetHandle(blob, blobid); + + blobKey = [NSString stringWithCString:blobid + length:FBBlobHandleByteSize + 3]; +#if BLOB_DEBUG + NSLog(@" got id %@ for blob %@ ...", blobKey, key); +#endif + if (blobKey == nil) { + if (blob) + fbcbhRelease(blob); + return NO; + } + + fbcbhRelease(blob); blob = NULL; + + handle = [[FBBlobHandle alloc] initWithBlobID:blobKey]; + [_mrow setObject:handle forKey:key]; + RELEASE(handle); handle = nil; + } + else { + NSLog(@"%@: writing of BLOB %@ failed !", self, key); + return NO; + } + } + return YES; + } + else + return YES; +} + +- (BOOL)insertRow:(NSDictionary *)row forEntity:(EOEntity *)entity { + EOSQLExpression *sqlexpr = nil; + NSMutableDictionary *mrow = nil; + NSDictionary *blobRow = nil; + + mrow = AUTORELEASE([row mutableCopyWithZone:[row zone]]); + + if (!isOpen) + [[ChannelIsNotOpenedException new] raise]; + + if((row == nil) || (entity == nil)) { + [[[InvalidArgumentException alloc] + initWithFormat:@"row and entity arguments for insertRow:forEntity:" + @"must not be the nil object"] raise]; + } + + if([self isFetchInProgress]) + [[AdaptorIsFetchingException exceptionWithAdaptor:self] raise]; + + if(![adaptorContext transactionNestingLevel]) + [[NoTransactionInProgressException exceptionWithAdaptor:self] raise]; + + if(delegateRespondsTo.willInsertRow) { + EODelegateResponse response; + + response = [delegate adaptorChannel:self + willInsertRow:mrow + forEntity:entity]; + if(response == EODelegateRejects) + return NO; + else if(response == EODelegateOverrides) + return YES; + } + + /* extract BLOB attributes */ + + blobRow = [self _extractBlobsFromRow:mrow entity:entity]; + + /* upload BLOBs */ + + if (![self _writeBlobs:blobRow ofRow:mrow]) + return NO; + + /* insert non-BLOB attributes */ + + sqlexpr = [[[adaptorContext adaptor] + expressionClass] + insertExpressionForRow:mrow + entity:entity + channel:self]; + + if(![self evaluateExpression:[sqlexpr expressionValueForContext:nil]]) + return NO; + + if(delegateRespondsTo.didInsertRow) + [delegate adaptorChannel:self didInsertRow:mrow forEntity:entity]; + + return YES; +} + +- (BOOL)updateRow:(NSDictionary *)row + describedByQualifier:(EOSQLQualifier *)qualifier +{ + /* + FrontBaseChannel's -updateRow:describedByQualifier: differs from the + EOAdaptorChannel one in that it updates BLOB columns seperatly. + */ + FrontBase2Adaptor *adaptor = (FrontBase2Adaptor *)[adaptorContext adaptor]; + EOEntity *entity = [qualifier entity]; + EOSQLExpression *sqlexpr = nil; + NSMutableDictionary *mrow = nil; + NSDictionary *blobRow = nil; + + self->rowsAffected = 0; + + mrow = AUTORELEASE([row mutableCopyWithZone:[row zone]]); + + if (!isOpen) + [[ChannelIsNotOpenedException new] raise]; + + if(row == nil) { + [[[InvalidArgumentException alloc] + initWithFormat:@"row argument for updateRow:describedByQualifier: " + @"must not be the nil object"] raise]; + } + + if([self isFetchInProgress]) + [[AdaptorIsFetchingException exceptionWithAdaptor:self] raise]; + + if(![adaptorContext transactionNestingLevel]) + [[NoTransactionInProgressException exceptionWithAdaptor:self] raise]; + + if(delegateRespondsTo.willUpdateRow) { + EODelegateResponse response; + + response = [delegate adaptorChannel:self + willUpdateRow:mrow + describedByQualifier:qualifier]; + if(response == EODelegateRejects) + return NO; + else if(response == EODelegateOverrides) + return YES; + } + + /* extract BLOB attributes */ + + blobRow = [self _extractBlobsFromRow:mrow entity:entity]; + + /* upload BLOBs */ + + if (![self _writeBlobs:blobRow ofRow:mrow]) + return NO; + + /* update non-BLOB attributes */ + + if ([mrow count] > 0) { + sqlexpr = [[adaptor expressionClass] + updateExpressionForRow:mrow + qualifier:qualifier + channel:self]; + + if(![self evaluateExpression:[sqlexpr expressionValueForContext:nil]]) + return NO; + + if (self->rowsAffected != 1) { + NSLog(@"%s: rows affected: %i", __PRETTY_FUNCTION__, self->rowsAffected); + return NO; + } + } + + /* inform delegate about sucess */ + + if(delegateRespondsTo.didUpdateRow) { + [delegate adaptorChannel:self + didUpdateRow:mrow + describedByQualifier:qualifier]; + } + return YES; +} + +- (BOOL)selectAttributes:(NSArray *)attributes + describedByQualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + lock:(BOOL)lockFlag +{ + static Class EOSortOrderingClass = Nil; + NSMutableArray *mattrs; + NSEnumerator *fetchOrders; + id fo; + + /* automatically add attributes used in fetchOrderings (required by FB) */ + + if (EOSortOrderingClass == Nil) + EOSortOrderingClass = [EOSortOrdering class]; + + mattrs = nil; + fetchOrders = [fetchOrder objectEnumerator]; + while ((fo = [fetchOrders nextObject])) { + EOAttribute *attr; + + attr = nil; + if ([fo isKindOfClass:EOSortOrderingClass]) { + NSString *attrName; + + attrName = [fo key]; + attr = [[qualifier entity] attributeNamed:attrName]; + } + else { + /* EOAttributeOrdering */ + attr = [fo attribute]; + } + + if (attr == nil) { + NSLog(@"ERROR(%s): could not resolve attribute of sort ordering %@ !", + __PRETTY_FUNCTION__, fo); + continue; + } + + if (mattrs) { + if (![mattrs containsObject:attr]) + [mattrs addObject:attr]; + } + else if (![attributes containsObject:attr]) { + mattrs = [[NSMutableArray alloc] initWithArray:attributes]; + [mattrs addObject:attr]; + } + } + + if (mattrs) { + attributes = [mattrs copy]; + RELEASE(mattrs); + AUTORELEASE(attributes); + } + + /* continue usual select .. */ + + ASSIGN(self->selectedAttributes, attributes); + + return [super selectAttributes:attributes + describedByQualifier:qualifier + fetchOrder:fetchOrder + lock:lockFlag]; +} + +@end /* FrontBaseChannel(BlobHandling) */ + +void __link_FBChannel() { + // used to force linking of object file + __link_FBChannel(); +} diff --git a/sope-gdl1/FrontBase2/FBContext.h b/sope-gdl1/FrontBase2/FBContext.h new file mode 100644 index 00000000..08ebd1fc --- /dev/null +++ b/sope-gdl1/FrontBase2/FBContext.h @@ -0,0 +1,46 @@ +/* + FBContext.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBContext.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_Context_H___ +#define ___FB_Context_H___ + +#import +#import "FBHeaders.h" + +@interface FBContext : EOAdaptorContext + ++ (FBContext *)activeContext; // used by sybase callback procedures + +- (BOOL)primaryBeginTransaction; +- (BOOL)primaryCommitTransaction; +- (BOOL)primaryRollbackTransaction; + +@end + +@interface FrontBaseContext : FBContext +@end + +#endif diff --git a/sope-gdl1/FrontBase2/FBContext.m b/sope-gdl1/FrontBase2/FBContext.m new file mode 100644 index 00000000..2a18f0e2 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBContext.m @@ -0,0 +1,94 @@ +/* + FBContext.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBContext.m 1 2004-08-20 10:38:46Z znek $ + +#import "FBContext.h" +#import "FBChannel.h" +#import "common.h" + +@implementation FBContext + +static FBContext *context = nil; + ++ (FBContext *)activeContext { + return context; +} + +- (void)channelDidInit:_channel { + if ([channels count] > 0) { + [NSException raise:@"TooManyOpenChannelsException" + format:@"SybaseAdaptor10 only supports one channel per context"]; + } + [super channelDidInit:_channel]; +} + +- (BOOL)primaryBeginTransaction { + return YES; +} + +- (BOOL)primaryCommitTransaction { + FrontBaseChannel *channel; + BOOL result; + + context = self; + channel = [[channels lastObject] nonretainedObjectValue]; + //NSLog(@"committing channel %@", channel); + result = [channel evaluateExpression:@"COMMIT"]; + context = nil; + return result; +} + +- (BOOL)primaryRollbackTransaction { + FrontBaseChannel *channel; + BOOL result; + + context = self; + channel = [[channels lastObject] nonretainedObjectValue]; + //NSLog(@"rolling back channel %@", channel); + result = [channel evaluateExpression:@"ROLLBACK"]; + context = nil; + return result; +} + +- (BOOL)canNestTransactions { + return YES; +} + +// NSCopying methods + +- (id)copyWithZone:(NSZone *)zone { + // copy is needed during creation of NSNotification object + return RETAIN(self); +} + +@end + +@implementation FrontBaseContext +@end + +void __link_FBContext() { + // used to force linking of object file + __link_FBContext(); +} diff --git a/sope-gdl1/FrontBase2/FBException.h b/sope-gdl1/FrontBase2/FBException.h new file mode 100644 index 00000000..9acb5762 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBException.h @@ -0,0 +1,39 @@ +/* + FBException.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBException.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_Exception_H___ +#define ___FB_Exception_H___ + +#import +#import "FBHeaders.h" + +@interface FrontBaseException : NSException +@end + +@interface FBCouldNotOpenChannelException : FrontBaseException +@end + +#endif diff --git a/sope-gdl1/FrontBase2/FBException.m b/sope-gdl1/FrontBase2/FBException.m new file mode 100644 index 00000000..43a556d5 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBException.m @@ -0,0 +1,35 @@ +/* + FBException.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBException.m 1 2004-08-20 10:38:46Z znek $ + +#import +#import +#import "FBException.h" + +@implementation FrontBaseException +@end /* FrontBaseException */ + +@implementation FBCouldNotOpenChannelException +@end /* FBCouldNotOpenChannelException */ diff --git a/sope-gdl1/FrontBase2/FBHeaders.h b/sope-gdl1/FrontBase2/FBHeaders.h new file mode 100644 index 00000000..cb757271 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBHeaders.h @@ -0,0 +1,43 @@ +/* + FBHeaders.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBHeaders.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_Headers_H___ +#define ___FB_Headers_H___ + +#include + +typedef struct { + unsigned char blobType; + unsigned int blobSize; + unsigned char *blobData; +} FBInlineBlob; + +typedef struct { + unsigned char blobType; + unsigned char *blobHandle; +} FBHandleBlob; + +#endif diff --git a/sope-gdl1/FrontBase2/FBSQLExpression.h b/sope-gdl1/FrontBase2/FBSQLExpression.h new file mode 100644 index 00000000..4ce24d55 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBSQLExpression.h @@ -0,0 +1,54 @@ +/* + FBSQLExpression.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBSQLExpression.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_SQLExpression_H___ +#define ___FB_SQLExpression_H___ + +#include + +@class NSString, NSArray; +@class EOSQLQualifier, EOAdaptorChannel; + +@interface FBSQLExpression : EOSQLExpression + ++ (Class)selectExpressionClass; + +@end + +@interface FBSelectSQLExpression : EOSelectSQLExpression +{ + BOOL lock; +} + +- (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel; + +@end + +#endif diff --git a/sope-gdl1/FrontBase2/FBSQLExpression.m b/sope-gdl1/FrontBase2/FBSQLExpression.m new file mode 100644 index 00000000..917801f9 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBSQLExpression.m @@ -0,0 +1,78 @@ +/* + FBSQLExpression.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBSQLExpression.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include +#include "FBSQLExpression.h" + +@implementation FBSQLExpression + ++ (int)version { + return [super version] + 0 /* v1 */; +} ++ (void)initialize { + NSAssert([super version] == 1, @"invalid superclass version !"); +} + ++ (Class)selectExpressionClass { + return [FBSelectSQLExpression class]; +} + +@end + +@implementation FBSelectSQLExpression + +- (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel +{ + self->lock = flag; + + return [super selectExpressionForAttributes:attributes + lock:flag + qualifier:qualifier + fetchOrder:fetchOrder + channel:channel]; +} + +- (NSString *)lockClause { +#warning no holdlock !!! + return @""; +#if 0 + return (self->lock) + ? @" HOLDLOCK" + : @""; +#endif +} + +@end + +void __link_FBSQLExpression() { + // used to force linking of object file + __link_FBSQLExpression(); +} diff --git a/sope-gdl1/FrontBase2/FBValues.h b/sope-gdl1/FrontBase2/FBValues.h new file mode 100644 index 00000000..6e4eb4f6 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBValues.h @@ -0,0 +1,80 @@ +/* + FBValues.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FrontBase Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBValues.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_Values_H___ +#define ___FB_Values_H___ + +#import +#import +#import +#import +#import +#import +#import "FBException.h" +#import "FBHeaders.h" + +@class EOAttribute; +@class FrontBaseChannel; + +@protocol FBValues + ++ (id)valueFromBytes:(const char *)_bytes + length:(unsigned)_length + frontBaseType:(int)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(FrontBaseChannel *)_channel; + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute; + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute; + +@end + +@interface NSString(FBValues) < FBValues > +@end + +@interface NSNumber(FBValues) < FBValues > +@end + +@interface NSData(FBValues) < FBValues > +@end + +@interface NSCalendarDate(FBValues) < FBValues > +@end + +@interface EONull(FBValues) + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute; + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute; + +@end + +#endif diff --git a/sope-gdl1/FrontBase2/FBValues.m b/sope-gdl1/FrontBase2/FBValues.m new file mode 100644 index 00000000..af8d4245 --- /dev/null +++ b/sope-gdl1/FrontBase2/FBValues.m @@ -0,0 +1,671 @@ +/* + FBValues.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FBValues.m 1 2004-08-20 10:38:46Z znek $ + +#include +#if HAVE_STRINGS_H +# include +#endif +#include +#import "common.h" +#include "FBException.h" +#import + +static Class NumberClass = Nil; + +@interface FBDataTypeMappingException : FrontBaseException +@end + +@interface NSTimeZone(UsedPrivates) +- (NSTimeZoneDetail *)timeZoneDetailForDate:(NSDate *)_date; +@end + +@implementation FBDataTypeMappingException + +- (id)initWithObject:(id)_obj forAttribute:(EOAttribute *)_attr + andFrontBaseType:(int)_fb inChannel:(FrontBaseChannel *)_channel +{ + NSString *typeName = nil; + + typeName = + [(id)[[_channel adaptorContext] adaptor] externalNameForTypeCode:_fb]; + + if (typeName == nil) + typeName = [NSString stringWithFormat:@"Type[%i]", _fb]; + + [self setName:@"FBDataTypeMappingNotSupported"]; + [self setReason:[NSString stringWithFormat: + @"mapping between %@ and " + @"frontbase type %@ is not supported", + [_obj description], + NSStringFromClass([_obj class]), + typeName]]; + + [self setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys: + _attr, @"attribute", + _channel, @"channel", + _obj, @"object", + nil]]; + return self; +} + +@end /* FBDataTypeMappingException */ + +static inline void FmtRaiseMapExc(id _object, + int _fb, + EOAttribute *_attribute, + id _channel) { + NSLog(@"%s: FmtRaiseMapExc objectClass=%@ object=%@ " + @"type=%i typeName=%@ attribute=%@", + __PRETTY_FUNCTION__, + NSStringFromClass([_object class]), + _object, + _fb, + [(id)[[_channel adaptorContext] adaptor] externalNameForTypeCode:_fb], + _attribute); + + [[[FBDataTypeMappingException alloc] + initWithObject:_object + forAttribute:_attribute + andFrontBaseType:_fb + inChannel:_channel] raise]; +} +static inline void RaiseMapExc(id _object, int _type, + EOAttribute *_attribute, + id _channel) { + NSLog(@"%s: RaiseMapExc objectClass=%@ object=%@ type=%i name=%@ attribute=%@", + __PRETTY_FUNCTION__, + NSStringFromClass([_object class]), + _object, + _type, + [(id)[[_channel adaptorContext] adaptor] externalNameForTypeCode:_type], + _attribute); + + [[[FBDataTypeMappingException alloc] + initWithObject:_object + forAttribute:_attribute + andFrontBaseType:_type + inChannel:_channel] raise]; +} + +@implementation NSString(FBValues) + ++ (id)valueFromBytes:(const char *)_bytes length:(unsigned)_length + frontBaseType:(int)_fb attribute:(EOAttribute *)_attribute + adaptorChannel:(FrontBaseChannel *)_channel +{ + id result = nil; + + switch (_fb) { + case FB_Character: + case FB_VCharacter: + result = [self stringWithCString:_bytes length:_length]; + break; + + case FB_BLOB: + case FB_CLOB: + result = [self stringWithCString:_bytes length:_length]; + break; + + case FB_SmallInteger: + result = [NSString stringWithFormat:@"%i", *(short *)_bytes]; + break; + case FB_Integer: + result = [NSString stringWithFormat:@"%i", *(int *)_bytes]; + break; + + case FB_Real: + case FB_Double: + result = [NSString stringWithFormat:@"%g", *(double *)_bytes]; + break; + + case FB_Float: + result = [NSString stringWithFormat:@"%g", *(float *)_bytes]; + break; + + default: + FmtRaiseMapExc(self, _fb, _attribute, _channel); + } + + return result; +} + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + /* NSString */ + return [NSData dataWithBytes:[self cString] length:[self cStringLength]]; +} + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + /* NSString */ + switch (_type) { + case FB_BLOB: + return [[NSData dataWithBytes:[self cString] length:[self cStringLength]] + stringValueForFrontBaseType:_type attribute:_attribute]; + + case FB_Character: + case FB_VCharacter: + case FB_CLOB: { + id expr = nil; + + expr = [[[EOQuotedExpression alloc] initWithExpression:self + quote:@"'" escape:@"''"] + autorelease]; + expr = [expr expressionValueForContext:nil]; + return expr; + } + + case FB_Bit: + case FB_SmallInteger: + case FB_Integer: + case FB_Real: + case FB_Double: + case FB_Numeric: + case FB_Decimal: + /* NSLog(@"returning %@ for number type", self); */ + return self; + } + + RaiseMapExc(self, _type, _attribute, nil); + + NSLog(@"impossible condition reached: %@", self); + abort(); + return nil; +} + +@end /* NSString(FBValues) */ + +@implementation NSNumber(FBValues) + +#define ReturnNumber(sybtype, def) {\ + if (valueType == -1) \ + return [NumberClass def *(sybtype*)_bytes]; \ + else if (valueType == 'c') \ + return [NumberClass numberWithChar:*(sybtype*)_bytes]; \ + else if (valueType == 'C') \ + return [NumberClass numberWithUnsignedChar:*(sybtype*)_bytes]; \ + else if (valueType == 's') \ + return [NumberClass numberWithShort:*(sybtype*)_bytes]; \ + else if (valueType == 'S') \ + return [NumberClass numberWithUnsignedShort:*(sybtype*)_bytes]; \ + else if (valueType == 'i') \ + return [NumberClass numberWithInt:*(sybtype*)_bytes]; \ + else if (valueType == 'I') \ + return [NumberClass numberWithUnsignedInt:*(sybtype*)_bytes]; \ + else if (valueType == 'f') \ + return [NumberClass numberWithFloat:*(sybtype*)_bytes]; \ + else if (valueType == 'd') \ + return [NumberClass numberWithDouble:*(sybtype*)_bytes]; \ + else \ + [NSException raise:@"InvalidValueTypeException" \ + format:@"value type %c is not recognized", valueType];\ + return nil; \ + } + ++ (id)valueFromBytes:(const char *)_bytes length:(unsigned)_length + frontBaseType:(int)_fb attribute:(EOAttribute *)_attribute + adaptorChannel:(FrontBaseChannel *)_channel +{ + char valueType; + + if ([_attribute valueType]) + valueType = [[_attribute valueType] cString][0]; + else + valueType = -1; + + switch (_fb) { + case FB_Character: + case FB_VCharacter: { + switch (valueType) { + case 'c': return [NumberClass numberWithChar:atoi(_bytes)]; + case 'C': return [NumberClass numberWithUnsignedChar:atol(_bytes)]; + case 's': return [NumberClass numberWithShort:atoi(_bytes)]; + case 'S': return [NumberClass numberWithUnsignedShort:atol(_bytes)]; + case 'i': return [NumberClass numberWithInt:atoi(_bytes)]; + case 'I': return [NumberClass numberWithUnsignedInt:atol(_bytes)]; + case 'f': return [NumberClass numberWithFloat:atof(_bytes)]; + case 'd': return [NumberClass numberWithDouble:atof(_bytes)]; + default: + [NSException raise:@"InvalidValueTypeException" + format:@"value type %c is not recognized", + valueType]; + return nil; + } + } + + case FB_Boolean: { + unsigned char v; + v = *(unsigned char *)_bytes; + return [NumberClass numberWithBool:v]; + } + + case FB_Integer: { + int v; + v = *(int *)_bytes; + return [NumberClass numberWithInt:v]; + } + case FB_SmallInteger: { + short v; + v = *(short *)_bytes; + return [NumberClass numberWithShort:v]; + } + + case FB_Real: + case FB_Double: + ReturnNumber(double, numberWithDouble:); + + case FB_Float: + ReturnNumber(float, numberWithFloat:); + + case FB_Numeric: + case FB_Decimal: +#if 0 + if (_fmt->scale > 0) { + ReturnNumber(CS_REAL, numberWithDouble:); + } + else { + ReturnNumber(int, numberWithInt:); + } +#endif + ReturnNumber(double, numberWithDouble:); + + default: + FmtRaiseMapExc(self, _fb, _attribute, _channel); + } + + [NSException raise:@"InvalidFrontBaseValueStateException" + format:@"reached invalid state in sybase NSNumber handler"]; + + return nil; +} + +#undef ReturnNumber + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + RaiseMapExc(self, _type, _attribute, nil); + return nil; +} + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + /* NSNumber */ + switch (_type) { + case FB_Boolean: + case FB_Bit: + case FB_SmallInteger: + case FB_Integer: + case FB_Real: + case FB_Float: + case FB_Numeric: + case FB_Decimal: + return [self stringValue]; + + case FB_Character: + case FB_VCharacter: + return [NSString stringWithFormat:@"'%s'", [[self stringValue] cString]]; + + default: + RaiseMapExc(self, _type, _attribute, nil); + } + return nil; +} + +@end /* NSNumber(FBValues) */ + +@implementation NSData(FBValues) + ++ (id)valueFromBytes:(const char *)_bytes length:(unsigned)_length + frontBaseType:(int)_fb attribute:(EOAttribute *)_attribute + adaptorChannel:(FrontBaseChannel *)_channel +{ + switch (_fb) { + case FB_Bit: + case FB_SmallInteger: + case FB_Integer: + case FB_Real: + case FB_Float: + case FB_Numeric: + case FB_Decimal: + case FB_Character: + case FB_VCharacter: + case FB_BLOB: + case FB_CLOB: + return [[[self alloc] initWithBytes:_bytes length:_length] autorelease]; + + default: + FmtRaiseMapExc(self, _fb, _attribute, _channel); + } + return nil; +} + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + return self; +} + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attribute +{ + switch (_type) { + case FB_Boolean: + return [[NumberClass numberWithChar:*(char *)[self bytes]] stringValue]; + + case FB_SmallInteger: + return [[NumberClass numberWithShort:*(short *)[self bytes]] stringValue]; + + case FB_Integer: + return [[NumberClass numberWithInt:*(int *)[self bytes]] stringValue]; + + case FB_Real: + case FB_Double: + return [[NumberClass numberWithDouble:*(double *)[self bytes]] + stringValue]; + + case FB_Float: + return [[NumberClass numberWithFloat:*(float *)[self bytes]] stringValue]; + + case FB_Character: + case FB_VCharacter: + case FB_CLOB: + case FB_BLOB: { + unsigned final_length = [self length]; + char *cstr = NULL, *tmp = NULL; + unsigned cnt; + const char *iBytes = [self bytes]; + + if (final_length == 0) return @"NULL"; + + final_length = 2 + 2 * final_length + 1; + cstr = objc_atomic_malloc(final_length + 4); + tmp = cstr + 2; + + cstr[0] = '\0'; + strcat(cstr, "0x"); + + for (cnt = 0; cnt < [self length]; cnt++, tmp += 2) + sprintf(tmp, "%02X", (unsigned char)iBytes[cnt]); + *tmp = '\0'; + + return [[[NSString alloc] initWithCStringNoCopy:cstr length:cstr?strlen(cstr):0 freeWhenDone:YES] autorelease]; + } + + default: + RaiseMapExc(self, _type, _attribute, nil); + } + return nil; +} + +@end /* NSData(FBValues) */ + +// 1234567890123456789012345 +// Frontbase Date: 1997-10-21 21:52:26+08:00 +static NSString *FRONTBASE_DATE_FORMAT = @"%Y-%m-%d %H:%M:%S%z"; + +@implementation NSDate(FBValues) + ++ (id)valueFromBytes:(const char *)_bytes length:(unsigned)_length + frontBaseType:(int)_fb attribute:(EOAttribute *)_attribute + adaptorChannel:(FrontBaseChannel *)_channel +{ + /* NSDate */ + return [NSCalendarDate valueFromBytes:_bytes length:_length + frontBaseType:_fb attribute:_attribute + adaptorChannel:_channel]; +} + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attr +{ + /* NSDate */ + NSCalendarDate *cdate; + + cdate = [NSCalendarDate dateWithTimeIntervalSince1970: + [self timeIntervalSince1970]]; + + return [cdate dataValueForFrontBaseType:_type attribute:_attr]; +} + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attr +{ + /* NSDate */ + NSCalendarDate *cdate; + + cdate = [NSCalendarDate dateWithTimeIntervalSince1970: + [self timeIntervalSince1970]]; + + return [cdate stringValueForFrontBaseType:_type attribute:_attr]; +} + +@end + +@implementation NSCalendarDate(FBValues) + ++ (id)valueFromBytes:(const char *)_bytes length:(unsigned)_length + frontBaseType:(int)_fb attribute:(EOAttribute *)_attribute + adaptorChannel:(FrontBaseChannel *)_channel +{ + /* NSCalendarDate */ + switch (_fb) { + case FB_TimestampTZ: { + /* a string of length 25 */ + NSCalendarDate *date; + NSString *str, *stampstr, *tzstr; + +#if DEBUG + NSAssert2(_length >= 25, + @"byte values for date creation are too short " + @"(len required is 25, got %i), attribute=%@", + _length, _attribute); + + if (_length != 25) { + NSLog(@"WARNING: invalid length, should be '25', got %i, attribute %@", + _length, _attribute); + } +#endif + + stampstr = [NSString stringWithCString:_bytes length:19]; + tzstr = [NSString stringWithCString:(_bytes + 19) length:3]; + str = [NSString stringWithCString:(_bytes + 23) length:2]; + tzstr = [tzstr stringByAppendingString:str]; + str = [stampstr stringByAppendingString:tzstr]; + + date = [NSCalendarDate dateWithString:str + calendarFormat:FRONTBASE_DATE_FORMAT]; +#if DEBUG + if (date == nil) { + NSLog(@"ERROR: couldn't construct calendar date from " + @"string %@ (src=%@) column %@.%@ " + @"(%i bytes), format=%@", + str, [NSString stringWithCString:_bytes length:19], + [[_attribute entity] externalName], + [_attribute columnName], + _length, date); + } +#if 0 + else { + NSLog(@"info: could construct calendar date from string %@ (len=%i)", + str, _length); + } +#endif +#endif + return date; + } + + case FB_Character: + case FB_VCharacter: + case FB_Date: + case FB_Timestamp: { + NSTimeZone *serverTimeZone; + NSCalendarDate *date; + NSString *formattedDate; + NSString *format; + + formattedDate = [NSString stringWithCString:_bytes length:_length]; + + serverTimeZone = [_attribute serverTimeZone]; + format = [_attribute calendarFormat]; + + if (serverTimeZone == nil) + serverTimeZone = [NSTimeZone localTimeZone]; + if (format == nil) + format = FRONTBASE_DATE_FORMAT; + + date = [NSCalendarDate dateWithString:formattedDate + calendarFormat:format]; + if (date == nil) { + NSLog(@"ERROR(%s): could not construct date from " + @"value '%@' with format '%@'", + __PRETTY_FUNCTION__, formattedDate, format); + } + return date; + } + + default: + FmtRaiseMapExc(self, _fb, _attribute, _channel); + } + return nil; +} + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attr +{ + /* NSCalendarDate */ + RaiseMapExc(self, _type, _attr, nil); + return nil; +} + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attr +{ + /* NSCalendarDate */ + + self = [self copy]; /* copy to rescue timezone setting */ + [self autorelease]; + + switch (_type) { + case FB_TimestampTZ: { + NSTimeZone *serverTimeZone; + NSString *str; + NSTimeInterval timeZoneOffset; + int i, j; + + serverTimeZone = [_attr serverTimeZone]; + + if (serverTimeZone == nil) + serverTimeZone = [NSTimeZone localTimeZone]; + +#if NeXT_Foundation_LIBRARY + timeZoneOffset = [serverTimeZone secondsFromGMTForDate:self]; +#else + timeZoneOffset = [[serverTimeZone timeZoneDetailForDate:self] + timeZoneSecondsFromGMT]; +#endif + + [self setTimeZone:serverTimeZone]; + + i = timeZoneOffset > 0; + j = (timeZoneOffset > 0 ? timeZoneOffset : -timeZoneOffset) / 60; + + str = [NSString stringWithFormat: + @"TIMESTAMP '%02i-%02i-%02i %02i:%02i:%02i%s%02i:%02i'", + [self yearOfCommonEra], + [self monthOfYear], + [self dayOfMonth], + [self hourOfDay], + [self minuteOfHour], + [self secondOfMinute], + i ? "+":"-", + j / 60, j % 60]; + return str; + } + + case FB_Date: { + NSTimeZone *serverTimeZone; + NSString *format; + id expr; + + serverTimeZone = [_attr serverTimeZone]; + format = [_attr calendarFormat]; + expr = nil; + + if (serverTimeZone == nil) + serverTimeZone = [NSTimeZone localTimeZone]; + + if (format == nil) + format = FRONTBASE_DATE_FORMAT; + + [self setTimeZone:serverTimeZone]; + + expr = [self descriptionWithCalendarFormat:format]; + expr = [[EOQuotedExpression alloc] initWithExpression:expr + quote:@"'" escape:@"''"]; + [expr autorelease]; + expr = [expr expressionValueForContext:nil]; + expr = [@"TIMESTAMP " stringByAppendingString:expr]; + + return expr; + } + + default: + RaiseMapExc(self, _type, _attr, nil); + } + return nil; +} + +@end /* NSCalendarDate(FBValues) */ + +@implementation EONull(FBValues) + +- (NSData *)dataValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attr +{ + return nil; +} + +- (NSString *)stringValueForFrontBaseType:(int)_type + attribute:(EOAttribute *)_attr +{ + return @"null"; +} + +@end /* EONull(FBValues) */ + +void __init_FBValues(void) { + NumberClass = [NSNumber class]; +} + +void __link_FBValues() { + // used to force linking of object file + __link_FBValues(); + __init_FBValues(); +} diff --git a/sope-gdl1/FrontBase2/FrontBase2Adaptor.h b/sope-gdl1/FrontBase2/FrontBase2Adaptor.h new file mode 100644 index 00000000..580aec07 --- /dev/null +++ b/sope-gdl1/FrontBase2/FrontBase2Adaptor.h @@ -0,0 +1,100 @@ +/* + FBAdaptor.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FrontBase2Adaptor.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_Adaptor_H___ +#define ___FB_Adaptor_H___ + +/* + The FB adaptor. + + The connection dictionary of this adaptor understands these keys: + hostName + userName + password + databaseName + databasePassword + transactionIsolationLevel + lockingDiscipline +*/ + +#import +#import +#import +#import "FBHeaders.h" + +@class NSString, NSMutableDictionary; +@class FrontBaseChannel; + +extern NSString *FBNotificationName; + +@interface FrontBase2Adaptor : EOAdaptor +{ +@private + NSMapTable *typeNameToCode; + NSMapTable *typeCodeToName; +} + +- (id)initWithName:(NSString *)_name; + +/* connection management */ + +- (NSString *)serverName; +- (NSString *)loginName; +- (NSString *)loginPassword; +- (NSString *)databaseName; +- (NSString *)databasePassword; +- (NSString *)transactionIsolationLevel; +- (NSString *)lockingDiscipline; + +/* key generation */ + +- (NSString *)newKeyExpression; + +/* value formatting */ + +- (id)formatValue:(id)value forAttribute:(EOAttribute *)attribute; + +/* classes used */ + +- (Class)adaptorContextClass; // FrontBaseContext +- (Class)adaptorChannelClass; // FrontBaseChannel +- (Class)expressionClass; // FBSQLExpression + +@end + +@interface FrontBase2Adaptor(ExternalTyping) + +- (int)typeCodeForExternalName:(NSString *)_typeName; +- (NSString *)externalNameForTypeCode:(int)_typeCode; + +- (BOOL)isInternalBlobType:(int)_type; +- (BOOL)isBlobAttribute:(EOAttribute *)_attr; +- (BOOL)isValidQualifierType:(NSString *)_typeName; +- (BOOL)attributeAllowedInDistinctSelects:(EOAttribute *)_attr; + +@end + +#endif diff --git a/sope-gdl1/FrontBase2/FrontBase2Adaptor.m b/sope-gdl1/FrontBase2/FrontBase2Adaptor.m new file mode 100644 index 00000000..a9f4de3d --- /dev/null +++ b/sope-gdl1/FrontBase2/FrontBase2Adaptor.m @@ -0,0 +1,165 @@ +/* + FBAdaptor.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: FrontBase2Adaptor.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" + +NSString *FBNotificationName = @"FBNotification"; + +@interface FrontBase2Adaptor(FetchUserTypes) +- (void)_fetchUserTypes; +@end + +@implementation FrontBase2Adaptor + ++ (void)initialize { + static BOOL isInitialized = NO; + + if (!isInitialized) { + void __init_FBValues(void); + isInitialized = YES; + __init_FBValues(); + } +} + +- (id)initWithName:(NSString *)_name { + if ((self = [super initWithName:_name])) { + } + return self; +} + +#if !LIB_FOUNDATION_BOEHM_GC +- (void)dealloc { + if (self->typeNameToCode) { + NSFreeMapTable(self->typeNameToCode); + self->typeCodeToName = NULL; + } + if (self->typeCodeToName) { + NSFreeMapTable(self->typeCodeToName); + self->typeCodeToName = NULL; + } + [super dealloc]; +} +#endif + +/* NSCopying methods */ + +- (id)copyWithZone:(NSZone *)_zone { + // copy is needed during creation of NSNotification object + return RETAIN(self); +} + +/* connections */ + +- (NSString *)serverName { + NSString *serverName; + + serverName = [[self connectionDictionary] objectForKey:@"hostName"]; + + return AUTORELEASE([serverName copy]); +} +- (NSString *)loginName { + return AUTORELEASE([[[self connectionDictionary] + objectForKey:@"userName"] copy]); +} +- (NSString *)loginPassword { + return AUTORELEASE([[[self connectionDictionary] + objectForKey:@"password"] copy]); +} +- (NSString *)databaseName { + return AUTORELEASE([[[self connectionDictionary] + objectForKey:@"databaseName"] copy]); +} +- (NSString *)databasePassword { + return AUTORELEASE([[[self connectionDictionary] + objectForKey:@"databasePassword"] copy]); +} + +- (NSString *)transactionIsolationLevel { + return AUTORELEASE([[[self connectionDictionary] + objectForKey:@"transactionIsolationLevel"] copy]); +} +- (NSString *)lockingDiscipline { + return AUTORELEASE([[[self connectionDictionary] + objectForKey:@"lockingDiscipline"] copy]); +} + +/* key generation */ + +- (NSString *)newKeyExpression { + return AUTORELEASE([[[self pkeyGeneratorDictionary] + objectForKey:@"newKeyExpression"] + copy]); +} + +/* formatting values */ + +- (NSString *)formatAttribute:(EOAttribute *)_attribute { + return [NSString stringWithFormat:@"\"%s\"", + [[_attribute columnName] cString]]; +} + +- (NSString *)lowerExpressionForTextAttributeNamed:(NSString *)_attrName { + return [NSString stringWithFormat:@"LOWER(%@)", _attrName]; +} + +- (NSString *)expressionForTextValue:(id)_value { + return [_value lowercaseString]; +} + +- (NSString *)charConvertExpressionForAttributeNamed:(NSString *)_attrName { + return [NSString stringWithFormat:@"CAST(%@ AS VARCHAR(255))", _attrName]; +} + +- (id)formatValue:(id)value forAttribute:(EOAttribute *)attribute { + int fbType; + NSString *result; + + fbType = [self typeCodeForExternalName:[attribute externalType]]; + result = [value stringValueForFrontBaseType:fbType + attribute:attribute]; + +#if 0 + NSLog(@"formatting value %@ result %@", value, result); + NSLog(@" value class %@ attr %@ attr type %@", + [value class], attribute, [attribute externalType]); +#endif + return result; +} + +/* adaptor info */ + +- (Class)adaptorContextClass { + return [FrontBaseContext class]; +} +- (Class)adaptorChannelClass { + return [FrontBaseChannel class]; +} + +- (Class)expressionClass { + return [FBSQLExpression class]; +} + +@end /* FrontBase2Adaptor */ diff --git a/sope-gdl1/FrontBase2/GNUmakefile b/sope-gdl1/FrontBase2/GNUmakefile new file mode 100644 index 00000000..a5d9aa1d --- /dev/null +++ b/sope-gdl1/FrontBase2/GNUmakefile @@ -0,0 +1,83 @@ +# +# GNUmakefile +# +# Copyright (C) 1999 MDlink online service center GmbH and Helge Hess +# +# Author: Helge Hess (helge.hess@mdlink.de) +# +# This file is part of the FrontBase Adaptor Library +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; see the file COPYING.LIB. +# If not, write to the Free Software Foundation, +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# $Id: GNUmakefile 1 2004-08-20 10:38:46Z znek $ + +include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/common.make + +CAN_COMPILE_FB = \ + $(shell ./cancompile.sh $(GNUSTEP_TARGET_CPU) $(GNUSTEP_TARGET_OS)) + +ifeq ($(CAN_COMPILE_FB),yes) + +GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) + +BUNDLE_NAME = FrontBase2 + +FrontBase2_OBJC_FILES = \ + FBSQLExpression.m \ + FBException.m \ + FrontBase2Adaptor.m \ + FBAdaptor+Types.m \ + FBContext.m \ + FBChannel.m \ + EOAttribute+FB.m \ + NSString+FB.m \ + FBValues.m \ + FBChannel+Model.m \ + FBBlobHandle.m \ + +FrontBase2_PRINCIPAL_CLASS = FrontBase2Adaptor +FrontBase2_RESOURCE_FILES = Info.plist Version + +BUNDLE_INSTALL = FrontBase2 +BUNDLE_INSTALL_DIR = $(GNUSTEP_SYSTEM_ROOT)/Libraries/Adaptors + +# Use .gdladaptor as the bundle extension +BUNDLE_EXTENSION = .gdladaptor + +# tool stuff + +TOOL_NAME = fbtest + +fbtest_OBJC_FILES = fbtest.m +#fbtest_OBJC_FILES += $(FrontBase2_OBJC_FILES) + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/bundle.make +#include $(GNUSTEP_MAKEFILES)/tool.make +-include GNUmakefile.postamble + +else # cannot compile FB + +cannotcompile : + echo "cannot compile FrontBase 2.x adaptor for OS $(GNUSTEP_TARGET_OS) CPU $(GNUSTEP_TARGET_CPU)" + +all :: cannotcompile + +clean :: + +install :: cannotcompile + +endif diff --git a/sope-gdl1/FrontBase2/GNUmakefile.preamble b/sope-gdl1/FrontBase2/GNUmakefile.preamble new file mode 100644 index 00000000..49aea874 --- /dev/null +++ b/sope-gdl1/FrontBase2/GNUmakefile.preamble @@ -0,0 +1,56 @@ +# $Id: GNUmakefile.preamble 1 2004-08-20 10:38:46Z znek $ + +FRONTBASE = ./fb2/$(GNUSTEP_TARGET_CPU)/$(GNUSTEP_TARGET_OS) + +ADDITIONAL_INCLUDE_DIRS += -I.. -I../GDLAccess + +ADDITIONAL_LIB_DIRS += \ + -L../GDLAccess/$(GNUSTEP_OBJ_DIR) \ + -L../$(GNUSTEP_OBJ_DIR) \ + +FrontBase2_BUNDLE_LIBS += \ + -lEOControl \ + -lNGExtensions \ + -lNGStreams \ + -lGDLAccess \ + +ifeq ($(FOUNDATION_LIB),nx) + +FrontBase2_BUNDLE_LIBS += -lFoundationExt +FrontBase2_LDFLAGS += -framework FBCAccess -framework Foundation + +else + +ifeq ($(uselib),yes) + +FrontBase2_BUNDLE_LIBS += -lFBCAccess + +else + +ADDITIONAL_INCLUDE_DIRS += -I$(FRONTBASE)/include +ADDITIONAL_LIB_DIRS += -L$(FRONTBASE)/lib + +ifneq ($(GNUSTEP_TARGET_OS),mingw32) +FrontBase2_LDFLAGS += $(FRONTBASE)/lib/FBCAccess.o +FrontBase2_BUNDLE_LIBS += -lGDLAccess +else +FrontBase2_LIB_DIRS += -L$(FRONTBASE)/lib +FrontBase2_BUNDLE_LIBS += \ + -lFBCAccessImp \ + -lGDLAccess \ + -lEOControl -lFoundation -lobjc +endif + +endif # uselib,yes +endif # FOUNDATION_LIB,nx + +#ifeq ($(GNUSTEP_TARGET_OS),mingw32) +#fbtest_LIB_DIRS += -L$(FRONTBASE)/lib +#fbtest_TOOL_LIBS += -lFBCAccessImp +#endif + +ADDITIONAL_TOOL_LIBS += \ + -lEOControl \ + -lNGExtensions \ + -lNGStreams \ + -lGDLAccess \ diff --git a/sope-gdl1/FrontBase2/Info.plist b/sope-gdl1/FrontBase2/Info.plist new file mode 100644 index 00000000..fbdf36d0 --- /dev/null +++ b/sope-gdl1/FrontBase2/Info.plist @@ -0,0 +1,4 @@ +{ + NSPrincipalClass = FrontBase2Adaptor; + NSExecutable = FrontBase2; +} diff --git a/sope-gdl1/FrontBase2/NSString+FB.h b/sope-gdl1/FrontBase2/NSString+FB.h new file mode 100644 index 00000000..027ea83a --- /dev/null +++ b/sope-gdl1/FrontBase2/NSString+FB.h @@ -0,0 +1,41 @@ +/* + NSString+FB.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: NSString+FB.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_NSString_H___ +#define ___FB_NSString_H___ + +#import + +@interface NSString(FBMiscStrings) + +- (NSString *)_sybModelMakeInstanceVarName; +- (NSString *)_sybModelMakeClassName; +- (NSString *)_sybStringWithCapitalizedFirstChar; +- (NSString *)_sybStripEndSpaces; + +@end + +#endif diff --git a/sope-gdl1/FrontBase2/NSString+FB.m b/sope-gdl1/FrontBase2/NSString+FB.m new file mode 100644 index 00000000..3604325b --- /dev/null +++ b/sope-gdl1/FrontBase2/NSString+FB.m @@ -0,0 +1,156 @@ +/* + NSString+FB.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: NSString+FB.m 1 2004-08-20 10:38:46Z znek $ + +#if LIB_FOUNDATION_BOEHM_GC +# include +#endif + +#import "NSString+FB.h" +#import "common.h" + +@implementation NSString(FBMiscStrings) + +- (NSString *)_sybModelMakeInstanceVarName { + if ([self length] == 0) + return @""; + else { + unsigned clen = 0; + char *s = NULL; + unsigned cnt, cnt2; + + clen = [self cStringLength]; + s = objc_atomic_malloc(clen + 5); + + [self getCString:s maxLength:clen]; + + for (cnt = cnt2 = 0; cnt < clen; cnt++, cnt2++) { + if ((s[cnt] == '_') && (s[cnt + 1] != '\0')) { + s[cnt2] = toupper(s[cnt + 1]); + cnt++; + } + else if ((s[cnt] == '2') && (s[cnt + 1] != '\0')) { + s[cnt2] = s[cnt]; + cnt++; + cnt2++; + s[cnt2] = toupper(s[cnt]); + } + else + s[cnt2] = tolower(s[cnt]); + } + s[cnt2] = '\0'; + + return AUTORELEASE([[NSString alloc] initWithCStringNoCopy:s length:strlen(s) freeWhenDone:YES]); + } +} + +- (NSString *)_sybModelMakeClassName { + if ([self length] == 0) + return @""; + else { + unsigned clen = 0; + char *s = NULL; + unsigned cnt, cnt2; + + clen = [self cStringLength]; + s = objc_atomic_malloc(clen + 1); + + [self getCString:s maxLength:clen]; + + for (cnt = cnt2 = 0; cnt < clen; cnt++, cnt2++) { + if ((s[cnt] == '_') && (s[cnt + 1] != '\0')) { + s[cnt2] = toupper(s[cnt + 1]); + cnt++; + } + else if ((s[cnt] == '2') && (s[cnt + 1] != '\0')) { + s[cnt2] = s[cnt]; + cnt++; + cnt2++; + s[cnt2] = toupper(s[cnt]); + } + else + s[cnt2] = tolower(s[cnt]); + } + s[cnt2] = '\0'; + + s[0] = toupper(s[0]); + + return AUTORELEASE([[NSString alloc] initWithCStringNoCopy:s length:s?strlen(s):0 freeWhenDone:YES]); + } +} + +- (NSString *)_sybStringWithCapitalizedFirstChar { + NSCharacterSet *upperSet = [NSCharacterSet uppercaseLetterCharacterSet]; + + if ([self length] == 0) + return @""; + else if ([upperSet characterIsMember:[self characterAtIndex:0]]) + return AUTORELEASE([self copy]); + else { + NSMutableString *str = [NSMutableString stringWithCapacity:[self length]]; + + [str appendString:[[self substringToIndex:1] uppercaseString]]; + [str appendString:[self substringFromIndex:1]]; + + return AUTORELEASE([str copy]); + } +} + +- (NSString *)_sybStripEndSpaces { + if ([self length] > 0) { + NSCharacterSet *spaceSet = [NSCharacterSet whitespaceCharacterSet]; + NSMutableString *str = [NSMutableString stringWithCapacity:[self length]]; + IMP charAtIndex; + NSRange range; + + charAtIndex = [self methodForSelector:@selector(characterAtIndex:)]; + range.length = 0; + + for (range.location = ([self length] - 1); + range.location >= 0; + range.location++, range.length++) { + unichar c; + + c = (unichar)(int)charAtIndex(self, @selector(characterAtIndex:), + range.location); + if (![spaceSet characterIsMember:c]) + break; + } + + if (range.length > 0) { + [str appendString:self]; + [str deleteCharactersInRange:range]; + return AUTORELEASE([str copy]); + } + } + return AUTORELEASE([self copy]); +} + +@end + +void __link_NSStringFB() { + // used to force linking of object file + __link_NSStringFB(); +} diff --git a/sope-gdl1/FrontBase2/README b/sope-gdl1/FrontBase2/README new file mode 100644 index 00000000..375e6f04 --- /dev/null +++ b/sope-gdl1/FrontBase2/README @@ -0,0 +1,19 @@ +# $Id: README 1 2004-08-20 10:38:46Z znek $ + +FrontBase GDL database adaptor + +This package contains a GDL database adaptor for the FrontBase database +(www.frontbase.com). It was written with a lot of help from the people +at Frontline Software. + +If you have any fixes, questions or patches to this adaptor, contact me at + + helge.hess@mdlink.de + +Notably the development of this adaptor was supported by + + MDlink online service center GmbH + http://www.mdlink.de/ + +Helge Hess, helge.hess@mdlink.de +1999-11-03 diff --git a/sope-gdl1/FrontBase2/Version b/sope-gdl1/FrontBase2/Version new file mode 100644 index 00000000..947c5a97 --- /dev/null +++ b/sope-gdl1/FrontBase2/Version @@ -0,0 +1,3 @@ +# $Id: Version 1 2004-08-20 10:38:46Z znek $ + +SUBMINOR_VERSION:=2 diff --git a/sope-gdl1/FrontBase2/cancompile.sh b/sope-gdl1/FrontBase2/cancompile.sh new file mode 100755 index 00000000..c3463ebb --- /dev/null +++ b/sope-gdl1/FrontBase2/cancompile.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if test -d ./fb2/$1/$2/include/FBCAccess; then + echo "yes" +else + echo "no" +fi diff --git a/sope-gdl1/FrontBase2/common.h b/sope-gdl1/FrontBase2/common.h new file mode 100644 index 00000000..70d7d942 --- /dev/null +++ b/sope-gdl1/FrontBase2/common.h @@ -0,0 +1,67 @@ +/* + common.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge.hess@mdlink.de) + + This file is part of the FB Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: common.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___FB_common_H___ +#define ___FB_common_H___ + +#import + +#if LIB_FOUNDATION_BOEHM_GC +# include +# include +# include +#endif + +#import + + +#if !LIB_FOUNDATION_LIBRARY +# import +# import +# import +# import +# import +# import +# import +#else +# import +#endif + +#import + +#import "FBException.h" +#import "FBSQLExpression.h" + +#import "FBChannel.h" +#import "FBContext.h" +#import "FrontBase2Adaptor.h" + +#import "FBChannel+Model.h" +#import "FBValues.h" +#import "EOAttribute+FB.h" +#import "NSString+FB.h" + +#endif diff --git a/sope-gdl1/FrontBase2/condict.plist b/sope-gdl1/FrontBase2/condict.plist new file mode 100644 index 00000000..668a9c8b --- /dev/null +++ b/sope-gdl1/FrontBase2/condict.plist @@ -0,0 +1,5 @@ +{ + userName = "test"; + databaseName = "helgetest"; + hostName = "localhost"; +} diff --git a/sope-gdl1/FrontBase2/fbtest.m b/sope-gdl1/FrontBase2/fbtest.m new file mode 100644 index 00000000..dd2df1b4 --- /dev/null +++ b/sope-gdl1/FrontBase2/fbtest.m @@ -0,0 +1,302 @@ +// $Id: fbtest.m 1 2004-08-20 10:38:46Z znek $ + +#import +#import +#import +//#include "FBAdaptor.h" + +#define ADAPTOR_LEVEL 1 + +unsigned txRepeatCount = 1; + +static int doAdPersTest1(EOModel *m,EOAdaptorContext *ctx, EOAdaptorChannel *ch) { + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + EOEntity *e; + EOSQLQualifier *q; + NSArray *attrs; + id record; + + /* fetch some person records */ + + e = [m entityNamed:@"Person"]; + q = [e qualifier]; + attrs = [e attributes]; +#if 0 + NSLog(@"entity: %@", e); + NSLog(@"qual: %@", q); + NSLog(@"attrs: %@", attrs); +#endif + + if (attrs == nil) { + NSLog(@"missing Person attributes in entity %@ !!!", e); + } + + { + NSCalendarDate *start; + unsigned count, i; + + q = [[EOSQLQualifier alloc] initWithEntity:e + qualifierFormat:@"%A=5010", @"personId"]; + + start = [NSCalendarDate date]; + + count = 1; + for (i = 0; i < count; i++) { + //NSCAssert(attrs, @"missing attributes !!!"); + + if ([ch selectAttributes:attrs + describedByQualifier:q + fetchOrder:nil + lock:NO]) { + while ((record = [ch fetchAttributes:attrs withZone:nil])) { +#if 1 + NSLog(@"fetched %@ id %@", + [record valueForKey:@"pname"], + [record valueForKey:@"personId"]); +#endif + } + } + else { + NSLog(@"select failed ..."); + break; + } + } + NSLog(@"duration: count %i %.3fs", count, + [[NSCalendarDate date] timeIntervalSinceDate:start]); + } + + RELEASE(pool); + return 1; +} + +static int doAdTest1(EOModel *m,EOAdaptorContext *ctx, EOAdaptorChannel *ch) { +{ +#if !LIB_FOUNDATION_BOEHM_GC + NSAutoreleasePool *pool = [NSAutoreleasePool new]; +#endif + EOEntity *e; + EOSQLQualifier *q; + NSArray *attrs; + + /* fetch some team records */ + + e = [m entityNamed:@"Team"]; + q = [e qualifier]; + attrs = [e attributes]; + + if ([ch selectAttributes:attrs + describedByQualifier:q + fetchOrder:nil + lock:NO]) { + NSDictionary *record; + + while ((record = [ch fetchAttributes:attrs withZone:nil])) { + NSLog(@"fetched %@ birthday %@", + [record valueForKey:@"description"], + [record valueForKey:@"companyId"]); + } + } + + /* do some update */ + + e = [m entityNamed:@"Person"]; + attrs = [e attributes]; + q = [[EOSQLQualifier alloc] initWithEntity:e + qualifierFormat:@"%A='helge'", @"login"]; + + q = AUTORELEASE(q); + + if ([ch selectAttributes:attrs + describedByQualifier:q + fetchOrder:nil + lock:NO]) { + NSDictionary *record; + + while ((record = [ch fetchAttributes:attrs withZone:nil])) + ; + } + #if 0 + /* fetch some expr */ + + if (expr) { + if ([ch evaluateExpression:expr]) { + NSDictionary *record; + + attrs = [ch describeResults]; + //NSLog(@"results: %@", attrs); + + while ((record = [ch fetchAttributes:attrs withZone:nil])) + NSLog(@"fetched %@", record); + } + } + #endif + + RELEASE(pool); + } + return 1; +} + +static void runAdTests(NSDictionary *conDict) { + EOModel *m; + EOAdaptor *a; + EOAdaptorContext *ctx; + EOAdaptorChannel *ch; + NSString *expr; + + a = [EOAdaptor adaptorWithName:@"FrontBase2"]; + //a = [[FrontBaseAdaptor alloc] initWithName:@"FrontBase"]; + [a setConnectionDictionary:conDict]; + NSLog(@"got adaptor[%@] %@", NSStringFromClass([a class]), a); + + ctx = [a createAdaptorContext]; + ch = [ctx createAdaptorChannel]; + + m = AUTORELEASE([[EOModel alloc] initWithContentsOfFile:@"test.eomodel"]); + [a setModel:m]; + [a setConnectionDictionary:conDict]; + + expr = [[NSUserDefaults standardUserDefaults] stringForKey:@"sql"]; + + NSLog(@"opening channel .."); + + //[ch setDebugEnabled:NO]; + + if ([ch openChannel]) { + int txi; + NSLog(@"channel is open"); + + for (txi = 0; txi < txRepeatCount; txi++) { + if ([ctx beginTransaction]) { + NSLog(@"began tx (%i) ..", txi); + + /* do something */ + if (!doAdPersTest1(m, ctx, ch)) + break; + + NSLog(@"committing tx .."); + if ([ctx commitTransaction]) + NSLog(@" could commit."); + else + NSLog(@" commit failed."); + } + else { + NSLog(@"tx open failed .."); + } + } + + NSLog(@"closing channel .."); + [ch closeChannel]; + } + else { + NSLog(@"open channel failed ..."); + } +} + +static void runDbTests(NSDictionary *conDict) { + EOModel *m; + EOAdaptor *a; + EODatabase *db; + EODatabaseContext *ctx; + EODatabaseChannel *ch; + NSString *expr; + + a = [EOAdaptor adaptorWithName:@"FrontBase2"]; + //a = [[FrontBaseAdaptor alloc] initWithName:@"FrontBase"]; + [a setConnectionDictionary:conDict]; + NSLog(@"got adaptor[%@] %@", NSStringFromClass([a class]), a); + + db = [[EODatabase alloc] initWithAdaptor:a]; + ctx = [db createContext]; + ch = [ctx createChannel]; + + m = AUTORELEASE([[EOModel alloc] initWithContentsOfFile:@"test.eomodel"]); + [a setModel:m]; + [a setConnectionDictionary:conDict]; + + expr = [[NSUserDefaults standardUserDefaults] stringForKey:@"sql"]; + + NSLog(@"opening channel .."); + + if ([ch openChannel]) { + int txi; + NSLog(@"channel is open"); + + for (txi = 0; txi < txRepeatCount; txi++) { + if ([(EOAdaptorContext *)ctx beginTransaction]) { + NSLog(@"began tx .."); + + /* do something */ + { +#if !LIB_FOUNDATION_BOEHM_GC + NSAutoreleasePool *pool = [NSAutoreleasePool new]; +#endif + EOEntity *e; + EOSQLQualifier *q; + NSArray *attrs; + id record; + + /* fetch some person records */ + + e = [m entityNamed:@"Person"]; + q = [e qualifier]; + attrs = [e attributes]; + + if ([ch selectObjectsDescribedByQualifier:q fetchOrder:nil]) { + while ((record = [ch fetchWithZone:nil])) { + NSLog(@"fetched %@ birthday %@", + [record valueForKey:@"description"], + [record valueForKey:@"companyId"]); + } + } + + /* fetch some team records */ + + e = [m entityNamed:@"Team"]; + q = [e qualifier]; + attrs = [e attributes]; + + /* do some update */ + + e = [m entityNamed:@"Person"]; + attrs = [e attributes]; + q = [[EOSQLQualifier alloc] initWithEntity:e + qualifierFormat:@"%A='helge'", @"login"]; + + q = AUTORELEASE(q); + + RELEASE(pool); + } + + NSLog(@"committing tx .."); + if ([ctx commitTransaction]) + NSLog(@" could commit."); + else + NSLog(@" commit failed."); + } + } + + NSLog(@"closing channel .."); + [ch closeChannel]; + } + else { + NSLog(@"open channel failed ..."); + } +} + +int main(int argc, char **argv, char **env) { + NSAutoreleasePool *pool; + NSDictionary *conDict; + + pool = [[NSAutoreleasePool alloc] init]; + +#if LIB_FOUNDATION_LIBRARY + [NSProcessInfo initializeWithArguments:argv count:argc environment:env]; +#endif + + conDict = [NSDictionary dictionaryWithContentsOfFile:@"condict.plist"]; + + runAdTests(conDict); + + RELEASE(pool); + return 0; +} diff --git a/sope-gdl1/FrontBase2/fbtest.py b/sope-gdl1/FrontBase2/fbtest.py new file mode 100755 index 00000000..4ef645e8 --- /dev/null +++ b/sope-gdl1/FrontBase2/fbtest.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python +# $Id: fbtest.py 2 2004-08-20 10:48:47Z znek $ + +from Foundation import * +from eoaccess import * + +conDict = { 'userName': "skyrix", + 'databaseName': "Skyrix", + 'hostName': "inster" } + +adaptor = EOAdaptor(name='FrontBase2') +adaptor.setConnectionDictionary(conDict) +print "got adaptor ", adaptor.invoke0("class"); + +ctx = adaptor.createAdaptorContext() +ch = ctx.createAdaptorChannel() + +model = EOModel(contentsOfFile='test.eomodel') +adaptor.setModel(model) +adaptor.setConnectionDictionary(conDict) + +ch.setDebugEnabled(YES) + +if ch.openChannel(): + print "channel is open" + + if ctx.beginTransaction(): + print "began tx .." + + pool = NSAutoreleasePool() + + e = model.entityNamed('Person') + q = e.qualifier() + attrs = e.attributes() + + if ch.selectAttributes(attrs, q): + record = ch.fetchAttributes(attrs) + while record is not None: + print " login=%(login)s name=%(name)s bday=%(birthday)s" % \ + record + record = ch.fetchAttributes(attrs) + + del pool + + pool = NSAutoreleasePool() + + e = model.entityNamed('Person') + attrs = e.attributes() + q = EOKeyValueQualifier('login', EOQualifierOperatorEqual, 'helge') + q = q.sqlQualifierForEntity(e) + + if ch.selectAttributes(attrs, q): + record = ch.fetchAttributes(attrs) + print " login=%(login)s name=%(name)s bday=%(birthday)s" % \ + record + ch.cancelFetch() + + date = NSCalendarDate() + print "date in localtime:", date + date.setTimeZone(NSTimeZone("PST")) + print "date in pacific time:", date + + record['birthday'] = date + print " login=%(login)s name=%(name)s bday=%(birthday)s" % record + + if ch.updateRow(record, q): + print "did update .." + else: + print "update failed .." + + if ch.selectAttributes(attrs, q): + nrecord = ch.fetchAttributes(attrs) + print " login=%(login)s name=%(name)s bday=%(birthday)s" % \ + nrecord + print nrecord['birthday'].__class__ + ch.cancelFetch() + + del pool + + ctx.rollbackTransaction() + else: + print "couldn't begin tx." + + ch.closeChannel() +else: + print "couldn't open channel." + diff --git a/sope-gdl1/FrontBase2/test.eomodel b/sope-gdl1/FrontBase2/test.eomodel new file mode 100644 index 00000000..725348d9 --- /dev/null +++ b/sope-gdl1/FrontBase2/test.eomodel @@ -0,0 +1,60 @@ +{ + EOModelVersion = 1; + adaptorClassName = FrontBase2Adaptor; + adaptorName = FrontBase; + + pkeyGeneratorDictionary = { + newKeyExpression = "SELECT UNIQUE FROM key_generator"; + }; + + entities = ( + { + externalName = person; + className = EOGenericRecord; + name = Person; + attributes = ( + { + valueClassName = NSNumber; + columnName = person_id; + name = personId; + valueType = i; + externalType = int; + }, + { + valueClassName = NSNumber; + columnName = blah; + name = blah; + valueType = i; + externalType = int; + }, + { + valueClassName = NSString; + columnName = pname; + name = pname; + externalType = varchar; + }, + { + valueClassName = NSString; + columnName = street; + name = street; + externalType = varchar; + }, + { + valueClassName = NSString; + columnName = city; + name = city; + externalType = varchar; + } + ); + classProperties = ( + personId,blah,pname,street,city + ); + relationships = ( + ); + primaryKeyAttributes = ( personId ); + attributesUsedForLocking = ( + personId + ); + } + ); +} diff --git a/sope-gdl1/GDLAccess/COPYING.LIB b/sope-gdl1/GDLAccess/COPYING.LIB new file mode 100644 index 00000000..eb685a5e --- /dev/null +++ b/sope-gdl1/GDLAccess/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/sope-gdl1/GDLAccess/ChangeLog b/sope-gdl1/GDLAccess/ChangeLog new file mode 100644 index 00000000..4adfba7b --- /dev/null +++ b/sope-gdl1/GDLAccess/ChangeLog @@ -0,0 +1,146 @@ +2004-08-20 Helge Hess + + * moved from ThirdParty to SOPE/sope-gdl1 (v1.0.32) + +2004-06-29 Helge Hess + + * v1.0.31 + + * EOAdaptorChannel.m: fixed a bug in the transaction check introduced + in v1.0.29 - resulted in OGo bug #824, #825 + + * EODatabaseChannel.m: use new "X" adaptor methods + + * GNUmakefile.preamble: added include path to SOPE/skyrix-core for + "inline" compilation (v1.0.30) + +2004-06-28 Helge Hess + + * EOAdaptorChannel.[hm]: added more "X" methods which do not raise + exceptions (v1.0.29) + + * EOAdaptorChannel.m: added new method -evaluateExpressionX: which + returns the exception instead of raising it. It returns + @"EOEvaluationError" if the -evaluateExpression: returned NO without + raising an exception. It is recommended that adaptor classes + implement -evaluateExpression: using -evaluateExpressionX:, not the + other way around (v1.0.28) + +2004-06-27 Helge Hess + + * EOModel.m: minor code cleanups (v1.0.27) + +2004-06-21 Helge Hess + + * EOModel.m: some code cleanups, improved description (v1.0.26) + +2004-06-06 Helge Hess + + * fixed Xcode compilation with embedded FoundationExt classes (v1.0.25) + +2004-05-14 Helge Hess + + * EOAdaptorDataSource.m: removed some ==YES comparisons, minor cleanups + (v1.0.24) + +2004-03-14 Helge Hess + + * v1.0.23 + + * EOSQLQualifier.m: improved -description method + + * EOSQLExpression.m: moved EOSelectSQLExpression to separate file, + added a -description method, various minor code cleanups + + * EOExpressionArray.m: added a -description method, minor cleanups + + * EOAdaptorChannel.m: minor code cleanups + + * EODatabaseContext.m: removed registration for + EOCooperatingObjectStoreNeeded notification (solves an issue with + gstep-base) + +2004-03-09 Helge Hess + + * EOAdaptorChannel.m, EOAdaptorDataSource.m, EOAttribute.m, + EODatabase.m, EOEntity.m, EOEntityClassDescription.m, + EOQualifier+SQL.m, EOSQLExpression.m, common.h, EOQualifierScanner.h: + various subminor fixes for compilation against gstep-base (v1.0.22) + +2004-02-12 Helge Hess + + * EODatabaseChannel.m: only check for GC objects on libFoundation + (v1.0.21) + +2004-01-29 Helge Hess + + * EORecordDictionary.m: disabled a profiling log (v1.0.20) + +2004-01-07 Helge Hess + + * some tweaks for Xcode compilation (v1.0.19) + +2004-01-04 Helge Hess + + * v1.0.18 + + * more tweaks to makefiles and source, now seems to compile fine on + MacOSX + + * added FoundationExt subproject containing the necessary classes from + the extensions library, that is, the FormatScanner, + PrintfFormatScanner and DefaultScannerHandler + +2004-01-03 Helge Hess + + * v1.0.17 + + * EORecordDictionary.m: cache -hash and -isEqual selector in + objectForKey: + + * various changes to make gnustep-db compile on MacOSX (eg do not use + InvalidArgumentException class but rather NSInvalidArgumentException + exception name, etc) + +2003-12-29 Helge Hess + + * EORecordDictionary.m(dealloc): cache release method of dict key, + which is basically always an NSString, also cache empty dictionary + (v1.0.16) + +2003-10-20 Helge Hess + + * v1.0.15 + + * common.h: do not use zones for memory allocation (read: speedup) + + * removed support for Boehm GC, makes code much more readable and + shorter (and isn't used in OGo anyway ...) + + * removed some warnings, some FoundationExt cleanups + + * EOExpressionArray.h: does not inherit from GCObject and use + GCMutableArray anymore (replaced with NSObject and NSMutableArray) + + * EODatabaseContext.m: removed some unused methods + + * removed some GCObject dependency + + * EODatabaseChannel.m: removed some unused methods + +Wed Oct 15 16:26:50 2003 Jan Reichmann + + * EOModel.m: initialize model name with the filename which contains the model + (*.eomodel) (v1.0.14) + +Sun Sep 07 00:30:59 2003 Marcus Mueller + + * GNUmakefile: reordered autodoc target + +Mon Jul 14 14:07:22 2003 Jan Reichmann + + * fixed license entries (v1.0.13) + +Fri Jul 4 19:15:35 2003 Helge Hess + + * imported into OpenGroupware.org (v1.0.11) diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAccess.h b/sope-gdl1/GDLAccess/EOAccess/EOAccess.h new file mode 100644 index 00000000..70d10c0a --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAccess.h @@ -0,0 +1,43 @@ +// $Id: EOAccess.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __GDLAccess_H__ +#define __GDLAccess_H__ + +#import +#import +#import + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import +#import + +// Kit class + +@interface GDLAccess : NSObject +@end + +#endif /* __GDLAccess_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAdaptor.h b/sope-gdl1/GDLAccess/EOAccess/EOAdaptor.h new file mode 100644 index 00000000..a4e27187 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAdaptor.h @@ -0,0 +1,136 @@ +/* + EOAdaptor.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOAdaptor_h__ +#define __EOAdaptor_h__ + +#import + +@class NSMutableArray, NSArray; +@class NSDictionary; +@class NSString; + +@class EOModel; +@class EOAttribute; +@class EOAdaptorContext; + +/* The EOAdaptor class could be overriden for a concrete database adaptor. + You have to override only those methods marked in this header with + `override'. +*/ + +/* Don't make EOAdaptor* classes garbage collectable because we want to make + the instances release the database allocated resources immediately when they + receive the -release message. */ + +@interface EOAdaptor : NSObject +{ +@protected + EOModel *model; + NSString *name; + NSDictionary *connectionDictionary; + NSDictionary *pkeyGeneratorDictionary; + NSMutableArray *contexts; // values with contexts + id delegate; // not retained + + /* Flags used to check if the delegate responds to several messages */ + BOOL delegateWillReportError:1; +} + +/* Creating an EOAdaptor */ ++ (id)adaptorWithModel:(EOModel *)aModel; ++ (id)adaptorWithName:(NSString *)aName; +- (id)initWithName:(NSString *)aName; + +/* Getting an adaptor's name */ +- (NSString*)name; + +/* Setting connection information */ +- (void)setConnectionDictionary:(NSDictionary*)aDictionary; +- (NSDictionary*)connectionDictionary; +- (BOOL)hasValidConnectionDictionary; // override + +/* Setting pkey generation info */ +- (void)setPkeyGeneratorDictionary:(NSDictionary*)aDictionary; +- (NSDictionary*)pkeyGeneratorDictionary; + +/* Setting the model */ +- (void)setModel:(EOModel*)aModel; +- (EOModel*)model; + +/* Creating and removing an adaptor context */ +- (EOAdaptorContext*)createAdaptorContext; // override +- (NSArray *)contexts; + +/* Checking connection status */ +- (BOOL)hasOpenChannels; + +/* Getting adaptor-specific information */ +- (Class)expressionClass; // override +- (Class)adaptorContextClass; // override +- (Class)adaptorChannelClass; // override +- (BOOL)isValidQualifierType:(NSString*)aTypeName; // override + +/* Formatting SQL */ +- (id)formatAttribute:(EOAttribute*)attribute; // override +- (id)formatValue:value forAttribute:(EOAttribute*)attribute; // override + +/* Reporting errors */ +- (void)reportError:(NSString*)anError; + +/* Setting the delegate */ +- (id)delegate; +- (void)setDelegate:(id)aDelegate; + +@end /* EOAdaptor */ + + +@interface EOAdaptor(Private) +- (void)contextDidInit:(id)aContext; +- (void)contextWillDealloc:(id)aContext; +@end + + +@interface NSObject(EOAdaptorDelegate) + +- (BOOL)adaptor:(EOAdaptor*)anAdaptor willReportError:(NSString*)anError; + +@end /* NSObject(EOAdaptorDelegate) */ + +@interface EOAdaptor(MDlinkExtensions) +- (NSString *)charConvertExpressionForAttributeNamed:(NSString *)_attrName; +- (NSString *)lowerExpressionForTextAttributeNamed:(NSString *)_attrName; +- (NSString *)expressionForTextValue:(id)_value; +- (BOOL)attributeAllowedInDistinctSelects:(EOAttribute *)attribute; +@end + +@interface EOAdaptor(EOF2Additions) + +- (BOOL)canServiceModel:(EOModel *)_model; + +@end + +#endif /* __EOAdaptor_h__*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel+Attributes.h b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel+Attributes.h new file mode 100644 index 00000000..1131816d --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel+Attributes.h @@ -0,0 +1,17 @@ +//$Id: EOAdaptorChannel+Attributes.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __EOAdaptorChannel_Attributes_h__ +#define __EOAdaptorChannel_Attributes_h__ + +@class NSString, NSArray; + +#import + +@interface EOAdaptorChannel(Attributes) + +- (NSArray *)attributesForTableName:(NSString *)_tableName; +- (NSArray *)primaryKeyAttributesForTableName:(NSString *)_tableName; + +@end + +#endif /* __EOAdaptorChannel_Attributes_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel.h b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel.h new file mode 100644 index 00000000..751b1b84 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel.h @@ -0,0 +1,202 @@ +/* + EOAdaptorChannel.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOAdaptorChannel_h__ +#define __EOAdaptorChannel_h__ + +#import + +@class NSArray, NSMutableArray, NSDictionary, NSMutableDictionary, NSString; +@class NSMutableString, NSCalendarDate, NSException; + +@class EOModel, EOEntity, EOAttribute, EOSQLQualifier, EOAdaptorContext; + +/* + The EOAdaptorChannel class can be subclassed in a database adaptor. You have + to override only those methods marked in this header with `override'. +*/ + +@interface EOAdaptorChannel : NSObject +{ +@protected + EOAdaptorContext *adaptorContext; + id delegate; // not retained + + /* Flags that determine the state of the adaptor */ + BOOL isFetchInProgress; + BOOL isOpen; + BOOL debugEnabled; + + /* Flags used to check if the delegate responds to several messages */ + struct { + BOOL willInsertRow:1; + BOOL didInsertRow:1; + BOOL willUpdateRow:1; + BOOL didUpdateRow:1; + BOOL willDeleteRows:1; + BOOL didDeleteRows:1; + BOOL willSelectAttributes:1; + BOOL didSelectAttributes:1; + BOOL willFetchAttributes:1; + BOOL didFetchAttributes:1; + BOOL didChangeResultSet:1; + BOOL didFinishFetching:1; + BOOL willEvaluateExpression:1; + BOOL didEvaluateExpression:1; + } delegateRespondsTo; +} + ++ (NSCalendarDate*)dateForAttribute:(EOAttribute*)attr + year:(int)year month:(unsigned)month day:(unsigned)day + hour:(unsigned)hour minute:(unsigned)minute second:(unsigned)second + zone:(NSZone*)zone; + +/* Initializing an adaptor context */ +- (id)initWithAdaptorContext:(EOAdaptorContext*)adaptorContext; + +/* Getting the adaptor context */ +- (EOAdaptorContext*)adaptorContext; + +/* Opening and closing a channel */ +- (BOOL)isOpen; +- (BOOL)openChannel; +- (void)closeChannel; + +/* Modifying rows, new world methods */ +- (NSException *)insertRowX:(NSDictionary *)_row forEntity:(EOEntity *)_entity; +- (NSException *)updateRowX:(NSDictionary*)aRow + describedByQualifier:(EOSQLQualifier*)aQualifier; +- (NSException *)deleteRowsDescribedByQualifierX:(EOSQLQualifier*)aQualifier; + +/* Modifying rows, old world methods (DEPRECATED) */ +- (BOOL)insertRow:(NSDictionary *)aRow forEntity:(EOEntity *)anEntity; +- (BOOL)updateRow:(NSDictionary *)aRow + describedByQualifier:(EOSQLQualifier *)aQualifier; +- (BOOL)deleteRowsDescribedByQualifier:(EOSQLQualifier *)aQualifier; + +/* Fetching rows */ +- (BOOL)selectAttributes:(NSArray*)attributes + describedByQualifier:(EOSQLQualifier*)aQualifier + fetchOrder:(NSArray*)aFetchOrder + lock:(BOOL)aLockFlag; +- (NSArray*)describeResults; // override +- (NSMutableDictionary*)fetchAttributes:(NSArray*)attributes + withZone:(NSZone*)zone; +- (BOOL)isFetchInProgress; +- (void)cancelFetch; // override +- (NSMutableDictionary*)dictionaryWithObjects:(id*)objects + forAttributes:(NSArray*)attributes zone:(NSZone*)zone; +- (NSMutableDictionary*)primaryFetchAttributes:(NSArray*)attributes + withZone:(NSZone*)zone; // override + +/* Sending SQL to the server */ +- (BOOL)evaluateExpression:(NSString *)_anExpression; // override +- (NSException *)evaluateExpressionX:(NSString*)_sql; + +/* Getting schema information */ +- (EOModel*)describeModelWithTableNames:(NSArray*)tableNames; // override +- (NSArray*)describeTableNames; // override +- (BOOL)readTypesForEntity:(EOEntity*)anEntity; // override +- (BOOL)readTypeForAttribute:(EOAttribute*)anAttribute; // override + +/* Debugging */ +- (void)setDebugEnabled:(BOOL)flag; +- (BOOL)isDebugEnabled; + +/* Setting the channel's delegate */ +- (id)delegate; +- (void)setDelegate:aDelegate; + +@end /* EOAdaptorChannel*/ + +@interface EOAdaptorChannel(PrimaryKeyGeneration) // new in EOF2 + +- (NSDictionary *)primaryKeyForNewRowWithEntity:(EOEntity *)_entity; + +@end + +@class EOEntity, EOFetchSpecification; + +@interface EOAdaptorChannel(EOF2Additions) + +- (void)selectAttributes:(NSArray *)_attributes + fetchSpecification:(EOFetchSpecification *)_fspec + lock:(BOOL)_flag + entity:(EOEntity *)_entity; + +- (void)setAttributesToFetch:(NSArray *)_attributes; +- (NSArray *)attributesToFetch; + +- (NSMutableDictionary *)fetchRowWithZone:(NSZone *)_zone; + +@end + +#import + +@interface NSObject(EOAdaptorChannelDelegation) + +- (EODelegateResponse)adaptorChannel:aChannel + willInsertRow:(NSMutableDictionary*)aRow + forEntity:(EOEntity*)anEntity; +- (void)adaptorChannel:channel + didInsertRow:(NSDictionary*)aRow + forEntity:(EOEntity*)anEntity; +- (EODelegateResponse)adaptorChannel:aChannel + willUpdateRow:(NSMutableDictionary*)aRow + describedByQualifier:(EOSQLQualifier*)aQualifier; +- (void)adaptorChannel:aChannel + didUpdateRow:(NSDictionary*)aRow + describedByQualifier:(EOSQLQualifier*)aQualifier; +- (EODelegateResponse)adaptorChannel:aChannel + willDeleteRowsDescribedByQualifier:(EOSQLQualifier*)aQualifier; +- (void)adaptorChannel:aChannel + didDeleteRowsDescribedByQualifier:(EOSQLQualifier*)aQualifier; +- (EODelegateResponse)adaptorChannel:aChannel + willSelectAttributes:(NSMutableArray*)attributes + describedByQualifier:(EOSQLQualifier*)aQualifier + fetchOrder:(NSMutableArray*)aFetchOrder + lock:(BOOL)aLockFlag; +- (void)adaptorChannel:aChannel + didSelectAttributes:(NSArray*)attributes + describedByQualifier:(EOSQLQualifier*)aQualifier + fetchOrder:(NSArray*)aFetchOrder + lock:(BOOL)aLockFlag; +- (NSMutableDictionary*)adaptorChannel:aChannel + willFetchAttributes:(NSArray*)attributes + withZone:(NSZone*)zone; +- (NSMutableDictionary*)adaptorChannel:aChannel + didFetchAttributes:(NSMutableDictionary*)attributes + withZone:(NSZone*)zone; +- (void)adaptorChannelDidChangeResultSet:aChannel; +- (void)adaptorChannelDidFinishFetching:aChannel; +- (EODelegateResponse)adaptorChannel:aChannel + willEvaluateExpression:(NSMutableString*)anExpression; +- (void)adaptorChannel:aChannel + didEvaluateExpression:(NSString*)anExpression; + +@end /* NSObject(EOAdaptorChannelDelegation) */ + +#endif /* __EOAdaptorChannel_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAdaptorContext.h b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorContext.h new file mode 100644 index 00000000..d7b3291d --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorContext.h @@ -0,0 +1,123 @@ +/* + EOAdaptorContext.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOAdaptorContext_h__ +#define __EOAdaptorContext_h__ + +#import + +@class NSArray, NSMutableArray; + +@class EOAdaptor; +@class EOAdaptorChannel; + +/* The EOAdaptorContext class could be overriden for a concrete database + adaptor. You have to override only those methods marked in this header + with `override'. +*/ + +@interface EOAdaptorContext : NSObject +{ + EOAdaptor *adaptor; + NSMutableArray *channels; // values with channels + id delegate; // not retained + int transactionNestingLevel; + + /* Flags used to check if the delegate responds to several messages */ + struct { + BOOL willBegin:1; + BOOL didBegin:1; + BOOL willCommit:1; + BOOL didCommit:1; + BOOL willRollback:1; + BOOL didRollback:1; + } delegateRespondsTo; +} + +/* Initializing an adaptor context */ +- (id)initWithAdaptor:(EOAdaptor*)adaptor; + +/* Setting and getting the adaptor */ +- (EOAdaptor*)adaptor; + +/* Creating a new channel */ +- (EOAdaptorChannel*)createAdaptorChannel; // override +- (NSArray *)channels; + +/* Checking connection status */ +- (BOOL)hasOpenChannels; + +/* Finding open channels */ +- (BOOL)hasBusyChannels; + +/* Controlling transactions */ +- (BOOL)beginTransaction; +- (BOOL)commitTransaction; +- (BOOL)rollbackTransaction; + +/* Notifying of other transactions */ +- (void)transactionDidBegin; +- (void)transactionDidCommit; +- (void)transactionDidRollback; + +/* Nesting transactions */ +- (BOOL)canNestTransactions; // override, deprecated +- (unsigned)transactionNestingLevel; // deprecated +- (BOOL)hasOpenTransaction; // new in WO 4.5 + +/* Setting the delegate */ +- (id)delegate; +- (void)setDelegate:(id)aDelegate; + +/* Primary methods that control the transactions. This methods dont't call the + delegate. You should implement these methods instead of the similar ones but + without the `primary' prefix. */ +- (BOOL)primaryBeginTransaction; // override +- (BOOL)primaryCommitTransaction; // override +- (BOOL)primaryRollbackTransaction; // override + +@end /* EOAdaptorContext*/ + + +@interface EOAdaptorContext(Private) +- (void)channelDidInit:(id)aChannel; +- (void)channelWillDealloc:(id)aChannel; +@end + +#import + +@interface NSObject(EOAdaptorContextDelegate) + +- (EODelegateResponse)adaptorContextWillBegin:(id)aContext; +- (void)adaptorContextDidBegin:(id)aContext; +- (EODelegateResponse)adaptorContextWillCommit:(id)aContext; +- (void)adaptorContextDidCommit:(id)aContext; +- (EODelegateResponse)adaptorContextWillRollback:(id)aContext; +- (void)adaptorContextDidRollback:(id)aContext; + +@end /* NSObject(EOAdaptorContextDelegate) */ + +#endif /* __EOAdaptorContext_h__*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAdaptorDataSource.h b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorDataSource.h new file mode 100644 index 00000000..6e1fdb4f --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorDataSource.h @@ -0,0 +1,110 @@ +/* + EOAdaptorDataSource.h + + Copyright (C) SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + Date: 1999-2004 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAdaptorDataSource.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __EOAdaptorDataSource_h__ +#define __EOAdaptorDataSource_h__ + +#import + +@class NSArray, NSDictionary; +@class EOFetchSpecification, EOAdaptorChannel, EOQualifier; + +/* + Fetch dictionaries from database tables. + The tablename has to be set in [FetchSpecification entityName]. + Qualifier, sortOrdering, distinct will be evaluated. + It handles now tables with more than one primary key. + Its possible to set the primary key in the fetchspecification hints + (EOPrimaryKeyAttributeNamesHint -> array with strings as columnnames + for the PKeys; EOPrimaryKeyAttributesHint -> array with EOAttributes for + the PKeys). + If no primary key is set, and now primary key could find in the table + schema, all keys will be taken as primary keys. + If only one primary key exsist, in insert object a new key will be generatet, + else all keys has to be set. + If fetch hint EOFetchResultTimeZone is set (NSTimeZone), this timezone will + be set in date objectes. +*/ + +extern NSString *EOPrimaryKeyAttributeNamesHint; +extern NSString *EOPrimaryKeyAttributesHint; +extern NSString *EOFetchResultTimeZone; + +@interface EOAdaptorDataSource : EODataSource +{ +@private + EOFetchSpecification *fetchSpecification; +@protected + EOAdaptorChannel *adChannel; + EOQualifier *__qualifier; + NSArray *__attributes; + BOOL commitTransaction; + NSDictionary *connectionDictionary; +} + +- (id)initWithAdaptorChannel:(EOAdaptorChannel *)_channel; + +- (id)initWithAdaptorChannel:(EOAdaptorChannel *)_channel + connectionDictionary:(NSDictionary *)_connDict; + +- (id)initWithAdaptorName:(NSString *)_adName + connectionDictionary:(NSDictionary *)_dict + primaryKeyGenerationDictionary:(NSDictionary *)_pkGen; + + +/* + Returns an array with dictionaries, who contains key/values from the + entity (use entityName/qualifier/sortOrdering). + Also it contains an key named 'globalID'. If EOAdaptorDataSource is + initialized with initWithAdaptorChannel the globaID is an EOKeyGlobalID + else if it is initialized with initWithAdaptorName the globalID is and + EOAdaptorGlobalID. +*/ +- (NSArray *)fetchObjects; + +/* + returns an mutable dictionary +*/ +- (id)createObject; + +- (void)insertObject:(id)_obj; +- (void)deleteObject:(id)_obj; +- (void)updateObject:(id)_obj; + +- (void)setFetchSpecification:(EOFetchSpecification *)_fs; +- (EOFetchSpecification *)fetchSpecification; + +/* for subclasses */ +- (EOAdaptorChannel *)beginTransaction; +- (void)commitTransaction; +- (void)rollbackTransaction; + +- (void)openChannel; +- (void)closeChannel; +@end + +#endif /* __EOAdaptorDataSource_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAdaptorGlobalID.h b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorGlobalID.h new file mode 100644 index 00000000..49d90117 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorGlobalID.h @@ -0,0 +1,28 @@ +// $Id: EOAdaptorGlobalID.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __EOAdaptorGlobalID_H__ +#define __EOAdaptorGlobalID_H__ + +#include + +@class EOKeyGlobalID, NSDictionary; + +@interface EOAdaptorGlobalID : EOGlobalID < NSCopying > +{ +@protected + EOGlobalID *gid; + NSDictionary *conDict; +} + +- (id)initWithGlobalID:(EOGlobalID *)_gid + connectionDictionary:(NSDictionary *)_conDict; + +- (EOGlobalID *)globalID; +- (NSDictionary *)connectionDictionary; + +- (BOOL)isEqual:(id)_obj; +- (BOOL)isEqualToEOAdaptorGlobalID:(EOAdaptorGlobalID *)_gid; + +@end + +#endif /* __EOAdaptorGlobalID_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAdaptorOperation.h b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorOperation.h new file mode 100644 index 00000000..5f74c271 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAdaptorOperation.h @@ -0,0 +1,11 @@ +// $If$ + +#ifndef __EOAdaptorOperation_H__ +#define __EOAdaptorOperation_H__ + +#import + +@interface EOAdaptorOperation : NSObject +@end + +#endif /* __EOAdaptorOperation_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOArrayProxy.h b/sope-gdl1/GDLAccess/EOAccess/EOArrayProxy.h new file mode 100644 index 00000000..bdcfb8ba --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOArrayProxy.h @@ -0,0 +1,67 @@ +/* + EOArrayProxy.h + + Copyright (C) 1999 MDlink online service center GmbH, Helge Hess + + Author: Helge Hess (hh@mdlink.de) + Date: 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOArrayProxy.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __eoaccess_EOArrayProxy_H__ +#define __eoaccess_EOArrayProxy_H__ + +#import + +/* + * EOArrayProxy class + */ + +@class NSArray, NSString; +@class EODatabaseChannel, EOSQLQualifier, EOEntity; + +@interface EOArrayProxy : NSArray +{ +@private + EODatabaseChannel *channel; + EOSQLQualifier *qualifier; + NSArray *fetchOrder; + NSArray *content; +} + ++ (id)arrayProxyWithQualifier:(EOSQLQualifier *)_qualifier + fetchOrder:(NSArray *)_fetchOrder + channel:(EODatabaseChannel *)_channel; + +// accessors + +- (BOOL)isFetched; +- (EODatabaseChannel *)databaseChannel; +- (EOEntity *)entity; +- (NSArray *)fetchOrder; +- (EOSQLQualifier *)qualifier; + +// operations + +- (BOOL)fetch; + +@end + +#endif /* __eoaccess_EOArrayProxy_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAttribute.h b/sope-gdl1/GDLAccess/EOAccess/EOAttribute.h new file mode 100644 index 00000000..86feb5c5 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAttribute.h @@ -0,0 +1,188 @@ +/* + EOAttribute.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOAttribute_h__ +#define __EOAttribute_h__ + +#import +#import +#import + +@class NSString, NSTimeZone, NSDate, NSException; +@class NSMutableArray; +@class EOEntity; + +@interface EOAttribute : NSObject +{ + NSString *name; + NSString *calendarFormat; + NSTimeZone *clientTimeZone; + NSTimeZone *serverTimeZone; + NSString *columnName; + NSString *definition; + NSString *externalType; + NSString *valueClassName; + NSString *valueType; + NSString *insertFormat; + NSString *selectFormat; + NSString *updateFormat; + NSDictionary *userDictionary; + + /* Garbage collectable objects */ + EOEntity *entity; /* non-retained */ + NSMutableArray *definitionArray; // These variables are meaningful only + EOAttribute *realAttribute; // if the attribute is flattened + unsigned width; + + struct { + BOOL isReadOnly:1; + BOOL isDerived:1; + BOOL isFlattened:1; + BOOL allowsNull:1; + } flags; +} + +/* Initializing new instances */ +- (id)initWithName:(NSString*)name; + +/* Accessing the entity */ +- (void)setEntity:(EOEntity*)entity; +- (EOEntity*)entity; +- (void)resetEntity; +- (BOOL)hasEntity; + +/* Accessing the name */ +- (BOOL)setName:(NSString*)name; +- (NSString*)name; ++ (BOOL)isValidName:(NSString*)name; + +/* Accessing date information */ ++ (NSString*)defaultCalendarFormat; +- (void)setCalendarFormat:(NSString*)format; +- (NSString*)calendarFormat; +- (void)setClientTimeZone:(NSTimeZone*)tz; +- (NSTimeZone*)clientTimeZone; +- (void)setServerTimeZone:(NSTimeZone*)tz; +- (NSTimeZone*)serverTimeZone; + +/* Accessing external definitions */ +- (void)setColumnName:(NSString*)columnName; +- (NSString*)columnName; +- (void)setDefinition:(NSString*)definition; +- (NSString*)definition; +- (NSMutableArray*)definitionArray; +- (void)setExternalType:(NSString*)type; +- (NSString*)externalType; + +/* Accessing value type information */ +- (void)setValueClassName:(NSString*)name; +- (NSString*)valueClassName; +- (void)setValueType:(NSString*)type; +- (NSString*)valueType; + +/* Checking type information */ +- (BOOL)referencesProperty:property; +- (BOOL)isDerived; +- (BOOL)isFlattened; +- (BOOL)setReadOnly:(BOOL)flag; +- (BOOL)isReadOnly; + +/* Accessing SQL statement formats */ +- (void)setInsertFormat:(NSString*)string; +- (NSString*)insertFormat; +- (void)setSelectFormat:(NSString*)string; +- (NSString*)selectFormat; +- (void)setUpdateFormat:(NSString*)string; +- (NSString*)updateFormat; + +/* Accessing the user dictionary */ +- (void)setUserDictionary:(NSDictionary*)dictionary; +- (NSDictionary*)userDictionary; + +/* Obsolete. This method always return NO, because you should always release + a property. */ +- (BOOL)referencesProperty:property; + +@end + + +@interface EOAttribute (EOAttributePrivate) + ++ (EOAttribute*)attributeFromPropertyList:(id)propertyList; +- (void)replaceStringsWithObjects; +- (id)propertyList; + +@end /* EOAttribute (EOAttributePrivate) */ + +@interface EOAttribute(ValuesConversion) + +- (id)convertValue:(id)aValue + toClass:(Class)aClass + forType:(NSString *)aValueType; +- (id)convertValueToModel:(id)aValue; + +@end /* EOAttribute (ValuesConversion) */ + +@interface NSString (EOAttributeTypeCheck) + +- (BOOL)isNameOfARelationshipPath; + +@end + +@class NSMutableDictionary; + +@interface EOAttribute(PropertyListCoding) + +- (void)encodeIntoPropertyList:(NSMutableDictionary *)_plist; + +@end + +@interface EOAttribute(EOF2Additions) + +- (void)beautifyName; + +/* constraints */ + +- (void)setAllowsNull:(BOOL)_flag; +- (BOOL)allowsNull; +- (void)setWidth:(unsigned)_width; +- (unsigned)width; + +- (NSException *)validateValue:(id *)_value; + +- (NSString *)readFormat; +- (NSString *)writeFormat; + +@end + +#endif /* __EOAttribute_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOAttributeOrdering.h b/sope-gdl1/GDLAccess/EOAccess/EOAttributeOrdering.h new file mode 100644 index 00000000..f62d7fcc --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOAttributeOrdering.h @@ -0,0 +1,65 @@ +/* + EOAttributeOrdering.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOAttributeOrdering_h__ +#define __EOAttributeOrdering_h__ + +#import + +@class EOAttribute; + +typedef enum { + EOAnyOrder, + EOAscendingOrder, + EODescendingOrder +} EOOrdering; + +@interface EOAttributeOrdering : NSObject +{ + EOAttribute* attribute; + EOOrdering ordering; +} + +/* Creating an attribute ordering */ ++ attributeOrderingWithAttribute:(EOAttribute*)attribute + ordering:(EOOrdering)ordering; +- initWithAttribute:(EOAttribute*)attribute + ordering:(EOOrdering)ordering; + +/* Getting values */ +- (EOAttribute*)attribute; +- (EOOrdering)ordering; + +@end + +#endif /* __EOAttributeOrdering_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOCustomValues.h b/sope-gdl1/GDLAccess/EOAccess/EOCustomValues.h new file mode 100644 index 00000000..0e331e3a --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOCustomValues.h @@ -0,0 +1,84 @@ +/* + EOCustomValues.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOCustomValues_h__ +#define __EOCustomValues_h__ + +#import +#import +#import + +/* + * Informal protocols to initialize value-instances (used as objects + * in the dictionaries for the enterprise objects) and to convert + * those values to string or data. + * NOT implemented in NSObject + */ + +@interface NSObject(EOCustomValues) +- (id)initWithString:(NSString*)string type:(NSString*)type; +- (NSString*)stringForType:(NSString*)type; +@end + +@interface NSObject(EODatabaseCustomValues) +- (id)initWithData:(NSData*)data type:(NSString*)type; +- (NSData*)dataForType:(NSString*)type; +@end + +/* + * These categories are added to NSString, NSData and NSNumber classes. + */ + +@interface NSString(EOCustomValues) ++ stringWithString:(NSString*)string type:(NSString*)type; +- (id)initWithString:(NSString*)string type:(NSString*)type; +- (NSString*)stringForType:(NSString*)type; +- (id)initWithData:(NSData*)data type:(NSString*)type; +- (NSData*)dataForType:(NSString*)type; +@end + +@interface NSData(EOCustomValues) +- initWithString:(NSString*)string type:(NSString*)type; +- (NSString*)stringForType:(NSString*)type; +- (id)initWithData:(NSData*)data type:(NSString*)type; +- (NSData*)dataForType:(NSString*)type; +@end + +@interface NSNumber(EOCustomValues) ++ (id)numberWithString:(NSString*)string type:(NSString*)type; +- (id)initWithString:(NSString*)string type:(NSString*)type; +- (NSString*)stringForType:(NSString*)type; +@end + +#endif /* __EOCustomValues_h__ */ + + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EODatabase.h b/sope-gdl1/GDLAccess/EOAccess/EODatabase.h new file mode 100644 index 00000000..d9005278 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EODatabase.h @@ -0,0 +1,169 @@ +/* + EODatabase.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __eoaccess_EODatabase_h__ +#define __eoaccess_EODatabase_h__ + +#import +#import + +@class NSArray; +@class NSMutableArray; +@class NSDictionary; +@class NSMutableDictionary; +@class NSString; +@class NSMutableString; + +@class EOAdaptor; +@class EOModel; +@class EOEntity; + +@class EOObjectUniquer; +@class EODatabase, EODatabaseContext, EODatabaseChannel; + +@protocol EOObjectRegistry + +- (void)forgetObject:(id)anObj; +- (id)objectForPrimaryKey:(NSDictionary *)aKey entity:(EOEntity *)anEntity; + +/* retrieving snapshots and primary keys */ + +- (NSDictionary *)snapshotForObject:(id)anObj; +- (NSDictionary *)primaryKeyForObject:(id)anObj; +- (void)primaryKey:(NSDictionary **)aKey + andSnapshot:(NSDictionary **)aSnapshot + forObject:(id)anObj; + +/* recording objects */ + +- (void)recordObject:(id)anObj + primaryKey:(NSDictionary *)aKey + snapshot:(NSDictionary *)aSnapshot; + +- (void)recordObject:(id)anObj + primaryKey:(NSDictionary *)aKey + entity:(EOEntity *)anEntity + snapshot:(NSDictionary *)aSnapshot; + +@end + +@interface EODatabase : NSObject < EOObjectRegistry > +{ + @private + EOAdaptor *adaptor; + EOObjectUniquer *objectsDictionary; + NSMutableArray *contexts; + + struct { + BOOL isUniquingObjects:1; + BOOL isKeepingSnapshots:1; + BOOL isLoggingWarnings:1; + } flags; +} + +// Initializing new instances +- (id)initWithAdaptor:(EOAdaptor *)anAdaptor; +- (id)initWithModel:(EOModel *)aModel; + +// Getting the adaptor +- (EOAdaptor*)adaptor; + +// Getting the database contexts +- (id)createContext; +- (NSArray*)contexts; + +// Checking connection status +- (BOOL)hasOpenChannels; + +// Uniquing/snapshotting +- (void)setUniquesObjects:(BOOL)yn; +- (BOOL)uniquesObjects; +- (void)setKeepsSnapshots:(BOOL)yn; +- (BOOL)keepsSnapshots; + +// Handle Objects ++ (void)forgetObject:(id)anObj; +- (void)forgetAllObjects; +- (void)forgetAllSnapshots; + +- (BOOL)isObject:(id)anObj updatedOutsideContext:(EODatabaseContext *)aContext; + +// Error messages +- (BOOL)logsErrorMessages; +- (void)setLogsErrorMessages:(BOOL)yn; +- (void)reportError:(NSString*)error; +- (void)reportErrorFormat:(NSString*)format, ...; +- (void)reportErrorFormat:(NSString*)format arguments:(va_list)arguments; + +@end /* EODatabase */ + +/* + * Methods used by database classes internally + */ + +@interface EODatabase(Private) +- (void)contextDidInit:(id)aContext; +- (void)contextWillDealloc:(id)aContext; +- (EOObjectUniquer*)objectUniquer; +@end + +@class EOGlobalID; + +extern NSTimeInterval NSDistantPastTimeInterval; + +@interface EODatabase(EOF2Additions) + +/* models */ + +- (NSArray *)models; +- (void)addModel:(EOModel *)_model; +- (BOOL)addModelIfCompatible:(EOModel *)_model; + +/* entities */ + +- (EOEntity *)entityForObject:(id)_object; +- (EOEntity *)entityNamed:(NSString *)_name; + +/* snapshots */ + +- (void)recordSnapshot:(NSDictionary *)_snapshot forGlobalID:(EOGlobalID *)_gid; +- (void)recordSnapshots:(NSDictionary *)_snapshots; + +- (void)recordSnapshot:(NSArray *)_gids + forSourceGlobalID:(EOGlobalID *)_gid + relationshipName:(NSString *)_name; +- (void)recordToManySnapshots:(NSDictionary *)_snapshots; + +- (NSDictionary *)snapshotForGlobalID:(EOGlobalID *)_gid + after:(NSTimeInterval)_duration; +- (NSDictionary *)snapshotForGlobalID:(EOGlobalID *)_gid; + +- (void)forgetSnapshotsForGlobalIDs:(NSArray *)_gids; +- (void)forgetSnapshotsForGlobalID:(EOGlobalID *)_gid; + +@end + +#endif /* __eoaccess_EODatabase_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EODatabaseChannel.h b/sope-gdl1/GDLAccess/EOAccess/EODatabaseChannel.h new file mode 100644 index 00000000..e6ac2076 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EODatabaseChannel.h @@ -0,0 +1,213 @@ +/* + EODatabaseChannel.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EODatabaseChannel_h__ +#define __EODatabaseChannel_h__ + +#import + +@class NSArray, NSMutableArray, NSDictionary, NSMutableDictionary; +@class NSString, NSMutableString, NSNotificationCenter; +@class EOAdaptor, EOAdaptorContext, EOAdaptorChannel; +@class EOEntity, EOSQLQualifier, EORelationship; +@class EOObjectUniquer, EODatabase, EODatabaseContext; +@class EOGlobalID; + +extern NSString *EODatabaseChannelWillOpenNotificationName; +extern NSString *EODatabaseChannelDidOpenNotificationName; +extern NSString *EODatabaseChannelCouldNotOpenNotificationName; +extern NSString *EODatabaseChannelWillCloseNotificationName; +extern NSString *EODatabaseChannelDidCloseNotificationName; +extern NSString *EODatabaseChannelWillInsertObjectName; +extern NSString *EODatabaseChannelDidInsertObjectName; +extern NSString *EODatabaseChannelWillUpdateObjectName; +extern NSString *EODatabaseChannelDidUpdateObjectName; +extern NSString *EODatabaseChannelWillDeleteObjectName; +extern NSString *EODatabaseChannelDidDeleteObjectName; +extern NSString *EODatabaseChannelWillLockObjectName; +extern NSString *EODatabaseChannelDidLockObjectName; + +@interface EODatabaseChannel : NSObject +{ +@private + NSNotificationCenter *notificationCenter; + EOAdaptorChannel *adaptorChannel; + EODatabaseContext *databaseContext; + id delegate; + EOEntity *currentEntity; + Class currentClass; + NSArray *currentAttributes; + NSArray *currentRelations; + BOOL currentReady; + id currentEditingContext; + + /* statistics */ + unsigned int successfulOpenCount; + unsigned int failedOpenCount; + unsigned int closeCount; + unsigned int insertCount; + unsigned int updateCount; + unsigned int deleteCount; + unsigned int lockCount; +} + +// Initializing a new instance +- (id)initWithDatabaseContext:(EODatabaseContext*)aDatabaseContext; + +// Getting the adaptor channel +- (EOAdaptorChannel*)adaptorChannel; + +// Getting the database context +- (EODatabaseContext*)databaseContext; + +// Setting the delegate +- (void)setDelegate:(id)aDelegate; +- (id)delegate; + +// Opening and closing a channel +- (BOOL)isOpen; +- (BOOL)openChannel; +- (void)closeChannel; + +// Modifying objects +- (BOOL)insertObject:(id)anObj; +- (BOOL)updateObject:(id)anObj; +- (BOOL)deleteObject:(id)anObj; +- (BOOL)lockObject:(id)anObj; +- (BOOL)refetchObject:(id)anObj; +- (id)allocateObjectForRow:(NSDictionary*)row + entity:(EOEntity*)anEntity + zone:(NSZone*)zone; +- (id)initializedObjectForRow:(NSDictionary*)row + entity:(EOEntity*)anEntity + zone:(NSZone*)zone; + +// Fetching objects +- (BOOL)selectObjectsDescribedByQualifier:(EOSQLQualifier*)qualifier + fetchOrder:(NSArray*)fetchOrder; +- (id)fetchWithZone:(NSZone*)zone; +- (BOOL)isFetchInProgress; +- (void)cancelFetch; +- (void)setCurrentEntity:(EOEntity*)anEntity; + +@end /* EODatabaseChannel */ + +/* statistics */ + +@interface EODatabaseChannel(Statistics) +- (unsigned int)successfulOpenCount; +- (unsigned int)failedOpenCount; +- (unsigned int)closeCount; +- (unsigned int)insertCount; +- (unsigned int)updateCount; +- (unsigned int)deleteCount; +- (unsigned int)lockCount; +@end + +/* + * Delegate methods + */ + +@interface NSObject(EODatabaseChannelDelegateProtocol) + +- (id)databaseChannel:aChannel + willInsertObject:anObj; +- (void)databaseChannel:aChannel + didInsertObject:anObj; +- (id)databaseChannel:aChannel + willDeleteObject:anObj; +- (void)databaseChannel:aChannel + didDeleteObject:anObj; +- (id)databaseChannel:aChannel + willUpdateObject:anObj; +- (void)databaseChannel:aChannel + didUpdateObject:anObj; +- (NSDictionary*)databaseChannel:aChannel + willRefetchObject:anObj; +- (NSDictionary*)databaseChannel:aChannel + didRefetchObject:anObj; +- (NSDictionary*)databaseChannel:aChannel + willRefetchObject:anObj + fromSnapshot:(NSDictionary*)snapshot; +- (NSDictionary*)databaseChannel:aChannel + willRefetchConflictingObject:anObj + withSnapshot:(NSMutableDictionary*)snapshot; +- (BOOL)databaseChannel:aChannel + willSelectObjectsDescribedByQualifier:(EOSQLQualifier*)qualifier + fetchOrder:(NSArray*)fetchOrder; +- (void)databaseChannel:aChannel + didSelectObjectsDescribedByQualifier:(EOSQLQualifier*)qualifier + fetchOrder:(NSArray*)fetchOrder; +- (void)databaseChannel:aChannel + willFetchObjectOfClass:(Class)class + withZone:(NSZone*)zone; +- (void)databaseChannel:aChannel + didFetchObject:anObj; +- databaseChannel:aChannel + willLockObject:anObj; +- (void)databaseChannel:aChannel + didLockObject:anObj; +- (Class)databaseChannel:aChannel + failedToLookupClassNamed:(const char*)name; +- (EORelationship*)databaseChannel:aChannel + relationshipForRow:(NSDictionary*)row + relationship:(EORelationship*)relationship; + +@end + +@interface NSObject(EODatabaseChannelEONotifications) + +- (BOOL)prepareForDeleteInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; +- (void)wasDeletedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; + +- (BOOL)prepareForInsertInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; +- (void)wasInsertedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; + +- (BOOL)prepareForUpdateInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; +- (void)wasUpdatedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; + +- (BOOL)prepareForLockInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; +- (void)wasLockedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx; + +@end + +/* + * Object Awaking (EODatabaseChannelNotification protocol) + */ + +@interface NSObject(EODatabaseChannelNotification) +- (void)awakeForDatabaseChannel:(EODatabaseChannel*)channel; +@end + +#endif /* __EODatabaseChannel_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EODatabaseContext.h b/sope-gdl1/GDLAccess/EOAccess/EODatabaseContext.h new file mode 100644 index 00000000..f6994bc4 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EODatabaseContext.h @@ -0,0 +1,190 @@ +/* + EODatabaseContext.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EODatabaseContext_h__ +#define __EODatabaseContext_h__ + +#import +#import + +@class NSArray, NSMutableArray, NSDictionary, NSMutableDictionary; +@class NSString, NSMutableString; +@class EOAdaptorContext; +@class EOEntity; +@class EOObjectUniquer, EODatabase, EODatabaseContext, EODatabaseChannel; + +typedef enum { + EOUpdateWithOptimisticLocking, + EOUpdateWithPessimisticLocking, + EOUpdateWithNoLocking, + EONoUpdate, +} EOUpdateStrategy; + +struct _EOTransactionScope; + +extern NSString *EODatabaseContextWillBeginTransactionName; +extern NSString *EODatabaseContextDidBeginTransactionName; +extern NSString *EODatabaseContextWillRollbackTransactionName; +extern NSString *EODatabaseContextDidRollbackTransactionName; +extern NSString *EODatabaseContextWillCommitTransactionName; +extern NSString *EODatabaseContextDidCommitTransactionName; + +struct EODatabaseContextModificationQueue; + +@interface EODatabaseContext : NSObject < EOObjectRegistry > +//EOCooperatingObjectStore < EOObjectRegistry > +{ + EOAdaptorContext *adaptorContext; + EODatabase *database; + NSMutableArray *channels; + EOUpdateStrategy updateStrategy; + id coordinator; + id delegate; /* non-retained */ + + struct _EOTransactionScope *transactionStackTop; + int transactionNestingLevel; + + // These fields should be in a bitfield but are ivars for debug purposes + BOOL isKeepingSnapshots; + BOOL isUniquingObjects; + + /* modified objects */ + struct EODatabaseContextModificationQueue *ops; + + /* statistics */ + unsigned int txBeginCount; + unsigned int txCommitCount; + unsigned int txRollbackCount; +} + +// Initializing instances +- (id)initWithDatabase:(EODatabase *)aDatabase; + +/* accessors */ + +- (void)setDelegate:(id)_delegate; +- (id)delegate; +- (EODatabase *)database; + +// Getting the adaptor context +- (EOAdaptorContext*)adaptorContext; + +// Finding channels +- (BOOL)hasBusyChannels; +- (BOOL)hasOpenChannels; +- (NSArray *)channels; +- (id)createChannel; + +// Controlling transactions +- (BOOL)beginTransaction; +- (BOOL)commitTransaction; +- (BOOL)rollbackTransaction; + +// Notifying of other transactions +- (void)transactionDidBegin; +- (void)transactionDidCommit; +- (void)transactionDidRollback; + +// Nesting transactions +- (BOOL)canNestTransactions; +- (unsigned)transactionNestingLevel; + +// Setting the update strategy +- (void)setUpdateStrategy:(EOUpdateStrategy)aStrategy; +- (EOUpdateStrategy)updateStrategy; +- (BOOL)keepsSnapshots; + +// Handle Objects + +- (void)recordLockedObject:(id)anObj; +- (BOOL)isObjectLocked:(id)anObj; +- (void)recordUpdatedObject:(id)anObj; +- (BOOL)isObjectUpdated:(id)anObj; + +@end /* EODatabaseContext */ + +@interface EODatabaseContext(Statistics) + +- (unsigned int)transactionBeginCount; +- (unsigned int)transactionCommitCount; +- (unsigned int)transactionRollbackCount; + +@end + +/* + * Methods used by database classess internally + */ + +@interface EODatabaseContext(Private) +- (void)channelDidInit:(id)aChannel; +- (void)channelWillDealloc:(id)aChannel; +- (void)privateBeginTransaction; +- (void)privateCommitTransaction; +- (void)privateRollbackTransaction; +@end + +@class EOModel; + +@interface EODatabaseContext(NewInEOF2) + ++ (void)setContextClassToRegister:(Class)_cclass; ++ (Class)contextClassToRegister; + +#if 0 ++ (EODatabaseContext *)registeredDatabaseContextForModel:(EOModel *)_model + editingContext:(id)_ec; + +- (id)coordinator; +#endif + +/* managing channels */ + +- (EODatabaseChannel *)availableChannel; +- (NSArray *)registeredChannels; +- (void)registerChannel:(EODatabaseChannel *)_channel; +- (void)unregisterChannel:(EODatabaseChannel *)_channel; + +@end + +@class EOFetchSpecification; + +@interface NSObject(EOF2DelegateMethods) + +- (BOOL)databaseContext:(EODatabaseContext *)_ctx + shouldSelectObjectsWithFetchSpecification:(EOFetchSpecification *)_fspec + databaseChannel:(EODatabaseChannel *)_channel; + +- (void)databaseContext:(EODatabaseContext *)_ctx + didSelectObjectsWithFetchSpecification:(EOFetchSpecification *)_fspec + databaseChannel:(EODatabaseChannel *)_channel; + +- (BOOL)databaseContext:(EODatabaseContext *)_ctx + shouldUsePessimisticLockWithFetchSpecification:(EOFetchSpecification *)_fspec + databaseChannel:(EODatabaseChannel *)_channel; + +@end + +#endif /* __EODatabaseContext_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EODatabaseFault.h b/sope-gdl1/GDLAccess/EOAccess/EODatabaseFault.h new file mode 100644 index 00000000..63e78c73 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EODatabaseFault.h @@ -0,0 +1,77 @@ +/* + EODatabaseFault.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __eoaccess_EODatabaseFault_h__ +#define __eoaccess_EODatabaseFault_h__ + +#import + +@class EOSQLQualifier, EOEntity, EODatabaseChannel; +@class NSArray, NSDictionary, NSString; + +/* + * EODatabaseFault class + */ + +@interface EODatabaseFault : EOFault + +// Creating a fault + ++ (id)objectFaultWithPrimaryKey:(NSDictionary*)key + entity:(EOEntity*)entity + databaseChannel:(EODatabaseChannel*)channel + zone:(NSZone*)zone; + ++ (NSArray *)arrayFaultWithQualifier:(EOSQLQualifier*)qualifier + fetchOrder:(NSArray*)fetchOrder + databaseChannel:(EODatabaseChannel*)channel + zone:(NSZone*)zone; ++ (NSArray *)gcArrayFaultWithQualifier:(EOSQLQualifier*)qualifier + fetchOrder:(NSArray*)fetchOrder + databaseChannel:(EODatabaseChannel*)channel + zone:(NSZone*)zone; + ++ (NSDictionary*)primaryKeyForFault:fault; ++ (EOEntity*)entityForFault:fault; ++ (EOSQLQualifier*)qualifierForFault:fault; ++ (NSArray*)fetchOrderForFault:fault; ++ (EODatabaseChannel*)databaseChannelForFault:fault; + +@end /* EODatabaseFault */ + +/* + * Informal protocol that informs an instance that a to-one + * relationship could not be resoved to get data for self. + * Its implementation in NSObject raises NSObjectNotAvailableException. + */ + +@interface NSObject(EOUnableToFaultToOne) +- (void)unableToFaultWithPrimaryKey:(NSDictionary*)key + entity:(EOEntity*)entity + databaseChannel:(EODatabaseChannel*)channel; +@end + +#endif /* __eoaccess_EODatabaseFault_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EODatabaseFaultResolver.h b/sope-gdl1/GDLAccess/EOAccess/EODatabaseFaultResolver.h new file mode 100644 index 00000000..4a76ffeb --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EODatabaseFaultResolver.h @@ -0,0 +1,93 @@ +/* + EODatabaseFaultResolver.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + Author: Helge Hess + Date: 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EODatabaseFaultResolver_h__ +#define __EODatabaseFaultResolver_h__ + +#import + +@class EODatabaseChannel; +@class EOSQLQualifier; +@class EOEntity; + +@interface EODatabaseFaultResolver : EOFaultHandler +{ +@public + EODatabaseChannel *channel; +} + +- (id)initWithDatabaseChannel:(EODatabaseChannel*)aChannel + zone:(NSZone*)zone + targetClass:(Class)targetClass; + +- (Class)targetClass; +- (NSDictionary *)primaryKey; +- (EOEntity *)entity; +- (EOSQLQualifier *)qualifier; +- (NSArray *)fetchOrder; +- (EODatabaseChannel *)databaseChannel; + +@end /* EODatabaseFaultResolver */ + +@interface EOArrayFault : EODatabaseFaultResolver +{ + EOSQLQualifier *qualifier; + NSArray *fetchOrder; +} + +- (id)initWithQualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + databaseChannel:(EODatabaseChannel *)channel + zone:(NSZone *)zone + targetClass:(Class)targetClass; + +- (EOEntity *)entity; +- (EOSQLQualifier *)qualifier; +- (NSArray *)fetchOrder; + +@end + +@interface EOObjectFault : EODatabaseFaultResolver +{ + EOEntity *entity; + NSDictionary *primaryKey; +} + +- (id)initWithPrimaryKey:(NSDictionary *)key + entity:(EOEntity *)entity + databaseChannel:(EODatabaseChannel *)channel + zone:(NSZone *)zone + targetClass:(Class)targetClass ; + +- (NSDictionary*)primaryKey; +- (EOEntity*)entity; + +@end + +#endif /* __EODatabaseFaultResolver_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EODelegateResponse.h b/sope-gdl1/GDLAccess/EOAccess/EODelegateResponse.h new file mode 100644 index 00000000..863fe62a --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EODelegateResponse.h @@ -0,0 +1,7 @@ +// $Id: EODelegateResponse.h 1 2004-08-20 10:38:46Z znek $ + +typedef enum { + EODelegateRejects, + EODelegateApproves, + EODelegateOverrides +} EODelegateResponse; diff --git a/sope-gdl1/GDLAccess/EOAccess/EOEntity+Factory.h b/sope-gdl1/GDLAccess/EOAccess/EOEntity+Factory.h new file mode 100644 index 00000000..4063b83b --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOEntity+Factory.h @@ -0,0 +1,31 @@ +// $Id: EOEntity+Factory.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __GDLAccess_EOEntity_Factory_H__ +#define __GDLAccess_EOEntity_Factory_H__ + +#import + +@class NSDictionary; +@class EOAttribute; + +@interface EOEntity(AttributeNames) + +- (NSArray *)attributeNames; + +@end + +@interface EOEntity(PrimaryKeys) + +- (BOOL)isPrimaryKeyAttribute:(EOAttribute *)_attribute; +- (unsigned)primaryKeyCount; + +@end + +@interface EOEntity(ObjectFactory) + +- (id)produceNewObjectWithPrimaryKey:(NSDictionary *)_key; +- (void)setAttributesOfObjectToEONull:(id)_object; + +@end + +#endif /* __GDLAccess_EOEntity_Factory_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOEntity.h b/sope-gdl1/GDLAccess/EOAccess/EOEntity.h new file mode 100644 index 00000000..414206b6 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOEntity.h @@ -0,0 +1,219 @@ +/* + EOEntity.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOEntity_h__ +#define __EOEntity_h__ + +#import + +@class EOModel, EOAttribute, EORelationship; +@class EOSQLQualifier, EOExpressionArray; +@class NSMutableDictionary; + +@interface EOEntity : NSObject +{ + NSString *name; + NSString *className; + NSString *externalName; + NSString *externalQuery; + NSDictionary *userDictionary; + NSArray *primaryKeyAttributeNames; /* sorted array of names */ + NSArray *attributesNamesUsedForInsert; + NSArray *classPropertyNames; + + /* Garbage collectable objects */ + EOModel *model; /* non-retained */ + EOSQLQualifier *qualifier; + NSArray *attributes; + NSMutableDictionary *attributesByName; + NSArray *relationships; + NSMutableDictionary *relationshipsByName; // name/EORelationship + NSArray *primaryKeyAttributes; + NSArray *classProperties; // EOAttribute/EORelationship + NSArray *attributesUsedForLocking; + + /* Cached properties */ + NSArray *attributesUsedForInsert; // cache from classProperties + NSArray *attributesUsedForFetch; // cache from classProperties + NSArray *relationsUsedForFetch; // cache from classProperties + + struct { + BOOL isReadOnly:1; + BOOL createsMutableObjects:1; + BOOL isPropertiesCacheValid:1; + } flags; +} + +/* Initializing instances */ +- (id)initWithName:(NSString *)name; + +/* Accessing the name */ +- (NSString *)name; +- (BOOL)setName:(NSString *)name; ++ (BOOL)isValidName:(NSString *)name; + +/* Accessing the model */ +- (void)setModel:(EOModel *)model; +- (EOModel *)model; +- (void)resetModel; +- (BOOL)hasModel; + +/* Getting the qualifier */ +- (EOSQLQualifier *)qualifier; + +/* Accessing attributes */ +- (BOOL)addAttribute:(EOAttribute *)attribute; +- (void)removeAttributeNamed:(NSString *)name; +- (EOAttribute *)attributeNamed:(NSString *)attributeName; +- (NSArray *)attributes; + +/* Accessing relationships */ +- (BOOL)addRelationship:(EORelationship *)relationship; +- (void)removeRelationshipNamed:(NSString *)name; +- (EORelationship *)relationshipNamed:(NSString *)relationshipName; +- (NSArray *)relationships; + +/* Accessing primary key attributes */ +- (BOOL)setPrimaryKeyAttributes:(NSArray *)keys; +- (NSArray *)primaryKeyAttributes; +- (NSArray *)primaryKeyAttributeNames; +- (BOOL)isValidPrimaryKeyAttribute:(EOAttribute *)anAttribute; + +/* Getting primary keys and snapshot for row */ +- (NSDictionary *)primaryKeyForRow:(NSDictionary *)row; +- (NSDictionary *)snapshotForRow:(NSDictionary *)aRow; + +/* Getting attributes used for fetch/insert/update operations */ +- (NSArray *)attributesUsedForInsert; +- (NSArray *)attributesUsedForFetch; +- (NSArray *)relationsUsedForFetch; +- (NSArray *)attributesNamesUsedForInsert; + +/* Accessing class properties */ +- (BOOL)setClassProperties:(NSArray *)properties; +- (NSArray *)classProperties; +- (NSArray *)classPropertyNames; +- (BOOL)isValidClassProperty:(id)aProp; +- (id)propertyNamed:(NSString *)name; +- (NSArray *)relationshipsNamed:(NSString *)_relationshipPath; + +/* Accessing locking attributes */ +- (BOOL)setAttributesUsedForLocking:(NSArray *)attributes; +- (NSArray *)attributesUsedForLocking; +- (BOOL)isValidAttributeUsedForLocking:(EOAttribute *)anAttribute; + +/* Accessing the enterprise object class */ +- (void)setClassName:(NSString *)name; +- (NSString *)className; + +/* Accessing external information */ +- (void)setExternalName:(NSString *)name; +- (NSString *)externalName; + +/* Accessing the external query */ +- (void)setExternalQuery:(NSString *)query; +- (NSString *)externalQuery; + +/* Accessing read-only status */ +- (void)setReadOnly:(BOOL)flag; +- (BOOL)isReadOnly; + +/* Accessing the user dictionary */ +- (void)setUserDictionary:(NSDictionary *)dictionary; +- (NSDictionary *)userDictionary; + +- (BOOL)referencesProperty:property; + +@end + + +@interface EOEntity (EOEntityPrivate) + ++ (EOEntity *)entityFromPropertyList:(id)propertyList model:(EOModel *)model; +- (void)replaceStringsWithObjects; + +- (id)propertyList; +- (void)setCreateMutableObjects:(BOOL)flag; +- (BOOL)createsMutableObjects; + +- (void)validatePropertiesCache; +- (void)invalidatePropertiesCache; + +@end + +@interface EOEntity(ValuesConversion) + +- (NSDictionary *)convertValuesToModel:(NSDictionary *)aRow; + +@end /* EOAttribute (ValuesConversion) */ + +@class EOGlobalID, EOFetchSpecification; + +@interface EOEntity(EOF2Additions) + +- (BOOL)isAbstractEntity; + +/* ids */ + +- (EOGlobalID *)globalIDForRow:(NSDictionary *)_row; +- (BOOL)isPrimaryKeyValidInObject:(id)_object; + +/* refs to other models */ + +- (NSArray *)externalModelsReferenced; + +/* fetch specs */ + +- (EOFetchSpecification *)fetchSpecificationNamed:(NSString *)_name; +- (NSArray *)fetchSpecificationNames; + +/* names */ + +- (void)beautifyName; + +@end + +@class NSMutableDictionary; + +@interface EOEntity(PropertyListCoding) + +- (void)encodeIntoPropertyList:(NSMutableDictionary *)_plist; + +@end + +#import + +@interface EOEntityClassDescription : EOClassDescription +{ + EOEntity *entity; +} + +- (id)initWithEntity:(EOEntity *)_entity; +- (EOEntity *)entity; + +@end + +#endif /* __EOEntity_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOExpressionArray.h b/sope-gdl1/GDLAccess/EOAccess/EOExpressionArray.h new file mode 100644 index 00000000..08f887f5 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOExpressionArray.h @@ -0,0 +1,106 @@ +/* + EOExpressionArray.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: September 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOExpressionArray_h__ +#define __EOExpressionArray_h__ + +#import + +@class EOAttribute, EOEntity, EOExpressionArray; + +@protocol EOExpressionContext + +- (NSString *)expressionValueForAttribute:(EOAttribute *)anAttribute; +- (NSString *)expressionValueForAttributePath:(NSArray *)path; + +@end + + +@interface EOExpressionArray : NSObject < NSMutableCopying > +{ +@protected + NSMutableArray *array; + NSString *prefix; + NSString *infix; + NSString *suffix; +} + +/* Initializing instances */ +- (id)initWithPrefix:(NSString*)prefix + infix:(NSString*)infix + suffix:(NSString*)suffix; + +/* Accessing the components */ +- (void)setPrefix:(NSString*)prefix; +- (NSString*)prefix; +- (void)setInfix:(NSString*)infix; +- (NSString*)infix; +- (void)setSuffix:(NSString*)suffix; +- (NSString*)suffix; + +/* Checking contents */ +- (BOOL)referencesObject:(id)anObject; + +- (NSString*)expressionValueForContext:(id)ctx; + ++ (EOExpressionArray*)parseExpression:(NSString*)expression + entity:(EOEntity*)entity + replacePropertyReferences:(BOOL)flag; + ++ (EOExpressionArray*)parseExpression:(NSString*)expression + entity:(EOEntity*)entity + replacePropertyReferences:(BOOL)flag + relationshipPaths:(NSMutableArray *)relationshipPaths; + +// array compatibility + +- (void)addObjectsFromExpressionArray:(EOExpressionArray *)_array; + +- (void)insertObject:(id)_obj atIndex:(unsigned int)_idx; +- (void)addObjectsFromArray:(NSArray *)_array; +- (void)addObject:(id)_object; +- (unsigned int)indexOfObject:(id)_object; +- (id)objectAtIndex:(unsigned int)_idx; +- (id)lastObject; +- (unsigned int)count; +- (NSEnumerator *)objectEnumerator; +- (NSEnumerator *)reverseObjectEnumerator; + +@end /* EOExpressionArray */ + + +@interface NSObject (EOExpression) +- (NSString*)expressionValueForContext:(id)context; +@end + +#endif /* __EOExpressionArray_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOFExceptions.h b/sope-gdl1/GDLAccess/EOAccess/EOFExceptions.h new file mode 100644 index 00000000..7f1045c4 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOFExceptions.h @@ -0,0 +1,117 @@ +/* + EOFExceptions.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOFExceptions_h__ +#define __EOFExceptions_h__ + +#import + +@class NSString; +@class EOEntity; +@class EORelationship; +@class EOAdaptorChannel; + +@interface EOFException : NSException +@end + +@interface ObjectNotAvailableException : EOFException +- initWithEntity:entity andPrimaryKey:key; +@end + +@interface PropertyDefinitionException : EOFException +@end + +@interface DestinationEntityDoesntMatchDefinitionException + : PropertyDefinitionException +- initForDestination:(EOEntity*)destinationEntity + andDefinition:(NSString*)definition + relationship:(EORelationship*)relationship; +@end + +@interface InvalidNameException : PropertyDefinitionException +- initWithName:(NSString*)name; +@end + +@interface InvalidPropertyException : PropertyDefinitionException +- initWithName:propertyNamed entity:currentEntity; +@end + +@interface RelationshipMustBeToOneException : PropertyDefinitionException +- initWithName:propertyNamed entity:currentEntity; +@end + +@interface InvalidValueTypeException : PropertyDefinitionException +- initWithType:type; +@end + +@interface InvalidAttributeException : EOFException +@end + +@interface InvalidQualifierException : EOFException +@end + +@interface EOAdaptorException : EOFException +@end + +@interface CannotFindAdaptorBundleException : EOAdaptorException +@end + +@interface InvalidAdaptorBundleException : EOAdaptorException +@end + +@interface InvalidAdaptorStateException : EOAdaptorException +{ + id adaptor; +} ++ exceptionWithAdaptor:(id)adaptor; +@end + +@interface DataTypeMappingNotSupportedException : EOAdaptorException +@end + +@interface ChannelIsNotOpenedException : InvalidAdaptorStateException +@end + +@interface AdaptorIsFetchingException : InvalidAdaptorStateException +@end + +@interface AdaptorIsNotFetchingException : InvalidAdaptorStateException +@end + +@interface NoTransactionInProgressException : InvalidAdaptorStateException +@end + +@interface TooManyOpenedChannelsException : EOAdaptorException +@end + +#endif /* __EOFExceptions_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOFault.h b/sope-gdl1/GDLAccess/EOAccess/EOFault.h new file mode 100644 index 00000000..21e8c815 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOFault.h @@ -0,0 +1,59 @@ +// $Id: EOFault.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __EOFault_h__ +#define __EOFault_h__ + +#import + +@class NSArray, NSDictionary, NSString, NSMethodSignature; + +@class EOFaultHandler; + +@interface EOFault +{ + Class isa; + EOFaultHandler *faultResolver; +} + ++ (void)makeObjectIntoFault:(id)_object withHandler:(EOFaultHandler *)_handler; ++ (EOFaultHandler *)handlerForFault:(id)_fault; + +/* Inquire about a fault */ + ++ (BOOL)isFault:(id)object; ++ (BOOL)isFault; +- (BOOL)isFault; ++ (void)clearFault:(id)fault; + ++ (Class)targetClassForFault:fault; + +/* Non-Faulting Instance methods */ + +- (Class)superclass; +- (Class)class; ++ (Class)class; +- (BOOL)isKindOfClass:(Class)aClass; +- (BOOL)isMemberOfClass:(Class)aClass; +- (BOOL)conformsToProtocol:(Protocol *)aProtocol; +- (BOOL)respondsToSelector:(SEL)aSelector; + ++ (id)self; + +- (void)dealloc; +- retain; +- (void)release; +- autorelease; +- (unsigned)retainCount; +- (NSZone*)zone; + +- (BOOL)isProxy; +- (BOOL)isGarbageCollectable; +- (NSString *)description; + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)_selector; + +@end /* EOFault */ + +#include + +#endif /* __EOFault_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOFaultHandler.h b/sope-gdl1/GDLAccess/EOAccess/EOFaultHandler.h new file mode 100644 index 00000000..300272f8 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOFaultHandler.h @@ -0,0 +1,47 @@ +// $Id: EOFaultHandler.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __EOFaultHandler_h__ +#define __EOFaultHandler_h__ + +#import + +@class NSInvocation, NSMethodSignature; +@class EOFault; + +@interface EOFaultHandler : NSObject +{ +@public + int faultReferences; + void *extraData; /* saved ivars overridden by 'faultHandler' ivar */ + Class targetClass; + NSZone *zone; +} + +- (Class)targetClass; +- (void *)extraData; +- (void)setTargetClass:(Class)_class extraData:(void *)_extraData; + +/* firing */ + +- (BOOL)shouldPerformInvocation:(NSInvocation *)_invocation; +- (void)faultWillFire:(EOFault *)_fault; +- (void)completeInitializationOfObject:(id)_object; + +/* fault reflection */ + +- (Class)classForFault:(EOFault *)_fault; +- (BOOL)respondsToSelector:(SEL)_selector forFault:(EOFault *)_fault; +- (BOOL)conformsToProtocol:(Protocol *)_protocol forFault:(EOFault *)_fault; +- (BOOL)isKindOfClass:(Class)_class forFault:(EOFault *)_fault; +- (BOOL)isMemberOfClass:(Class)_class forFault:(EOFault *)_fault; + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)_selector + forFault:(EOFault *)_fault; + +/* description */ + +- (NSString *)descriptionForObject:(id)_fault; + +@end /* EOFaultHandler */ + +#endif /* __EOFaultHandler_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOGenericRecord.h b/sope-gdl1/GDLAccess/EOAccess/EOGenericRecord.h new file mode 100644 index 00000000..ec4b89b3 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOGenericRecord.h @@ -0,0 +1,54 @@ +// $Id: EOGenericRecord.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __eoaccess_EOGenericRecord_H__ +#define __eoaccess_EOGenericRecord_H__ + +#import + +@class NSDictionary; +@class EOEntity; + +@interface EOGenericRecord(EOAccess) + +// Initializing new instances + +- (id)initWithPrimaryKey:(NSDictionary *)aKey entity:(EOEntity *)anEntity; + +// Getting the associated entity + +- (EOEntity *)entity; + +@end + +/* + * Informal protocol. NOT implemented by NSObject. + * Before sending one of this messages the caller must + * check if the object responds to them. + */ + +@interface NSObject(EOGenericRecord) + +/* + * Initialize an new instance of an object. + * If an enterprise object does not respond + * to this method it will receive -init. + */ +- (id)initWithPrimaryKey:(NSDictionary *)key entity:(EOEntity *)entity; + +/* + * Determines the entity of user defined objects, + * when more than one entity uses the same class for its objects. + */ +- (EOEntity *)entity; + +/* + * Determine the class for object based on its fetched row. + * The returned class *must* be a subclass of the class that + * receives this method. + */ ++ (Class)classForEntity:(EOEntity *)entity values:(NSDictionary *)values; + +@end + +#endif /* __eoaccess_EOGenericRecord_H__ */ + diff --git a/sope-gdl1/GDLAccess/EOAccess/EOJoinTypes.h b/sope-gdl1/GDLAccess/EOAccess/EOJoinTypes.h new file mode 100644 index 00000000..9010e789 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOJoinTypes.h @@ -0,0 +1,19 @@ +// $Id: EOJoinTypes.h 1 2004-08-20 10:38:46Z znek $ + +typedef enum { + EOInnerJoin = 0, + EOFullOuterJoin, + EOLeftOuterJoin, + EORightOuterJoin +} EOJoinSemantic; + +typedef enum { + EOJoinEqualTo = 0, + EOJoinNotEqualTo, + EOJoinGreaterThan, + EOJoinGreaterThanOrEqualTo, + EOJoinLessThan, + EOJoinLessThanOrEqualTo +} EOJoinOperator; + +@class EOJoin; diff --git a/sope-gdl1/GDLAccess/EOAccess/EOKeySortOrdering.h b/sope-gdl1/GDLAccess/EOAccess/EOKeySortOrdering.h new file mode 100644 index 00000000..c8b9399d --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOKeySortOrdering.h @@ -0,0 +1,55 @@ +/* + EOKeySortOrdering.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import +#import + +@interface EOKeySortOrdering : NSObject +{ + NSString* key; + NSComparisonResult ordering; +} + ++ keyOrderingWithKey:(NSString*)aKey ordering:(NSComparisonResult)anOrdering; +- initWithKey:(NSString*)aKey ordering:(NSComparisonResult)anOrdering; +- (NSString*)key; +- (NSComparisonResult)ordering; +@end + +@interface NSArray(EOKeyBasedSorting) +- (NSArray*)sortedArrayUsingKeyOrderArray:(NSArray*)orderArray; +@end + +@interface NSMutableArray(EOKeyBasedSorting) +- (void)sortUsingKeyOrderArray:(NSArray *)orderArray; +@end + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOModel.h b/sope-gdl1/GDLAccess/EOAccess/EOModel.h new file mode 100644 index 00000000..75823655 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOModel.h @@ -0,0 +1,124 @@ +/* + EOModel.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOModel_h__ +#define __EOModel_h__ + +#import + +@class EOEntity; + +@interface EOModel : NSObject +{ + NSString *name; + NSString *path; + NSString *adaptorName; + NSString *adaptorClassName; + NSDictionary *connectionDictionary; + NSDictionary *pkeyGeneratorDictionary; + NSDictionary *userDictionary; + + NSArray *entities; // values with EOEntities + NSMutableDictionary *entitiesByName; // name/value with EOEntity + NSMutableDictionary *entitiesByClassName; // class name/value with EOEntity + + struct { + BOOL createsMutableObjects:1; + BOOL errors:1; + } flags; +} + +/* Searching for a model file */ ++ (NSString*)findPathForModelNamed:(NSString*)name; + +/* Initializing instances */ +- (id)initWithContentsOfFile:(NSString*)filename; +- (id)initWithPropertyList:propertyList; +- (id)initWithName:(NSString*)name; + +/* Getting the filename */ +- (NSString*)path; + +/* Getting a property list representation */ +- (id)modelAsPropertyList; + +/* Getting the name */ +- (NSString*)name; + +/* Using entities */ +- (BOOL)addEntity:(EOEntity *)entity; +- (void)removeEntityNamed:(NSString *)name; +- (EOEntity *)entityNamed:(NSString *)name; +- (NSArray *)entities; + +/* Checking references */ +- (NSArray *)referencesToProperty:(id)property; + +/* Getting an object's entity */ +- (EOEntity *)entityForObject:(id)object; + +/* Adding model information */ +- (BOOL)incorporateModel:(EOModel *)model; + +/* Accessing the adaptor bundle */ +- (void)setAdaptorName:(NSString *)adaptorName; +- (NSString *)adaptorName; + +/* Setting and getting the adaptor class name. */ +- (void)setAdaptorClassName:(NSString *)adaptorClassName; +- (NSString *)adaptorClassName; + +/* Accessing the connection dictionary */ +- (void)setConnectionDictionary:(NSDictionary *)connectionDictionary; +- (NSDictionary *)connectionDictionary; + +/* Accessing the pkey generator dictionary */ +- (void)setPkeyGeneratorDictionary:(NSDictionary *)connectionDictionary; +- (NSDictionary *)pkeyGeneratorDictionary; + +/* Accessing the user dictionary */ +- (void)setUserDictionary:(NSDictionary *)dictionary; +- (NSDictionary *)userDictionary; + +@end + + +@interface EOModel (EOModelPrivate) + +- (void)setCreateMutableObjects:(BOOL)flag; +- (BOOL)createsMutableObjects; + +- (void)errorInReading; + +@end /* EOModel (EOModelPrivate) */ + +@interface EOModel(NewInEOF2) + +- (void)loadAllModelObjects; + +@end + +#endif /* __EOModel_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOModelGroup.h b/sope-gdl1/GDLAccess/EOAccess/EOModelGroup.h new file mode 100644 index 00000000..95e0d8e2 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOModelGroup.h @@ -0,0 +1,88 @@ +// $Id: EOModelGroup.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __EOAccess_EOModelGroup_H__ +#define __EOAccess_EOModelGroup_H__ + +#import + +@class NSDictionary; +@class EOGlobalID, EOFetchSpecification; +@class EOModelGroup, EOModel, EOEntity, EORelationship; + +@protocol EOModelGroupClassDelegation < NSObject > + +- (EOModelGroup *)defaultModelGroup; + +@end + +@protocol EOModelGroupDelegation < NSObject > + +- (Class)entity:(EOEntity *)_entity + classForObjectWithGlobalID:(EOGlobalID *)_oid; + +- (Class)entity:(EOEntity *)_entity + failedToLookupClassNamed:(NSString *)_className; + +- (EOEntity *)relationship:(EORelationship *)_relship + failedToLookupDestinationNamed:(NSString *)_entityName; + +- (EOEntity *)subEntityForEntity:(EOEntity *)_entity + primaryKey:(NSDictionary *)_pkey + isFinal:(BOOL *)_flag; + +- (EOModel *)modelGroup:(EOModelGroup *)_group + entityNamed:(NSString *)_name; + +- (EORelationship *)entity:(EOEntity *)_entity + relationshipForRow:(NSDictionary *)_row + relationship:(EORelationship *)_relship; + +@end + +@class NSArray, NSMutableDictionary; + +@interface EOModelGroup : NSObject +{ + NSMutableDictionary *nameToModel; + id delegate; /* non-retained */ +} + ++ (void)setDefaultGroup:(EOModelGroup *)_group; ++ (EOModelGroup *)defaultGroup; + ++ (EOModelGroup *)globalModelGroup; + +/* class delegate */ + ++ (void)setClassDelegate:(id)_delegate; ++ (id)classDelegate; + +/* instance delegate */ + +- (void)setDelegate:(id)_delegate; +- (id)delegate; + +/* models */ + +- (void)addModel:(EOModel *)_model; +- (void)removeModel:(EOModel *)_model; + +- (EOModel *)modelNamed:(NSString *)_name; +- (NSArray *)modelNames; +- (NSArray *)models; +- (EOModel *)modelWithPath:(NSString *)_path; +- (EOModel *)addModelWithFile:(NSString *)_path; + +- (void)loadAllModelObjects; + +/* entities */ + +- (EOEntity *)entityForObject:(id)_object; +- (EOEntity *)entityNamed:(NSString *)_name; + +- (EOFetchSpecification *)fetchSpecificationNamed:(NSString *)_name + entityNamed:(NSString *)_entityName; + +@end + +#endif /* __EOAccess_EOModelGroup_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EONull.h b/sope-gdl1/GDLAccess/EOAccess/EONull.h new file mode 100644 index 00000000..64b561f1 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EONull.h @@ -0,0 +1,8 @@ +// $Id: EONull.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __eoaccess_EONull_H__ +#define __eoaccess_EONull_H__ + +#import + +#endif /* __eoaccess_EONull_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOObjectUniquer.h b/sope-gdl1/GDLAccess/EOAccess/EOObjectUniquer.h new file mode 100644 index 00000000..17d99fd4 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOObjectUniquer.h @@ -0,0 +1,84 @@ +/* + EOObjectUniquer.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOObjectUniquer_h__ +#define __EOObjectUniquer_h__ + +#import +#import + +@class EOEntity; +@class NSDictionary; +@class NSArray; + +typedef struct _EOUniquerRecord { + int refCount; + id pkey; + id entity; + id object; + id snapshot; +} EOUniquerRecord; + +@interface EOObjectUniquer : NSObject +{ +@protected + NSMapTable *primaryKeyToRec; + NSMapTable *objectsToRec; + struct _EOUniquerRecord *keyRecord; +} + +// Initializing a uniquing dictionary +- init; + +// Transfer self to parent +- (void)transferTo:(EOObjectUniquer*)dest + objects:(BOOL)isObj andSnapshots:(BOOL)isSnap; + +// Handling objects +- (void)forgetObject:(id)anObj; +- (void)forgetAllObjects; +- (void)forgetAllSnapshots; + +- (id)objectForPrimaryKey:(NSDictionary *)aKey + entity:(EOEntity *)anEntity; + +- (EOUniquerRecord *)recordForObject:(id)anObj; + +- (void)recordObject:(id)anObj + primaryKey:(NSDictionary *)aKey + entity:(EOEntity *)anEntity + snapshot:(NSDictionary *)aSnapshot; + +@end /* EOObjectUniquer */ + +#endif /* __EOObjectUniquer_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOPrimaryKeyDictionary.h b/sope-gdl1/GDLAccess/EOAccess/EOPrimaryKeyDictionary.h new file mode 100644 index 00000000..b53536ab --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOPrimaryKeyDictionary.h @@ -0,0 +1,52 @@ +/* + EOPrimaryKeyDictionary.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOPrimaryKeyDictionary_h__ +#define __EOPrimaryKeyDictionary_h__ + +#import + +@interface EOPrimaryKeyDictionary : NSDictionary +{ + @public + unsigned fastHash; + @protected +} + ++ dictionaryWithKeys:(NSArray*)keys fromDictionary:(NSDictionary*)dict; ++ dictionaryWithObject:(id)object forKey:(id)key; +- (unsigned)fastHash; +- (BOOL)fastIsEqual:aDict; +@end /* EOPrimaryKeyDictionary */ + +#endif /* __EOPrimaryKeyDictionary_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOQualifierScanner.h b/sope-gdl1/GDLAccess/EOAccess/EOQualifierScanner.h new file mode 100644 index 00000000..a6c7a7d9 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOQualifierScanner.h @@ -0,0 +1,59 @@ +/* + EOQualifierScanner.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Helge Hess + Date: September 1996 + November 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOQualifierScanner.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __EOAccess_EOQualifierScanner_H__ +#define __EOAccess_EOQualifierScanner_H__ + +#if !LIB_FOUNDATION_LIBRARY +# import "DefaultScannerHandler.h" +#else +# import +#endif + +@class EOEntity; + +@interface EOQualifierScannerHandler : DefaultScannerHandler +{ + EOEntity *entity; +} + +- (void)setEntity:(EOEntity *)entity; + +@end + +@interface EOQualifierEnumScannerHandler : DefaultEnumScannerHandler +{ + EOEntity *entity; +} + +- (void)setEntity:(EOEntity *)entity; + +@end + +#endif /* __EOAccess_EOQualifierScanner_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOQuotedExpression.h b/sope-gdl1/GDLAccess/EOAccess/EOQuotedExpression.h new file mode 100644 index 00000000..ef0e4b7d --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOQuotedExpression.h @@ -0,0 +1,49 @@ +/* + EOQuotedExpression.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOQuotedExpression_h__ +#define __EOQuotedExpression_h__ + +#import + +@class NSString; + +@interface EOQuotedExpression : NSObject +{ + id expression; + NSString *quote; + NSString *escape; +} + +- (id)expressionValueForContext:(id)context; + +- (id)initWithExpression:(id)expression + quote:(NSString *)quote + escape:(NSString *)escape; + +@end + +#endif /* __EOQuotedExpression_h__ */ diff --git a/sope-gdl1/GDLAccess/EOAccess/EORecordDictionary.h b/sope-gdl1/GDLAccess/EOAccess/EORecordDictionary.h new file mode 100644 index 00000000..ac51a19d --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EORecordDictionary.h @@ -0,0 +1,50 @@ +/* +*/ + +#ifndef __EORecordDictionary_h__ +#define __EORecordDictionary_h__ + +#import + +typedef struct _EORecordDictionaryEntry { + unsigned hash; + id key; + id value; +} EORecordDictionaryEntry; + +@interface EORecordDictionary : NSDictionary +{ + unsigned char count; + EORecordDictionaryEntry entries[1]; +} + +/* Allocating and Initializing an Dictionary */ +- (id)initWithObjects:(id*)objects forKeys:(id*)keys + count:(unsigned int)count; +- (id)initWithDictionary:(NSDictionary*)dictionary; + +/* Accessing keys and values */ +- (id)objectForKey:(id)aKey; +- (unsigned int)count; +- (NSEnumerator *)keyEnumerator; + +@end /* EORecordDictionary */ + +#import + +@interface _EORecordDictionaryKeyEnumerator : NSEnumerator +{ + NSDictionary *dict; + EORecordDictionaryEntry *currentEntry; + unsigned char count; +} + +- (id)initWithDictionary:(EORecordDictionary *)_dict + firstEntry:(EORecordDictionaryEntry *)_firstEntry + count:(unsigned char)_count; + +- (id)nextObject; + +@end + +#endif diff --git a/sope-gdl1/GDLAccess/EOAccess/EORelationship.h b/sope-gdl1/GDLAccess/EOAccess/EORelationship.h new file mode 100644 index 00000000..ab7f9f21 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EORelationship.h @@ -0,0 +1,162 @@ +/* + EORelationship.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EORelationship_h__ +#define __EORelationship_h__ + +#import +#import + +@class NSString, NSDictionary, NSException; +@class EOModel, EOEntity, EOAttribute; + +@interface EORelationship : NSObject +{ + NSString *name; + NSString *definition; + NSDictionary *userDictionary; + + /* Garbage collectable objects */ + EOEntity *entity; /* non-retained */ + EOEntity *destinationEntity; /* non-retained */ + + /* Computed values */ + NSMutableArray *componentRelationships; + + struct { + BOOL isFlattened:1; + BOOL isToMany:1; + BOOL createsMutableObjects:1; + BOOL isMandatory:1; + } flags; + + // EOJoin + + EOAttribute *sourceAttribute; + EOAttribute *destinationAttribute; +} + +/* Initializing instances */ +- (id)initWithName:(NSString*)name; + +/* Accessing the name */ +- (BOOL)setName:(NSString*)name; +- (NSString*)name; ++ (BOOL)isValidName:(NSString*)name; + +/* Using joins */ + +- (NSArray*)joins; + +/* Convering source row in destination row */ +- (NSDictionary*)foreignKeyForRow:(NSDictionary*)row; + +/* Accessing the definition */ +- (NSArray*)componentRelationships; +- (void)setDefinition:(NSString*)definition; +- (NSString*)definition; + +/* Accessing the entities joined */ +- (void)setEntity:(EOEntity*)entity; +- (EOEntity*)entity; +- (void)resetEntities; +- (BOOL)hasEntity; +- (BOOL)hasDestinationEntity; +- (EOEntity*)destinationEntity; + +/* Checking type */ +- (BOOL)isCompound; // always NO (no compound joins supported) +- (BOOL)isFlattened; + +/* Accessing to-many property */ +- (BOOL)setToMany:(BOOL)flag; +- (BOOL)isToMany; + +/* Checking references */ +- (BOOL)referencesProperty:(id)property; + +/* Accessing the user dictionary */ +- (void)setUserDictionary:(NSDictionary*)dictionary; +- (NSDictionary*)userDictionary; + +@end + +@interface EORelationship(EOJoin) + +- (void)loadJoinPropertyList:(id)propertyList; + +/* Accessing join properties */ +- (void)setDestinationAttribute:(EOAttribute*)attribute; +- (EOAttribute*)destinationAttribute; +- (void)setSourceAttribute:(EOAttribute*)attribute; +- (EOAttribute*)sourceAttribute; +- (EORelationship*)relationship; + +@end + +@interface EORelationship (EORelationshipPrivate) + ++ (EORelationship*)relationshipFromPropertyList:(id)propertyList + model:(EOModel*)model; +- (void)replaceStringsWithObjects; +- (void)initFlattenedRelationship; + +- (id)propertyList; + +- (void)setCreateMutableObjects:(BOOL)flag; +- (BOOL)createsMutableObjects; + +@end /* EORelationship (EORelationshipPrivate) */ + +@class NSMutableDictionary; + +@interface EORelationship(PropertyListCoding) + +- (void)encodeIntoPropertyList:(NSMutableDictionary *)_plist; + +@end + +@class NSException; + +@interface EORelationship(EOF2Additions) + +/* constraints */ + +- (void)setIsMandatory:(BOOL)_flag; +- (BOOL)isMandatory; + +- (NSException *)validateValue:(id *)_value; + +@end + +#endif /* __EORelationship_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOSQLExpression.h b/sope-gdl1/GDLAccess/EOAccess/EOSQLExpression.h new file mode 100644 index 00000000..5c91e2de --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOSQLExpression.h @@ -0,0 +1,268 @@ +/* + EOSQLExpression.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: September 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOSQLExpression_h__ +#define __EOSQLExpression_h__ + +#import +#import + +#import +#import + +@class EOAdaptor; +@class EOAdaptorChannel; +@class EOEntity; +@class EOSQLQualifier; + +extern NSString *EOBindVariableNameKey; +extern NSString *EOBindVariablePlaceHolderKey; +extern NSString *EOBindVariableAttributeKey; +extern NSString *EOBindVariableValueKey; + +@interface EOSQLExpression : NSObject +{ + EOEntity *entity; + EOAdaptor *adaptor; + NSMutableDictionary *entitiesAndPropertiesAliases; + NSMutableArray *fromListEntities; + NSMutableString *content; + + /* new in EOF2 */ + NSString *whereClauseString; + NSMutableString *listString; + NSMutableArray *bindings; +} + +/* Building SQL expressions */ + ++ (id)deleteExpressionWithQualifier:(EOSQLQualifier *)qualifier + channel:(EOAdaptorChannel *)channel; ++ (id)insertExpressionForRow:(NSDictionary *)row + entity:(EOEntity *)entity + channel:(EOAdaptorChannel *)channel; ++ (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel; ++ (id)updateExpressionForRow:(NSDictionary *)row + qualifier:(EOSQLQualifier *)qualifier + channel:(EOAdaptorChannel *)channel; + +- (id)deleteExpressionWithQualifier:(EOSQLQualifier *)qualifier + channel:(EOAdaptorChannel *)channel; +- (id)insertExpressionForRow:(NSDictionary *)row + entity:(EOEntity *)entity + channel:(EOAdaptorChannel *)channel; +- (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel; +- (id)updateExpressionForRow:(NSDictionary *)row + qualifier:(EOSQLQualifier *)qualifier + channel:(EOAdaptorChannel *)channel; + +/* factory classes */ + ++ (Class)selectExpressionClass; ++ (Class)insertExpressionClass; ++ (Class)deleteExpressionClass; ++ (Class)updateExpressionClass; + +/* Getting the adaptor */ +- (EOAdaptor *)adaptor; + +// Private methods. + +/* Creating components for the SELECT operation */ +- (NSString *)selectListWithAttributes:(NSArray *)attributes + qualifier:(EOSQLQualifier *)qualifier; +- (NSString *)fromClause; +- (NSString *)whereClauseForQualifier:(EOSQLQualifier *)qualifier; +- (NSString *)joinExpressionForRelationshipPaths:(NSArray *)relationshipPaths; +- (NSString *)lockClause; +- (NSString *)orderByClauseForFetchOrder:(NSArray *)fetchOrder; + +/* Creating components for the UPDATE operation */ +- (id)updateListForRow:(NSDictionary *)row; + +/* Creating components for the INSERT operation */ +- (id)columnListForRow:(NSDictionary *)row; +- (id)valueListForRow:(NSDictionary *)row; + +/* Final initialization */ +- (id)finishBuildingExpression; + +/* Caching aliases */ +- (NSArray *)relationshipPathsForAttributes:(NSArray *)attributes + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder; + +/* Getting the entity */ +- (EOEntity *)entity; + +/* Getting the expression value of an attribute in a given context. This + method is used by the expressionValueForAttribute: method. */ +- (NSString *)expressionValueForAttribute:(EOAttribute *)attribute + context:context; + +@end + +@class NSArray; +@class EOFetchSpecification, EOKeyComparisonQualifier, EOKeyValueQualifier; +@class EOQualifier; + +@interface EOSQLExpression(NewInEOF2) + ++ (EOSQLExpression *)selectStatementForAttributes:(NSArray *)_attributes + lock:(BOOL)_flag + fetchSpecification:(EOFetchSpecification *)_fspec + entity:(EOEntity *)_entity; ++ (EOSQLExpression *)expressionForString:(NSString *)_sql; + +/* accessors */ + +- (void)setStatement:(NSString *)_stmt; +- (NSString *)statement; +- (NSString *)whereClauseString; + +/* tables */ + +- (NSString *)tableListWithRootEntity:(EOEntity *)_entity; + +/* assembly */ + +- (NSString *)assembleDeleteStatementWithQualifier:(EOQualifier *)_qualifier + tableList:(NSString *)_tableList + whereClause:(NSString *)_whereClause; + +- (NSString *)assembleInsertStatementWithRow:(NSDictionary *)_row + tableList:(NSString *)_tables + columnList:(NSString *)_columns + valueList:(NSString *)_values; + +- (NSString *)assembleSelectStatementWithAttributes:(NSArray *)_attributes + lock:(BOOL)_lock + qualifier:(EOQualifier *)_qualifier + fetchOrder:(NSArray *)_fetchOrder + selectString:(NSString *)_selectString + columnList:(NSString *)_columns + tableList:(NSString *)_tables + whereClause:(NSString *)_whereClause + joinClause:(NSString *)_joinClause + orderByClause:(NSString *)_orderByClause + lockClause:(NSString *)_lockClause; + +- (NSString *)assembleUpdateStatementWithRow:(NSDictionary *)_row + qualifier:(EOQualifier *)_qualifier + tableList:(NSString *)_tables + updateList:(NSString *)_updates + whereClause:(NSString *)_whereClause; + +- (NSString *)assembleJoinClauseWithLeftName:(NSString *)_leftName + rightName:(NSString *)_rightName + joinSemantic:(EOJoinSemantic)_semantic; + +/* bind variables */ + +- (BOOL)mustUseBindVariableForAttribute:(EOAttribute *)_attr; +- (BOOL)shouldUseBindVariableForAttribute:(EOAttribute *)_attr; ++ (BOOL)useBindVariables; +- (NSMutableDictionary *)bindVariableDictionaryForAttribute:(EOAttribute *)_attr + value:(id)_value; +- (void)addBindVariableDictionary:(NSMutableDictionary *)_dictionary; +- (NSArray *)bindVariableDictionaries; + +/* values */ + ++ (NSString *)formatValue:(id)_value forAttribute:(EOAttribute *)_attribute; +- (NSString *)sqlStringForValue:(id)_value attributeNamed:(NSString *)_attrName; ++ (NSString *)sqlPatternFromShellPattern:(NSString *)_pattern; + +/* attributes */ + +- (NSString *)sqlStringForAttribute:(EOAttribute *)_attribute; +- (NSString *)sqlStringForAttributePath:(NSString *)_attrPath; +- (NSString *)sqlStringForAttributeNamed:(NSString *)_attrName; + +/* SQL formats */ + ++ (NSString *)formatSQLString:(NSString *)_sqlString format:(NSString *)_fmt; + +/* qualifier operators */ + +- (NSString *)sqlStringForSelector:(SEL)_selector value:(id)_value; + +/* qualifiers */ + +- (NSString *)sqlStringForKeyComparisonQualifier:(EOKeyComparisonQualifier *)_q; +- (NSString *)sqlStringForKeyValueQualifier:(EOKeyValueQualifier *)_q; +- (NSString *)sqlStringForNegatedQualifier:(EOQualifier *)_q; +- (NSString *)sqlStringForConjoinedQualifiers:(NSArray *)_qs; +- (NSString *)sqlStringForDisjoinedQualifiers:(NSArray *)_qs; + +/* list strings */ + +- (NSMutableString *)listString; +- (void)appendItem:(NSString *)_itemString toListString:(NSMutableString *)_lstr; + +/* deletes */ + +- (void)prepareDeleteExpressionForQualifier:(EOQualifier *)_qualifier; + +/* updates */ + +- (void)addUpdateListAttribute:(EOAttribute *)_attr value:(NSString *)_value; + +- (void)prepareUpdateExpressionWithRow:(NSDictionary *)_row + qualifier:(EOQualifier *)_qualifier; + +@end + +/* Private subclasses used by EOSQLExpression. */ + +@interface EOSelectSQLExpression : EOSQLExpression +@end + +@interface EOUpdateSQLExpression : EOSQLExpression +@end + +@interface EOInsertSQLExpression : EOSQLExpression +@end + +@interface EODeleteSQLExpression : EOSQLExpression +@end + +#endif /* __EOSQLExpression_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/EOSQLQualifier.h b/sope-gdl1/GDLAccess/EOAccess/EOSQLQualifier.h new file mode 100644 index 00000000..8528f650 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/EOSQLQualifier.h @@ -0,0 +1,140 @@ +/* + EOSQLQualifier.h + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Helge Hess + Date: September 1996 + November 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __EOSQLQualifier_h__ +#define __EOSQLQualifier_h__ + +#import + +#import + +@class NSDictionary, NSString, NSMutableSet; +@class EOEntity, EORelationship, EOExpressionArray, EOSQLQualifier; +@class EOSQLExpression; + +@protocol EOQualifierSQLGeneration + +- (NSString *)sqlStringForSQLExpression:(EOSQLExpression *)_sqlExpr; +- (EOQualifier *)schemaBasedQualifierWithRootEntity:(EOEntity *)_entity; + +@end + +@interface EOSQLQualifier : EOQualifier < NSCopying > +{ + /* TODO: these should be GCMutableSet */ + NSMutableSet *relationshipPaths; + NSMutableSet *additionalEntities; + + /* Garbage collectable objects */ + EOEntity *entity; + EOExpressionArray *content; + BOOL usesDistinct; +} + +/* Combining qualifiers */ +- (void)negate; +- (void)conjoinWithQualifier:(EOSQLQualifier*)qualifier; +- (void)disjoinWithQualifier:(EOSQLQualifier*)qualifier; + +/* Getting the entity */ +- (EOEntity *)entity; + +/* Checking the definition */ +- (BOOL)isEmpty; + +/* Accessing the distinct selection */ +- (void)setUsesDistinct:(BOOL)flag; +- (BOOL)usesDistinct; + +/* Accessing the relationships referred within qualifier */ +- (NSMutableSet*)relationshipPaths; +- (NSMutableSet*)additionalEntities; + +/* Getting the expression value */ +- (NSString*)expressionValueForContext:(id)ctx; + +/* Private methods */ +- (void)_computeRelationshipPaths:(NSArray *)_relationshipPaths; +- (void)_computeRelationshipPaths; + +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity; + +@end + +@interface EOSQLQualifier(QualifierCreation) + +- (id)initWithEntity:(EOEntity *)_entity + qualifierFormat:(NSString *)_qualifierFormat, ...; + +- (id)initWithEntity:(EOEntity *)_entity + qualifierFormat:(NSString *)_qualifierFormat + argumentsArray:(NSArray *)_args; + +/* Creating instances */ + ++ (EOSQLQualifier *)qualifierForRow:(NSDictionary *)row + entity:(EOEntity *)entity; + ++ (EOSQLQualifier *)qualifierForPrimaryKey:(NSDictionary *)key + entity:(EOEntity *)entity; + ++ (EOSQLQualifier *)qualifierForRow:(NSDictionary *)row + relationship:(EORelationship *)relationship; + ++ (EOSQLQualifier *)qualifierForObject:(id)sourceObject + relationship:(EORelationship *)relationship; + +@end + +@interface EOQualifier(SQLQualifier) +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity; +@end + +@interface EOAndQualifier(SQLGeneration) < EOQualifierSQLGeneration > +@end + +@interface EOOrQualifier(SQLGeneration) < EOQualifierSQLGeneration > +@end + +@interface EONotQualifier(SQLGeneration) < EOQualifierSQLGeneration > +@end + +@interface EOKeyValueQualifier(SQLGeneration) < EOQualifierSQLGeneration > +@end + +@interface EOKeyComparisonQualifier(SQLGeneration) < EOQualifierSQLGeneration > +@end + +#endif /* __EOSQLQualifier_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOAccess/GDLAccess.h b/sope-gdl1/GDLAccess/EOAccess/GDLAccess.h new file mode 100644 index 00000000..8ac7ebab --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/GDLAccess.h @@ -0,0 +1,3 @@ +// $Id: GDLAccess.h 1 2004-08-20 10:38:46Z znek $ + +#import diff --git a/sope-gdl1/GDLAccess/EOAccess/NSObject+EONullInit.h b/sope-gdl1/GDLAccess/EOAccess/NSObject+EONullInit.h new file mode 100644 index 00000000..569d607e --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAccess/NSObject+EONullInit.h @@ -0,0 +1,18 @@ +// $Id: NSObject+EONullInit.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __GDLAccess_NSObject_EONull_H__ +#define __GDLAccess_NSObject_EONull_H__ + +#import +#import + +@class EOEntity; + +@interface NSObject(EONullInit) + +- (void)setAllAttributesToEONull:(EOEntity *)_entity; +- (void)setAllAttributesToEONull; // assume the object respondsTo: entity + +@end + +#endif /* __GDLAccess_NSObject_EONull_H__ */ diff --git a/sope-gdl1/GDLAccess/EOAdaptor.m b/sope-gdl1/GDLAccess/EOAdaptor.m new file mode 100644 index 00000000..366329e3 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAdaptor.m @@ -0,0 +1,342 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// $Id: EOAdaptor.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import "EOAdaptor.h" +#import "EOAdaptorChannel.h" +#import "EOAdaptorContext.h" +#import "EOAttribute.h" +#import "EOFExceptions.h" +#import "EOModel.h" +#import "EOSQLExpression.h" + + +@implementation EOAdaptor + ++ (id)adaptorWithModel:(EOModel*)_model { + /* Check first to see if the adaptor class exists in the running program + by testing the existence of [_model adaptorClassName]. */ + NSString *adaptorName = [_model adaptorName]; + Class adaptorClass = NSClassFromString([_model adaptorClassName]); + id adaptor; + + adaptor = adaptorClass + ? AUTORELEASE([[adaptorClass alloc] initWithName:adaptorName]) + : [self adaptorWithName:adaptorName]; + + [adaptor setModel:_model]; + return adaptor; +} + ++ (id)adaptorWithName:(NSString *)adaptorName { + int i, count; + NSBundle *bundle = [NSBundle mainBundle]; + NSString *adaptorBundlePath = nil; + NSArray *adaptorsPath = nil; + NSMutableArray *paths = nil; + Class adaptorClass = Nil; + NSProcessInfo *pInfo = nil; + NSDictionary *env = nil; + NSMutableString *gdl, *user, *local, *system; + + bundle = [NSBundle mainBundle]; + + /* Check error */ + if ((adaptorName == nil) || [adaptorName isEqual:@""]) + return nil; + + /* Look in application bundle */ + adaptorBundlePath = + [bundle pathForResource:adaptorName ofType:@"gdladaptor"]; + + /* Look in standard paths */ + if (adaptorBundlePath == nil) { + /* + The path of where to search for the adaptor files + is based upon environment variables. + GDL_ADAPTORS_PATH + GNUSTEP_USER_ROOT + GNUSTEP_LOCAL_ROOT + GNUSTEP_SYSTEM_ROOT + */ + pInfo = [NSProcessInfo processInfo]; + env = [pInfo environment]; + paths = [NSMutableArray array]; + + /* GDL_ADAPTORS_PATH is a separated list of paths */ + gdl = [env objectForKey: @"GDL_ADAPTORS_PATH"]; + if (gdl) adaptorsPath = [gdl componentsSeparatedByString:@":"]; + + if (adaptorsPath) [paths addObjectsFromArray: adaptorsPath]; + + user = AUTORELEASE([[env objectForKey: @"GNUSTEP_USER_ROOT"] + mutableCopyWithZone:[self zone]]); + [user appendString: @"/Libraries"]; + if (user) [paths addObject: user]; + + local = AUTORELEASE([[env objectForKey: @"GNUSTEP_LOCAL_ROOT"] + mutableCopyWithZone:[self zone]]); + [local appendString: @"/Libraries"]; + if (local) [paths addObject: local]; + + system = AUTORELEASE([[env objectForKey: @"GNUSTEP_SYSTEM_ROOT"] + mutableCopy]); + [system appendString: @"/Libraries"]; + if (system) + [paths addObject: system]; + + /* Loop through the paths and check each one */ + for(i = 0, count = [paths count]; i < count; i++) { + bundle = [NSBundle bundleWithPath: [paths objectAtIndex:i]]; + adaptorBundlePath = [bundle pathForResource:adaptorName + ofType:@"gdladaptor" + inDirectory:@"Adaptors"]; + + if((adaptorBundlePath != nil) && [adaptorBundlePath length]) + break; + } + } + + /* Make adaptor bundle */ + bundle = adaptorBundlePath + ? [NSBundle bundleWithPath:adaptorBundlePath] + : nil; + + /* Check bundle */ + if (bundle == nil) { + NSLog(@"Cannot find adaptor bundle '%@'", adaptorName); +#if 0 + [[[[CannotFindAdaptorBundleException alloc] + initWithFormat:@"Cannot find adaptor bundle '%@'", + adaptorName] autorelease] raise]; +#endif + return nil; + } + + /* load bundle */ + + if (![bundle load]) { + NSLog(@"Cannot load adaptor bundle '%@'", adaptorName); +#if 1 + [[[[InvalidAdaptorBundleException alloc] + initWithFormat:@"Cannot load adaptor bundle '%@'", + adaptorName] autorelease] raise]; +#endif + return nil; + } + + /* Get the adaptor bundle "infoDictionary", and pricipal class, ie. the + adaptor class. Other info about the adaptor should be put in the + bundle's "Info.plist" file (property list format - see NSBundle class + documentation for details about reserved keys in this dictionary + property list containing one entry whose key is adaptorClassName. It + identifies the actual adaptor class from the bundle. */ + + adaptorClass = [bundle principalClass]; + if (adaptorClass == Nil) { + NSLog(@"The adaptor bundle '%@' at '%@' doesn't contain " + @"a principal class (infoDict=%@)", + adaptorName, [bundle bundlePath], [bundle infoDictionary]); + + [[[InvalidAdaptorBundleException alloc] + initWithFormat:@"The adaptor bundle '%@' doesn't contain " + @"a principal class (infoDict=%@)", + adaptorName, [bundle infoDictionary]] + raise]; + } + return AUTORELEASE([[adaptorClass alloc] initWithName:adaptorName]); +} + +- (id)initWithName:(NSString*)_name { + ASSIGN(self->name, _name); + self->contexts = [[NSMutableArray allocWithZone:[self zone]] init]; + return self; +} + +- (void)dealloc { + RELEASE(self->model); + RELEASE(self->name); + RELEASE(self->connectionDictionary); + RELEASE(self->pkeyGeneratorDictionary); + RELEASE(self->contexts); + [super dealloc]; +} + +/* accessors */ + +- (void)setConnectionDictionary:(NSDictionary*)_dictionary { + if([self hasOpenChannels]) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot set the connection dictionary " + @"while the adaptor is connected!"]; + } + ASSIGN(self->connectionDictionary, _dictionary); + [self->model setConnectionDictionary:_dictionary]; +} +- (NSDictionary *)connectionDictionary { + return self->connectionDictionary; +} +- (BOOL)hasValidConnectionDictionary { + return NO; +} + +- (EOAdaptorContext*)createAdaptorContext { + return AUTORELEASE([[[self adaptorContextClass] alloc] + initWithAdaptor:self]); +} +- (NSArray *)contexts { + NSMutableArray *ma; + unsigned i, count; + + if ((count = [self->contexts count]) == 0) + return nil; + + ma = [NSMutableArray arrayWithCapacity:count]; + for (i = 0; i < count; i++) + [ma addObject:[[self->contexts objectAtIndex:i] nonretainedObjectValue]]; + + return ma; +} + +/* Setting pkey generation info */ + +- (void)setPkeyGeneratorDictionary:(NSDictionary*)aDictionary { + ASSIGN(self->pkeyGeneratorDictionary, aDictionary); + [self->model setPkeyGeneratorDictionary:aDictionary]; +} +- (NSDictionary*)pkeyGeneratorDictionary { + return self->pkeyGeneratorDictionary; +} + +// notifications + +- (void)contextDidInit:aContext { + [self->contexts addObject:[NSValue valueWithNonretainedObject:aContext]]; +} + +- (void)contextWillDealloc:aContext { + int i; + + for (i = [contexts count]-1; i >= 0; i--) { + if ([[contexts objectAtIndex:i] nonretainedObjectValue] == aContext) { + [contexts removeObjectAtIndex:i]; + break; + } + } +} + +- (BOOL)hasOpenChannels { + int i; + + for (i = [contexts count] - 1; i >= 0; i--) { + EOAdaptorContext* ctx = [[contexts objectAtIndex:i] + nonretainedObjectValue]; + if ([ctx hasOpenChannels]) + return YES; + } + return NO; +} + +- (id)formatAttribute:(EOAttribute *)_attribute { + return [_attribute expressionValueForContext:nil]; +} + +- (id)formatValue:(id)_value forAttribute:(EOAttribute *)attribute { + if (_value == nil) _value = [NSNull null]; + return [_value expressionValueForContext:nil]; +} + +- (void)reportError:(NSString*)error { + if(delegateWillReportError) { + if([delegate adaptor:self willReportError:error] == NO) + return; + } + NSLog(@"%@ adaptor error: %@", name, error); +} + +- (void)setDelegate:(id)_delegate { + self->delegate = _delegate; + self->delegateWillReportError + = [self->delegate respondsToSelector: + @selector(adaptor:willReportError:)]; +} + +- (void)setModel:(EOModel *)_model { + ASSIGN(self->model, _model); + [self setConnectionDictionary:[_model connectionDictionary]]; + [self setPkeyGeneratorDictionary:[_model pkeyGeneratorDictionary]]; +} +- (EOModel *)model { + return self->model; +} + +- (NSString *)name { + return self->name; +} + +- (Class)expressionClass { + return [EOSQLExpression class]; +} +- (Class)adaptorContextClass { + return [EOAdaptorContext class]; +} +- (Class)adaptorChannelClass { + return [EOAdaptorChannel class]; +} + +- (BOOL)attributeAllowedInDistinctSelects:(EOAttribute *)_attr { + return YES; +} +- (BOOL)isValidQualifierType:(NSString*)typeName { + return NO; +} +- (id)delegate { + return self->delegate; +} + +// description + +- (NSString *)description { + return [NSString stringWithFormat: + @"<%@[0x%08X]: name=%@ " + @"model=%s connection-dict=%s>", + NSStringFromClass([self class]), self, + [self name], + [self model] ? "yes" : "no", + [self connectionDictionary] ? "yes" : "no"]; +} + +@end /* EOAdaptor */ + +@implementation EOAdaptor(EOF2Additions) + +- (BOOL)canServiceModel:(EOModel *)_model { + return YES; +} + +@end diff --git a/sope-gdl1/GDLAccess/EOAdaptorChannel+Attributes.m b/sope-gdl1/GDLAccess/EOAdaptorChannel+Attributes.m new file mode 100644 index 00000000..0f198fb8 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAdaptorChannel+Attributes.m @@ -0,0 +1,78 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAdaptorChannel+Attributes.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import "EOAdaptorChannel+Attributes.h" +#import "EOAdaptorContext.h" +#import "EOEntity.h" +#import "EOAdaptor.h" +#import "EOModel.h" + +@implementation EOAdaptorChannel(Attributes) + +- (EOEntity *)_entityForTableName:(NSString *)_tableName { + EOModel *model = nil; + EOEntity *entity = nil; + + if (_tableName == nil || [_tableName length] == 0) + return nil; + + model = [[self->adaptorContext adaptor] model]; + + if ((entity = [model entityNamed:_tableName]) == nil) { + NSEnumerator *enumerator = nil; + enumerator = [[model entities] objectEnumerator]; + while ((entity = [enumerator nextObject])) { + if ([[entity externalName] isEqualToString:_tableName]) + break; + } + } + if (entity == nil) { + model = [self describeModelWithTableNames: + [NSArray arrayWithObject:_tableName]]; + + if ((entity = [model entityNamed:_tableName]) == nil) { + NSEnumerator *enumerator = nil; + enumerator = [[model entities] objectEnumerator]; + while ((entity = [enumerator nextObject])) { + if ([[entity externalName] isEqualToString:_tableName]) + break; + } + } + } + return entity; +} + +- (NSArray *)attributesForTableName:(NSString *)_tableName { + return [[self _entityForTableName:_tableName] attributes]; +} + +- (NSArray *)primaryKeyAttributesForTableName:(NSString *)_tableName { + return [[self _entityForTableName:_tableName] primaryKeyAttributes]; +} + +@end /* EOAdaptorChannel(Attributes) */ diff --git a/sope-gdl1/GDLAccess/EOAdaptorChannel.m b/sope-gdl1/GDLAccess/EOAdaptorChannel.m new file mode 100644 index 00000000..e8af497a --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAdaptorChannel.m @@ -0,0 +1,621 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOAdaptorChannel.h" +#import "EOAttribute.h" +#import "EOAdaptor.h" +#import "EOAdaptorContext.h" +#import "EOSQLExpression.h" +#import "EOFExceptions.h" + +@interface EOAdaptorChannel(Internals) +- (NSArray *)_sortAttributesForSelectExpression:(NSArray *)_attrs; +@end /* EOAdaptorChannel(Internals) */ + +@implementation EOAdaptorChannel + ++ (NSCalendarDate*)dateForAttribute:(EOAttribute*)attr + year:(int)year month:(unsigned)month day:(unsigned)day + hour:(unsigned)hour minute:(unsigned)minute second:(unsigned)second + zone:(NSZone*)zone +{ + NSTimeZone *serverTimeZone = [attr serverTimeZone]; + NSTimeZone *clientTimeZone = [attr clientTimeZone]; + NSCalendarDate *date; + NSString *fmt; + + if (serverTimeZone == nil) serverTimeZone = [NSTimeZone localTimeZone]; + if (clientTimeZone == nil) clientTimeZone = [NSTimeZone localTimeZone]; + + date = AUTORELEASE([[NSCalendarDate allocWithZone:zone] + initWithYear:year month:month day:day hour:hour + minute:minute second:second timeZone:serverTimeZone]); + [date setTimeZone:clientTimeZone]; + fmt = [attr calendarFormat]; + [date setCalendarFormat:fmt ? fmt : [EOAttribute defaultCalendarFormat]]; + return date; +} + +- (id)initWithAdaptorContext:(EOAdaptorContext*)_adaptorContext { + ASSIGN(self->adaptorContext, _adaptorContext); + + NS_DURING + [self->adaptorContext channelDidInit:self]; + NS_HANDLER { + AUTORELEASE(self); + [localException raise]; + } + NS_ENDHANDLER; + + return self; +} + +- (void)dealloc { + [self->adaptorContext channelWillDealloc:self]; + RELEASE(self->adaptorContext); + [super dealloc]; +} + +/* open/close channel */ + +- (BOOL)openChannel { + if(self->isOpen) + return NO; + self->isOpen = YES; + + return YES; +} + +- (void)closeChannel { + if ([self isFetchInProgress]) + [self cancelFetch]; + self->isOpen = NO; +} + +/* modifications */ + +- (Class)_adaptorExpressionClass { + return [[self->adaptorContext adaptor] expressionClass]; +} + +- (BOOL)_isNoRaiseOnModificationException:(NSException *)_exception { + /* for compatibility with non-X methods, translate some errors to a bool */ + NSString *n; + + n = [_exception name]; + if ([n isEqualToString:@"EOEvaluationError"]) + return YES; + if ([n isEqualToString:@"EODelegateRejects"]) + return YES; + + return NO; +} + +- (NSException *)insertRowX:(NSDictionary *)row forEntity:(EOEntity *)entity { + EOSQLExpression *sqlexpr; + NSMutableDictionary *mrow = (id)row; + NSException *ex; + + if (!isOpen) + return [[ChannelIsNotOpenedException new] autorelease]; + + if((row == nil) || (entity == nil)) { + return [NSException exceptionWithName:NSInvalidArgumentException + reason:@"row and entity arguments for " + @"insertRow:forEntity: must not be the nil object" + userInfo:nil]; + } + + if([self isFetchInProgress]) + return [AdaptorIsFetchingException exceptionWithAdaptor:self]; + + if ([self->adaptorContext transactionNestingLevel] == 0) + return [NoTransactionInProgressException exceptionWithAdaptor:self]; + + if (delegateRespondsTo.willInsertRow) { + EODelegateResponse response; + + mrow = AUTORELEASE([row mutableCopyWithZone:[row zone]]); + response = [delegate adaptorChannel:self + willInsertRow:mrow + forEntity:entity]; + if (response == EODelegateRejects) { + return [NSException exceptionWithName:@"EODelegateRejects" + reason:@"delegate rejected insert" + userInfo:nil]; + } + if (response == EODelegateOverrides) + return nil; + } + + sqlexpr = [[[self->adaptorContext adaptor] + expressionClass] + insertExpressionForRow:mrow + entity:entity + channel:self]; + + ex = [self evaluateExpressionX:[sqlexpr expressionValueForContext:nil]]; + if (ex != nil) + return ex; + + if(delegateRespondsTo.didInsertRow) + [delegate adaptorChannel:self didInsertRow:mrow forEntity:entity]; + + return nil; +} + +- (NSException *)updateRowX:(NSDictionary *)row + describedByQualifier:(EOSQLQualifier *)qualifier +{ + EOSQLExpression *sqlexpr = nil; + NSMutableDictionary *mrow = (id)row; + NSException *ex; + + if (!isOpen) + return [[ChannelIsNotOpenedException new] autorelease]; + + if (row == nil) { + return [NSException exceptionWithName:NSInvalidArgumentException + reason: + @"row argument for updateRow:describedByQualifier: " + @"must not be the nil object" + userInfo:nil]; + } + + if ([self isFetchInProgress]) + return [AdaptorIsFetchingException exceptionWithAdaptor:self]; + + if ([self->adaptorContext transactionNestingLevel] == 0) + return [NoTransactionInProgressException exceptionWithAdaptor:self]; + + if (delegateRespondsTo.willUpdateRow) { + EODelegateResponse response; + + mrow = AUTORELEASE([row mutableCopyWithZone:[row zone]]); + response = [delegate adaptorChannel:self + willUpdateRow:mrow + describedByQualifier:qualifier]; + if (response == EODelegateRejects) { + return [NSException exceptionWithName:@"EODelegateRejects" + reason:@"delegate rejected update" + userInfo:nil]; + } + if (response == EODelegateOverrides) + return nil; + } + + sqlexpr = [[self _adaptorExpressionClass] + updateExpressionForRow:mrow + qualifier:qualifier + channel:self]; + + ex = [self evaluateExpressionX:[sqlexpr expressionValueForContext:nil]]; + if (ex != nil) return ex; + + if (delegateRespondsTo.didUpdateRow) { + [delegate adaptorChannel:self + didUpdateRow:mrow + describedByQualifier:qualifier]; + } + return nil; +} + +- (NSException *)deleteRowsDescribedByQualifierX:(EOSQLQualifier *)qualifier { + EOSQLExpression *sqlexpr = nil; + NSException *ex; + + if (!isOpen) + return [[ChannelIsNotOpenedException new] autorelease]; + + if ([self isFetchInProgress]) + return [AdaptorIsFetchingException exceptionWithAdaptor:self]; + + if ([self->adaptorContext transactionNestingLevel] == 0) + return [NoTransactionInProgressException exceptionWithAdaptor:self]; + + if (delegateRespondsTo.willDeleteRows) { + EODelegateResponse response; + + response = [delegate adaptorChannel:self + willDeleteRowsDescribedByQualifier:qualifier]; + if (response == EODelegateRejects) { + return [NSException exceptionWithName:@"EODelegateRejects" + reason:@"delegate rejected delete" + userInfo:nil]; + } + if (response == EODelegateOverrides) + return nil; + } + + sqlexpr = [[self _adaptorExpressionClass] + deleteExpressionWithQualifier:qualifier + channel:self]; + + ex = [self evaluateExpressionX:[sqlexpr expressionValueForContext:nil]]; + if (ex != nil) return ex; + + if (delegateRespondsTo.didDeleteRows) + [delegate adaptorChannel:self didDeleteRowsDescribedByQualifier:qualifier]; + + return nil; +} + +/* compatibility methods (DEPRECATED, use the ...X methods */ + +- (BOOL)insertRow:(NSDictionary *)_row forEntity:(EOEntity *)_entity { + NSException *ex; + + ex = [self insertRowX:_row forEntity:_entity]; + if (ex == nil) + return YES; + if ([self _isNoRaiseOnModificationException:ex]) + return NO; + [ex raise]; + return NO; +} + +- (BOOL)updateRow:(NSDictionary *)_row + describedByQualifier:(EOSQLQualifier *)_q +{ + NSException *ex; + + ex = [self updateRowX:_row describedByQualifier:_q]; + if (ex == nil) + return YES; + if ([self _isNoRaiseOnModificationException:ex]) + return NO; + [ex raise]; + return NO; +} + +- (BOOL)deleteRowsDescribedByQualifier:(EOSQLQualifier *)_qualifier { + NSException *ex; + + ex = [self deleteRowsDescribedByQualifierX:_qualifier]; + if (ex == nil) + return YES; + if ([self _isNoRaiseOnModificationException:ex]) + return NO; + [ex raise]; + return NO; +} + +/* fetch operations */ + +- (BOOL)selectAttributes:(NSArray *)attributes + describedByQualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + lock:(BOOL)lockFlag +{ + EOSQLExpression *sqlexpr = nil; + NSMutableArray *mattrs = (NSMutableArray *)attributes; + NSMutableArray *mfetch = (NSMutableArray *)fetchOrder; + + if (!isOpen) + [[ChannelIsNotOpenedException new] raise]; + + if (attributes == nil) { + [NSException raise:NSInvalidArgumentException + format:@"attributes argument for selectAttributes:" + @"describedByQualifier:fetchOrder:lock: " + @"must not be the nil object"]; + } + + if ([self isFetchInProgress]) + [[AdaptorIsFetchingException exceptionWithAdaptor:self] raise]; + + if ([self->adaptorContext transactionNestingLevel] == 0) + [[NoTransactionInProgressException exceptionWithAdaptor:self] raise]; + + if(delegateRespondsTo.willSelectAttributes) { + EODelegateResponse response; + + mattrs = [[attributes mutableCopy] autorelease]; + mfetch = [[fetchOrder mutableCopy] autorelease]; + + response = [delegate adaptorChannel:self + willSelectAttributes:mattrs + describedByQualifier:qualifier + fetchOrder:mfetch + lock:lockFlag]; + if (response == EODelegateRejects) + return NO; + if (response == EODelegateOverrides) + return YES; + } + +#if 0 +#warning DEBUG LOG, REMOVE! + [self logWithFormat:@"fetch qualifier: %@", qualifier]; +#endif + + sqlexpr = [[[self->adaptorContext adaptor] + expressionClass] + selectExpressionForAttributes:attributes + lock:lockFlag + qualifier:qualifier + fetchOrder:fetchOrder + channel:self]; + + if (![self evaluateExpression:[sqlexpr expressionValueForContext:nil]]) + return NO; + + if (delegateRespondsTo.didSelectAttributes) { + [delegate adaptorChannel:self + didSelectAttributes:mattrs + describedByQualifier:qualifier + fetchOrder:mfetch + lock:lockFlag]; + } + + return YES; +} + +- (NSArray *)describeResults { + [self subclassResponsibility:_cmd]; + return nil; +} + +- (NSMutableDictionary *)fetchAttributes:(NSArray *)attributes + withZone:(NSZone *)_zone +{ + NSMutableDictionary *row = nil; + + if (!self->isOpen) + [[ChannelIsNotOpenedException new] raise]; + + if (_zone == NULL) + _zone = NSDefaultMallocZone(); + + if(![self isFetchInProgress]) + [[AdaptorIsNotFetchingException exceptionWithAdaptor:self] raise]; + + if(delegateRespondsTo.willFetchAttributes) { + row = [delegate adaptorChannel:self + willFetchAttributes:attributes + withZone:_zone]; + } + + /* NOTE: primaryFetchAttributes:withZone: have to set the isFetchInProgress + status */ + if(row == nil) + row = [self primaryFetchAttributes:attributes withZone:_zone]; + + if(row) { + if(delegateRespondsTo.didFetchAttributes) + row = [delegate adaptorChannel:self + didFetchAttributes:row + withZone:_zone]; + if(delegateRespondsTo.didChangeResultSet) + [delegate adaptorChannelDidChangeResultSet:self]; + } + else { + /* Do not set here the isFetchInProgress status since only subclasses + can know whether there are more SELECT commands to be executed. + Setting the status here to NO will overwrite the adaptor subclass + intention. */ + if(delegateRespondsTo.didFinishFetching) + [delegate adaptorChannelDidFinishFetching:self]; + } + return row; +} + +- (BOOL)isFetchInProgress { + return self->isFetchInProgress; +} + +- (void)cancelFetch { + if (!isOpen) + [[ChannelIsNotOpenedException new] raise]; + + self->isFetchInProgress = NO; +} + +- (NSMutableDictionary *)dictionaryWithObjects:(id *)objects + forAttributes:(NSArray *)attributes zone:(NSZone *)zone +{ + [self notImplemented:_cmd]; + return nil; +} + +- (NSMutableDictionary*)primaryFetchAttributes:(NSArray *)attributes + withZone:(NSZone *)zone +{ + [self subclassResponsibility:_cmd]; + return nil; +} + +- (BOOL)evaluateExpression:(NSString *)anExpression { + [self subclassResponsibility:_cmd]; + return NO; +} +- (NSException *)evaluateExpressionX:(NSString *)_sql { + NSException *ex; + BOOL ok; + + ex = nil; + ok = NO; + NS_DURING + ok = [self evaluateExpression:_sql]; + NS_HANDLER + ex = [localException retain]; + NS_ENDHANDLER; + + if (ex) return [ex autorelease]; + if (ok) return nil; + + return [NSException exceptionWithName:@"EOEvaluationError" + reason:@"could not evaluate SQL expression" + userInfo:nil]; +} + +- (EOAdaptorContext *)adaptorContext { + return self->adaptorContext; +} + +- (EOModel *)describeModelWithTableNames:(NSArray *)tableNames { + [self subclassResponsibility:_cmd]; + return nil; +} + +- (NSArray *)describeTableNames { + [self subclassResponsibility:_cmd]; + return nil; +} + +- (BOOL)readTypesForEntity:(EOEntity*)anEntity { + [self subclassResponsibility:_cmd]; + return NO; +} + +- (BOOL)readTypeForAttribute:(EOAttribute*)anAttribute { + [self subclassResponsibility:_cmd]; + return NO; +} + +// delegate + +- (id)delegate { + return self->delegate; +} + +- (void)setDelegate:(id)_delegate { + self->delegate = _delegate; + + delegateRespondsTo.willInsertRow = + [delegate respondsToSelector: + @selector(adaptorChannel:willInsertRow:forEntity:)]; + delegateRespondsTo.didInsertRow = + [delegate respondsToSelector: + @selector(adaptorChannel:didInsertRow:forEntity:)]; + delegateRespondsTo.willUpdateRow = + [delegate respondsToSelector: + @selector(adaptorChannel:willUpdateRow:describedByQualifier:)]; + delegateRespondsTo.didUpdateRow = + [delegate respondsToSelector: + @selector(adaptorChannel:didUpdateRow:describedByQualifier:)]; + delegateRespondsTo.willDeleteRows = + [delegate respondsToSelector: + @selector(adaptorChannel:willDeleteRowsDescribedByQualifier:)]; + delegateRespondsTo.didDeleteRows = + [delegate respondsToSelector: + @selector(adaptorChannel:didDeleteRowsDescribedByQualifier:)]; + delegateRespondsTo.willSelectAttributes = + [delegate respondsToSelector: + @selector(adaptorChannel:willSelectAttributes: + describedByQualifier:fetchOrder:lock:)]; + delegateRespondsTo.didSelectAttributes = + [delegate respondsToSelector: + @selector(adaptorChannel:didSelectAttributes: + describedByQualifier:fetchOrder:lock:)]; + delegateRespondsTo.willFetchAttributes = + [delegate respondsToSelector: + @selector(adaptorChannel:willFetchAttributes:withZone:)]; + delegateRespondsTo.didFetchAttributes = + [delegate respondsToSelector: + @selector(adaptorChannel:didFetchAttributes:withZone:)]; + delegateRespondsTo.didChangeResultSet = + [delegate respondsToSelector: + @selector(adaptorChannelDidChangeResultSet:)]; + delegateRespondsTo.didFinishFetching = + [delegate respondsToSelector: + @selector(adaptorChannelDidFinishFetching:)]; + delegateRespondsTo.willEvaluateExpression = + [delegate respondsToSelector: + @selector(adaptorChannel:willEvaluateExpression:)]; + delegateRespondsTo.didEvaluateExpression = + [delegate respondsToSelector: + @selector(adaptorChannel:didEvaluateExpression:)]; +} + +- (void)setDebugEnabled:(BOOL)flag { + self->debugEnabled = flag; +} + +- (BOOL)isDebugEnabled { + return self->debugEnabled; +} +- (BOOL)isOpen { + return self->isOpen; +} + +@end /* EOAdaptorChannel */ + +#import + +@implementation EOAdaptorChannel(PrimaryKeyGeneration) // new in EOF2 + +- (NSDictionary *)primaryKeyForNewRowWithEntity:(EOEntity *)_entity { + return nil; +} + +@end /* EOAdaptorChannel(PrimaryKeyGeneration) */ + +@implementation EOAdaptorChannel(EOF2Additions) + +- (void)selectAttributes:(NSArray *)_attributes + fetchSpecification:(EOFetchSpecification *)_fspec + lock:(BOOL)_flag + entity:(EOEntity *)_entity +{ + EOSQLQualifier *q; + BOOL isOk; + + q = (EOSQLQualifier *)[_fspec qualifier]; + + isOk = [self selectAttributes:_attributes + describedByQualifier:q + fetchOrder:[_fspec sortOrderings] + lock:_flag]; + if (!isOk) { + [NSException raise:@"Select failed" + format:@"could not select attributes for fetch spec"]; + } +} + +- (void)setAttributesToFetch:(NSArray *)_attributes { + [self notImplemented:_cmd]; +} +- (NSArray *)attributesToFetch { + NSLog(@"ERROR(%s): subclasses must override this method!", + __PRETTY_FUNCTION__); + return nil; +} + +- (NSMutableDictionary *)fetchRowWithZone:(NSZone *)_zone { + return [self fetchAttributes:[self attributesToFetch] withZone:_zone]; +} + +@end /* EOAdaptorChannel(EOF2Additions) */ + +@implementation EOAdaptorChannel(Internals) + +- (NSArray *)_sortAttributesForSelectExpression:(NSArray *)_attrs { + return _attrs; +} + +@end /* EOAdaptorChannel(Internals) */ diff --git a/sope-gdl1/GDLAccess/EOAdaptorContext.m b/sope-gdl1/GDLAccess/EOAdaptorContext.m new file mode 100644 index 00000000..82026ee8 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAdaptorContext.m @@ -0,0 +1,257 @@ +/* + EOAdaptorContext.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import +#import +#import + +#import "common.h" +#import "EOAdaptor.h" +#import "EOAdaptorContext.h" +#import "EOAdaptorChannel.h" + +@implementation EOAdaptorContext + +- (id)initWithAdaptor :(EOAdaptor*)_adaptor +{ + ASSIGN(self->adaptor, _adaptor); + self->channels = [[NSMutableArray alloc] initWithCapacity:2]; + [self->adaptor contextDidInit:self]; + return self; +} + +- (void)dealloc +{ + [self->adaptor contextWillDealloc:self]; + RELEASE(self->adaptor); + RELEASE(self->channels); + [super dealloc]; +} + +- (EOAdaptorChannel*)createAdaptorChannel +{ + return AUTORELEASE([[[adaptor adaptorChannelClass] alloc] + initWithAdaptorContext:self]); +} +- (NSArray *)channels +{ + NSMutableArray *ma; + unsigned i, count; + + if ((count = [self->channels count]) == 0) + return nil; + + ma = [NSMutableArray arrayWithCapacity:count]; + for (i = 0; i < count; i++) + [ma addObject:[[self->channels objectAtIndex:i] nonretainedObjectValue]]; + + return ma; +} + +- (void)channelDidInit:aChannel +{ + [self->channels addObject:[NSValue valueWithNonretainedObject:aChannel]]; +} + +- (void)channelWillDealloc:(id)aChannel +{ + int i; + + for (i = [self->channels count] - 1; i >= 0; i--) + if ([[channels objectAtIndex:i] nonretainedObjectValue] == aChannel) { + [channels removeObjectAtIndex:i]; + break; + } +} + +- (BOOL)hasOpenChannels +{ + int i, count = [channels count]; + + for (i = 0; i < count; i++) + if ([[[channels objectAtIndex:i] nonretainedObjectValue] isOpen]) + return YES; + + return NO; +} + +- (BOOL)hasBusyChannels +{ + int i, count = [channels count]; + + for (i = 0; i < count; i++) + if ([[[channels objectAtIndex:i] nonretainedObjectValue] + isFetchInProgress]) + return YES; + + return NO; +} + +- (BOOL)beginTransaction +{ + if (transactionNestingLevel && ![self canNestTransactions]) + return NO; + + if ([self->channels count] == 0) + return NO; + + if(delegateRespondsTo.willBegin) { + EODelegateResponse response = [delegate adaptorContextWillBegin:self]; + if(response == EODelegateRejects) + return NO; + else if(response == EODelegateOverrides) + return YES; + } + if([self primaryBeginTransaction] == NO) + return NO; + + [self transactionDidBegin]; + + if(delegateRespondsTo.didBegin) + [delegate adaptorContextDidBegin:self]; + return YES; +} + +- (BOOL)commitTransaction +{ + if(!transactionNestingLevel || [self hasBusyChannels]) + return NO; + + if (![channels count]) + return NO; + + if(delegateRespondsTo.willCommit) { + EODelegateResponse response = [delegate adaptorContextWillCommit:self]; + if(response == EODelegateRejects) + return NO; + else if(response == EODelegateOverrides) + return YES; + } + + if([self primaryCommitTransaction] == NO) + return NO; + + [self transactionDidCommit]; + + if(delegateRespondsTo.didCommit) + [delegate adaptorContextDidCommit:self]; + return YES; +} + +- (BOOL)rollbackTransaction +{ + if(!transactionNestingLevel || [self hasBusyChannels]) + return NO; + + if (![channels count]) + return NO; + + if(delegateRespondsTo.willRollback) { + EODelegateResponse response + = [delegate adaptorContextWillRollback:self]; + if(response == EODelegateRejects) + return NO; + else if(response == EODelegateOverrides) + return YES; + } + + if([self primaryRollbackTransaction] == NO) + return NO; + + [self transactionDidRollback]; + + if(delegateRespondsTo.didRollback) + [delegate adaptorContextDidRollback:self]; + return YES; +} + +- (void)transactionDidBegin +{ + /* Increment the transaction scope */ + transactionNestingLevel++; +} + +- (void)transactionDidCommit +{ + /* Decrement the transaction scope */ + transactionNestingLevel--; +} + +- (void)transactionDidRollback +{ + /* Decrement the transaction scope */ + transactionNestingLevel--; +} + +- (void)setDelegate:(id)_delegate { + self->delegate = _delegate; + + delegateRespondsTo.willBegin = + [delegate respondsToSelector:@selector(adaptorContextWillBegin:)]; + delegateRespondsTo.didBegin = + [delegate respondsToSelector:@selector(adaptorContextDidBegin:)]; + delegateRespondsTo.willCommit = + [delegate respondsToSelector:@selector(adaptorContextWillCommit:)]; + delegateRespondsTo.didCommit = + [delegate respondsToSelector:@selector(adaptorContextDidCommit:)]; + delegateRespondsTo.willRollback = + [delegate respondsToSelector:@selector(adaptorContextWillRollback:)]; + delegateRespondsTo.didRollback = + [delegate respondsToSelector:@selector(adaptorContextDidRollback:)]; +} +- (id)delegate { + return self->delegate; +} + +- (EOAdaptor *)adaptor { + return self->adaptor; +} +- (BOOL)canNestTransactions { + /* deprecated in WO 4.5 */ + return NO; +} +- (unsigned)transactionNestingLevel { + /* deprecated in WO 4.5 */ + return self->transactionNestingLevel; +} +- (BOOL)hasOpenTransaction { + /* new in WO 4.5 */ + return self->transactionNestingLevel > 0 ? YES : NO; +} + +- (BOOL)primaryBeginTransaction { + return NO; +} + +- (BOOL)primaryCommitTransaction { + return NO; +} + +- (BOOL)primaryRollbackTransaction { + return NO; +} + +@end /* EOAdaptorContext */ diff --git a/sope-gdl1/GDLAccess/EOAdaptorDataSource.m b/sope-gdl1/GDLAccess/EOAdaptorDataSource.m new file mode 100644 index 00000000..38ca9090 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAdaptorDataSource.m @@ -0,0 +1,1406 @@ +/* + EOAdaptorDataSource.m + + Copyright (C) SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + Date: 1999-2004 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAdaptorDataSource.m 1 2004-08-20 10:38:46Z znek $ + +/* + column-names must have small letterso + hints: + EOPrimaryKeyAttributeNamesHint - name of primary key attributes + EOPrimaryKeyAttributesHint - primary key attributes + EOFetchResultTimeZone - NSTimeZone object for dates +*/ + +#define EOAdaptorDataSource_DEBUG 0 + +#include +#include +#include +#include "common.h" + +NSString *EOPrimaryKeyAttributeNamesHint = @"EOPrimaryKeyAttributeNamesHint"; +NSString *EOPrimaryKeyAttributesHint = @"EOPrimaryKeyAttributesHint"; +NSString *EOFetchResultTimeZone = @"EOFetchResultTimeZoneHint"; + +@interface NSObject(Private) +- (NSString *)newKeyExpression; +- (NSArray *)_primaryKeyAttributesForTableName:(NSString *)_entityName + channel:(EOAdaptorChannel *)_adChannel; +- (NSArray *)_primaryKeyAttributeNamesForTableName:(NSString *)_entityName + channel:(EOAdaptorChannel *)_adChannel; +@end + +static EONull *null = nil; + +@interface EOAdaptorChannel(Internals) +- (NSArray *)_sortAttributesForSelectExpression:(NSArray *)_attrs; +@end /* EOAdaptorChannel(Internals) */ + +@interface EOQualifier(SqlExpression) +- (NSString *)sqlExpressionWithAdaptor:(EOAdaptor *)_adaptor + attributes:(NSArray *)_attrs; +@end /* EOQualifier(SqlExpression) */ + +@interface EOAdaptorDataSource(Private) +- (NSMutableString *)_selectListWithChannel:(EOAdaptorChannel *)_adChan; +- (NSString *)_whereExprWithChannel:(EOAdaptorChannel *)_adChan; +- (NSString *)_whereClauseForGlobaID:(EOKeyGlobalID *)_gid + adaptor:(EOAdaptor *)_adaptor channel:(EOAdaptorChannel *)_adChan; +- (NSDictionary *)_mapAttrsWithValues:(NSDictionary *)_keyValues + tableName:(NSString *)_tableName channel:(EOAdaptorChannel *)_adChan; +@end /* EOAdaptorDataSource(Private) */ + +@interface EOAdaptorDataSource(Internals) +- (id)initWithAdaptorChannel:(EOAdaptorChannel *)_channel + connectionDictionary:(NSDictionary *)_connDict; +@end /* EOAdaptorDataSource(Internals) */ + +@interface EODataSource(Notificiations) +- (void)postDataSourceChangedNotification; +@end + +@implementation EOAdaptorDataSource + +static NSNotificationCenter *nc = nil; + +static NSNotificationCenter *getNC(void ) { + if (nc == nil) + nc = [[NSNotificationCenter defaultCenter] retain]; + return nc; +} + ++ (void)initialize { + NSAssert2([super version] == 1, + @"invalid superclass (%@) version %i !", + NSStringFromClass([self superclass]), [super version]); + if (null == nil) + null = [[EONull null] retain]; +} ++ (int)version { + return [super version] + 1; /* v2 */ +} + +- (id)initWithAdaptorName:(NSString *)_adName + connectionDictionary:(NSDictionary *)_dict + primaryKeyGenerationDictionary:(NSDictionary *)_pkGen +{ + EOAdaptor *ad = nil; + EOAdaptorContext *ctx = nil; + EOAdaptorChannel *adc = nil; + + ad = [EOAdaptor adaptorWithName:_adName]; + [ad setConnectionDictionary:_dict]; + [ad setPkeyGeneratorDictionary:_pkGen]; + ctx = [ad createAdaptorContext]; + adc = [ctx createAdaptorChannel]; + + return [self initWithAdaptorChannel:adc connectionDictionary:_dict]; +} + +- (id)initWithAdaptorChannel:(EOAdaptorChannel *)_channel { + return [self initWithAdaptorChannel:_channel connectionDictionary:nil]; +} + +- (id)initWithAdaptorChannel:(EOAdaptorChannel *)_channel + connectionDictionary:(NSDictionary *)_connDict +{ + if ((self = [super init])) { + self->adChannel = [_channel retain]; + self->connectionDictionary = [_connDict copy]; + self->commitTransaction = NO; + + [getNC() + addObserver:self selector:@selector(_adDataSourceChanged:) + name:@"EOAdaptorDataSourceChanged" object:nil]; + } + return self; +} + +- (void)dealloc { + [getNC() removeObserver:self]; + [self->fetchSpecification release]; + [self->connectionDictionary release]; + [self->adChannel release]; + [self->__attributes release]; + [self->__qualifier release]; + [super dealloc]; +} + +/* notifications */ + +- (void)postDataSourceItselfChangedNotification { + [super postDataSourceChangedNotification]; +} + +- (void)postDataSourceChangedNotification { + [getNC() postNotificationName:@"EOAdaptorDataSourceChanged" object:self]; + [self postDataSourceItselfChangedNotification]; +} + +- (void)_adDataSourceChanged:(NSNotification *)_notification { + EOAdaptorDataSource *ads; + + if ((ads = [_notification object]) == self) + return; + if (ads == nil) + return; + + [self postDataSourceItselfChangedNotification]; + +#if 0 + if (![ads->connectionDictionary isEqual:self->connectionDictionary]) + /* different database ... */ + return; + + if ((ads->fetchSpecification == nil) || (self->fetchSpecification == nil)) { + [self postDataSourceChangedNotification]; + return; + } + + /* check fspecs for entity ... */ + if ([[ads->fetchSpecification entityName] + isEqualToString: + [self->fetchSpecification entityName]]) { + [self postDataSourceChangedNotification]; + return; + } +#endif +} + +/* fetching */ + +- (EOAdaptorChannel *)beginTransaction { + EOAdaptorContext *ctx = nil; + + [self openChannel]; + ctx = [self->adChannel adaptorContext]; + if ([ctx hasOpenTransaction] == NO) { + [ctx beginTransaction]; + self->commitTransaction = YES; + } + return self->adChannel; +} + +- (void)commitTransaction { + if (self->commitTransaction) { + [[self->adChannel adaptorContext] commitTransaction]; + // [self->adChannel closeChannel]; + self->commitTransaction = NO; + } +} + +- (void)rollbackTransaction { + [[self->adChannel adaptorContext] rollbackTransaction]; + // [self->adChannel closeChannel]; + self->commitTransaction = NO; +} + +- (void)openChannel { + if (![self->adChannel isOpen]) { + [self->adChannel openChannel]; + } +} + +- (void)closeChannel { + if (![self->adChannel isOpen]) + return; + + if ([[self->adChannel adaptorContext] transactionNestingLevel]) { + NSLog(@"%s was called while transaction in progress, rollback will called", + __PRETTY_FUNCTION__); + [self rollbackTransaction]; + } + [self->adChannel closeChannel]; +} + +- (NSArray *)fetchObjects { + /* TODO: split up this HUGE method! */ + NSString *entityName = nil; + NSString *whereExpr = nil; + NSMutableString *orderByExpr = nil; + NSMutableString *selectList = nil; + NSMutableString *expression = nil; + NSMutableArray *result = nil; + NSArray *attrs = nil; + EOAdaptor *adaptor = nil; + NSArray *pKeys = nil; + EOQualifier *qual = nil; + EOAdaptorChannel *adChan = nil; + int pKeyCnt = 0; + NSTimeZone *tz = nil; + BOOL localComTrans; + + if (self->fetchSpecification == nil) { + [NSException raise:NSInvalidArgumentException + format:@"fetchSpecification required for table name"]; + return nil; + } + + entityName = [self->fetchSpecification entityName]; + + if (entityName == nil || [entityName length] == 0) { + [NSException raise:NSInvalidArgumentException + format:@"missing entity name"]; + } + localComTrans = [[self->adChannel adaptorContext] hasOpenTransaction] + ? NO : YES; + + adChan = [self beginTransaction]; + pKeys = [self _primaryKeyAttributeNamesForTableName:entityName + channel:adChan]; + + if ((pKeyCnt = [pKeys count]) == 0) { + NSLog(@"ERROR[%s]: missing primary keys for table %@", + __PRETTY_FUNCTION__, entityName); + return nil; + } + qual = [self->fetchSpecification qualifier]; + + if (qual == nil) + qual = [EOQualifier qualifierWithQualifierFormat:@"1=1"]; + + ASSIGN(self->__qualifier, qual); + + attrs = [adChan attributesForTableName:entityName]; + + if (attrs == nil) { + RELEASE(self->__qualifier); self->__qualifier = nil; + + NSLog(@"ERROR[%s]: could not find table '%@' in database.", + __PRETTY_FUNCTION__, entityName); + [self rollbackTransaction]; + return nil; + } + if ([attrs count] == 0) { + RELEASE(self->__qualifier); self->__qualifier = nil; + + NSLog(@"ERROR[%s]: missing columns in table '%@'.", + __PRETTY_FUNCTION__, entityName); + [self rollbackTransaction]; + return nil; + } + tz = [[self->fetchSpecification hints] objectForKey:EOFetchResultTimeZone]; + + ASSIGN(self->__attributes, attrs); + adaptor = [[adChan adaptorContext] adaptor]; + { + NSArray *a; + NSSet *tableKeys = nil; + NSSet *qualifierKeys = nil; + + a = [[[qual allQualifierKeys] allObjects] map:@selector(lowercaseString)]; + qualifierKeys = [[NSSet alloc] initWithArray:a]; + a = [[attrs map:@selector(columnName)] map:@selector(lowercaseString)]; + tableKeys = [[NSSet alloc] initWithArray:a]; + + if ([qualifierKeys isSubsetOfSet:tableKeys] == NO) { + NSString *format = nil; + + format = [NSString stringWithFormat: + @"EOAdaptorDataSource: using unmapped key in " + @"qualifier tableKeys <%@> qualifierKeys <%@> " + @"qualifier <%@>", + tableKeys, qualifierKeys, qual]; + + RELEASE(self->__attributes); self->__attributes = nil; + RELEASE(self->__qualifier); self->__qualifier = nil; + RELEASE(tableKeys); tableKeys = nil; + [self rollbackTransaction]; + [[[InvalidQualifierException alloc] initWithFormat:format] raise]; + } + RELEASE(tableKeys); tableKeys = nil; + RELEASE(qualifierKeys); qualifierKeys = nil; + } + + whereExpr = [self _whereExprWithChannel:adChan]; + selectList = [self _selectListWithChannel:adChan]; + { /* order by expr */ + NSEnumerator *enumerator = nil; + EOSortOrdering *sortOrdering = nil; + int orderCnt = 0; + + enumerator = [[self->fetchSpecification sortOrderings] objectEnumerator]; + + while ((sortOrdering = [enumerator nextObject])) { + SEL selector = NULL; + NSString *key = nil; + EOAttribute *keyAttr = nil; + int order = 0; /* 0 - not used; 1 - asc; 2 - desc */ + BOOL inSensitive = NO; + NSString *orderTmp = nil; + + if (orderByExpr == nil) { + orderByExpr = [NSMutableString stringWithCapacity:64]; + } + else { + [orderByExpr appendString:@", "]; + } + if ((selector = [sortOrdering selector])) { + if (SEL_EQ(selector, EOCompareAscending)) { + order = 1; + } + else if (SEL_EQ(selector, EOCompareDescending)) { + order = 2; + } + else if (SEL_EQ(selector, EOCompareCaseInsensitiveAscending)) { + order = 1; + inSensitive = YES; + } + else if (SEL_EQ(selector, EOCompareCaseInsensitiveDescending)) { + inSensitive = YES; + order = 2; + } + } + key = [sortOrdering key]; + + if (key == nil || [key length] == 0) { + NSLog(@"WARNING[%s]: wrong key in sortordering %@", + __PRETTY_FUNCTION__, key); + continue; + } + { + NSEnumerator *en = nil; + id obj = nil; + + key = [key lowercaseString]; + en = [attrs objectEnumerator]; + while ((obj = [en nextObject])) { + if ([[[(EOAttribute *)obj columnName] lowercaseString] + isEqualToString:key]) + break; + } + if (obj == nil) { + RELEASE(self->__attributes); self->__attributes = nil; + RELEASE(self->__qualifier); self->__qualifier = nil; + RELEASE(expression); expression = nil; + [self rollbackTransaction]; + [[[InvalidAttributeException alloc] + initWithFormat:@"couldn`t find EOAttribute for SortOrdering" + @" %@ Attributes %@", + sortOrdering, attrs] raise]; + } + keyAttr = obj; + } + key = [adaptor formatAttribute:keyAttr]; + orderTmp = [NSString stringWithFormat:@"order_by_expr_%d", orderCnt++]; + [orderByExpr appendString:orderTmp]; + if (order == 1) { + [orderByExpr appendString:@" ASC"]; + } + else if (order == 2) { + [orderByExpr appendString:@" DESC"]; + } + { /* manipulate select expr */ + if (inSensitive) { + if ([[keyAttr valueClassName] isEqualToString:@"NSString"]) { + key = [NSString stringWithFormat:@"LOWER(%@)", key]; + } + else + NSLog(@"WARNING[%s]: inSensitive expression for no text attribute", + __PRETTY_FUNCTION__); + } + { + NSString *str = nil; + + str = [key stringByAppendingString:@" "]; + str = [str stringByAppendingString:orderTmp]; + str = [str stringByAppendingString:@", "]; + + [selectList insertString:str atIndex:0]; + } + } + } + } + expression = [[NSMutableString alloc] initWithCapacity:256]; + [expression appendString:@"SELECT "]; + + if ([self->fetchSpecification usesDistinct]) + [expression appendString:@"DISTINCT "]; + + [expression appendString:selectList]; + [expression appendString:@" FROM "]; + [expression appendString:entityName]; + if ([whereExpr length] > 0) { + [expression appendString:@" WHERE "]; + [expression appendString:whereExpr]; + } + if (orderByExpr != nil && [orderByExpr length] > 0) { + [expression appendString:@" ORDER BY "]; + [expression appendString:orderByExpr]; + } + + if (![adChan evaluateExpression:expression]) { + RELEASE(self->__attributes); self->__attributes = nil; + RELEASE(self->__qualifier); self->__qualifier = nil; + AUTORELEASE(expression); + [adChan cancelFetch]; + [self rollbackTransaction]; + [[[EOAdaptorException alloc] + initWithFormat:@"evaluateExpression of %@ failed", expression] raise]; + } + result = [NSMutableArray arrayWithCapacity:64]; + { + NSMutableDictionary *row = nil; + unsigned fetchCnt = 0; + unsigned fetchLimit = 0; + unsigned attrCnt = 0; + id *values = NULL; + id *keys = NULL; + + attrCnt = [attrs count]; + values = calloc(attrCnt + 2, sizeof(id)); + keys = calloc(attrCnt + 2, sizeof(id)); + fetchLimit = [self->fetchSpecification fetchLimit]; + + while ((row = [adChan fetchAttributes:attrs withZone:NULL])) { + NSEnumerator *enumerator = nil; + id attr = nil; + int rowCnt = 0; + NSDictionary *r = nil; + id *pKeyVs = NULL; + int pKeyVCnt = 0; + + pKeyVs = calloc(pKeyCnt, sizeof(id)); + enumerator = [attrs objectEnumerator]; + + while ((attr = [enumerator nextObject])) { + id obj; + NSString *cn; + + + obj = [row objectForKey:[(EOAttribute *)attr name]]; + + if (obj == nil) + continue; + + if (tz) { + static Class NSCalendarDateClass = nil; + + if (NSCalendarDateClass == nil) + NSCalendarDateClass = [NSCalendarDate class]; + + if ([obj isKindOfClass:NSCalendarDateClass]) { + [obj setTimeZone:tz]; + } + } + cn = [[attr columnName] lowercaseString]; + values[rowCnt] = obj; + keys[rowCnt] = cn; + rowCnt++; + + if ([pKeys containsObject:cn]) { + int idx; + + idx = [pKeys indexOfObject:cn]; + NSAssert4(idx <= (pKeyCnt - 1) && pKeyVs[idx] == nil, + @"internal inconsistency in EOAdaptorDataSource " + @"while fetch idx[%d] > (pKeyCnt - 1)[%d] " + @"pKeyVs[idx] (%@[%d]);", idx, (pKeyCnt - 1), + pKeyVs[idx], idx); + + pKeyVs[idx] = obj; + pKeyVCnt++; + } + } + if (pKeyCnt != pKeyVCnt) + NSAssert(NO, @"internal inconsistency in EOAdaptorDataSource " + @"while fetch"); + + { + EOGlobalID *gid; + + gid = [EOKeyGlobalID globalIDWithEntityName:entityName + keys:pKeyVs keyCount:pKeyVCnt zone:NULL]; + + if (self->connectionDictionary) { + gid = [[EOAdaptorGlobalID alloc] initWithGlobalID:gid + connectionDictionary: + self->connectionDictionary]; + AUTORELEASE(gid); + } + values[rowCnt] = gid; + keys[rowCnt] = @"globalID"; + rowCnt++; + } + fetchCnt++; + r = [[NSMutableDictionary alloc] + initWithObjects:values forKeys:keys count:rowCnt]; + [result addObject:r]; + RELEASE(r); r = nil; + free(pKeyVs); pKeyVs = NULL; + if (fetchLimit == fetchCnt) { + break; + } + } + free(values); values = NULL; + free(keys); keys = NULL; + } + [adChan cancelFetch]; + if (localComTrans) + [self commitTransaction]; + + RELEASE(expression); expression = nil; + RELEASE(self->__qualifier); self->__qualifier = nil; + RELEASE(self->__attributes); self->__attributes = nil; + return result; +} + +- (id)createObject { + return [NSMutableDictionary dictionary]; +} + +- (void)insertObject:(id)_obj { + NSString *key = nil; + NSString *tableName = nil; + NSMutableString *expression = nil; + EOAdaptor *adaptor = nil; + NSArray *pKeys = nil; + id obj = nil; + EOAdaptorChannel *adChan = nil; + + int oVCnt = 0; + NSString **objectKeyAttrValue = NULL; + + NSEnumerator *enumerator = nil; + id pKey = nil; + + BOOL localComTrans; + + if ([[self->adChannel adaptorContext] hasOpenTransaction]) + localComTrans = NO; + else + localComTrans = YES; + + adChan = [self beginTransaction]; + adaptor = [[adChan adaptorContext] adaptor]; + + if ((tableName = [self->fetchSpecification entityName]) == nil) { + [self rollbackTransaction]; + [NSException raise:NSInvalidArgumentException + format:@"couldn`t insert obj %@ missing entityName in " + @"fetchSpecification", _obj]; + } + + /* create or apply primary keys */ +#if EOAdaptorDataSource_DEBUG + NSLog(@"insert obj %@", _obj); +#endif + + pKeys = [self _primaryKeyAttributeNamesForTableName:tableName channel:adChan]; + +#if EOAdaptorDataSource_DEBUG + NSLog(@"got primary keys %@", pKeys); +#endif + + objectKeyAttrValue = calloc([pKeys count], sizeof(id)); + enumerator = [pKeys objectEnumerator]; + + while ((pKey = [enumerator nextObject])) { + id pKeyObj; + + pKeyObj = [_obj valueForKey:pKey]; + +#if EOAdaptorDataSource_DEBUG + NSLog(@"pk in obj %@:<%@> ", pKey, pKeyObj); +#endif + + if (![pKeyObj isNotNull]) { + /* try to build primary key */ + NSString *newKeyExpr = nil; + NSDictionary *row = nil; + +#if EOAdaptorDataSource_DEBUG + NSLog(@"pKeyObj !isNotNull"); +#endif + + if ([pKeys count] != 1) { + [self rollbackTransaction]; + [NSException raise:NSInternalInconsistencyException + format:@"more than one primary key, " + @"and primary key for %@ is not set", pKey]; + } + if (![adaptor respondsToSelector:@selector(newKeyExpression)]) { + [self rollbackTransaction]; + [NSException raise:NSInternalInconsistencyException + format:@"got no newkey expression, insert failed"]; + } + newKeyExpr = [(id)adaptor newKeyExpression]; + if (newKeyExpr == nil) { + [self rollbackTransaction]; + [NSException raise:NSInternalInconsistencyException + format:@"missing newKeyExpression for adaptor[%@] %@...", + NSStringFromClass([adaptor class]), adaptor]; + } + if (![adChan evaluateExpression:newKeyExpr]) { + [adChan cancelFetch]; + [self rollbackTransaction]; + [[[EOAdaptorException alloc] + initWithFormat:@"couldn`t evaluate new key expression %@", + newKeyExpr] raise]; + } + row = [adChan fetchAttributes:[adChan describeResults] + withZone:NULL]; + [adChan cancelFetch]; + if ((key = [[row objectEnumerator] nextObject]) == nil) { + [self rollbackTransaction]; + [[[EOAdaptorException alloc] + initWithFormat:@"couldn`t fetch primary key"] raise];; + } + objectKeyAttrValue[oVCnt++] = key; + [_obj takeValue:key forKey:pKey]; +#if EOAdaptorDataSource_DEBUG + NSLog(@"_obj %@ after takeValue:%@ forKey:%@", _obj, key, pKey); +#endif + } + else { + objectKeyAttrValue[oVCnt++] = pKeyObj; +#if EOAdaptorDataSource_DEBUG + NSLog(@"objectKeyAttrValue takeValue %@ for idx %d", pKeyObj, oVCnt); +#endif + } + } + + /* construct SQL INSERT expression .. */ + + expression = [[NSMutableString alloc] initWithCapacity:256]; + [expression appendString:@"INSERT INTO "]; + [expression appendString:tableName]; + [expression appendString:@"("]; + { + NSDictionary *objects = nil; + NSEnumerator *enumerator = nil; + NSArray *allKeys = nil; + BOOL isFirst = YES; + + objects = [self _mapAttrsWithValues:_obj + tableName:tableName + channel:adChan]; + allKeys = [objects allKeys]; + enumerator = [allKeys objectEnumerator]; + while ((obj = [enumerator nextObject])) { + if (isFirst) + isFirst = NO; + else + [expression appendString:@", "]; + [expression appendString:[adaptor formatAttribute:obj]]; + } + [expression appendString:@") VALUES ("]; + enumerator = [allKeys objectEnumerator]; + isFirst = YES; + while ((obj = [enumerator nextObject])) { + id value; + + if (isFirst) + isFirst = NO; + else + [expression appendString:@", "]; + value = [objects objectForKey:obj]; + if (value == nil) value = null; + [expression appendString:[adaptor formatValue:value forAttribute:obj]]; + } + } + [expression appendString:@")"]; + + /* execute insert in SQL server .. */ + + if (![adChan evaluateExpression:expression]) { + [adChan cancelFetch]; + enumerator = [pKeys objectEnumerator]; + while ((pKey = [enumerator nextObject])) { + [_obj takeValue:[EONull null] forKey:pKey]; + } + [self rollbackTransaction]; + AUTORELEASE(expression); + [[[EOAdaptorException alloc] + initWithFormat:@"evaluateExpression %@ failed", expression] raise]; + } + [adChan cancelFetch]; + if (localComTrans) + [self commitTransaction]; + + /* construct new global id for record */ + + { + EOGlobalID *gid; + + gid = [EOKeyGlobalID globalIDWithEntityName:tableName + keys:objectKeyAttrValue keyCount:oVCnt zone:NULL]; + if (self->connectionDictionary != nil) { + EOAdaptorGlobalID *agid = nil; + + agid = [[EOAdaptorGlobalID alloc] initWithGlobalID:gid + connectionDictionary: + self->connectionDictionary]; + AUTORELEASE(agid); + gid = agid; + } + [_obj takeValue:gid forKey:@"globalID"]; + } + + RELEASE(expression); expression = NULL; + + /* mark datasource as changed */ + + [self postDataSourceChangedNotification]; +} + +- (void)updateObject:(id)_obj { + NSString *whereClause = nil; + NSMutableString *expression = nil; + EOAdaptor *adaptor = nil; + EOKeyGlobalID *gid = nil; + NSEnumerator *enumerator = nil; + NSString *tableName = nil; + EOAttribute *attr = nil; + BOOL isFirst = YES; + NSDictionary *objects = nil; + EOAdaptorChannel *adChan = nil; + + BOOL localComTrans; + + if ((gid = [_obj valueForKey:@"globalID"]) == nil) { + [NSException raise:NSInvalidArgumentException + format:@"missing globalID, couldn`t update"]; + } + if ([gid isKindOfClass:[EOAdaptorGlobalID class]]) { + NSDictionary *conD = nil; + + conD = [(EOAdaptorGlobalID *)gid connectionDictionary]; + if (![conD isEqualToDictionary:self->connectionDictionary]) { + [NSException raise:NSInvalidArgumentException + format:@"try to update object %@ in " + @"wrong AdaptorDataSource %@", _obj, self]; + } + gid = (EOKeyGlobalID *)[(EOAdaptorGlobalID *)gid globalID]; + } + if ([[self->adChannel adaptorContext] hasOpenTransaction]) + localComTrans = NO; + else + localComTrans = YES; + + adChan = [self beginTransaction]; + tableName = [gid entityName]; + adaptor = [[adChan adaptorContext] adaptor]; + whereClause = [self _whereClauseForGlobaID:gid adaptor:adaptor + channel:adChan]; + if (whereClause == nil) { + [self rollbackTransaction]; + return; + } + expression = [[NSMutableString alloc] initWithCapacity:256]; + [expression appendString:@"UPDATE "]; + [expression appendString:[gid entityName]]; + [expression appendString:@" SET "]; + + objects = [self _mapAttrsWithValues:_obj tableName:tableName + channel:adChan]; + enumerator = [objects keyEnumerator]; + + while ((attr = [enumerator nextObject])) { + id value; + + if (isFirst) + isFirst = NO; + else + [expression appendString:@", "]; + [expression appendString:[adaptor formatAttribute:attr]]; + [expression appendString:@"="]; + + value = [objects objectForKey:attr]; + if (value == nil) value = null; + + [expression appendString:[adaptor formatValue:value forAttribute:attr]]; + } + [expression appendString:@" WHERE "]; + [expression appendString:whereClause]; + if (![adChan evaluateExpression:expression]) { + [adChan cancelFetch]; + [self rollbackTransaction]; + AUTORELEASE(expression); + [[[EOAdaptorException alloc] + initWithFormat:@"evaluate expression %@ failed", expression] raise]; + } + [adChan cancelFetch]; + if (localComTrans) + [self commitTransaction]; + + RELEASE(expression); expression = nil; + + { + EOGlobalID *newGID; + NSArray *attrs; + NSEnumerator *enumerator; + id *objs; + int objCnt; + NSString *attr; + + attrs = [self _primaryKeyAttributeNamesForTableName:[gid entityName] + channel:adChan]; + enumerator = [attrs objectEnumerator]; + objCnt = 0; + objs = calloc([attrs count], sizeof(id)); + + while ((attr = [enumerator nextObject])) { + objs[objCnt] = [_obj valueForKey:attr]; + objCnt++; + } + newGID = [EOKeyGlobalID globalIDWithEntityName:[gid entityName] + keys:objs keyCount:objCnt zone:NULL]; + if (self->connectionDictionary != nil) { + newGID = [[EOAdaptorGlobalID alloc] initWithGlobalID:newGID + connectionDictionary: + self->connectionDictionary]; + [newGID autorelease]; + } + [_obj setObject:newGID forKey:@"globalID"]; + } + [self postDataSourceChangedNotification]; +} + +- (void)deleteObject:(NSDictionary *)_obj { + NSString *whereClause = nil; + NSMutableString *expression = nil; + EOKeyGlobalID *gid = nil; + EOAdaptorChannel *adChan = nil; + + BOOL localComTrans; + + if ((gid = [_obj valueForKey:@"globalID"]) == nil) { + [NSException raise:NSInvalidArgumentException + format:@"missing globalID, could not delete"]; + } + if ([gid isKindOfClass:[EOAdaptorGlobalID class]]) { + NSDictionary *conD = nil; + + conD = [(EOAdaptorGlobalID *)gid connectionDictionary]; + if (![conD isEqualToDictionary:self->connectionDictionary]) { + [NSException raise:NSInvalidArgumentException + format:@"try to delete object %@ in wrong " + @"AdaptorDataSource %@", _obj, self]; + } + gid = (EOKeyGlobalID *)[(EOAdaptorGlobalID *)gid globalID]; + } + + if ([[self->adChannel adaptorContext] hasOpenTransaction]) + localComTrans = NO; + else + localComTrans = YES; + + adChan = [self beginTransaction]; + whereClause = [self _whereClauseForGlobaID:gid + adaptor:[[adChan adaptorContext] adaptor] channel:adChan]; + if (whereClause == nil) { + [self rollbackTransaction]; + return; + } + expression = [[NSMutableString alloc] initWithCapacity:256]; + [expression appendString:@"DELETE FROM "]; + [expression appendString:[gid entityName]]; + [expression appendString:@" WHERE "]; + [expression appendString:whereClause]; + if (![adChan evaluateExpression:expression]) { + [adChan cancelFetch]; + [self rollbackTransaction]; + AUTORELEASE(expression); + [[[EOAdaptorException alloc] + initWithFormat:@"couldn`t evaluate expression %@ failed", + expression] raise]; + } + [adChan cancelFetch]; + if (localComTrans) + [self commitTransaction]; + RELEASE(expression); expression = nil; + [self postDataSourceChangedNotification]; +} + +- (void)setFetchSpecification:(EOFetchSpecification *)_fs { + if (![self->fetchSpecification isEqual:_fs]) { +#if DEBUG && 0 + NSLog(@"%s: 0x%08X: fetch-spec mismatch:\n%@\n%@", + __PRETTY_FUNCTION__, self, + self->fetchSpecification, _fs); +#endif + + ASSIGNCOPY(self->fetchSpecification, _fs); + + [self postDataSourceItselfChangedNotification]; + } +#if DEBUG && 0 + else { + NSLog(@"%s: 0x%08X: no fetch-spec mismatch:\n%@\n%@\n", + __PRETTY_FUNCTION__, self, + self->fetchSpecification, _fs); + } +#endif +} + +- (EOFetchSpecification *)fetchSpecification { + return [[self->fetchSpecification copy] autorelease]; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"%@: adaptorChannel: %@", + [super description], self->adChannel]; +} + +@end /* EOAdaptorDataSource */ + +@implementation EOAdaptorDataSource(Private) + +- (NSArray *)_primaryKeyAttributeNamesForTableName:(NSString *)_entityName + channel:(EOAdaptorChannel *)_adChannel +{ + NSDictionary *hints; + NSArray *attrs; + + hints = [self->fetchSpecification hints]; + attrs = [hints objectForKey:EOPrimaryKeyAttributeNamesHint]; + if (attrs) + return attrs; + + attrs = [hints objectForKey:EOPrimaryKeyAttributesHint]; + + if (attrs == nil) { + if (!(attrs = [_adChannel primaryKeyAttributesForTableName:_entityName])) { + attrs = [_adChannel attributesForTableName:_entityName]; + } + } + + attrs = [[attrs map:@selector(columnName)] map:@selector(lowercaseString)]; + attrs = [attrs sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; + + return attrs; +} + +- (NSArray *)_primaryKeyAttributesForTableName:(NSString *)_entityName + channel:(EOAdaptorChannel *)_adChannel +{ + NSArray *attrs; + NSDictionary *hints; + + hints = [self->fetchSpecification hints]; + + attrs = [hints objectForKey:EOPrimaryKeyAttributesHint]; + if (attrs != nil) + return attrs; + + attrs = [hints objectForKey:EOPrimaryKeyAttributeNamesHint]; + if (attrs != nil) { + NSArray *allAttrs; + NSEnumerator *enumerator; + id *objs; + int objCnt; + id obj; + + allAttrs = [_adChannel attributesForTableName:_entityName]; + objs = malloc(sizeof(id) * [allAttrs count]); + enumerator = [allAttrs objectEnumerator]; + + objCnt = 0; + + while ((obj = [enumerator nextObject])) { + if ([attrs containsObject:[[obj columnName] lowercaseString]]) { + objs[objCnt++] = obj; + } + } + attrs = [NSArray arrayWithObjects:objs count:objCnt]; + free(objs); objs = NULL; + return attrs; + } + if (!(attrs = [_adChannel primaryKeyAttributesForTableName:_entityName])) { + attrs = [_adChannel attributesForTableName:_entityName]; + } + return attrs; +} + +- (NSString *)_whereExprWithChannel:(EOAdaptorChannel *)_adChan { + EOQualifier *qual = nil; + NSArray *attrs = nil; + NSString *entityName = nil; + EOAdaptor *adaptor; + + entityName = [self->fetchSpecification entityName]; + + if ((attrs = self->__attributes) == nil) + attrs = [_adChan attributesForTableName:entityName]; + + if ((qual = self->__qualifier) == nil) + qual = [self->fetchSpecification qualifier]; + + if (qual == nil) + return nil; + + adaptor = [[_adChan adaptorContext] adaptor]; + + return [qual sqlExpressionWithAdaptor:adaptor attributes:attrs]; +} + +- (NSMutableString *)_selectListWithChannel:(EOAdaptorChannel *)_adChan { + NSArray *attrs = nil; + NSEnumerator *enumerator = nil; + EOAttribute *attribute = nil; + BOOL first = YES; + NSMutableString *select = nil; + EOAdaptor *adaptor = nil; + NSString *entityName = nil; + + adaptor = [[_adChan adaptorContext] adaptor]; + entityName = [self->fetchSpecification entityName]; + + if ((attrs = self->__attributes) == nil) + attrs = [_adChan attributesForTableName:entityName]; + + attrs = [_adChan _sortAttributesForSelectExpression:attrs]; + select = [NSMutableString stringWithCapacity:128]; + enumerator = [attrs objectEnumerator]; + while ((attribute = [enumerator nextObject])) { + if (first) + first = NO; + else + [select appendString:@", "]; + + [select appendString:[adaptor formatAttribute:attribute]]; + } + return select; +} + +- (NSString *)_whereClauseForGlobaID:(EOKeyGlobalID *)_gid + adaptor:(EOAdaptor *)_adaptor + channel:(EOAdaptorChannel *)_adChan +{ + NSEnumerator *enumerator; + NSMutableString *result; + NSArray *pKeys; + NSArray *pkAttrs; + NSString *pKey; + int pkCnt; + + + pKeys = [self _primaryKeyAttributeNamesForTableName:[_gid entityName] + channel:_adChan]; + pkAttrs = [self _primaryKeyAttributesForTableName:[_gid entityName] + channel:_adChan]; + + + if ([pKeys count] != [_gid keyCount]) { + NSLog(@"ERROR[%s]: internal inconsitency pkeys %@ gid %@", + __PRETTY_FUNCTION__, pKeys, _gid); + return nil; + } + enumerator = [pKeys objectEnumerator]; + + pkCnt = 0; + result = nil; + while ((pKey = [enumerator nextObject])) { + EOAttribute *attr; + id value; + + if (result == nil) + result = [NSMutableString stringWithCapacity:128]; + else + [result appendString:@" AND "]; + + { + NSEnumerator *enumerator; + + enumerator = [pkAttrs objectEnumerator]; + while ((attr = [enumerator nextObject])) { + if ([[[attr columnName] lowercaseString] isEqual:pKey]) + break; + } + NSAssert2(attr != nil, @"missing attribute for pkName %@ attrs %@", + pKey, pkAttrs); + } + [result appendString:[_adaptor formatAttribute:attr]]; + + + value = [(EOKeyGlobalID *)_gid keyValues][pkCnt++]; + if (value == nil) value = null; + + [result appendString:[value isNotNull] ? @"=" : @" IS "]; + [result appendString:[_adaptor formatValue:value forAttribute:attr]]; + } + return result; +} + +- (NSDictionary *)_mapAttrsWithValues:(id)_keyValues + tableName:(NSString *)_tableName + channel:(EOAdaptorChannel *)_adChan +{ + id *keys, *values; + int mapCnt; + NSEnumerator *en; + EOAttribute *attr; + NSDictionary *result; + NSArray *attrs; + + attrs = [_adChan attributesForTableName:_tableName]; + mapCnt = [attrs count]; + keys = calloc(mapCnt, sizeof(id)); + values = calloc(mapCnt, sizeof(id)); + en = [attrs objectEnumerator]; + mapCnt = 0; + + while ((attr = [en nextObject])) { + id v; + + v = (v = [_keyValues valueForKey:[[attr columnName] lowercaseString]]) + ? v : null; + + keys[mapCnt] = attr; + values[mapCnt] = v; + mapCnt++; + } + result = [[NSDictionary alloc] + initWithObjects:values forKeys:keys count:mapCnt]; + free(keys); keys = NULL; + free(values); values = NULL; + return [result autorelease]; +} + +@end /* EOAdaptorDataSource(Private) */ + +@implementation EOAndQualifier(SqlExpression) + +- (NSString *)sqlExpressionWithAdaptor:(EOAdaptor *)_adaptor + attributes:(NSArray *)_attributes +{ + NSMutableString *str = nil; + NSEnumerator *enumerator = nil; + EOQualifier *qual = nil; + BOOL isFirst = YES; + NSString *result = nil; + + str = [[NSMutableString alloc] initWithCapacity:128]; + + enumerator = [self->qualifiers objectEnumerator]; + while ((qual = [enumerator nextObject])) { + NSString *s; + + s = [qual sqlExpressionWithAdaptor:_adaptor attributes:_attributes]; + if (isFirst) { + [str appendFormat:@"(%@)", s]; + isFirst = NO; + } + else + [str appendFormat:@" AND (%@)", s]; + } + result = [str copy]; + [str release]; str = nil; + return [result autorelease]; +} +@end /* EOAndQualifier(SqlExpression) */ + +@implementation EOOrQualifier(SqlExpression) + +- (NSString *)sqlExpressionWithAdaptor:(EOAdaptor *)_adaptor + attributes:(NSArray *)_attributes +{ + NSMutableString *str = nil; + NSEnumerator *enumerator = nil; + EOQualifier *qual = nil; + BOOL isFirst = YES; + NSString *result = nil; + + str = [[NSMutableString alloc] initWithCapacity:128]; + + enumerator = [self->qualifiers objectEnumerator]; + while ((qual = [enumerator nextObject])) { + NSString *s; + + s = [qual sqlExpressionWithAdaptor:_adaptor attributes:_attributes]; + if (isFirst) { + [str appendFormat:@"(%@)", s]; + isFirst = NO; + } + else + [str appendFormat:@" OR (%@)", s]; + } + result = [str copy]; + [str release]; str = nil; + return [result autorelease]; +} + +@end /* EOOrQualifier(SqlExpression) */ + +@implementation EOKeyValueQualifier(SqlExpression) + ++ (NSString *)sqlStringForOperatorSelector:(SEL)_sel { + static NSMapTable *selectorToOperator = NULL; + NSString *s, *ss; + + if ((s = NSStringFromSelector(_sel)) == nil) + return nil; + + if (selectorToOperator == NULL) { + selectorToOperator = NSCreateMapTable(NSObjectMapKeyCallBacks, + NSObjectMapValueCallBacks, + 10); + NSMapInsert(selectorToOperator, + NSStringFromSelector(EOQualifierOperatorEqual), + @"="); + NSMapInsert(selectorToOperator, + NSStringFromSelector(EOQualifierOperatorNotEqual), + @"<>"); + NSMapInsert(selectorToOperator, + NSStringFromSelector(EOQualifierOperatorLessThan), + @"<"); + NSMapInsert(selectorToOperator, + NSStringFromSelector(EOQualifierOperatorGreaterThan), + @">"); + NSMapInsert(selectorToOperator, + NSStringFromSelector(EOQualifierOperatorLessThanOrEqualTo), + @"<="); + NSMapInsert(selectorToOperator, + NSStringFromSelector(EOQualifierOperatorGreaterThanOrEqualTo), + @">="); + } + + if ((ss = NSMapGet(selectorToOperator, s))) + return ss; + + return nil; +} + +- (NSString *)sqlExpressionWithAdaptor:(EOAdaptor *)_adaptor + attributes:(NSArray *)_attributes +{ + EOAttribute *attr = nil; + NSEnumerator *en = nil; + NSString *k = nil; + NSString *sql = nil; + NSString *sqlKey, *sqlValue; + + k = [self->key lowercaseString]; + en = [_attributes objectEnumerator]; + + while ((attr = [en nextObject])) { + if ([[[attr columnName] lowercaseString] isEqualToString:k]) { + break; + } + } + if (!attr) { + en = [_attributes objectEnumerator]; + while ((attr = [en nextObject])) { + if ([[attr name] isEqualToString:self->key]) + break; + } + } + if (!attr) { + NSLog(@"WARNING[%s]: missing attribute [%@] for qualifier %@", + __PRETTY_FUNCTION__, + _attributes, self); + return @"1=2"; + } + + sqlKey = [_adaptor formatAttribute:attr]; + + sqlValue = [_adaptor formatValue:self->value ? self->value : null + forAttribute:attr]; + + sql = nil; + + if (SEL_EQ(EOQualifierOperatorEqual, self->operator)) { + if ([self->value isNotNull]) + sql = [NSString stringWithFormat:@"%@ = %@", sqlKey, sqlValue]; + else + sql = [NSString stringWithFormat:@"%@ IS NULL", sqlKey]; + } + else if (SEL_EQ(EOQualifierOperatorNotEqual, self->operator)) { + if ([self->value isNotNull]) + sql = [NSString stringWithFormat:@"NOT (%@ = %@)", sqlKey, sqlValue]; + else + sql = [NSString stringWithFormat:@"%@ IS NOT NULL", sqlKey]; + } + else if (SEL_EQ(EOQualifierOperatorLessThan, self->operator)) { + sql = [NSString stringWithFormat:@"%@ < %@", sqlKey, sqlValue]; + } + else if (SEL_EQ(EOQualifierOperatorLessThanOrEqualTo, self->operator)) { + sql = [NSString stringWithFormat:@"%@ <= %@", sqlKey, sqlValue]; + } + else if (SEL_EQ(EOQualifierOperatorGreaterThan, self->operator)) { + sql = [NSString stringWithFormat:@"%@ > %@", sqlKey, sqlValue]; + } + else if (SEL_EQ(EOQualifierOperatorGreaterThanOrEqualTo, self->operator)) { + sql = [NSString stringWithFormat:@"%@ >= %@", sqlKey, sqlValue]; + } + else if (SEL_EQ(EOQualifierOperatorLike, self->operator)) { + sqlValue = [[self->value stringValue] + stringByReplacingString:@"*" withString:@"%"]; + sqlValue = [_adaptor formatValue:sqlValue forAttribute:attr]; + + sql = [NSString stringWithFormat:@"%@ LIKE %@", sqlKey, sqlValue]; + } + else if (SEL_EQ(EOQualifierOperatorCaseInsensitiveLike, self->operator)) { + sqlValue = [[self->value stringValue] + stringByReplacingString:@"*" withString:@"%"]; + sqlValue = [sqlValue lowercaseString]; + sqlValue = [_adaptor formatValue:sqlValue forAttribute:attr]; + + sql = [NSString stringWithFormat:@"LOWER(%@) LIKE %@", sqlKey, sqlValue]; + } +#if 0 + else if (SEL_EQ(EOQualifierOperatorLessThanOrEqualTo, self->operator)) { + } + else if (SEL_EQ(EOQualifierOperatorGreaterThanOrEqualTo, self->operator)) { + } +#endif + else { + NSLog(@"ERROR(%s): unsupported SQL operator: %@", __PRETTY_FUNCTION__, + [EOQualifier stringForOperatorSelector:self->operator]); + [self notImplemented:_cmd]; + return nil; + } + + return sql; +} + +@end /* EOKeyValueQualifier(SqlExpression) */ + +@implementation EONotQualifier(SqlExpression) + +- (NSString *)sqlExpressionWithAdaptor:(EOAdaptor *)_adaptor + attributes:(NSArray *)_attributes +{ + NSString *s; + + s = [self->qualifier sqlExpressionWithAdaptor:_adaptor + attributes:_attributes]; + return [NSString stringWithFormat:@"NOT(%@)", s]; +} + +@end /* EONotQualifier(SqlExpression) */ + +@implementation EOKeyComparisonQualifier(SqlExpression) + +- (NSString *)sqlExpressionWithAdaptor:(EOAdaptor *)_adaptor + attributes:(NSArray *)_attributes +{ + NSLog(@"ERROR(%s): subclass needs to override this method!", + __PRETTY_FUNCTION__); + return nil; +} + +@end /* EOKeyComparisonQualifier(SqlExpression) */ diff --git a/sope-gdl1/GDLAccess/EOAdaptorGlobalID.m b/sope-gdl1/GDLAccess/EOAdaptorGlobalID.m new file mode 100644 index 00000000..8682a6df --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAdaptorGlobalID.m @@ -0,0 +1,86 @@ +/* + EOArrayProxy.h + + Copyright (C) 1999 MDlink online service center GmbH, Helge Hess + + Author: Helge Hess (hh@mdlink.de) + Date: 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAdaptorGlobalID.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include "common.h" + +@implementation EOAdaptorGlobalID + +- (id)initWithGlobalID:(EOGlobalID *)_gid + connectionDictionary:(NSDictionary *)_conDict +{ + if ((self = [super init])) { + ASSIGN(self->gid, _gid); + ASSIGN(self->conDict, _conDict); + } + return self; +} + +- (void)dealloc { + RELEASE(self->gid); + RELEASE(self->conDict); + [super dealloc]; +} + +- (EOGlobalID *)globalID { + return self->gid; +} + +- (NSDictionary *)connectionDictionary { + return self->conDict; +} + +/* NSCopying */ + +- (id)copyWithZone:(NSZone *)_zone { + return RETAIN(self); +} + +/* equality */ + +- (BOOL)isEqual:(id)_obj { + if ([_obj isKindOfClass:[EOAdaptorGlobalID class]]) + return [self isEqualToEOAdaptorGlobalID:_obj]; + return NO; +} + +- (BOOL)isEqualToEOAdaptorGlobalID:(EOAdaptorGlobalID *)_gid { + if ([[_gid globalID] isEqual:self->gid] && + [[_gid connectionDictionary] isEqual:self->conDict]) + return YES; + + return NO; +} + +/* description */ + +- (NSString *)description { + return [NSString stringWithFormat:@"%@: globalID: %@ connectionDictionary: %@", + [super description], self->gid, self->conDict]; +} + +@end /* SkyDBGlobalKey */ diff --git a/sope-gdl1/GDLAccess/EOAdaptorOperation.m b/sope-gdl1/GDLAccess/EOAdaptorOperation.m new file mode 100644 index 00000000..7d685653 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAdaptorOperation.m @@ -0,0 +1,32 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAdaptorOperation.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include "common.h" + +@implementation EOAdaptorOperation +@end /* EOAdaptorOperation */ diff --git a/sope-gdl1/GDLAccess/EOAndQualifier+SQL.m b/sope-gdl1/GDLAccess/EOAndQualifier+SQL.m new file mode 100644 index 00000000..3df7e9d7 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAndQualifier+SQL.m @@ -0,0 +1,72 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// $Id: EOAndQualifier+SQL.m 1 2004-08-20 10:38:46Z znek $ + +#import "EOSQLQualifier.h" +#include "common.h" + +@implementation EOAndQualifier(SQLQualifier) + +/* SQL qualifier generation */ + +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity { + unsigned cc = [self->qualifiers count]; + + if (cc == 0) { + return nil; + } + else if (cc == 1) { + return [[self->qualifiers objectAtIndex:0] sqlQualifierForEntity:_entity]; + } + else if (cc == 2) { + id left; + id right; + + left = [[self->qualifiers objectAtIndex:0] sqlQualifierForEntity:_entity]; + right = [[self->qualifiers objectAtIndex:1] sqlQualifierForEntity:_entity]; + [left conjoinWithQualifier:right]; + return left; + } + else { + EOSQLQualifier *masterQ; + unsigned i; + + for (i = 0, masterQ = nil; i < cc; i++) { + EOSQLQualifier *q; + + q = [[self->qualifiers objectAtIndex:i] + sqlQualifierForEntity:_entity]; + if (masterQ == nil) + masterQ = q; + else + [masterQ conjoinWithQualifier:q]; + } + return masterQ; + } +} + +@end /* EOAndQualifier */ diff --git a/sope-gdl1/GDLAccess/EOArrayProxy.m b/sope-gdl1/GDLAccess/EOArrayProxy.m new file mode 100644 index 00000000..2a5eca96 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOArrayProxy.m @@ -0,0 +1,213 @@ +/* + EOArrayProxy.m + + Copyright (C) 1999 MDlink online service center GmbH, Helge Hess + + Author: Helge Hess (hh@mdlink.de) + Date: 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOArrayProxy.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import "EOArrayProxy.h" +#import "EODatabaseChannel.h" +#import "EODatabaseContext.h" +#import "EOEntity.h" +#import "EOSQLQualifier.h" +#import "EOGenericRecord.h" + +@implementation EOArrayProxy + +- (id)initWithQualifier:(EOSQLQualifier *)_qualifier + fetchOrder:(NSArray *)_fetchOrder + channel:(EODatabaseChannel *)_channel +{ + self->qualifier = RETAIN(_qualifier); + self->fetchOrder = RETAIN(_fetchOrder); + self->channel = RETAIN(_channel); + return self; +} + ++ (id)arrayProxyWithQualifier:(EOSQLQualifier *)_qualifier + fetchOrder:(NSArray *)_fetchOrder + channel:(EODatabaseChannel *)_channel +{ + return AUTORELEASE([[self alloc] initWithQualifier:_qualifier + fetchOrder:_fetchOrder + channel:_channel]); +} + +- (void)dealloc { + AUTORELEASE(self->content); + RELEASE(self->qualifier); + RELEASE(self->fetchOrder); + RELEASE(self->channel); + [super dealloc]; +} + +// accessors + +- (BOOL)isFetched { + return self->content ? YES : NO; +} + +- (EODatabaseChannel *)databaseChannel { + return self->channel; +} +- (EOEntity *)entity { + return [self->qualifier entity]; +} +- (NSArray *)fetchOrder { + return self->fetchOrder; +} +- (EOSQLQualifier *)qualifier { + return self->qualifier; +} + +// operations + +- (void)clear { + RELEASE(self->content); + self->content = nil; +} + +- (BOOL)fetch { + BOOL inTransaction; + BOOL didOpenChannel; + NSMutableArray *result; + + [self clear]; + result = [NSMutableArray arrayWithCapacity:16]; + + didOpenChannel = (![self->channel isOpen]) + ? [self->channel openChannel] + : NO; + + if ([self->channel isFetchInProgress]) { + [NSException raise:NSInvalidArgumentException + format:@"attempt to fetch with busy channel: %@", self]; + } + + inTransaction = + [[self->channel databaseContext] transactionNestingLevel] > 0; + if (!inTransaction) { + if (![[self->channel databaseContext] beginTransaction]) { + NSLog(@"WARNING: could not begin transaction to fetch array proxy !"); + + if (didOpenChannel) + [self->channel closeChannel]; + return NO; + } + } + + if (![self->channel selectObjectsDescribedByQualifier:self->qualifier + fetchOrder:self->fetchOrder]) { + if (!inTransaction) + [[self->channel databaseContext] rollbackTransaction]; + if (didOpenChannel) + [self->channel closeChannel]; + + NSLog(@"ERROR: select on array proxy failed .."); + return NO; + } + + { // fetch objects + NSZone *z = [self zone]; + id object; + + while ((object = [self->channel fetchWithZone:z])) + [result addObject:object]; + object = nil; + } + [self->channel cancelFetch]; + + if (!inTransaction) { + if (![[self->channel databaseContext] commitTransaction]) { + NSLog(@"WARNING: could not commit array proxy's transaction !"); + + if (didOpenChannel) + [self->channel closeChannel]; + return NO; + } + } + + if (didOpenChannel) + [self->channel closeChannel]; + + self->content = [result copyWithZone:[self zone]]; + return YES; +} + +// turn fault to real array .. + +void _checkFetch(EOArrayProxy *self) { + if (self->content) return; + [self fetch]; +} + +// NSArray operations + +- (id)objectAtIndex:(unsigned int)_index { + _checkFetch(self); + return [self->content objectAtIndex:_index]; +} +- (unsigned int)count { + _checkFetch(self); + return [self->content count]; +} +- (unsigned int)indexOfObjectIdenticalTo:(id)_object { + _checkFetch(self); + return [self->content indexOfObjectIdenticalTo:_object]; +} + +// NSCopying + +- (id)copyWithZone:(NSZone*)zone { + if (NSShouldRetainWithZone(self, zone)) + return RETAIN(self); + else { + _checkFetch(self); + return [[NSArray allocWithZone:zone] initWithArray:self->content copyItems:NO]; + } +} + +- (id)mutableCopyWithZone:(NSZone*)zone { + _checkFetch(self); + return [[NSMutableArray alloc] initWithArray:self->content]; +} + + +#if 0 + +// forwarding + +- (void)forwardInvocation:(NSInvocation *)_invocation { + _checkFetch(self); + [_invocation invokeWithTarget:self->content]; +} + +- (retval_t)forward:(SEL)_selector:(arglist_t)_frame { + _checkFetch(self); + return objc_msg_sendv(self->content, _selector, _frame); +} + +#endif + +@end diff --git a/sope-gdl1/GDLAccess/EOAttribute.m b/sope-gdl1/GDLAccess/EOAttribute.m new file mode 100644 index 00000000..59a72be1 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAttribute.m @@ -0,0 +1,729 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// $Id: EOAttribute.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import "EOAttribute.h" +#import "EOModel.h" +#import "EOEntity.h" +#import "EORelationship.h" +#import "EOExpressionArray.h" +#import "EOCustomValues.h" +#import +#import "EOFExceptions.h" + +@interface NSString(BeautifyAttributeName) + +- (NSString *)_beautifyAttributeName; + +@end + +@implementation EOAttribute + +static NSString *defaultCalendarFormat = @"%b %d %Y %H:%M"; +static EONull *null = nil; + ++ (void)initialize { + if (null == nil) + null = [[EONull null] retain]; +} + +- (id)initWithName:(NSString*)_name { + if ((self = [super init])) { + ASSIGN(self->name,_name); + self->entity = nil; + } + return self; +} +- (id)init { + return [self initWithName:nil]; +} + +- (void)dealloc { + RELEASE(self->name); + RELEASE(self->calendarFormat); + RELEASE(self->clientTimeZone); + RELEASE(self->serverTimeZone); + RELEASE(self->columnName); + RELEASE(self->definition); + RELEASE(self->externalType); + RELEASE(self->valueClassName); + RELEASE(self->valueType); + RELEASE(self->insertFormat); + RELEASE(self->selectFormat); + RELEASE(self->updateFormat); + RELEASE(self->userDictionary); + self->entity = nil; /* non-retained */ + RELEASE(self->definitionArray); + RELEASE(self->realAttribute); + [super dealloc]; +} + +// These methods should be here to let the library work with NeXT foundation +- (id)copy { + return RETAIN(self); +} +- (id)copyWithZone:(NSZone *)_zone { + return RETAIN(self); +} + +// Is equal only if same name; used to make aliasing ordering stable +- (unsigned)hash { + return [self->name hash]; +} + +- (BOOL)setName:(NSString*)_name { + if([name isEqual:_name]) + return YES; + + if([entity attributeNamed:_name]) + return NO; + + ASSIGN(name, _name); + return YES; +} + ++ (BOOL)isValidName:(NSString*)_name { + return [EOEntity isValidName:_name]; +} + +- (BOOL)setReadOnly:(BOOL)flag { + if(!flag && ([self isDerived] || [self isFlattened])) + return NO; + flags.isReadOnly = flag; + return YES; +} + +- (BOOL)referencesProperty:(id)property { + return (flags.isDerived) + ? [self->definitionArray indexOfObject:property] != NSNotFound + : NO; +} + +- (void)setDefinition:(NSString *)def { + NSArray *defArray; + int i, count; + EOEntity *currentEntity; + id realAttributeName; + + if (def == nil) { + [NSException raise:NSInvalidArgumentException + format:@"invalid (nil) definition argument!"]; + } + + self->flags.isDerived = YES; + self->flags.isFlattened = NO; + + ASSIGN(self->definition, def); + + if ([definition isNameOfARelationshipPath]) { + self->flags.isFlattened = YES; + defArray = [definition componentsSeparatedByString:@"."]; + count = [defArray count]; + + RELEASE(self->definitionArray); + self->definitionArray = [[NSMutableArray alloc] initWithCapacity:count]; + + NS_DURING { + currentEntity = self->entity; + + for (i = 0; i < count - 1; i++) { + id relationshipName, relationship; + + relationshipName = [defArray objectAtIndex:i]; + + if(![EOEntity isValidName:relationshipName]) { + [[[InvalidNameException alloc] + initWithName:relationshipName] raise]; + } + + relationship + = [currentEntity relationshipNamed:relationshipName]; + + if(relationship == nil) { + [[[InvalidPropertyException alloc] + initWithName:relationshipName entity:currentEntity] raise]; + } + if([relationship isToMany]) { + [[[RelationshipMustBeToOneException alloc] + initWithName:relationshipName entity:currentEntity] raise]; + } + [self->definitionArray addObject:relationship]; + currentEntity = [relationship destinationEntity]; + } + realAttributeName = [defArray lastObject]; + + RELEASE(self->realAttribute); + self->realAttribute = + RETAIN([currentEntity attributeNamed:realAttributeName]); + if (self->realAttribute == nil) { + [[[InvalidPropertyException alloc] + initWithName:realAttributeName entity:currentEntity] raise]; + } + [self->definitionArray addObject:self->realAttribute]; + } + NS_HANDLER { + RELEASE(self->definitionArray); + self->definitionArray = nil; + [localException raise]; + } + NS_ENDHANDLER; + } + else { + [self->definitionArray release]; + self->definitionArray = nil; + self->definitionArray + = [[EOExpressionArray parseExpression:definition + entity:entity + replacePropertyReferences:YES] + retain]; + } +} + +- (NSString *)expressionValueForContext:(id)context { + return (context) + ? [context expressionValueForAttribute:self] + : columnName; +} + +- (void)setEntity:(EOEntity*)_entity { + self->entity = _entity; /* non-retained */ +} +- (EOEntity *)entity { + return self->entity; +} +- (void)resetEntity { + self->entity = nil; +} +- (BOOL)hasEntity { + return (self->entity != nil) ? YES : NO; +} + +- (void)setCalendarFormat:(NSString*)format { + ASSIGN(self->calendarFormat, format); +} +- (NSString *)calendarFormat { + return self->calendarFormat; +} + +- (void)setClientTimeZone:(NSTimeZone*)tz { + ASSIGN(self->clientTimeZone, tz); +} +- (NSTimeZone *)clientTimeZone { + return self->clientTimeZone; +} + +- (void)setServerTimeZone:(NSTimeZone*)tz { + ASSIGN(self->serverTimeZone, tz); +} +- (NSTimeZone *)serverTimeZone { + return self->serverTimeZone; +} + +- (void)setColumnName:(NSString*)_name { + ASSIGN(self->columnName, _name); +} +- (NSString *)columnName { + return self->columnName; +} + +- (void)setExternalType:(NSString*)type { + ASSIGN(self->externalType, type); +} +- (NSString *)externalType { + return ((self->externalType == nil) && self->flags.isFlattened) + ? [self->realAttribute externalType] + : self->externalType; +} + +- (void)setValueClassName:(NSString *)_name { + ASSIGN(self->valueClassName, _name); +} +- (NSString *)valueClassName { + return ((self->valueClassName == nil) && self->flags.isFlattened) + ? [self->realAttribute valueClassName] + : self->valueClassName; +} + +- (void)setValueType:(NSString *)type { + ASSIGN(self->valueType, type); +} +- (NSString *)valueType { + return ((self->valueType == nil) && self->flags.isFlattened) + ? [self->realAttribute valueType] + : self->valueType; +} + +- (void)setInsertFormat:(NSString *)string { + ASSIGN(self->insertFormat, string); +} +- (NSString *)insertFormat { + return self->insertFormat; +} + +- (void)setSelectFormat:(NSString *)string { + ASSIGN(self->selectFormat, string); +} +- (NSString *)selectFormat { + return self->selectFormat; +} + +- (void)setUpdateFormat:(NSString*)string { + ASSIGN(self->updateFormat, string); +} +- (NSString *)updateFormat { + return self->updateFormat; +} + +- (void)setUserDictionary:(NSDictionary *)dict { + ASSIGN(self->userDictionary, dict); +} +- (NSDictionary *)userDictionary { + return self->userDictionary; +} + ++ (NSString *)defaultCalendarFormat { + return defaultCalendarFormat; +} +- (NSString *)name { + return self->name; +} +- (NSString *)definition { + return self->definition; +} +- (NSMutableArray *)definitionArray { + return self->definitionArray; +} +- (BOOL)isDerived { + return self->flags.isDerived; +} +- (BOOL)isFlattened { + return self->flags.isFlattened; +} + +- (BOOL)isReadOnly { + return self->flags.isDerived ? YES : self->flags.isReadOnly; +} + +/* description */ + +- (NSString *)description { + return [[self propertyList] description]; +} + +@end /* EOAttribute */ + + +@implementation EOAttribute (EOAttributePrivate) + ++ (EOAttribute*)attributeFromPropertyList:(id)propertyList { + EOAttribute *attribute = nil; + NSString *timeZoneName; + id tmp; + + attribute = [[EOAttribute alloc] init]; + AUTORELEASE(attribute); + + [attribute setName:[propertyList objectForKey:@"name"]]; + [attribute setCalendarFormat:[propertyList objectForKey:@"calendarFormat"]]; + + timeZoneName = [propertyList objectForKey:@"clientTimeZone"]; + if (timeZoneName) + [attribute setClientTimeZone:[NSTimeZone timeZoneWithName:timeZoneName]]; + + timeZoneName = [propertyList objectForKey:@"serverTimeZone"]; + if (timeZoneName) + [attribute setServerTimeZone:[NSTimeZone timeZoneWithName:timeZoneName]]; + + [attribute setColumnName: [propertyList objectForKey:@"columnName"]]; + [attribute setExternalType: [propertyList objectForKey:@"externalType"]]; + [attribute setValueClassName:[propertyList objectForKey:@"valueClassName"]]; + [attribute setValueType: [propertyList objectForKey:@"valueType"]]; + [attribute setInsertFormat: [propertyList objectForKey:@"insertFormat"]]; + [attribute setSelectFormat: [propertyList objectForKey:@"selectFormat"]]; + [attribute setUpdateFormat: [propertyList objectForKey:@"updateFormat"]]; + [attribute setUserDictionary:[propertyList objectForKey:@"userDictionary"]]; + + [attribute setReadOnly: + [[propertyList objectForKey:@"isReadOnly"] isEqual:@"Y"]]; + + if ((tmp = [propertyList objectForKey:@"allowsNull"])) + [attribute setAllowsNull:[tmp isEqual:@"Y"]]; + else + [attribute setAllowsNull:YES]; + + [attribute setWidth: + [[propertyList objectForKey:@"width"] unsignedIntValue]]; + + /* Don't call setDefinition: now. The attributes array in + entity is not yet set. */ + attribute->definition = RETAIN([propertyList objectForKey:@"definition"]); + + return attribute; +} + +/* WARNING: You should call this method from entity after the relationships + were constructed and after the `attributes' array contains the real + attributes. */ +- (void)replaceStringsWithObjects { + if(self->definition) { + NS_DURING + [self setDefinition:self->definition]; + NS_HANDLER { + //CATCH(PropertyDefinitionException) + NSLog([localException reason]); + [[self->entity model] errorInReading]; + } + NS_ENDHANDLER; + } +} + +- (id)propertyList { + NSMutableDictionary *propertyList; + + propertyList = [NSMutableDictionary dictionaryWithCapacity:16]; + [self encodeIntoPropertyList:propertyList]; + return propertyList; +} + +- (int)compareByName:(EOAttribute *)_other { + return [[(EOAttribute *)self name] compare:[_other name]]; +} + +@end /* EOAttribute (EOAttributePrivate) */ + +@implementation EOAttribute(ValuesConversion) + +- (id)convertValue:(id)aValue toClass:(Class)aClass forType:(NSString*)_type { + // Check nil/EONull + if (aValue == nil) + return nil; + if (aValue == [EONull null]) + return aValue; + + // Check if we need conversion; we use is kind of because + // a string is not a NSString but some concrete class, so is NSData, + // NSNumber and may be other classes + if ([aValue isKindOfClass:aClass]) + return aValue; + + // We have to convert the aValue + + // Try EOCustomValues + if ([aValue respondsToSelector:@selector(stringForType:)]) { + // Special case if aClass is NSNumber + if (aClass == [NSNumber class]) { + return [NSNumber + numberWithString:[aValue stringForType:_type] + type:_type]; + } + + // Even more Special case if aClass is NSCalendar date + if (aClass == [NSCalendarDate class]) { + id format, date; + + format = [self calendarFormat]; + if (format == nil) + format = [EOAttribute defaultCalendarFormat]; + date = [NSCalendarDate + dateWithString:[aValue stringForType:_type] + calendarFormat:format]; + [date setCalendarFormat:format]; + return date; + } + + // See if we can alloc a new aValue and initilize it + if ([aClass instancesRespondToSelector: + @selector(initWithString:type:)]) { + return AUTORELEASE([[aClass alloc] + initWithString:[aValue stringForType:_type] + type:_type]); + } + } + + // Try EODatabaseCustomValues + if ([aValue respondsToSelector:@selector(dataForType:)]) { + // See if we can alloc a new aValue and initilize it + if ([aClass instancesRespondToSelector: + @selector(initWithData:type:)]) { + return AUTORELEASE([[aClass alloc] + initWithData:[aValue dataForType:_type] + type:_type]); + } + } + + // Could not convert if got here + return nil; +} + +- (id)convertValueToModel:(id)aValue { + id aValueClassName; + Class aValueClass; + + // Check value class from attribute + aValueClassName = [self valueClassName]; + aValueClass = NSClassFromString(aValueClassName); + if (aValueClass == Nil) + return aValue; + + return [self convertValue:aValue + toClass:aValueClass forType:[self valueType]]; +} + +@end + +@implementation NSString (EOAttributeTypeCheck) + +- (BOOL)isNameOfARelationshipPath { + BOOL result = NO; + char buf[[self cStringLength] + 1]; + const char *s; + + s = buf; + [self getCString:buf]; + + if(!isalnum((int)*s) && *s != '@' && *s != '_' && *s != '#') + return NO; + + for(++s; *s; s++) { + if(!isalnum((int)*s) && *s != '@' && *s != '_' && *s != '#' && *s != '$' + && *s != '.') + return NO; + if(*s == '.') + result = YES; + } + + return result; +} + +@end + +@implementation EOAttribute(PropertyListCoding) + +static inline void _addToPropList(NSMutableDictionary *propertyList, + id _value, NSString *key) { + if (_value) [propertyList setObject:_value forKey:key]; +} + +- (void)encodeIntoPropertyList:(NSMutableDictionary *)_plist { + _addToPropList(_plist, self->name, @"name"); + _addToPropList(_plist, self->calendarFormat, @"calendarFormat"); + _addToPropList(_plist, self->columnName, @"columnName"); + _addToPropList(_plist, self->definition, @"definition"); + _addToPropList(_plist, self->externalType, @"externalType"); + _addToPropList(_plist, self->valueClassName, @"valueClassName"); + _addToPropList(_plist, self->valueType, @"valueType"); + _addToPropList(_plist, self->insertFormat, @"insertFormat"); + _addToPropList(_plist, self->selectFormat, @"selectFormat"); + _addToPropList(_plist, self->updateFormat, @"updateFormat"); + _addToPropList(_plist, self->userDictionary, @"userDictionary"); + + if (self->clientTimeZone) { + [_plist setObject:[self->clientTimeZone timeZoneName] + forKey:@"clientTimeZone"]; + } + if (self->serverTimeZone) { + [_plist setObject:[self->serverTimeZone timeZoneName] + forKey:@"serverTimeZone"]; + } + + if (self->width != 0) { + [_plist setObject:[NSNumber numberWithUnsignedInt:self->width] + forKey:@"width"]; + } + + if (self->flags.isReadOnly) { + [_plist setObject:[NSString stringWithCString:"Y"] + forKey:@"isReadOnly"]; + } + if (self->flags.allowsNull) { + [_plist setObject:[NSString stringWithCString:"Y"] + forKey:@"allowsNull"]; + } +} + +@end /* EOAttribute(PropertyListCoding) */ + +@implementation EOAttribute(EOF2Additions) + +- (void)beautifyName { + [self setName:[[self name] _beautifyAttributeName]]; +} + +/* constraints */ + +- (void)setAllowsNull:(BOOL)_flag { + self->flags.allowsNull = _flag ? 1 : 0; +} +- (BOOL)allowsNull { + return self->flags.allowsNull ? YES : NO; +} + +- (void)setWidth:(unsigned)_width { + self->width = _width; +} +- (unsigned)width { + return self->width; +} + +- (NSException *)validateValue:(id *)_value { + if (_value == NULL) return nil; + + /* check NULL constraint */ + if (!self->flags.allowsNull) { + if ((*_value == nil) || (*_value == null)) { + NSException *e; + NSDictionary *ui; + + ui = [NSDictionary dictionaryWithObjectsAndKeys: + *_value ? *_value : null, @"value", + self, @"attribute", + nil]; + + e = [NSException exceptionWithName:@"EOValidationException" + reason:@"violated not-null constraint" + userInfo:ui]; + return e; + } + } + + /* check width constraint */ + + if (self->width != 0) { + static Class NSDataClass = Nil; + static Class NSStringClass = Nil; + + if (NSDataClass == nil) NSDataClass = [NSData class]; + if (NSStringClass == nil) NSStringClass = [NSString class]; + + if ([[*_value class] isKindOfClass:NSDataClass]) { + unsigned len; + + len = [*_value length]; + if (len > self->width) { + NSException *e; + NSDictionary *ui; + + ui = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInt:self->width], + @"maxWidth", + [NSNumber numberWithUnsignedInt:len], @"width", + *_value ? *_value : null, @"value", + self, @"attribute", + nil]; + + e = [NSException exceptionWithName:@"EOValidationException" + reason:@"data value exceeds allowed attribute width" + userInfo:ui]; + return e; + } + } + else if ([[*_value class] isKindOfClass:NSStringClass]) { + unsigned len; + + len = [*_value cStringLength]; + if (len > self->width) { + NSException *e; + NSDictionary *ui; + + ui = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithUnsignedInt:self->width], + @"maxWidth", + [NSNumber numberWithUnsignedInt:len], @"width", + *_value ? *_value : null, @"value", + self, @"attribute", + nil]; + + e = [NSException exceptionWithName:@"EOValidationException" + reason:@"string value exceeds allowed attribute width" + userInfo:ui]; + return e; + } + } + } + + return nil; +} + +- (NSString *)readFormat { + return nil; +} +- (NSString *)writeFormat { + return nil; +} + +@end /* EOAttribute(EOF2Additions) */ + +@implementation NSString(BeautifyAttributeName) + +- (NSString *)_beautifyAttributeName { + unsigned clen = 0; + char *s = NULL; + unsigned cnt, cnt2; + + if ([self length] == 0) + return @""; + + clen = [self cStringLength]; +#if GNU_RUNTIME + s = objc_atomic_malloc(clen + 4); +#else + s = malloc(clen + 4); +#endif + + [self getCString:s maxLength:clen]; + + for (cnt = cnt2 = 0; cnt < clen; cnt++, cnt2++) { + if ((s[cnt] == '_') && (s[cnt + 1] != '\0')) { + s[cnt2] = toupper(s[cnt + 1]); + cnt++; + } + else if ((s[cnt] == '2') && (s[cnt + 1] != '\0')) { + s[cnt2] = s[cnt]; + cnt++; + cnt2++; + s[cnt2] = toupper(s[cnt]); + } + else + s[cnt2] = tolower(s[cnt]); + } + s[cnt2] = '\0'; + +#if !LIB_FOUNDATION_LIBRARY + { + NSString *os; + + os = [NSString stringWithCString:s]; + free(s); + return os; + } +#else + return [NSString stringWithCStringNoCopy:s freeWhenDone:YES]; +#endif +} + +@end /* NSString(BeautifyAttributeName) */ diff --git a/sope-gdl1/GDLAccess/EOAttributeOrdering.m b/sope-gdl1/GDLAccess/EOAttributeOrdering.m new file mode 100644 index 00000000..bf1408f7 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOAttributeOrdering.m @@ -0,0 +1,53 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import +#import +#import "common.h" + +@implementation EOAttributeOrdering + ++ (id)attributeOrderingWithAttribute:(EOAttribute*)_attribute + ordering:(EOOrdering)_ordering +{ + return AUTORELEASE([[EOAttributeOrdering alloc] + initWithAttribute:_attribute ordering:_ordering]); +} + +- (id)initWithAttribute:(EOAttribute*)_attribute ordering:(EOOrdering)_ordering { + ASSIGN(self->attribute, _attribute); + self->ordering = _ordering; + return self; +} + +- (EOAttribute *)attribute { + return self->attribute; +} +- (EOOrdering)ordering { + return self->ordering; +} + +@end /* EOAttributeOrdering */ diff --git a/sope-gdl1/GDLAccess/EOCustomValues.m b/sope-gdl1/GDLAccess/EOCustomValues.m new file mode 100644 index 00000000..d63d9f4e --- /dev/null +++ b/sope-gdl1/GDLAccess/EOCustomValues.m @@ -0,0 +1,171 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// $Id: EOCustomValues.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import "EOCustomValues.h" + +@implementation NSString(EOCustomValues) + ++ stringWithString:(NSString*)string type:(NSString*)type { + // If mutable return a copy if not return self + + if ([string isKindOfClass:[NSMutableString class]]) + return [[NSString alloc] initWithString:string type:type]; + else + return RETAIN(self); +} + +- initWithString:(NSString*)string type:(NSString*)type { + return [self initWithString:string]; +} + +- (NSString*)stringForType:(NSString*)type { + // If mutable return a copy if not return self (handled in NSString) + return [self copyWithZone:[self zone]]; +} + +- (id)initWithData:(NSData*)data type:(NSString*)type { + return [self initWithCString:[data bytes] length:[data length]]; +} + +- (NSData *)dataForType:(NSString *)type { + unsigned len = [self cStringLength]; + char buf[len + 1]; + [self getCString:buf]; + return [NSData dataWithBytes:buf length:len]; +} + +@end /* NSString(EOCustomValues) */ + + +@implementation NSData(EOCustomValues) + +- (id)initWithString:(NSString*)string type:(NSString*)type { + unsigned len = [string cStringLength]; + char buf[len + 1]; + [string getCString:buf]; + + return [self initWithBytes:buf length:len]; +} + +- (NSString*)stringForType:(NSString*)type { + return [NSString stringWithCString:[self bytes] length:[self length]]; +} + +- initWithData:(NSData*)data type:(NSString*)type { + return [self initWithBytes:[data bytes] length:[data length]]; +} + +- (NSData*)dataForType:(NSString*)type { + return [self copyWithZone:[self zone]]; +} + +@end /* NSData(EOCustomValues) */ + + +@implementation NSNumber(EOCustomValues) + ++ (id)numberWithString:(NSString*)string type:(NSString*)type { + char buf[[string cStringLength] + 1]; + const char *cstring; + + [string getCString:buf]; + cstring = buf; + + if ([type cStringLength] == 1) + switch ((unsigned char)[type characterAtIndex:0]) { + case 'c' : { + char value = atoi(cstring); + return [NSNumber numberWithChar:value]; + } + case 'C' : { + unsigned char value = atoi(cstring); + return [NSNumber numberWithUnsignedChar:value]; + } + case 's' : { + short value = atoi(cstring); + return [NSNumber numberWithShort:value]; + } + case 'S' : { + unsigned short value = atoi(cstring); + return [NSNumber numberWithUnsignedShort:value]; + } + case 'i' : { + int value = atoi(cstring); + return [NSNumber numberWithInt:value]; + } + case 'I' : { + unsigned int value = atoi(cstring); + return [NSNumber numberWithUnsignedInt:value]; + } + case 'l' : { + long value = atol(cstring); + return [NSNumber numberWithLong:value]; + } + case 'L' : { + unsigned long value = atol(cstring); + return [NSNumber numberWithUnsignedLong:value]; + } + case 'q' : { + long long value = atol(cstring); + return [NSNumber numberWithLongLong:value]; + } + case 'Q' : { + unsigned long long value = atol(cstring); + return [NSNumber numberWithUnsignedLongLong:value]; + } + case 'f' : { + float value = atof(cstring); + return [NSNumber numberWithFloat:value]; + } + case 'd' : { + double value = atof(cstring); + return [NSNumber numberWithDouble:value]; + } + } + + [NSException raise:NSInvalidArgumentException + format:@"invalid type `%@' for NSNumber in " + @"numberWithString:type:", type]; + return nil; +} + +- initWithString:(NSString*)string type:(NSString*)type { + (void)AUTORELEASE(self); + return RETAIN([NSNumber numberWithString:string type:type]); +} + +- (NSString*)stringForType:(NSString*)type { + return [self stringValue]; +} + +@end /* NSNumber(EOCustomValues) */ + +void EOAccess_EOCustomValues_link(void) { + EOAccess_EOCustomValues_link(); +} diff --git a/sope-gdl1/GDLAccess/EODatabase.m b/sope-gdl1/GDLAccess/EODatabase.m new file mode 100644 index 00000000..8f5ef430 --- /dev/null +++ b/sope-gdl1/GDLAccess/EODatabase.m @@ -0,0 +1,523 @@ +/* + EODatabase.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EODatabase.h" +#import "EOAdaptor.h" +#import "EOModel.h" +#import "EOEntity.h" +#import "EOGenericRecord.h" +#import "EODatabaseContext.h" +#import "EOObjectUniquer.h" +#import "EODatabaseFault.h" + +NSTimeInterval NSDistantPastTimeInterval = 0.0; + +@implementation EODatabase + +// Database Global Methods + +static NSMutableArray *databaseInstances = nil; +static NSRecursiveLock *lock = nil; + ++ (void)initialize { + static BOOL isInitialized = NO; + // THREAD + if (!isInitialized) { + isInitialized = YES; + databaseInstances = [[NSMutableArray alloc] init]; + lock = [[NSRecursiveLock alloc] init]; + } +} + +static inline void _addDatabaseInstance(EODatabase *_db) { + [lock lock]; + [databaseInstances addObject:[NSValue valueWithNonretainedObject:_db]]; + [lock unlock]; +} +static inline void _removeDatabaseInstance(EODatabase *_db) { + [lock lock]; + { + int i; + + for (i = [databaseInstances count] - 1; i >= 0; i--) { + EODatabase *db; + + db = [[databaseInstances objectAtIndex:i] nonretainedObjectValue]; + if (db == _db) { + [databaseInstances removeObjectAtIndex:i]; + break; + } + } + } + [lock unlock]; +} + +/* + * Initializing new instances + */ + +- (id)initWithAdaptor:(EOAdaptor *)_adaptor { + if (_adaptor == nil) { + AUTORELEASE(self); + return nil; + } + + self->adaptor = RETAIN(_adaptor); + self->objectsDictionary = [[EOObjectUniquer allocWithZone:[self zone]] init]; + self->contexts = [[NSMutableArray allocWithZone:[self zone]] init]; + + self->flags.isUniquingObjects = YES; + self->flags.isKeepingSnapshots = YES; + self->flags.isLoggingWarnings = YES; + + _addDatabaseInstance(self); + + return self; +} + +- (id)initWithModel:(EOModel *)_model { + return [self initWithAdaptor:[EOAdaptor adaptorWithModel:_model]]; +} +- (id)init { + return [self initWithAdaptor:nil]; +} + +- (void)dealloc { + _removeDatabaseInstance(self); + + RELEASE(self->adaptor); + RELEASE(self->objectsDictionary); + RELEASE(self->contexts); + [super dealloc]; +} + +// accessors + +- (EOAdaptor *)adaptor { + return self->adaptor; +} + +- (EOObjectUniquer *)objectUniquer { + return self->objectsDictionary; +} + +// Checking connection status + +- (BOOL)hasOpenChannels { + int i; + + for (i = ([self->contexts count] - 1); i >= 0; i--) { + if ([[[self->contexts objectAtIndex:i] nonretainedObjectValue] + hasOpenChannels]) + return YES; + } + return NO; +} + +/* + * Getting the database contexts + */ + +- (id)createContext { + return AUTORELEASE([[EODatabaseContext alloc] initWithDatabase:self]); +} + +- (NSArray *)contexts { + NSMutableArray *array = nil; + int i, n; + + n = [self->contexts count]; + array = [[NSMutableArray alloc] initWithCapacity:n]; + + for (i = 0; i < n; i++) { + EODatabaseContext *ctx; + + ctx = [[self->contexts objectAtIndex:i] nonretainedObjectValue]; + [array addObject:ctx]; + } + return AUTORELEASE(array); +} + +- (void)contextDidInit:(id)_context { + [self->contexts addObject:[NSValue valueWithNonretainedObject:_context]]; +} + +- (void)contextWillDealloc:(id)aContext { + int i; + + for (i = [self->contexts count]-1; i >= 0; i--) { + if ([[self->contexts objectAtIndex:i] nonretainedObjectValue] == aContext) { + [self->contexts removeObjectAtIndex:i]; + break; + } + } +} + +/* + * Uniquing/snapshotting + */ + +- (void)setUniquesObjects:(BOOL)yn { + if ([self hasOpenChannels]) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabase:%x: All channels must be closed when changing " + @"uniquing mode in the EODatabase, " + @"in [EODatabase setUniquesObjects:]", + self]; + } + + if ((!yn) && (self->flags.isUniquingObjects)) + [self->objectsDictionary forgetAllObjects]; + self->flags.isUniquingObjects = yn; +} +- (BOOL)uniquesObjects { + return self->flags.isUniquingObjects; +} + +- (void)setKeepsSnapshots:(BOOL)yn { + if ([self hasOpenChannels]) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabase:%x: All channels must be closed when changing " + @"snapshoting mode in the EODatabase, " + @"in [EODatabase setKeepsSnapshots:]", + self]; + } + + if ((yn == NO) && self->flags.isKeepingSnapshots) + [self->objectsDictionary forgetAllSnapshots]; + + self->flags.isKeepingSnapshots = yn; +} +- (BOOL)keepsSnapshots { + return self->flags.isKeepingSnapshots; +} + +// ******************** Handle Objects ******************** + +- (void)forgetAllObjects { + [self->objectsDictionary forgetAllObjects]; +} + ++ (void)forgetObject:(id)_object { + [EOObjectUniquer forgetObject:_object]; + + [lock lock]; + { + int i; + + for (i = [databaseInstances count] - 1; i >= 0; i--) { + EODatabase *db; + + db = [[databaseInstances objectAtIndex:i] nonretainedObjectValue]; + [db forgetObject:_object]; + } + } + [lock unlock]; +} + +- (void)forgetObject:(id)_object { + /* + NSLog(@"DB[0x%08X]: forget object 0x%08X<%s> entity=%@", + self, _object, class_get_class_name(*(Class *)_object), + [[_object entity] name]); + */ + [self->objectsDictionary forgetObject:_object]; +} + +- (void)forgetAllSnapshots { + [self->objectsDictionary forgetAllSnapshots]; +} + +- (id)objectForPrimaryKey:(NSDictionary *)_key entity:(EOEntity *)_entity { + if (self->flags.isUniquingObjects && (_key != nil) && (_entity != nil)) { + _key = [_entity primaryKeyForRow:_key]; + if (_key == nil) + return nil; + else { + id object = [self->objectsDictionary objectForPrimaryKey:_key entity:_entity]; + +#if 0 + if (object) { + if (![object isKindOfClass:[EOGenericRecord class]]) + NSLog(@"object 0x%08X pkey=%@ entity=%@", object, _key, _entity); + } +#endif + return object; + } + } + return nil; +} + +- (NSDictionary *)snapshotForObject:_object { + EOUniquerRecord* rec = [self->objectsDictionary recordForObject:_object]; + + return rec ? rec->snapshot : nil; +} + +- (NSDictionary *)primaryKeyForObject:(id)_object { + EOUniquerRecord* rec = [self->objectsDictionary recordForObject:_object]; + + return rec ? rec->pkey : nil; +} + +- (void)primaryKey:(NSDictionary**)_key + andSnapshot:(NSDictionary**)_snapshot + forObject:(id)_object { + + EOUniquerRecord *rec = [self->objectsDictionary recordForObject:_object]; + + if (rec) { + if (_key) *_key = rec->pkey; + if (_snapshot) *_snapshot = rec->snapshot; + } + else { + if (_key) *_key = nil; + if (_snapshot) *_snapshot = nil; + } +} + +- (void)recordObject:(id)_object + primaryKey:(NSDictionary *)_key + snapshot:(NSDictionary *)_snapshot { + + EOEntity *entity; + + entity = [_object respondsToSelector:@selector(entity)] + ? [_object entity] + : [[self->adaptor model] entityForObject:_object]; + + [self recordObject:_object + primaryKey:_key + entity:entity + snapshot:_snapshot]; +} + +- (void)recordObject:(id)_object + primaryKey:(NSDictionary *)_key + entity:(EOEntity *)_entity + snapshot:(NSDictionary *)_snapshot { + + if (_object == nil) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabase:%x: Cannot record null object, " + @"in [EODatabase recordObject:primaryKey:entity:snapshot:]", + self]; + } + if ((_entity == nil) && self->flags.isUniquingObjects) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabase:%x: Cannot record object with null entity " + @"when the database is uniquing objects, " + @"in [EODatabase recordObject:primaryKey:entity:snapshot:]", + self]; + } + _key = [_entity primaryKeyForRow:_key]; + if ((_key == nil) && self->flags.isUniquingObjects) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabase:%x: Cannot record object with null key " + @"when the database is uniquing objects, " + @"in [EODatabase recordObject:primaryKey:entity:snapshot:]", + self]; + } + if ((_snapshot == nil) && self->flags.isKeepingSnapshots) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabase:%x: Cannot record object with null snapshot " + @"when the database is keeping snapshots, " + @"in [EODatabase recordObject:primaryKey:entity:snapshot:]", + self]; + } + + [objectsDictionary recordObject:_object + primaryKey:self->flags.isUniquingObjects?_key:nil + entity:self->flags.isUniquingObjects ?_entity:nil + snapshot:self->flags.isKeepingSnapshots?_snapshot:nil]; +} + +- (BOOL)isObject:(id)_object + updatedOutsideContext:(EODatabaseContext *)_context +{ + int i; + + for (i = [contexts count] - 1; i >= 0; i--) { + EODatabaseContext *ctx; + + ctx = [[self->contexts objectAtIndex:i] nonretainedObjectValue]; + + if ((ctx != _context) && [ctx isObjectUpdated:_object]) + return YES; + } + return NO; +} + +// ******************** Error messages ******************** + +- (void)setLogsErrorMessages:(BOOL)yn { + self->flags.isLoggingWarnings = yn; +} +- (BOOL)logsErrorMessages { + return self->flags.isLoggingWarnings; +} + +- (void)reportErrorFormat:(NSString*)format, ... { + va_list va; + + va_start(va, format); + [self reportErrorFormat:format arguments:va]; + va_end(va); +} + +- (void)reportErrorFormat:(NSString*)format arguments:(va_list)arguments { + [self reportError:AUTORELEASE([[NSString alloc] initWithFormat:format + arguments:arguments])]; +} + +- (void)reportError:(NSString*)error { + if (self->flags.isLoggingWarnings) + NSLog(@"EODatabase:%x:%@", self, error); +} + +@end /* EODatabase */ + +@implementation EODatabase(EOF2Additions) + +- (NSArray *)models { + EOModel *model; + + model = [[self adaptor] model]; + return model ? [NSArray arrayWithObject:model] : nil; +} + +- (void)addModel:(EOModel *)_model { + EOModel *model; + + model = [[self adaptor] model]; + + if (model == nil) + [[self adaptor] setModel:_model]; + else + [self notImplemented:_cmd]; +} + +- (BOOL)addModelIfCompatible:(EOModel *)_model { + NSEnumerator *e; + EOModel *m; + + if (![[self adaptor] canServiceModel:_model]) + return NO; + + e = [[self models] objectEnumerator]; + while ((m = [e nextObject])) { + if (m == _model) + return YES; + + if (![[m adaptorName] isEqualToString:[_model adaptorName]]) + return NO; + } + + [self addModel:_model]; + return YES; +} + +- (EOEntity *)entityForObject:(id)_object { + return [[[self adaptor] model] entityForObject:_object]; +} +- (EOEntity *)entityNamed:(NSString *)_name { + return [[[self adaptor] model] entityNamed:_name]; +} + +/* snapshots */ + +- (void)forgetSnapshotsForGlobalIDs:(NSArray *)_gids { + NSEnumerator *e; + EOGlobalID *gid; + + e = [_gids objectEnumerator]; + while ((gid = [e nextObject])) + [self forgetSnapshotsForGlobalID:gid]; +} +- (void)forgetSnapshotsForGlobalID:(EOGlobalID *)_gid { + [self notImplemented:_cmd]; +} + +- (void)recordSnapshot:(NSDictionary *)_snapshot forGlobalID:(EOGlobalID *)_gid { + [self notImplemented:_cmd]; +} +- (void)recordSnapshots:(NSDictionary *)_snapshots { + NSEnumerator *gids; + EOGlobalID *gid; + + gids = [_snapshots keyEnumerator]; + while ((gid = [gids nextObject])) + [self recordSnapshot:[_snapshots objectForKey:gid] forGlobalID:gid]; +} + +- (void)recordSnapshot:(NSArray *)_gids + forSourceGlobalID:(EOGlobalID *)_gid + relationshipName:(NSString *)_name +{ + /* to-many snapshot */ + [self notImplemented:_cmd]; +} +- (void)recordToManySnapshots:(NSDictionary *)_snapshots { + NSEnumerator *gids; + EOGlobalID *gid; + + gids = [_snapshots keyEnumerator]; + while ((gid = [gids nextObject])) { + NSDictionary *d; + NSEnumerator *relNames; + NSString *relName; + + d = [_snapshots objectForKey:gid]; + relNames = [d keyEnumerator]; + + while ((relName = [relNames nextObject])) { + [self recordSnapshot:[d objectForKey:relName] + forSourceGlobalID:gid + relationshipName:relName]; + } + } +} + +- (NSDictionary *)snapshotForGlobalID:(EOGlobalID *)_gid + after:(NSTimeInterval)_duration +{ + NSLog(@"ERROR(%s): subclasses must override this method!", + __PRETTY_FUNCTION__); + return nil; +} + +- (NSDictionary *)snapshotForGlobalID:(EOGlobalID *)_gid { + return [self snapshotForGlobalID:_gid after:NSDistantPastTimeInterval]; +} + +@end /* EODatabase(EOF2Additions) */ diff --git a/sope-gdl1/GDLAccess/EODatabaseChannel.m b/sope-gdl1/GDLAccess/EODatabaseChannel.m new file mode 100644 index 00000000..2853305d --- /dev/null +++ b/sope-gdl1/GDLAccess/EODatabaseChannel.m @@ -0,0 +1,1469 @@ +/* + EODatabaseChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EODatabaseChannel.h" +#import "EOAdaptor.h" +#import "EOAdaptorChannel.h" +#import "EOAdaptorContext.h" +#import "EOAttribute.h" +#import "EODatabase.h" +#import "EODatabaseContext.h" +#import "EOEntity.h" +#import "EODatabaseFault.h" +#import "EOGenericRecord.h" +#import "EOModel.h" +#import "EOObjectUniquer.h" +#import "EOSQLQualifier.h" +#import "EORelationship.h" +#import +#import +#import + +@class EOGenericRecord; + +NSString *EODatabaseChannelWillOpenNotificationName = + @"EODatabaseChannelWillOpenNotification"; +NSString *EODatabaseChannelDidOpenNotificationName = + @"EODatabaseChannelDidOpenNotification"; +NSString *EODatabaseChannelWillCloseNotificationName = + @"EODatabaseChannelWillCloseNotification"; +NSString *EODatabaseChannelDidCloseNotificationName = + @"EODatabaseChannelDidCloseNotification"; +NSString *EODatabaseChannelCouldNotOpenNotificationName = + @"EODatabaseChannelCouldNotOpenNotification"; +NSString *EODatabaseChannelWillInsertObjectName = + @"EODatabaseChannelWillInsertObjectName"; +NSString *EODatabaseChannelDidInsertObjectName = + @"EODatabaseChannelDidInsertObjectName"; +NSString *EODatabaseChannelWillUpdateObjectName = + @"EODatabaseChannelWillUpdateObjectName"; +NSString *EODatabaseChannelDidUpdateObjectName = + @"EODatabaseChannelDidUpdateObjectName"; +NSString *EODatabaseChannelWillDeleteObjectName = + @"EODatabaseChannelWillDeleteObjectName"; +NSString *EODatabaseChannelDidDeleteObjectName = + @"EODatabaseChannelDidDeleteObjectName"; +NSString *EODatabaseChannelWillLockObjectName = + @"EODatabaseChannelWillLockObjectName"; +NSString *EODatabaseChannelDidLockObjectName = + @"EODatabaseChannelDidLockObjectName"; + +/* + * Private methods declaration + */ + +@interface EODatabaseChannel(Private) +- (id)privateFetchWithZone:(NSZone *)_zone; +- (Class)privateClassForEntity:(EOEntity *)anEntity; +- (void)privateUpdateCurrentEntityInfo; +- (void)privateClearCurrentEntityInfo; +- (void)privateReportError:(SEL)method:(NSString *)format, ...; +@end + +/* + * EODatabaseChannel implementation + */ + +@implementation EODatabaseChannel + +/* + * Initializing a new instance + */ + +- (id)initWithDatabaseContext:(EODatabaseContext *)_dbContext { + if (_dbContext == nil) { + AUTORELEASE(self); + return nil; + } + + self->notificationCenter = RETAIN([NSNotificationCenter defaultCenter]); + + self->databaseContext = RETAIN(_dbContext); + [self setDelegate:[self->databaseContext delegate]]; + [self->databaseContext channelDidInit:self]; + + return self; +} + +- (void)dealloc { + [self->databaseContext channelWillDealloc:self]; + RELEASE(self->currentEditingContext); + RELEASE(self->databaseContext); + RELEASE(self->adaptorChannel); + RELEASE(self->notificationCenter); + [super dealloc]; +} + +// notifications + +- (void)postNotification:(NSString *)_name { + [self->notificationCenter postNotificationName:_name object:self]; +} +- (void)postNotification:(NSString *)_name object:(id)_obj { + [self->notificationCenter postNotificationName:_name + object:self + userInfo:[NSDictionary dictionaryWithObject:_obj + forKey:@"object"]]; +} + +// accessors + +- (EOAdaptorChannel *)adaptorChannel { + if (self->adaptorChannel == nil) { + static int reuseAdaptorCh = -1; + if (reuseAdaptorCh == -1) { + reuseAdaptorCh = [[[NSUserDefaults standardUserDefaults] + objectForKey:@"EOReuseAdaptorChannel"] + boolValue] ? 1 : 0; + } + + if (reuseAdaptorCh) { + NSEnumerator *channels; + EOAdaptorChannel *channel; + + channels = + [[[[self databaseContext] adaptorContext] channels] objectEnumerator]; + + while ((channel = [channels nextObject])) { + if ([channel isFetchInProgress]) + continue; + +#if DEBUG + NSLog(@"reuse adaptor channel: %@", channel); +#endif + self->adaptorChannel = channel; + break; + } + } + + if (self->adaptorChannel == nil) { + self->adaptorChannel = + [[[self databaseContext] adaptorContext] createAdaptorChannel]; + } + + RETAIN(self->adaptorChannel); + } + return self->adaptorChannel; +} + +- (EODatabaseContext *)databaseContext { + return self->databaseContext; +} + +// delegate + +- (void)setDelegate:(id)_delegate { + self->delegate = _delegate; +} +- (id)delegate { + return self->delegate; +} + +// Opening and closing a channel + +- (BOOL)isOpen { + return [[self adaptorChannel] isOpen]; +} + +- (BOOL)openChannel { + BOOL result; + + [self postNotification:EODatabaseChannelWillOpenNotificationName]; + + if ((result = [[self adaptorChannel] openChannel])) { + self->successfulOpenCount++; + [self postNotification:EODatabaseChannelDidOpenNotificationName]; + } + else { + self->failedOpenCount++; + [self postNotification:EODatabaseChannelCouldNotOpenNotificationName]; + } + + return result; +} + +- (void)closeChannel { + [self postNotification:EODatabaseChannelWillCloseNotificationName]; + [[self adaptorChannel] closeChannel]; + self->closeCount++; + [self postNotification:EODatabaseChannelDidCloseNotificationName]; +} + +// Modifying objects + +- (BOOL)_isNoRaiseOnModificationException:(NSException *)_exception { + /* for compatibility with non-X methods, translate some errors to a bool */ + NSString *n; + + n = [_exception name]; + if ([n isEqualToString:@"EOEvaluationError"]) + return YES; + if ([n isEqualToString:@"EODelegateRejects"]) + return YES; + + return NO; +} + +- (BOOL)insertObject:(id)anObj { + // TODO: split up this method + // TODO: write an insertObjectX: which returns an exception + NSException *exception = nil; + EOEntity *entity = nil; + NSDictionary *pkey = nil; + NSDictionary *values = nil; + NSDictionary *snapshot = nil; + NSArray *attributes = nil; + int i; + + [self postNotification:EODatabaseChannelWillInsertObjectName object:anObj]; + + if (![anObj prepareForInsertInChannel:self context:self->databaseContext]) + return NO; + + // Check the delegate + if ([self->delegate respondsToSelector: + @selector(databaseChannel:willInsertObject:)]) + anObj = [delegate databaseChannel:self willInsertObject:anObj]; + + // Check nil (delegate disallowes or given object was nil) + if (anObj == nil) + return NO; + + // Check if fault + if ([EOFault isFault:anObj]) { + [NSException raise:NSInvalidArgumentException + format:@"Attempt to insert a fault in a database channel"]; + } + + // Check if we can insert + if ([databaseContext updateStrategy] == EONoUpdate) { + [self privateReportError:_cmd : + @"cannot insert if context has 'NoUpdate' update strategy."]; + return NO; + } + + /* validate object for insert */ + + if ((exception = [anObj validateForInsert])) { + /* validation failed */ + [exception raise]; + } + + // Check if in a transaction + if (![databaseContext transactionNestingLevel]) { + [self privateReportError:_cmd : + @"cannot insert if contex has no transaction opened."]; + return NO; + } + + // Get entity + entity = [anObj respondsToSelector:@selector(entity)] + ? [anObj entity] + : [[[[adaptorChannel adaptorContext] adaptor] model] entityForObject:anObj]; + + // Check entity + if (entity == nil) { + [self privateReportError:_cmd : + @"cannot determine entity for object %p class %@.", + anObj, NSStringFromClass([anObj class])]; + return NO; + } + if ([entity isReadOnly]) { + [self privateReportError:_cmd : + @"cannot insert object %p for readonly entity %@.", + anObj, [entity name]]; + return NO; + } + + // Get array of attributes to insert + attributes = [entity attributesUsedForInsert]; + + // Get simple values and convert them to adaptor values + values = [anObj valuesForKeys:[entity attributesNamesUsedForInsert]]; + values = [entity convertValuesToModel:values]; + + // Get and check *must insert* attributes (primary key, lock, readonly) + for (i = [attributes count]-1; i >= 0; i--) { + EOAttribute *attribute = [attributes objectAtIndex:i]; + + NSAssert(attribute, @"invalid attribute object .."); + + if (![values objectForKey:[attribute name]]) { + [self privateReportError:_cmd : + @"null value for insert attribute %@ for object %@ entity %@", + [attribute name], anObj, [entity name]]; + return NO; + } + } + + // Make primary key and snapshot + snapshot = [entity snapshotForRow:values]; + if (snapshot == nil) { + [self privateReportError:_cmd : + @"cannot determine snapshot for %p from values %@ entity %@.", + anObj, [values description], [entity name]]; + return NO; + } + pkey = [entity primaryKeyForRow:values]; + if (pkey == nil) { + [self privateReportError:_cmd : + @"cannot determine primary key for %p from values %@ entity %@.", + anObj, [values description], [entity name]]; + return NO; + } + + // Insert adaptor row + exception = [adaptorChannel insertRowX:values forEntity:entity]; + if (exception) { + if (![self _isNoRaiseOnModificationException:exception]) [exception raise]; + return NO; + } + + // Record object in database context + [databaseContext recordObject:anObj + primaryKey:pkey entity:entity snapshot:values]; + + self->insertCount++; + [anObj wasInsertedInChannel:self context:self->databaseContext]; + + // Notify delegate + if ([delegate respondsToSelector:@selector(databaseChannel:didInsertObject:)]) + [delegate databaseChannel:self didInsertObject:anObj]; + + [self postNotification:EODatabaseChannelDidInsertObjectName object:anObj]; + return YES; +} + +- (BOOL)updateObject:(id)anObj { + // TODO: split up this huge method + // TODO: make an updateObjectX: method which returns an exception + NSException *exception = nil; + EOEntity *entity = nil; + EOSQLQualifier *qualifier = nil; + NSDictionary *old_pkey = nil; + NSDictionary *old_snapshot = nil; + NSDictionary *new_pkey = nil; + NSDictionary *new_snapshot = nil; + NSDictionary *values = nil; + BOOL needsOptimisticLock; + + [self postNotification:EODatabaseChannelWillUpdateObjectName object:anObj]; + + if (![anObj prepareForUpdateInChannel:self context:self->databaseContext]) + return NO; + + // Check the delegate + if ([delegate respondsToSelector:@selector(databaseChannel:willUpdateObject:)]) + anObj = [delegate databaseChannel:self willUpdateObject:anObj]; + + // Check nil (delegate disallowes or given object was nil) + if (anObj == nil) + return NO; + + // Check if fault + if ([EOFault isFault:anObj]) { + [NSException raise:NSInvalidArgumentException + format:@"Attempt to update a fault in a database channel"]; + } + + // Check if we can update + if ([databaseContext updateStrategy] == EONoUpdate) { + [self privateReportError:_cmd : + @"cannot update if context has 'NoUpdate' update strategy."]; + return NO; + } + + /* validate object for update */ + + if ((exception = [anObj validateForUpdate])) { + /* validation failed */ + [exception raise]; + } + + // Check if in a transaction + if (![databaseContext transactionNestingLevel]) { + [self privateReportError:_cmd : + @"cannot update if contex has no transaction opened."]; + return NO; + } + + // Get entity + entity = [anObj respondsToSelector:@selector(entity)] + ? [anObj entity] + : [[[[adaptorChannel adaptorContext] adaptor] model] entityForObject:anObj]; + + // Check entity + { + if (entity == nil) { + [self privateReportError:_cmd : + @"cannot determine entity for object %p class %@.", + anObj, NSStringFromClass([anObj class])]; + return NO; + } + if ([entity isReadOnly]) { + [self privateReportError:_cmd : + @"cannot update object %p for readonly entity %@.", + anObj, [entity name]]; + return NO; + } + } + + // Get and check old snapshot and primary key + { + [databaseContext primaryKey:&old_pkey + andSnapshot:&old_snapshot + forObject:anObj]; + + if (old_snapshot == nil) { + [self privateReportError:_cmd : + @"cannot update object %p because there is no snapshot for it."]; + return NO; + } + if (old_pkey == nil) + old_pkey = [entity primaryKeyForRow:old_snapshot]; + if (old_pkey == nil) { + [self privateReportError:_cmd : + @"cannot determine primary key for %p from snapshot %@ entity %@.", + anObj, [old_snapshot description], [entity name]]; + return NO; + } + } + + // Get simple values and convert them to adaptor values + values = [anObj valuesForKeys:[entity attributesNamesUsedForInsert]]; + values = [entity convertValuesToModel:values]; + + // Get and check new primary key and snapshot + { + new_snapshot = [entity snapshotForRow:values]; + if (new_snapshot == nil) { + [self privateReportError:_cmd : + @"cannot determine snapshot for %p from values %@ entity %@.", + anObj, [values description], [entity name]]; + return NO; + } + new_pkey = [entity primaryKeyForRow:new_snapshot]; + if (new_pkey == nil) { + [self privateReportError:_cmd : + @"cannot determine primary key for %p from values %@ entity %@.", + anObj, [values description], [entity name]]; + return NO; + } + } + + // Check if we need to lock optimistic before update + // that is compare locking attributes with the existing ones in database + switch([databaseContext updateStrategy]) { + case EOUpdateWithOptimisticLocking: + case EOUpdateWithPessimisticLocking: + needsOptimisticLock = ![databaseContext isObjectLocked:anObj]; + break; + case EOUpdateWithNoLocking: + needsOptimisticLock = NO; + break; + default: + return NO; + } + + // If we need an "optimistic lock" then perform lock + // else just make the qualifier based on the primary key only + if (needsOptimisticLock) { + int i; + BOOL canUseQualifier = YES; + NSArray *lockAttrs = [entity attributesUsedForLocking]; + EOAdaptor *adaptor = [[adaptorChannel adaptorContext] adaptor]; + NSDictionary *row; + + // Check if attributes used for locking can be used in a qualifier + for (i = [lockAttrs count]-1; i >= 0; i--) { + if (![adaptor isValidQualifierType: + [[lockAttrs objectAtIndex:i] externalType]]) { + canUseQualifier = NO; + break; + } + } + + if (canUseQualifier) + // If YES just build the qualifier + qualifier = [EOSQLQualifier qualifierForRow:old_snapshot + entity:entity]; + else { + // If NO then lock the row in the database server, fetch the + // new snapshot and compare it with the old one + qualifier = [EOSQLQualifier qualifierForPrimaryKey:old_pkey + entity:entity]; +#ifdef DEBUG + NSAssert2([lockAttrs count] > 0, + @"missing locking attributes: lock=%@ object=%@", + lockAttrs, anObj); +#endif + if (![adaptorChannel selectAttributes:lockAttrs + describedByQualifier:qualifier + fetchOrder:nil + lock:YES]) { + [self privateReportError:_cmd : + @"could not lock=%@ with qualifier=%@ entity=%@.", + anObj, [qualifier description], [entity name]]; + return NO; + } + row = [adaptorChannel fetchAttributes:lockAttrs withZone:NULL]; + [adaptorChannel cancelFetch]; + if (row == nil) { + [self privateReportError:_cmd : + @"could not get row to lock %p with qualifier %@.", + anObj, [qualifier description]]; + return NO; + } + [databaseContext recordLockedObject:anObj]; + if (![row isEqual:old_snapshot]) { + [self privateReportError:_cmd : + @"could not lock %p. Snapshots: self %@ database %@.", + anObj, [old_snapshot description], [row description]]; + return NO; + } + } + } + else { + qualifier = [EOSQLQualifier qualifierForPrimaryKey:old_pkey + entity:entity]; + } + + // Compute values as delta from values and old_snapshot + { + NSMutableDictionary *delta; + NSString *attributeName; + NSArray *allKeys; + int i, count; + + allKeys = [values allKeys]; + delta = [NSMutableDictionary dictionary]; + for (i = 0, count = [allKeys count]; i < count; i++) { + id new_v, old_v; + + attributeName = [allKeys objectAtIndex:i]; + new_v = [values objectForKey:attributeName]; + old_v = [old_snapshot objectForKey:attributeName]; + + if ((old_v == nil) || ![new_v isEqual:old_v]) + [delta setObject:new_v forKey:attributeName]; + } + values = delta; + } + + // no reason for update --> fetch to be sure, that no one has deleted it + // HH: The object was not changed, so we refetch to determine whether it + // was deleted + if ([values count] == 0) { + if (![self refetchObject:anObj]) + return NO; + } + // Update in adaptor + else { + NSException *ex; + + ex = [adaptorChannel updateRowX:values describedByQualifier:qualifier]; + if (ex != nil) { + if (![self _isNoRaiseOnModificationException:ex]) [ex raise]; + return NO; + } + } + // Record object in database context + if (![new_pkey isEqual:old_pkey]) { + NSLog(@"WARNING: (%@) primary key changed from %@ to %@", + __PRETTY_FUNCTION__, old_pkey, new_pkey); + [databaseContext forgetObject:anObj]; + } + + [databaseContext recordObject:anObj + primaryKey:new_pkey + entity:entity + snapshot:new_snapshot]; + [databaseContext recordUpdatedObject:anObj]; + + self->updateCount++; + [anObj wasUpdatedInChannel:self context:self->databaseContext]; + + // Notify delegate + if ([delegate respondsToSelector:@selector(databaseChannel:didUpdateObject:)]) + [delegate databaseChannel:self didUpdateObject:anObj]; + + [self postNotification:EODatabaseChannelDidUpdateObjectName object:anObj]; + return YES; +} + +- (BOOL)deleteObject:(id)anObj { + // TODO: split this method + // TODO: add an deleteObjectX: method which returns an NSException + NSException *exception = nil; + EOEntity *entity = nil; + NSDictionary *pkey = nil; + NSDictionary *snapshot = nil; + EOSQLQualifier *qualifier = nil; + + [self postNotification:EODatabaseChannelWillDeleteObjectName object:anObj]; + + if (![anObj prepareForDeleteInChannel:self context:self->databaseContext]) + return NO; + + // Check the delegate + if ([delegate respondsToSelector:@selector(databaseChannel:willDeleteObject:)]) + anObj = [delegate databaseChannel:self willDeleteObject:anObj]; + + // Check nil (delegate disallowes or given object was nil) + if (anObj == nil) + return NO; + + // Check if fault + if ([EOFault isFault:anObj]) { + [NSException raise:NSInvalidArgumentException + format:@"Attempt to delete a fault in a database channel"]; + } + + // Check if we can delete + if ([databaseContext updateStrategy] == EONoUpdate) { + [self privateReportError:_cmd : + @"cannot delete if context has 'NoUpdate' update strategy."]; + return NO; + } + + /* validate object for delete */ + + if ((exception = [anObj validateForDelete])) { + /* validation failed */ + [exception raise]; + } + + // Check if in a transaction + if (![databaseContext transactionNestingLevel]) { + [self privateReportError:_cmd : + @"cannot update if contex has no transaction opened."]; + return NO; + } + + // Get entity + entity = [anObj respondsToSelector:@selector(entity)] + ? [anObj entity] + : [[[[adaptorChannel adaptorContext] adaptor] model] entityForObject:anObj]; + + // Check entity + if (entity == nil) { + [self privateReportError:_cmd : + @"cannot determine entity for object %p class %s.", + anObj, NSStringFromClass([anObj class])]; + return NO; + } + if ([entity isReadOnly]) { + [self privateReportError:_cmd : + @"cannot delete object %p for readonly entity %@.", + anObj, [entity name]]; + return NO; + } + + // Get snapshot and old primary key + [databaseContext primaryKey:&pkey andSnapshot:&snapshot forObject:anObj]; + if (pkey == nil) { + if (snapshot == nil) + [self privateReportError:_cmd : + @"cannot delete object %p because there is no snapshot for it."]; + pkey = [entity primaryKeyForRow:snapshot]; + } + if (pkey == nil) { + [self privateReportError:_cmd : + @"cannot determine primary key for %p from values %@ entity %@.", + anObj, [snapshot description], [entity name]]; + return NO; + } + + // Get and check qualifier for object to delete + qualifier = [EOSQLQualifier qualifierForPrimaryKey:pkey entity:entity]; + if (qualifier == nil) { + [self privateReportError:_cmd : + @"cannot make qualifier to delete %p primary key %@ entity %@.", + anObj, [pkey description], [entity name]]; + return NO; + } + + // Delete adaptor row + exception = [adaptorChannel deleteRowsDescribedByQualifierX:qualifier]; + if (exception != nil) { + if (![self _isNoRaiseOnModificationException:exception]) [exception raise]; + return NO; + } + + AUTORELEASE(RETAIN(anObj)); + + // Forget object in database context + [databaseContext forgetObject:anObj]; + + self->deleteCount++; + [anObj wasDeletedInChannel:self context:self->databaseContext]; + + // Notify delegate + if ([delegate respondsToSelector: + @selector(databaseChannel:didDeleteObject:)]) + [delegate databaseChannel:self didDeleteObject:anObj]; + + [self postNotification:EODatabaseChannelDidDeleteObjectName object:anObj]; + return YES; +} + +- (BOOL)lockObject:(id)anObj { + EOEntity *entity = nil; + NSDictionary *pkey = nil; + NSDictionary *snapshot = nil; + EOSQLQualifier *qualifier = nil; + + [self postNotification:EODatabaseChannelWillLockObjectName object:anObj]; + + if (![anObj prepareForLockInChannel:self context:self->databaseContext]) + return NO; + + // Check the delegate + if ([delegate respondsToSelector:@selector(databaseChannel:willLockObject:)]) + anObj = [delegate databaseChannel:self willLockObject:anObj]; + + // Check nil (delegate disallowes or given object was nil) + if (anObj == nil) + return NO; + + // Check if fault + if ([EOFault isFault:anObj]) { + [NSException raise:NSInvalidArgumentException + format:@"Attempt to lock a fault in a database channel"]; + } + + // Check if we can lock + if ([databaseContext updateStrategy] == EONoUpdate) { + [self privateReportError:_cmd : + @"cannot lock if context has 'NoUpdate' update strategy."]; + return NO; + } + + // Check if in a transaction + if (![databaseContext transactionNestingLevel]) { + [self privateReportError:_cmd : + @"cannot lock if contex has no transaction opened."]; + return NO; + } + + // Check if fetch is in progress + if ([self isFetchInProgress]) { + [self privateReportError:_cmd : + @"cannot lock if contex has a fetch in progress."]; + return NO; + } + + // Get entity + entity = [anObj respondsToSelector:@selector(entity)] + ? [anObj entity] + : [[[[adaptorChannel adaptorContext] adaptor] model] entityForObject:anObj]; + + // Check entity + if (entity == nil) { + [self privateReportError:_cmd : + @"cannot determine entity for object %p class %s.", + anObj, NSStringFromClass([anObj class])]; + return NO; + } + if ([entity isReadOnly]) { + [self privateReportError:_cmd : + @"cannot lock object %p for readonly entity %@.", + anObj, [entity name]]; + return NO; + } + + // Get snapshot and old primary key + [databaseContext primaryKey:&pkey andSnapshot:&snapshot forObject:anObj]; + if (snapshot == nil) { + [self privateReportError:_cmd : + @"cannot lock object %p because there is no snapshot for it."]; + return NO; + } + + if (pkey == nil) + pkey = [entity primaryKeyForRow:snapshot]; + + if (pkey == nil) { + [self privateReportError:_cmd : + @"cannot determine primary key for %p from values %@ entity %@.", + anObj, [snapshot description], [entity name]]; + return NO; + } + + { + NSArray *lockAttrs = [entity attributesUsedForLocking]; + NSDictionary *row = nil; + + qualifier = [EOSQLQualifier qualifierForPrimaryKey:pkey entity:entity]; + +#ifdef DEBUG + NSAssert2([lockAttrs count] > 0, + @"missing locking attributes: lock=%@ object=%@", + lockAttrs, anObj); +#endif + if (![adaptorChannel selectAttributes:lockAttrs + describedByQualifier:qualifier + fetchOrder:nil + lock:YES]) { + [self privateReportError:_cmd : + @"could not lock %p with qualifier %@.", + anObj, [qualifier description]]; + return NO; + } + row = [adaptorChannel fetchAttributes:lockAttrs withZone:NULL]; + [adaptorChannel cancelFetch]; + if (row == nil) { + [self privateReportError:_cmd : + @"could not lock %p with qualifier %@.", + anObj, [qualifier description]]; + return NO; + } + if (![row isEqual:snapshot]) { + [self privateReportError:_cmd : + @"could not lock %p. Snapshots: self %@ database %@.", + anObj, [snapshot description], [row description]]; + return NO; + } + } + + // Register lock object in database context + [databaseContext recordLockedObject:anObj]; + + self->lockCount++; + [anObj wasLockedInChannel:self context:self->databaseContext]; + + // Notify delegate + if ([delegate respondsToSelector:@selector(databaseChannel:didLockObject:)]) + [delegate databaseChannel:self didLockObject:anObj]; + [self postNotification:EODatabaseChannelDidLockObjectName object:anObj]; + return YES; +} + +- (BOOL)refetchObject:(id)anObj { + EOEntity *entity = nil; + NSDictionary *pkey = nil; + NSDictionary *snapshot = nil; + EOSQLQualifier *qualifier = nil; + + // Check the delegate + if ([delegate respondsToSelector: + @selector(databaseChannel:willRefetchObject:)]) + anObj = [delegate databaseChannel:self willRefetchObject:anObj]; + + // Check nil (delegate disallowes or given object was nil) + if (anObj == nil) + return NO; + + // Check if fault + if ([EOFault isFault:anObj]) { + [NSException raise:NSInvalidArgumentException + format:@"Attempt to refetch a fault in a database channel"]; + } + + // Check if in a transaction + if (![databaseContext transactionNestingLevel]) { + [self privateReportError:_cmd : + @"cannot refetch if context has no transaction opened."]; + return NO; + } + + // Check if fetch is in progress + if ([self isFetchInProgress]) { + [self privateReportError:_cmd : + @"cannot refetch if context has a fetch in progress."]; + return NO; + } + + // Get entity + entity = [anObj respondsToSelector:@selector(entity)] + ? [anObj entity] + : [[[[adaptorChannel adaptorContext] adaptor] model] entityForObject:anObj]; + + // Check entity + if (entity == nil) { + [self privateReportError:_cmd : + @"cannot determine entity for object %p class %s.", + anObj, NSStringFromClass([anObj class])]; + return NO; + } + + // Get snapshot and old primary key + [databaseContext primaryKey:&pkey andSnapshot:&snapshot forObject:anObj]; + if (pkey == nil) { + if (snapshot == nil) + [self privateReportError:_cmd : + @"cannot refetch object %p because there is no snapshot for it."]; + pkey = [entity primaryKeyForRow:snapshot]; + } + if (pkey == nil) { + [self privateReportError:_cmd : + @"cannot determine primary key for %p from values %@ entity %@.", + anObj, [snapshot description], [entity name]]; + return NO; + } + + // Get and check qualifier for object to refetch + qualifier = [EOSQLQualifier qualifierForPrimaryKey:pkey entity:entity]; + if (qualifier == nil) { + [self privateReportError:_cmd : + @"cannot make qualifier to refetch %p primary key %@ entity %@.", + anObj, [pkey description], [entity name]]; + return NO; + } + + // Request object from adaptor + [self setCurrentEntity:entity]; + [self privateUpdateCurrentEntityInfo]; + if (currentAttributes == nil) { + [self privateReportError:_cmd : + @"internal inconsitency while refetching %p.", anObj]; + return NO; + } + +#ifdef DEBUG + NSAssert3([currentAttributes count] > 0, + @"missing attributes for select: lock=%@ object=%@ entity=%@", + currentAttributes, anObj, entity); +#endif + if (![adaptorChannel selectAttributes:currentAttributes + describedByQualifier:qualifier + fetchOrder:nil + lock:([databaseContext updateStrategy] == + EOUpdateWithPessimisticLocking)]) { + [self privateClearCurrentEntityInfo]; + return NO; + } + + // Get object from adaptor, re-build its faults and record new snapshot + anObj = [self privateFetchWithZone:NULL]; + [self cancelFetch]; + if (anObj == nil) { + [self privateReportError:_cmd : + @"could not refetch %p with qualifier %@.", + anObj, [qualifier description]]; + return NO; + } + + // Notify delegate + if ([delegate respondsToSelector:@selector(databaseChannel:didRefetchObject:)]) + [delegate databaseChannel:self didRefetchObject:anObj]; + return YES; +} + +- (id)_createObjectForRow:(NSDictionary*)aRow entity:(EOEntity*)anEntity + isPrimaryKey:(BOOL)yn zone:(NSZone*)zone { + Class class = Nil; + id anObj = nil; + + if (anEntity == nil) + return nil; + + class = [self privateClassForEntity:anEntity]; + + // Create new instance + if ([class respondsToSelector:@selector(classForEntity:values:)]) + class = [class classForEntity:anEntity values:aRow]; + + anObj = [class allocWithZone:zone]; + + return anObj; +} + +- (id)allocateObjectForRow:(NSDictionary *)row entity:(EOEntity *)anEntity + zone:(NSZone *)zone { + + Class class = Nil; + id anObj = nil; + + if (anEntity == nil) + return nil; + + class = [self privateClassForEntity:anEntity]; + + // Create new instance + if ([class respondsToSelector:@selector(classForEntity:values:)]) + class = [class classForEntity:anEntity values:row]; + + anObj = [class allocWithZone:zone]; + + return anObj; +} + +- (id)initializedObjectForRow:(NSDictionary *)row + entity:(EOEntity *)anEntity + zone:(NSZone *)zone +{ + id anObj; + + anObj = [self allocateObjectForRow:row entity:anEntity zone:zone]; + + anObj = [anObj respondsToSelector:@selector(initWithPrimaryKey:entity:)] + ? [anObj initWithPrimaryKey:row entity:anEntity] + : [anObj init]; + + return AUTORELEASE(anObj); +} + +/* + * Fetching objects + */ + +- (id)_fetchObject:(id)anObj qualifier:(EOSQLQualifier *)qualifier { + id obj; + + [self selectObjectsDescribedByQualifier:qualifier fetchOrder:nil]; + obj = [self fetchWithZone:NULL]; + [self cancelFetch]; + return obj; +} + +- (BOOL)selectObjectsDescribedByQualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder +{ + if ([delegate respondsToSelector: + @selector(databaseChannel:willSelectObjectsDescribedByQualifier:fetchOrder:)]) + if (![delegate databaseChannel:self + willSelectObjectsDescribedByQualifier:qualifier + fetchOrder:fetchOrder]) + return NO; + + [self setCurrentEntity:[qualifier entity]]; + [self privateUpdateCurrentEntityInfo]; + if (self->currentAttributes == nil) { + [self privateReportError:_cmd : + @"internal inconsitency while selecting."]; + } +#ifdef DEBUG + NSAssert3([self->currentAttributes count] > 0, + @"missing select attributes: attrs=%@, qualifier=%@, entity=%@", + self->currentAttributes, qualifier, self->currentEntity); +#endif + if (![adaptorChannel selectAttributes:self->currentAttributes + describedByQualifier:qualifier + fetchOrder:fetchOrder + lock:([databaseContext updateStrategy] == + EOUpdateWithPessimisticLocking)]) { + [self privateClearCurrentEntityInfo]; + [self privateReportError:_cmd : + @"could not select attributes with qualifier %@.", + [qualifier description]]; + return NO; + } + + if ([delegate respondsToSelector: + @selector(databaseChannel:didSelectObjectsDescribedByQualifier:fetchOrder:)]) + [delegate databaseChannel:self + didSelectObjectsDescribedByQualifier:qualifier + fetchOrder:fetchOrder]; + return YES; +} + +- (id)fetchWithZone:(NSZone *)zone { + id object = nil; + + if ([delegate respondsToSelector: + @selector(databaseChannel:willFetchObjectOfClass:withZone:)]) { + Class class; + + class = currentClass + ? currentClass + : [self privateClassForEntity:currentEntity]; + + [delegate databaseChannel:self + willFetchObjectOfClass:class + withZone:zone]; + } + object = [self privateFetchWithZone:zone]; + if (object == nil) + return nil; + + if ([delegate respondsToSelector:@selector(databaseChannel:didFetchObject:)]) + [delegate databaseChannel:self didFetchObject:object]; + + return object; +} + +- (BOOL)isFetchInProgress { + return [[self adaptorChannel] isFetchInProgress]; +} + +- (void)cancelFetch { + if ([[self adaptorChannel] isFetchInProgress]) { + [self privateClearCurrentEntityInfo]; + [[self adaptorChannel] cancelFetch]; + } +} + +- (void)setCurrentEntity:(EOEntity *)_entity { + // Clear entity info + [self privateClearCurrentEntityInfo]; + // Set new entity + NSAssert(self->currentEntity == nil, @"entity not cleared correctly .."); + self->currentEntity = RETAIN(_entity); +} + +- (void)privateClearCurrentEntityInfo { + RELEASE(self->currentEntity); self->currentEntity = nil; + RELEASE(self->currentAttributes); self->currentAttributes = nil; + RELEASE(self->currentRelations); self->currentRelations = nil; + self->currentClass = Nil; + self->currentReady = NO; +} + +- (void)privateUpdateCurrentEntityInfo { + if (self->currentEntity == nil) { + [NSException raise:NSInvalidArgumentException + format:@"Must use setCurrentEntity if select is not done " + @"through database"]; + } + + if (self->currentAttributes == nil) + self->currentAttributes = + RETAIN([self->currentEntity attributesUsedForFetch]); + if (self->currentRelations == nil) + self->currentRelations = RETAIN([self->currentEntity relationsUsedForFetch]); + self->currentReady = YES; +} + +/* + * Private methods + */ + +- (Class)privateClassForEntity:(EOEntity *)anEntity { + Class class; + + if (anEntity == currentEntity && currentClass) + return currentClass; + + // Get class for new object + class = NSClassFromString([anEntity className]); + + if (!class && [delegate respondsToSelector: + @selector(databaseChannel:failedToLookupClassNamed:)]) + class = [delegate databaseChannel:self + failedToLookupClassNamed:[[anEntity className] cString]]; + if (class == Nil) + class = [EOGenericRecord class]; + + if (anEntity == currentEntity) + currentClass = class; + + return class; +} + +- (id)privateFetchWithZone:(NSZone *)_zone { + NSMutableDictionary *values = nil; + id object = nil; + NSDictionary *pkey = nil; + NSDictionary *snapshot = nil; + NSDictionary *row = nil; + NSDictionary *dict = nil;; + + // Be sure we have entity info (raises if no entity is set) + if (!self->currentReady) + [self privateUpdateCurrentEntityInfo]; + + // fetch row from adaptor + row = [[self adaptorChannel] fetchAttributes:self->currentAttributes + withZone:_zone]; + if (row == nil) + // Results set finished or no more result sets + return nil; +#if 0 + row = [row copyWithZone:_zone]; + AUTORELEASE(row); +#endif + + // determine primary key and snapshot + snapshot = [self->currentEntity snapshotForRow:row]; + pkey = [self->currentEntity primaryKeyForRow:row]; + + if ((pkey == nil) || (snapshot == nil)) { + // TODO - should we have a delegate method here ? + [NSException raise:NSInvalidArgumentException + format:@"Cannot determine primary key and snapshot for row"]; + } + + // lookup object in context/database + object = [self->databaseContext objectForPrimaryKey:pkey + entity:currentEntity]; + + // use old, make new, clear fault + if (object == nil) { + //NSLog(@"new anObj\n"); + object = [self initializedObjectForRow:row + entity:currentEntity + zone:_zone]; + } + if ([EOFault isFault:object]) { + [EODatabaseFault clearFault:object]; + + object = [object respondsToSelector:@selector(initWithPrimaryKey:entity:)] + ? [object initWithPrimaryKey:row entity:currentEntity] + : [object init]; + + if (object == nil) { + [NSException raise:NSInvalidArgumentException + format:@"could not initialize cleared fault with " + @"row `%@' and entity %@", + [row description], [currentEntity name]]; + } + } + + // make values + // TODO - handle only class properties to object + values = [NSMutableDictionary dictionaryWithCapacity: + ([row count] + [currentRelations count])]; + [values addEntriesFromDictionary:row]; + + // resolve relationships (to-one and to-many) + { + EORelationship *rel = nil; + int i, n = [self->currentRelations count]; + id fault = nil; + + for (i = 0; i < n; i++) { + rel = [self->currentRelations objectAtIndex:i]; + + // Check if the delegate can provide a different relationship + if ([delegate respondsToSelector: + @selector(databaseChannel:relationshipForRow:relationship:)]) { + id nrel = [delegate databaseChannel:self + relationshipForRow:row + relationship:rel]; + rel = nrel ? nrel : rel; + } + if ([rel isToMany]) { + // Build to-many fault + EOSQLQualifier* qualifier = + [EOSQLQualifier qualifierForRow:row relationship:rel]; + + if (qualifier == nil) { + // HH: THROW was uncommented .. + [NSException raise:NSInvalidArgumentException + format: + @"Cannot build fault qualifier for relationship"]; + // TODO + continue; + } + +#if LIB_FOUNDATION_LIBRARY + if ([NSClassFromString([[rel destinationEntity] className]) + isGarbageCollectable]) + fault = [EODatabaseFault gcArrayFaultWithQualifier:qualifier + fetchOrder:nil + databaseChannel:self + zone:_zone]; + else +#endif + fault = [EODatabaseFault arrayFaultWithQualifier:qualifier + fetchOrder:nil + databaseChannel:self + zone:_zone]; + } + else { + // Build to-one fault + EOEntity *faultEntity; + NSDictionary *faultKey; + + faultEntity = [rel destinationEntity]; + faultKey = [rel foreignKeyForRow:row]; + faultKey = [faultEntity primaryKeyForRow:faultKey]; + + if (faultEntity == nil) { + [NSException raise:NSInvalidArgumentException + format:@"Cannot get entity for relationship"]; + } + + if (faultKey) { + fault = [self->databaseContext objectForPrimaryKey:faultKey + entity:faultEntity]; + if (fault == nil) { + fault = [EODatabaseFault objectFaultWithPrimaryKey:faultKey + entity:faultEntity + databaseChannel:self + zone:_zone]; + [databaseContext recordObject:fault + primaryKey:faultKey + entity:faultEntity + snapshot:nil]; + } + } + else + fault = [EONull null]; + } + + if (fault) + [values setObject:fault forKey:[rel name]]; + } + } + + // check if is updated in another context or just updated or new (delegate) + dict = values; + if ([[databaseContext database] isObject:object + updatedOutsideContext:databaseContext]) { + if ([delegate respondsToSelector: + @selector(databaseChannel:willRefetchConflictingObject:withSnapshot:)]) { + dict = [delegate databaseChannel:self + willRefetchConflictingObject:object + withSnapshot:values]; + } + else { + [NSException raise:NSInvalidArgumentException + format:@"object updated in an uncommitted transaction " + @"was fetched"]; + } + } + else { + if ([delegate respondsToSelector: + @selector(databaseChannel:willRefetchObject:fromSnapshot:)]) { + dict = [delegate databaseChannel:self + willRefetchObject:object + fromSnapshot:values]; + } + } + // does delegate disallow setting the new values and recording the fetch ? + if (dict == nil) + return object; + + // put values + [object takeValuesFromDictionary:dict]; + + // register lock if locked + if ([databaseContext updateStrategy] == EOUpdateWithPessimisticLocking) + [databaseContext recordLockedObject:object]; + + // register object in context + [databaseContext recordObject:object + primaryKey:pkey + entity:currentEntity + snapshot:snapshot]; + + // awake object from database channel + if ([object respondsToSelector:@selector(awakeForDatabaseChannel:)]) + [object awakeForDatabaseChannel:self]; + + // Done. + return object; +} + +// ******************** Reporting errors ******************** + +- (void)privateReportError:(SEL)method :(NSString*)format,... { + NSString* message; + va_list va; + + if (![[databaseContext database] logsErrorMessages]) + return; + + va_start(va, format); + message = AUTORELEASE([[NSString alloc] initWithFormat:format arguments:va]); + va_end(va); + + [[databaseContext database] + reportErrorFormat: + @"EODatabaseChannel:error in [EODatabaseChannel %@]: %@", + NSStringFromSelector(method), message]; +} + +@end /* EODatabaseChannel */ + +@implementation NSObject(EODatabaseChannelEONotifications) + +- (BOOL)prepareForDeleteInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ + return YES; +} +- (void)wasDeletedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ +} + +- (BOOL)prepareForInsertInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ + return YES; +} +- (void)wasInsertedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ +} + +- (BOOL)prepareForUpdateInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ + return YES; +} +- (void)wasUpdatedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ +} + +- (BOOL)prepareForLockInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ + return YES; +} +- (void)wasLockedInChannel:(EODatabaseChannel *)_channel + context:(EODatabaseContext *)_ctx +{ +} + +@end /* NSObject(EODatabaseChannelNotifications) */ + +@implementation EODatabaseChannel(Statistics) + +- (unsigned int)successfulOpenCount { + return self->successfulOpenCount; +} + +- (unsigned int)failedOpenCount { + return self->failedOpenCount; +} + +- (unsigned int)closeCount { + return self->closeCount; +} + +- (unsigned int)insertCount { + return self->insertCount; +} + +- (unsigned int)updateCount { + return self->updateCount; +} + +- (unsigned int)deleteCount { + return self->deleteCount; +} + +- (unsigned int)lockCount { + return self->lockCount; +} + +@end diff --git a/sope-gdl1/GDLAccess/EODatabaseContext.m b/sope-gdl1/GDLAccess/EODatabaseContext.m new file mode 100644 index 00000000..99346997 --- /dev/null +++ b/sope-gdl1/GDLAccess/EODatabaseContext.m @@ -0,0 +1,870 @@ +/* + EODatabaseContext.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + Author: Helge Hess + Date: 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EODatabaseContext.h" +#import "EOAdaptor.h" +#import "EOAdaptorContext.h" +#import "EODatabase.h" +#import "EODatabaseChannel.h" +#import "EOEntity.h" +#import "EODatabaseFault.h" +#import "EOGenericRecord.h" +#import "EOModel.h" +#import "EOObjectUniquer.h" +#include "EOModelGroup.h" +#include +#include + +NSString *EODatabaseContextWillBeginTransactionName = + @"EODatabaseContextWillBeginTransaction"; +NSString *EODatabaseContextDidBeginTransactionName = + @"EODatabaseContextDidBeginTransaction"; +NSString *EODatabaseContextWillRollbackTransactionName = + @"EODatabaseContextWillRollbackTransaction"; +NSString *EODatabaseContextDidRollbackTransactionName = + @"EODatabaseContextDidRollbackTransaction"; +NSString *EODatabaseContextWillCommitTransactionName = + @"EODatabaseContextWillCommitTransaction"; +NSString *EODatabaseContextDidCommitTransactionName = + @"EODatabaseContextDidCommitTransaction"; + +struct EODatabaseContextModificationQueue { + struct EODatabaseContextModificationQueue *next; + enum { + update, + delete, + insert + } op; + id object; +}; + +/* + * Transaction scope + */ + +typedef struct _EOTransactionScope { + struct _EOTransactionScope *previous; + EOObjectUniquer *objectsDictionary; + NSMutableArray *objectsUpdated; + NSMutableArray *objectsDeleted; + NSMutableArray *objectsLocked; +} EOTransactionScope; + +static inline EOTransactionScope *_newTxScope(NSZone *_zone) { + EOTransactionScope *newScope; + + newScope = NSZoneMalloc(_zone, sizeof(EOTransactionScope)); + newScope->objectsDictionary = [[EOObjectUniquer allocWithZone:_zone] init]; + newScope->objectsUpdated = [[NSMutableArray allocWithZone:_zone] init]; + newScope->objectsDeleted = [[NSMutableArray allocWithZone:_zone] init]; + newScope->objectsLocked = [[NSMutableArray allocWithZone:_zone] init]; + + return newScope; +} +static inline void _freeTxScope(NSZone *_zone, EOTransactionScope *_txScope) { + RELEASE(_txScope->objectsDictionary); _txScope->objectsDictionary = nil; + RELEASE(_txScope->objectsUpdated); _txScope->objectsUpdated = nil; + RELEASE(_txScope->objectsDeleted); _txScope->objectsDeleted = nil; + RELEASE(_txScope->objectsLocked); _txScope->objectsLocked = nil; + NSZoneFree(_zone, _txScope); _txScope = NULL; +} + +@implementation EODatabaseContext + +#if 0 // no such callback! ++ (void)initialize { + static BOOL isInitialized = NO; + if (!isInitialized) { + isInitialized = YES; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(_objectStoreNeeded:) + name:@"EOCooperatingObjectStoreNeeded" + object:nil]; + } +} +#endif + +static inline void _checkTxInProgress(EODatabaseContext *self, + const char *_function) +{ + if (self->transactionNestingLevel == 0) { + [NSException raise:NSInternalInconsistencyException + format: + @"EODatabaseContext:%x: No transaction in progress " + @"in %s", self, _function]; + } +} + +// init + +- (id)initWithDatabase:(EODatabase *)aDatabase { + static int reuseAdaptorCtx = -1; + if (reuseAdaptorCtx == -1) { + reuseAdaptorCtx = [[[NSUserDefaults standardUserDefaults] + objectForKey:@"EOReuseAdaptorContext"] + boolValue] ? 1 : 0; + } + if (reuseAdaptorCtx) { + NSEnumerator *contexts; + EOAdaptorContext *actx; + + contexts = [[[aDatabase adaptor] contexts] objectEnumerator]; + while ((actx = [contexts nextObject])) { + if (![actx hasOpenTransaction]) { +#if DEBUG + NSLog(@"reuse adaptor context: %@", actx); +#endif + self->adaptorContext = actx; + break; + } + } + if (self->adaptorContext == nil) + self->adaptorContext = [[aDatabase adaptor] createAdaptorContext]; + } + else + self->adaptorContext = [[aDatabase adaptor] createAdaptorContext]; + + if ((aDatabase == nil) || (adaptorContext == nil)) { + NSLog(@"EODatabaseContext could not create adaptor context"); + AUTORELEASE(self); + return nil; + } + RETAIN(self->adaptorContext); + + self->database = RETAIN(aDatabase); + self->channels = [[NSMutableArray allocWithZone:[self zone]] init]; + self->transactionStackTop = NULL; + self->transactionNestingLevel = 0; + self->updateStrategy = EOUpdateWithOptimisticLocking; + self->isKeepingSnapshots = YES; + self->isUniquingObjects = [self->database uniquesObjects]; + + [database contextDidInit:self]; + return self; +} + +- (void)dealloc { + [database contextWillDealloc:self]; + + if (self->ops) { + struct EODatabaseContextModificationQueue *q; + + while ((q = self->ops)) { + self->ops = q->next; + RELEASE(q->object); + free(q); + } + } + + while (self->transactionNestingLevel) { + if (![self rollbackTransaction]) + break; + } + while (self->transactionStackTop) + [self privateRollbackTransaction]; + + RELEASE(self->adaptorContext); self->adaptorContext = nil; + RELEASE(self->database); self->database = nil; + RELEASE(self->channels); self->channels = nil; + [super dealloc]; +} + +/* accessors */ + +- (void)setDelegate:(id)_delegate { + self->delegate = _delegate; +} +- (id)delegate { + return self->delegate; +} + +- (EODatabase *)database { + return self->database; +} + +- (EOAdaptorContext *)adaptorContext { + return self->adaptorContext; +} + +// channels + +- (BOOL)hasBusyChannels { + int i; + + for (i = [channels count]-1; i >= 0; i--) { + if ([[[channels objectAtIndex:i] nonretainedObjectValue] + isFetchInProgress]) + return YES; + } + return NO; +} + +- (BOOL)hasOpenChannels { + int i; + + for (i = [channels count]-1; i >= 0; i--) { + if ([[[channels objectAtIndex:i] nonretainedObjectValue] isOpen]) + return YES; + } + return NO; +} + +- (NSArray *)channels { + return [self registeredChannels]; +} + +- (id)createChannel { + return AUTORELEASE([[EODatabaseChannel alloc] initWithDatabaseContext:self]); +} + +- (void)channelDidInit:(id)aChannel { + [self registerChannel:aChannel]; +} + +- (void)channelWillDealloc:(id)aChannel { + [self unregisterChannel:aChannel]; +} + +/* + * Controlling transactions + */ + +- (BOOL)beginTransaction { + NSNotificationCenter *nc; + + if ([adaptorContext transactionNestingLevel] != + (unsigned)transactionNestingLevel) { + [NSException raise:NSInternalInconsistencyException + format: + @"EODatabaseContext:%x:transaction nesting levels do not match: " + @"database has %d, adaptor has %d, " + @"in [EODatabaseContext beginTransaction]", + self, transactionNestingLevel, + [adaptorContext transactionNestingLevel]]; + } + + nc = [NSNotificationCenter defaultCenter]; + + [nc postNotificationName:EODatabaseContextWillBeginTransactionName + object:self]; + + if (![self->adaptorContext beginTransaction]) + return NO; + [self privateBeginTransaction]; + + txBeginCount++; + [nc postNotificationName:EODatabaseContextDidBeginTransactionName + object:self]; + return YES; +} + +- (BOOL)commitTransaction { + NSNotificationCenter *nc; + + _checkTxInProgress(self, __PRETTY_FUNCTION__); + + if ([adaptorContext transactionNestingLevel] != + (unsigned)self->transactionNestingLevel) { + [NSException raise:NSInternalInconsistencyException + format: + @"EODatabaseContext:%x:transaction nesting levels do not match: " + @"database has %d, adaptor has %d, " + @"in [EODatabaseContext commitTransaction]", + self, transactionNestingLevel, + [adaptorContext transactionNestingLevel]]; + } + + nc = [NSNotificationCenter defaultCenter]; + [nc postNotificationName:EODatabaseContextWillCommitTransactionName + object:self]; + + if (![adaptorContext commitTransaction]) + return NO; + [self privateCommitTransaction]; + + self->txCommitCount++; + [nc postNotificationName:EODatabaseContextDidCommitTransactionName + object:self]; + return YES; +} + +- (BOOL)rollbackTransaction { + NSNotificationCenter *nc; + + _checkTxInProgress(self, __PRETTY_FUNCTION__); + + if ([self->adaptorContext transactionNestingLevel] != + (unsigned)self->transactionNestingLevel) { + [NSException raise:NSInternalInconsistencyException + format: + @"EODatabaseContext:%x:transaction nesting levels do not match: " + @"database has %d, adaptor has %d, " + @"in [EODatabaseContext rollbackTransaction]", + self, transactionNestingLevel, + [adaptorContext transactionNestingLevel]]; + } + + nc = [NSNotificationCenter defaultCenter]; + [nc postNotificationName:EODatabaseContextWillRollbackTransactionName + object:self]; + + if (![self->adaptorContext rollbackTransaction]) + return NO; + [self privateRollbackTransaction]; + + self->txRollbackCount++; + [nc postNotificationName:EODatabaseContextDidRollbackTransactionName + object:self]; + return YES; +} + + +// ******************** notifications ******************** + +- (void)transactionDidBegin { + [self->adaptorContext transactionDidBegin]; + [self privateBeginTransaction]; +} + +- (void)transactionDidCommit { + _checkTxInProgress(self, __PRETTY_FUNCTION__); + [self->adaptorContext transactionDidCommit]; + [self privateCommitTransaction]; +} + +- (void)transactionDidRollback { + _checkTxInProgress(self, __PRETTY_FUNCTION__); + [adaptorContext transactionDidRollback]; + [self privateRollbackTransaction]; +} + +/* + * Nesting transactions + */ + +- (BOOL)canNestTransactions { + return [adaptorContext canNestTransactions]; +} +- (unsigned)transactionNestingLevel { + return transactionNestingLevel; +} + +/* + * Setting the update strategy + */ + +- (void)setUpdateStrategy:(EOUpdateStrategy)aStrategy { + if ([self transactionNestingLevel]) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot change update strategy " + @"when context has a transaction open, " + @"in [EODatabaseContext setUpdateStrategy]", + self]; + } + updateStrategy = aStrategy; + isKeepingSnapshots = (updateStrategy == EOUpdateWithNoLocking) ? NO : YES; + isUniquingObjects = [database uniquesObjects]; +} + +- (EOUpdateStrategy)updateStrategy { + return self->updateStrategy; +} + +- (BOOL)keepsSnapshots { + return self->isKeepingSnapshots; +} + +/* + * Processing transactions internally + */ + +- (void)privateBeginTransaction { + EOTransactionScope *newScope = NULL; + + newScope = _newTxScope([self zone]); + newScope->previous = transactionNestingLevel ? transactionStackTop : NULL; + transactionStackTop = newScope; + transactionNestingLevel++; + + if (transactionNestingLevel == 1) + self->isUniquingObjects = [database uniquesObjects]; +} + +- (void)privateCommitTransaction { + EOTransactionScope *newScope = transactionStackTop; + + transactionStackTop = newScope->previous; + transactionNestingLevel--; + + // In nested transaction fold updated and deleted objects + // into the parent transaction; locked objects are forgotten + // deleted objects are deleted form the parent transaction + if (transactionNestingLevel) { + // Keep updated objects + [transactionStackTop->objectsUpdated + addObjectsFromArray:newScope->objectsUpdated]; + // Keep deleted objects + [transactionStackTop->objectsDeleted + addObjectsFromArray:newScope->objectsDeleted]; + // Register objects in parent transaction scope + [newScope->objectsDictionary + transferTo:transactionStackTop->objectsDictionary + objects:YES andSnapshots:YES]; + } + // If this was the first transaction then fold the changes + // into the database; locked and updateted objects are forgotten + else { + int i, n; + + for (i = 0, n = [newScope->objectsDeleted count]; i < n; i++) + [database forgetObject:[newScope->objectsDeleted objectAtIndex:i]]; + + // Register objects into the database + if (self->isUniquingObjects || [database keepsSnapshots]) { + [newScope->objectsDictionary transferTo:[database objectUniquer] + objects:self->isUniquingObjects + andSnapshots:[database keepsSnapshots]]; + } + } + + // Kill transaction scope + _freeTxScope([self zone], newScope); +} + +- (void)privateRollbackTransaction { + EOTransactionScope *newScope = transactionStackTop; + + transactionStackTop = newScope->previous; + transactionNestingLevel--; + + // Forget snapshots, updated, deleted and locked objects + // in current transaction + + // Kill transaction scope + _freeTxScope([self zone], newScope); +} + +// Handle Objects + +- (void)forgetObject:(id)_object { + EOTransactionScope *scope = NULL; + + _checkTxInProgress(self, __PRETTY_FUNCTION__); + + if (_object == nil) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot forget null object, " + @"in [EODatabaseContext forgetObject]", + self]; + } + if ([EOFault isFault:_object]) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot forget forget a fault object, " + @"in [EODatabaseContext forgetObject]", + self]; + } + + [transactionStackTop->objectsDeleted addObject:_object]; + + for (scope = transactionStackTop; scope; scope = scope->previous) { + [scope->objectsDictionary forgetObject:_object]; + } +} + +- (id)objectForPrimaryKey:(NSDictionary *)_key entity:(EOEntity *)_entity { + EOTransactionScope *scope = NULL; + id _object = nil; + + if (!self->isUniquingObjects || (_key == nil) || (_entity == nil)) + return nil; + + _key = [_entity primaryKeyForRow:_key]; + if (_key == nil) return nil; + + for (scope = transactionStackTop; scope; scope = scope->previous) { + _object = [scope->objectsDictionary objectForPrimaryKey:_key + entity:_entity]; + if (_object) + return _object; + } + + return [self->database objectForPrimaryKey:_key entity:_entity]; +} + +- (void)recordObject:(id)_object + primaryKey:(NSDictionary *)_key + entity:(EOEntity *)_entity + snapshot:(NSDictionary *)snapshot +{ + _checkTxInProgress(self, __PRETTY_FUNCTION__); + + if (_object == nil) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record null object, " + @"in [EODatabaseContext recordObject:primaryKey:entity:snapshot:]", + self]; + } + if ((_entity == nil) && self->isUniquingObjects) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record object with null entity " + @"when uniquing objects, " + @"in [EODatabaseContext recordObject:primaryKey:entity:snapshot:]", + self]; + } + + _key = [_entity primaryKeyForRow:_key]; + + if ((_key == nil) && self->isUniquingObjects) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record object with null key " + @"when uniquing objects, " + @"in [EODatabaseContext recordObject:primaryKey:entity:snapshot:]", + self]; + } + if ((snapshot == nil) && isKeepingSnapshots && ![EOFault isFault:_object]) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record object with null snapshot " + @"when keeping snapshots, " + @"in [EODatabaseContext recordObject:primaryKey:entity:snapshot:]" + @": snapshot=%s keepsSnapshots=%s isFault=%s", + self, + snapshot ? "yes" : "no", + isKeepingSnapshots ? "yes" : "no", + [EOFault isFault:_object] ? "yes" : "no"]; + } + + if (self->isKeepingSnapshots || self->isUniquingObjects) { + EOObjectUniquer *cache = transactionStackTop->objectsDictionary; + + [cache recordObject:_object + primaryKey: self->isUniquingObjects ? _key : nil + entity: self->isUniquingObjects ? _entity : nil + snapshot: self->isKeepingSnapshots ? snapshot : nil]; + } +} + +- (void)recordObject:(id)_object + primaryKey:(NSDictionary *)_key + snapshot:(NSDictionary *)_snapshot +{ + EOEntity *entity = nil; + + entity = [_object respondsToSelector:@selector(entity)] + ? [_object entity] + : [[[database adaptor] model] entityForObject:_object]; + + [self recordObject:_object primaryKey:_key entity:entity snapshot:_snapshot]; +} + +- (NSDictionary *)snapshotForObject:(id)_object { + EOTransactionScope *scope = NULL; + EOUniquerRecord *rec = NULL; + + if (!isKeepingSnapshots) + return nil; + + for (scope = transactionStackTop; scope; scope = scope->previous) { + rec = [scope->objectsDictionary recordForObject:_object]; + if (rec) + return rec->snapshot; + } + + rec = [[self->database objectUniquer] recordForObject:_object]; + if (rec) return rec->snapshot; + + return nil; +} + +- (NSDictionary*)primaryKeyForObject:(id)_object { + EOTransactionScope *scope = NULL; + EOUniquerRecord *rec = NULL; + + if ([self->database uniquesObjects]) + return nil; + + for (scope = transactionStackTop; scope; scope = scope->previous) { + rec = [scope->objectsDictionary recordForObject:_object]; + if (rec) return rec->pkey; + } + + rec = [[self->database objectUniquer] recordForObject:_object]; + if (rec) return rec->pkey; + return nil; +} + +- (void)primaryKey:(NSDictionary **)_key + andSnapshot:(NSDictionary **)_snapshot + forObject:_object +{ + EOTransactionScope *scope = NULL; + EOUniquerRecord *rec = NULL; + + if (!self->isKeepingSnapshots && ![self->database uniquesObjects]) { + *_key = *_snapshot = nil; + return; + } + + for (scope = transactionStackTop; scope; scope = scope->previous) { + rec = [scope->objectsDictionary recordForObject:_object]; + if (rec) { + if (_key) *_key = rec->pkey; + if (_snapshot) *_snapshot = rec->snapshot; + return; + } + } + + rec = [[self->database objectUniquer] recordForObject:_object]; + if (rec) { + if (_key) *_key = rec->pkey; + if (_snapshot) *_snapshot = rec->snapshot; + return; + } + + if (_key) *_key = nil; + if (_snapshot) *_snapshot = nil; +} + +- (void)recordLockedObject:(id)_object { + _checkTxInProgress(self, __PRETTY_FUNCTION__); + + if (_object == nil) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record null object as locked, " + @"in [EODatabaseContext recordLockedObject:]", + self]; + } + if ([EOFault isFault:_object]) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record a fault object as locked, " + @"in [EODatabaseContext recordLockedObject:]", + self]; + } + [transactionStackTop->objectsLocked addObject:_object]; +} + +- (BOOL)isObjectLocked:(id)_object { + EOTransactionScope *scope; + + for (scope = transactionStackTop; scope; scope = scope->previous) { + if ([scope->objectsLocked indexOfObjectIdenticalTo:_object]!=NSNotFound) + return YES; + } + return NO; +} + +- (void)recordUpdatedObject:(id)_object { + _checkTxInProgress(self, __PRETTY_FUNCTION__); + + if (_object == nil) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record null object as updatetd, " + @"in [EODatabaseContext recordUpdatedObject:]", + self]; + } + if ([EOFault isFault:_object]) { + [NSException raise:NSInvalidArgumentException + format: + @"EODatabaseContext:%x: Cannot record fault object as updated, " + @"in [EODatabaseContext recordUpdatedObject:]", + self]; + } + + [transactionStackTop->objectsUpdated addObject:_object]; +} + +- (BOOL)isObjectUpdated:(id)_object { + EOTransactionScope *scope; + + for (scope = transactionStackTop; scope; scope = scope->previous) { + if ([scope->objectsUpdated indexOfObjectIdenticalTo:_object] != NSNotFound) + return YES; + if ([scope->objectsDeleted indexOfObjectIdenticalTo:_object] != NSNotFound) + return YES; + } + return NO; +} + +/* description */ + +- (NSString *)description { + return [NSString stringWithFormat: + @"<%@[0x%08X]: #channels=%i tx-nesting=%i>", + NSStringFromClass([self class]), self, + [self->channels count], + [self transactionNestingLevel]]; +} + +@end /* EODatabaseContext */ + +@implementation EODatabaseContext(Statistics) + +- (unsigned int)transactionBeginCount { + return self->txBeginCount; +} +- (unsigned int)transactionCommitCount { + return self->txCommitCount; +} +- (unsigned int)transactionRollbackCount { + return self->txRollbackCount; +} + +@end /* EODatabaseContext(Statistics) */ + +@implementation EODatabaseContext(NewInEOF2) + +// THREAD +static Class EODatabaseContextClass = Nil; + ++ (void)setContextClassToRegister:(Class)_cclass { + EODatabaseContextClass = _cclass; +} ++ (Class)contextClassToRegister { + return EODatabaseContextClass ? EODatabaseContextClass : self; +} + +- (EODatabaseChannel *)availableChannel { + int i; + + for (i = [self->channels count] - 1; i >= 0; i--) { + EODatabaseChannel *channel; + + channel = [[self->channels objectAtIndex:i] nonretainedObjectValue]; + if (![channel isFetchInProgress]) + return channel; + } + + [[NSNotificationCenter defaultCenter] + postNotificationName:@"EODatabaseChannelNeeded" + object:self]; + + /* recheck for channel */ + + for (i = [self->channels count] - 1; i >= 0; i--) { + EODatabaseChannel *channel; + + channel = [[self->channels objectAtIndex:i] nonretainedObjectValue]; + if (![channel isFetchInProgress]) + return channel; + } + + return nil; +} + +- (NSArray *)registeredChannels { + NSMutableArray *array; + int i, n; + + array = [NSMutableArray array]; + for (i=0, n=[channels count]; i < n; i++) { + EODatabaseChannel *channel = + [[channels objectAtIndex:i] nonretainedObjectValue]; + + [array addObject:channel]; + } + + return array; +} +- (void)registerChannel:(EODatabaseChannel *)_channel { + [self->channels addObject:[NSValue valueWithNonretainedObject:_channel]]; +} +- (void)unregisterChannel:(EODatabaseChannel *)_channel { + int i; + + for (i = [self->channels count] - 1; i >= 0; i--) { + EODatabaseChannel *channel; + + channel = [[self->channels objectAtIndex:i] nonretainedObjectValue]; + + if (channel == _channel) { + [channels removeObjectAtIndex:i]; + break; + } + } +} + +/* cooperating object store */ + +- (void)commitChanges { + [self commitTransaction]; +} +- (void)rollbackChanges { + [self rollbackTransaction]; +} + +- (void)performChanges { + [self notImplemented:_cmd]; +} + +/* store specific properties */ + +- (NSDictionary *)valuesForKeys:(NSArray *)_keys object:(id)_object { + return [_object valuesForKeys:_keys]; +} + +/* capability */ + +- (BOOL)handlesFetchSpecification:(EOFetchSpecification *)_fspec { + EOEntity *entity; + + entity = [[self database] entityNamed:[_fspec entityName]]; + return entity ? YES : NO; +} + +/* graph */ + +- (BOOL)ownsObject:(id)_object { + EOEntity *entity; + + entity = [[self database] entityNamed:[_object entityName]]; + return entity ? YES : NO; +} + +- (BOOL)ownsGlobalID:(EOGlobalID *)_oid { + EOEntity *entity; + + if (![_oid respondsToSelector:@selector(entityName)]) + return NO; + + entity = [[self database] entityNamed:[(id)_oid entityName]]; + return entity ? YES : NO; +} + +@end /* EODatabaseContext(NewInEOF2) */ diff --git a/sope-gdl1/GDLAccess/EODatabaseFault.m b/sope-gdl1/GDLAccess/EODatabaseFault.m new file mode 100644 index 00000000..ce6895a3 --- /dev/null +++ b/sope-gdl1/GDLAccess/EODatabaseFault.m @@ -0,0 +1,246 @@ +/* + EODatabaseFault.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + Author: Helge Hess + Date: 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "EODatabaseFault.h" +#import "EODatabase.h" +#import "EODatabaseChannel.h" +#import "EOEntity.h" +#import "EOFExceptions.h" +#import "EODatabaseFaultResolver.h" +#import "EOArrayProxy.h" +#import "common.h" + +#if NeXT_RUNTIME || APPLE_RUNTIME +# include +#endif + +typedef struct { + Class isa; +} *my_objc_object; + +#define object_is_instance(object) \ + ((object!=nil)&&CLS_ISCLASS(((my_objc_object)object)->isa)) + +/* + * EODatabaseFault class + */ + +@implementation EODatabaseFault + +// Fault class methods + ++ (id)objectFaultWithPrimaryKey:(NSDictionary *)key + entity:(EOEntity *)entity + databaseChannel:(EODatabaseChannel *)channel + zone:(NSZone *)zone +{ + EODatabaseFault *fault = nil; + + fault = [channel allocateObjectForRow:key entity:entity zone:zone]; + + if (fault == nil) + return nil; + + if ([fault class]->instance_size < ((Class)self)->instance_size) { + [fault autorelease]; + [NSException raise:NSInvalidArgumentException + format: + @"Instances from class %@ must be at least %d in size " + @"to fault", + NSStringFromClass([fault class]), + ((Class)self)->instance_size]; + } + fault->faultResolver = [[EOObjectFault alloc] initWithPrimaryKey:key + entity:entity databaseChannel:channel zone:zone + targetClass:fault->isa]; + fault->isa = self; + + return (EODatabaseFault *)AUTORELEASE(fault); +} + ++ (NSArray*)arrayFaultWithQualifier:(EOSQLQualifier*)qualifier + fetchOrder:(NSArray*)fetchOrder + databaseChannel:(EODatabaseChannel*)channel + zone:(NSZone*)zone +{ + return [EOArrayProxy arrayProxyWithQualifier:qualifier + fetchOrder:fetchOrder + channel:channel]; +#if 0 + EODatabaseFault* fault; + + fault = [NSMutableArray allocWithZone:zone]; + + if ([fault class]->instance_size < ((Class)(self))->instance_size) { + (void)AUTORELEASE(fault); + THROW([[InvalidArgumentException alloc] + initWithFormat: + @"Instances from class %s must be at least %d " + @"in size to fault", + NSStringFromClass([fault class]), + ((Class)self)->instance_size]); + } + fault->faultResolver = [[EOArrayFault alloc] initWithQualifier:qualifier + fetchOrder:fetchOrder databaseChannel:channel zone:zone + targetClass:fault->isa fault:fault]; + fault->isa = self; + + return (NSArray*)AUTORELEASE(fault); +#endif +} + +// no more garbage collecting ++ (NSArray *)gcArrayFaultWithQualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + databaseChannel:(EODatabaseChannel *)channel + zone:(NSZone *)zone +{ + EODatabaseFault *fault; + + fault = [NSMutableArray allocWithZone:zone]; + + if ([fault class]->instance_size < ((Class)(self))->instance_size) { + (void)[fault autorelease]; + [NSException raise:NSInvalidArgumentException + format: + @"Instances from class %s must be at least %d " + @"in size to fault", + NSStringFromClass([fault class]), + ((Class)self)->instance_size]; + } + fault->faultResolver = [[EOArrayFault alloc] initWithQualifier:qualifier + fetchOrder:fetchOrder databaseChannel:channel zone:zone + targetClass:fault->isa]; + fault->isa = self; + + return (NSArray *)AUTORELEASE(fault); +} + ++ (NSDictionary *)primaryKeyForFault:(id)fault { + EODatabaseFault *aFault = (EODatabaseFault *)fault; + + // Check that argument is fault + if (aFault->isa != self) + return nil; + + return [(EODatabaseFaultResolver *)aFault->faultResolver primaryKey]; +} + ++ (EOEntity *)entityForFault:(id)fault { + EODatabaseFault *aFault = (EODatabaseFault *)fault; + + // Check that argument is fault + if (aFault->isa != self) + return nil; + + return [(EODatabaseFaultResolver *)aFault->faultResolver entity]; +} + ++ (EOSQLQualifier *)qualifierForFault:(id)fault { + EODatabaseFault *aFault = (EODatabaseFault *)fault; + + // Check that argument is fault + if (aFault->isa != self) + return nil; + + return [(EODatabaseFaultResolver *)aFault->faultResolver qualifier]; +} + ++ (NSArray *)fetchOrderForFault:(id)fault { + EODatabaseFault *aFault = (EODatabaseFault *)fault; + + // Check that argument is fault + if (aFault->isa != self) + return nil; + + return [(EODatabaseFaultResolver *)aFault->faultResolver fetchOrder]; +} + ++ (EODatabaseChannel *)databaseChannelForFault:fault { + EODatabaseFault *aFault = (EODatabaseFault *)fault; + + // Check that argument is fault + if (aFault->isa != self) + return nil; + + return [(EODatabaseFaultResolver *)aFault->faultResolver databaseChannel]; +} + +- (void)dealloc { + [EODatabase forgetObject:self]; + [super dealloc]; +} + +// Forwarding stuff + ++ (void)initialize { + // Must be here as initialize is called for each root class + // without asking if it responds to it ! +} + +- (EOEntity *)entity { + return [EODatabaseFault entityForFault:self]; +} + +@end /* EODatabaseFault */ + +/* + * Informal protocol that informs an instance that a to-one + * relationship could not be resoved to get data for self. + * Its implementation in NSObject raises NSObjectNotAvailableException. + */ + +@implementation NSObject(EOUnableToFaultToOne) + +- (void)unableToFaultWithPrimaryKey:(NSDictionary*)key + entity:(EOEntity*)entity + databaseChannel:(EODatabaseChannel*)channel +{ + // TODO - throw exception form derived class + [[[ObjectNotAvailableException alloc] + initWithFormat:@"cannot fault to-one for primary key %@ entity %@", + [key description], [entity name]] raise]; +} + +@end /* NSObject(EOUnableToFaultToOne) */ + +@implementation EOFault(EOUnableToFaultToOne) + +- (void)unableToFaultWithPrimaryKey:(NSDictionary*)key + entity:(EOEntity *)entity + databaseChannel:(EODatabaseChannel*)channel +{ + // TODO - throw exception from derived class + [[[ObjectNotAvailableException alloc] + initWithFormat:@"cannot fault to-one for primary key %@ entity %@", + [key description], [entity name]] + raise]; +} + +@end /* EOFault(EOUnableToFaultToOne) */ diff --git a/sope-gdl1/GDLAccess/EODatabaseFaultResolver.m b/sope-gdl1/GDLAccess/EODatabaseFaultResolver.m new file mode 100644 index 00000000..e0e19404 --- /dev/null +++ b/sope-gdl1/GDLAccess/EODatabaseFaultResolver.m @@ -0,0 +1,314 @@ +/* + EODatabaseFaultResolver.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + Author: Helge Hess + Date: 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EODatabaseFaultResolver.h" +#import "EODatabaseChannel.h" +#import "EODatabaseContext.h" +#import "EOEntity.h" +#import "EODatabaseFault.h" +#import "EOSQLQualifier.h" +#import "EOGenericRecord.h" + +@implementation EODatabaseFaultResolver + +- (id)initWithDatabaseChannel:(EODatabaseChannel *)aChannel + zone:(NSZone *)aZone + targetClass:(Class)_targetClass +{ + if ((self = [super init])) { + self->channel = aChannel; + self->targetClass = _targetClass; + self->zone = aZone; + self->faultReferences = 0; + } + return self; +} + +- (BOOL)fault { + return NO; +} + +- (EODatabaseChannel *)databaseChannel { + return self->channel; +} + +- (Class)targetClass; { + return self->targetClass; +} + +- (NSDictionary *)primaryKey { + return nil; +} +- (EOEntity *)entity { + return nil; +} +- (EOSQLQualifier *)qualifier { + return nil; +} +- (NSArray *)fetchOrder { + return nil; +} + +@end /* EODatabaseFaultResolver */ + +@implementation EOArrayFault + +- (id)initWithQualifier:(EOSQLQualifier *)aQualifier + fetchOrder:(NSArray *)aFetchOrder + databaseChannel:(EODatabaseChannel *)aChannel + zone:(NSZone *)aZone + targetClass:(Class)_targetClass +{ + + if ((self = [super initWithDatabaseChannel:aChannel zone:aZone + targetClass:_targetClass])) { + self->qualifier = RETAIN(aQualifier); + self->fetchOrder = RETAIN(aFetchOrder); + + NSAssert([self->targetClass isKindOfClass:[NSArray class]], + @"target class of an array fault is not an array class"); + } + return self; +} + +- (void)dealloc { + RELEASE(self->qualifier); + RELEASE(self->fetchOrder); + [super dealloc]; +} + +- (EOEntity *)entity { + return [self->qualifier entity]; +} + +- (EOSQLQualifier *)qualifier { + return self->qualifier; +} + +- (NSArray *)fetchOrder { + return self->fetchOrder; +} + +- (void)completeInitializationOfObject:(id)_fault { + unsigned int oldRetainCount; + BOOL inTransaction; + + NSAssert([self->targetClass isKindOfClass:[NSArray class]], + @"target class of an array fault is not an array class"); + + oldRetainCount = [_fault retainCount]; + + [EOFault clearFault:_fault]; + NSAssert([(id)_fault init] == _fault, @"init modified fault reference .."); + + NSAssert([_fault isKindOfClass:[NSArray class]], + @"resolved-object of an array fault is not of an array class"); + + if ([self->channel isFetchInProgress]) { + [NSException raise:NSInvalidArgumentException + format:@"attempt to fault with busy channel: %@", self]; + } + + inTransaction = [[self->channel databaseContext] transactionNestingLevel] > 0; + if (!inTransaction) { + if (![[self->channel databaseContext] beginTransaction]) { + [NSException raise:@"DBFaultResolutionException" + format:@"could not begin transaction to resolve fault !"]; + } + } + + if (![self->channel selectObjectsDescribedByQualifier:self->qualifier + fetchOrder:self->fetchOrder]) { + if (!inTransaction) + [[self->channel databaseContext] rollbackTransaction]; + [NSException raise:@"DBFaultResolutionException" + format:@"select for fault failed !"]; + } + + { // fetch objects + id object; + + while ((object = [self->channel fetchWithZone:zone])) { + if (![object isKindOfClass:[EOGenericRecord class]]) { + NSLog(@"Object is of class %@", NSStringFromClass([object class])); + abort(); + } + NSAssert([object isKindOfClass:[EOGenericRecord class]], + @"fetched object is not a EOGenericRecord .."); + [(id)_fault addObject:object]; + } + + object = nil; + } + + [self->channel cancelFetch]; + + if (!inTransaction) { + if (![[self->channel databaseContext] commitTransaction]) { + NSLog(@"WARNING: could not commit fault's transaction !"); + [NSException raise:@"DBFaultResolutionException" + format:@"could not commit fault's transaction !"]; + } + } + +#if MOF2_DEBUG + if ([fault retainCount] != oldRetainCount) { + NSLog(@"fault retain count does not match replacement (old=%d, new=%d)", + oldRetainCount, [fault retainCount]); + } +#endif + + NSAssert([_fault retainCount] == oldRetainCount, + @"fault retain count does not match replacement's retain count"); +} + +- (NSString *)descriptionForObject:(id)_fault { + return [NSString stringWithFormat: + @"", + _fault, qualifier, fetchOrder, channel]; +} + +@end /* EOArrayFault */ + +@implementation EOObjectFault + +- (id)initWithPrimaryKey:(NSDictionary *)_key + entity:(EOEntity *)anEntity + databaseChannel:(EODatabaseChannel *)aChannel + zone:(NSZone *)aZone + targetClass:(Class)_targetClass +{ + [super initWithDatabaseChannel:aChannel + zone:aZone + targetClass:_targetClass]; + self->entity = RETAIN(anEntity); + self->primaryKey = RETAIN(_key); + return self; +} + +- (void)dealloc { + RELEASE(self->entity); + RELEASE(self->primaryKey); + [super dealloc]; +} + +- (NSDictionary*)primaryKey { + return self->primaryKey; +} + +- (EOEntity *)entity { + return self->entity; +} + +- (void)completeInitializationOfObject:(id)_fault { + EOSQLQualifier *qualifier = nil; + BOOL channelIsOpen = YES; + BOOL inTransaction = YES; + id object = nil; + + if ([self->channel isFetchInProgress]) { + [NSException raise:NSInvalidArgumentException + format:@"attempt to fault with busy channel: %@", self]; + } + + qualifier = + [EOSQLQualifier qualifierForPrimaryKey:primaryKey entity:self->entity]; + if (qualifier == nil) { + [NSException raise:NSInvalidArgumentException + format:@"could not build qualifier for fault: %@", self]; + } + + channelIsOpen = [self->channel isOpen]; + if (!channelIsOpen) { + if (![self->channel openChannel]) + goto done; + } + + inTransaction = [[self->channel databaseContext] transactionNestingLevel] != 0; + if (!inTransaction) { + if (![[self->channel databaseContext] beginTransaction]) { + if (!channelIsOpen) [self->channel closeChannel]; + goto done; + } + } + + if (![self->channel selectObjectsDescribedByQualifier:qualifier fetchOrder:nil]) { + if (!inTransaction) { + [[self->channel databaseContext] rollbackTransaction]; + if (!channelIsOpen) [self->channel closeChannel]; + } + goto done; + } + + // Fetch the object + object = [self->channel fetchWithZone:zone]; + + // The fetch failed! + if (object == nil) { + [self->channel cancelFetch]; + if (!inTransaction) [[self->channel databaseContext] rollbackTransaction]; + if (!channelIsOpen) [self->channel closeChannel]; + goto done; + } + + // Make sure we only fetched one object + if ([self->channel fetchWithZone:zone]) + object = nil; + + [self->channel cancelFetch]; + + if (!inTransaction) { + if (![[self->channel databaseContext] commitTransaction]) object = nil; + if (!channelIsOpen) [self->channel closeChannel]; + } + + done: + if (object != _fault) { + if ([EOFault isFault:_fault]) + [EOFault clearFault:_fault]; + + [(id)_fault unableToFaultWithPrimaryKey:primaryKey + entity:self->entity + databaseChannel:self->channel]; + } +} + +- (NSString *)descriptionForObject:(id)_fault { + return [NSString stringWithFormat: + @"", + _fault, + NSStringFromClass(targetClass), + [entity name], + [primaryKey description], + [channel description]]; +} + +@end /* EOObjectFault */ diff --git a/sope-gdl1/GDLAccess/EOEntity+Factory.m b/sope-gdl1/GDLAccess/EOEntity+Factory.m new file mode 100644 index 00000000..ce83d1c0 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOEntity+Factory.m @@ -0,0 +1,123 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// $Id: EOEntity+Factory.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include +#include +#include +#include "common.h" + +@interface NSObject(PKeyInitializer) +- (id)initWithPrimaryKey:(NSDictionary *)_pkey entity:(EOEntity *)_entity; +@end + +@implementation EOEntity(AttributeNames) + +- (NSArray *)attributeNames { + NSMutableArray *attrNames = [[[NSMutableArray alloc] init] autorelease]; + NSEnumerator *attrs = [self->attributes objectEnumerator]; + EOAttribute *attr = nil; + + while ((attr = [attrs nextObject])) + [attrNames addObject:[attr name]]; + + return attrNames; +} + +@end /* EOEntity(AttributeNames) */ + +@implementation EOEntity(PrimaryKeys) + +- (BOOL)isPrimaryKeyAttribute:(EOAttribute *)_attribute { + NSEnumerator *pkeys = [self->primaryKeyAttributeNames objectEnumerator]; + NSString *aname = [_attribute name]; + NSString *n = nil; + + while ((n = [pkeys nextObject])) { + if ([aname isEqualToString:n]) + return YES; + } + return NO; +} + +- (unsigned)primaryKeyCount { + return [self->primaryKeyAttributeNames count]; +} + +@end /* EOEntity(PrimaryKeys) */ + +@implementation EOEntity(ObjectFactory) + +- (id)produceNewObjectWithPrimaryKey:(NSDictionary *)_key { + /* Note: used by LSDBObjectNewCommand */ + Class objectClass = Nil; + id obj; + + objectClass = NSClassFromString([self className]); + NSAssert(objectClass != nil, @"no enterprise object class set in entity"); + + obj = [objectClass alloc]; + NSAssert(objectClass != nil, @"could not allocate enterprise object"); + + if ([obj respondsToSelector:@selector(initWithPrimaryKey:entity:)]) + [obj initWithPrimaryKey:_key entity:self]; + else + [obj init]; + + return AUTORELEASE(obj); +} + +- (void)setAttributesOfObjectToEONull:(id)_object { + static EONull *null = nil; + NSEnumerator *attrs; + EOAttribute *attr; + int pkeyCount; + + if (null == nil) + null = [[NSNull null] retain]; + + attrs = [self->attributes objectEnumerator]; + attr = nil; + pkeyCount = [self->primaryKeyAttributeNames count]; + + NSAssert(NSClassFromString([self className]) == [_object class], + @"object does not belong to entity"); + + while ((attr = [attrs nextObject])) { + if (pkeyCount > 0) { + if ([self isPrimaryKeyAttribute:attr]) { + pkeyCount--; + continue; + } + } + + [_object takeValue:null forKey:[attr name]]; + } +} + +@end /* EOEntity(ObjectFactory) */ diff --git a/sope-gdl1/GDLAccess/EOEntity.m b/sope-gdl1/GDLAccess/EOEntity.m new file mode 100644 index 00000000..e3989dd1 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOEntity.m @@ -0,0 +1,1143 @@ +/* + EOEntity.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + Author: Helge Hess + Date: November 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOEntity.h" +#import "EOAttribute.h" +#import "EOFExceptions.h" +#import "EOModel.h" +#import "EOPrimaryKeyDictionary.h" +#import "EOSQLQualifier.h" +#import "EORelationship.h" +#import +#import + +static int _compareByName(id obj1, id obj2, void * context); + +@interface NSObject(MappedArrayProtocol) +- (NSArray *)mappedArrayUsingSelector:(SEL)_selector; +@end + +@interface NSString(EntityBeautify) +- (NSString *)_beautifyEntityName; +@end + +@implementation EOEntity + +- (id)init { + if ((self = [super init])) { + self->attributes = [[NSArray alloc] init]; + self->attributesByName = [[NSMutableDictionary alloc] init]; + self->relationships = [[NSArray alloc] init]; + self->relationshipsByName = [[NSMutableDictionary alloc] init]; + self->classProperties = [[NSArray alloc] init]; + self->model = nil; + } + return self; +} + +- (void)resetAttributes { + [self->attributes makeObjectsPerformSelector:@selector(resetEntity)]; +} +- (void)resetRelationships { + [self->relationships makeObjectsPerformSelector:@selector(resetEntities)]; +} + +- (void)dealloc { + self->model = nil; + RELEASE(self->qualifier); + [self resetAttributes]; + RELEASE(self->attributes); + RELEASE(self->attributesByName); + [self resetRelationships]; + RELEASE(self->relationships); + RELEASE(self->relationshipsByName); + RELEASE(self->primaryKeyAttributes); + RELEASE(self->classProperties); + RELEASE(self->attributesUsedForLocking); + RELEASE(self->attributesUsedForInsert); + RELEASE(self->attributesUsedForFetch); + RELEASE(self->relationsUsedForFetch); + RELEASE(self->name); self->name = nil; + RELEASE(self->className); self->className = nil; + RELEASE(self->externalName); self->externalName = nil; + RELEASE(self->externalQuery); self->externalQuery = nil; + RELEASE(self->userDictionary); self->userDictionary = nil; + RELEASE(self->primaryKeyAttributeNames); + self->primaryKeyAttributeNames = nil; + RELEASE(self->attributesNamesUsedForInsert); + self->attributesNamesUsedForInsert = nil; + RELEASE(self->classPropertyNames); self->classPropertyNames = nil; + [super dealloc]; +} + +// These methods should be here to let the library work with NeXT foundation +- (id)copy { + return RETAIN(self); +} +- (id)copyWithZone:(NSZone *)_zone { + return RETAIN(self); +} + +// Is equal only if same name; used to make aliasing ordering stable +- (unsigned)hash { + return [name hash]; +} + +- (id)initWithName:(NSString *)_name { + [self init]; + ASSIGN(name, _name); + return self; +} + +- (BOOL)setName:(NSString *)_name { + if([model entityNamed:name]) return NO; + ASSIGN(name, _name); + return YES; +} + ++ (BOOL)isValidName:(NSString *)attributeName { + unsigned len = [attributeName cStringLength]; + char buf[len + 1]; + const char *s; + + s = buf; + [attributeName getCString:buf]; + + if(!isalnum((int)*s) && *s != '@' && *s != '_' && *s != '#') + return NO; + + for(++s; *s; s++) + if(!isalnum((int)*s) && *s != '@' && *s != '_' && *s != '#' && *s != '$') + return NO; + + return YES; +} + +- (BOOL)addAttribute:(EOAttribute *)attribute { + NSString* attributeName = [attribute name]; + + if([self->attributesByName objectForKey:attributeName]) + return NO; + + if([self->relationshipsByName objectForKey:attributeName]) + return NO; + + if([self createsMutableObjects]) + [(NSMutableArray*)self->attributes addObject:attribute]; + else { + id newAttributes = [self->attributes arrayByAddingObject:attribute]; + ASSIGN(self->attributes, newAttributes); + } + + [self->attributesByName setObject:attribute forKey:attributeName]; + [attribute setEntity:self]; + [self invalidatePropertiesCache]; + return YES; +} + +- (void)removeAttributeNamed:(NSString *)attributeName { + id attribute = [self->attributesByName objectForKey:attributeName]; + + if(attribute) { + [attribute resetEntity]; + if([self createsMutableObjects]) + [(NSMutableArray*)attributes removeObject:attribute]; + else { + self->attributes = [AUTORELEASE(self->attributes) mutableCopy]; + [(NSMutableArray*)self->attributes removeObject:attribute]; + self->attributes = [AUTORELEASE(self->attributes) copy]; + } + [self->attributesByName removeObjectForKey:attributeName]; + [self invalidatePropertiesCache]; + } +} + +- (EOAttribute *)attributeNamed:(NSString *)attributeName { + return [self->attributesByName objectForKey:attributeName]; +} + +- (BOOL)addRelationship:(EORelationship *)relationship { + NSString* relationshipName = [relationship name]; + + if([self->attributesByName objectForKey:relationshipName]) + return NO; + + if([self->relationshipsByName objectForKey:relationshipName]) + return NO; + + if([self createsMutableObjects]) + [(NSMutableArray*)relationships addObject:relationship]; + else { + id newRelationships = [self->relationships arrayByAddingObject:relationship]; + ASSIGN(self->relationships, newRelationships); + } + + [self->relationshipsByName setObject:relationship forKey:relationshipName]; + [relationship setEntity:self]; + [self invalidatePropertiesCache]; + return YES; +} + +- (void)removeRelationshipNamed:(NSString*)relationshipName { + id relationship = [relationshipsByName objectForKey:relationshipName]; + + if(relationship) { + [relationship setEntity:nil]; + if([self createsMutableObjects]) + [(NSMutableArray*)self->relationships removeObject:relationship]; + else { + self->relationships = [AUTORELEASE(self->relationships) mutableCopy]; + [(NSMutableArray*)self->relationships removeObject:relationship]; + self->relationships = [AUTORELEASE(relationships) copy]; + } + [self->relationshipsByName removeObjectForKey:relationship]; + [self invalidatePropertiesCache]; + } +} + +- (EORelationship*)relationshipNamed:(NSString *)relationshipName { + if([relationshipName isNameOfARelationshipPath]) { + NSArray *defArray; + int i, count; + EOEntity *currentEntity = self; + NSString *relName = nil; + EORelationship *relationship = nil; + + defArray = [relationshipName componentsSeparatedByString:@"."]; + relName = [defArray objectAtIndex:0]; + + for(i = 0, count = [defArray count]; i < count; i++) { + if(![EOEntity isValidName:relName]) + return nil; + relationship = [currentEntity->relationshipsByName objectForKey:relName]; + if(relationship == nil) + return nil; + currentEntity = [relationship destinationEntity]; + } + return relationship; + } + else + return [self->relationshipsByName objectForKey:relationshipName]; +} + +- (BOOL)setPrimaryKeyAttributes:(NSArray *)keys { + int i, count = [keys count]; + + for(i = 0; i < count; i++) + if(![self isValidPrimaryKeyAttribute:[keys objectAtIndex:i]]) + return NO; + + RELEASE(self->primaryKeyAttributes); + RELEASE(self->primaryKeyAttributeNames); + + if([keys isKindOfClass:[NSArray class]] + || [keys isKindOfClass:[NSMutableArray class]]) + self->primaryKeyAttributes = [keys copy]; + else + self->primaryKeyAttributes = [[NSArray alloc] initWithArray:keys]; + + self->primaryKeyAttributeNames = [NSMutableArray arrayWithCapacity:count]; + for(i = 0; i < count; i++) { + id key = [keys objectAtIndex:i]; + + [(NSMutableArray*)self->primaryKeyAttributeNames + addObject:[(EOAttribute*)key name]]; + } + self->primaryKeyAttributeNames + = RETAIN([self->primaryKeyAttributeNames + sortedArrayUsingSelector:@selector(compare:)]); + + [self invalidatePropertiesCache]; + + return YES; +} + +- (BOOL)isValidPrimaryKeyAttribute:(EOAttribute*)anAttribute { + if(![anAttribute isKindOfClass:[EOAttribute class]]) + return NO; + + if([self->attributesByName objectForKey:[anAttribute name]]) + return YES; + + return NO; +} + +- (NSDictionary *)primaryKeyForRow:(NSDictionary *)_row { + return [EOPrimaryKeyDictionary dictionaryWithKeys: + self->primaryKeyAttributeNames + fromDictionary:_row]; +} + +- (NSDictionary *)snapshotForRow:(NSDictionary *)aRow { + NSArray *array; + int i, n; + NSMutableDictionary *dict; + + array = [self attributesUsedForLocking]; + n = [array count]; + dict = [NSMutableDictionary dictionaryWithCapacity:n]; + + for (i = 0; i < n; i++) { + EOAttribute *attribute; + NSString *columnName; + NSString *attributeName; + id value; + + attribute = [array objectAtIndex:i]; + columnName = [attribute columnName]; + attributeName = [attribute name]; + + value = [aRow objectForKey:attributeName]; + +#if DEBUG + NSAssert1(columnName, @"missing column name in attribute %@ !", attribute); + NSAssert3(value, @"missing value for column '%@' (attr '%@') in row %@", + columnName, attribute, aRow); +#endif + + [dict setObject:value forKey:attributeName]; + } + return dict; +} + +/* Getting attributes used for database oprations */ + +- (NSArray*)attributesUsedForInsert +{ + if (!flags.isPropertiesCacheValid) + [self validatePropertiesCache]; + return self->attributesUsedForInsert; +} + +- (NSArray *)attributesUsedForFetch { + if (!flags.isPropertiesCacheValid) + [self validatePropertiesCache]; + return self->attributesUsedForFetch; +} + +- (NSArray *)relationsUsedForFetch { + if (!flags.isPropertiesCacheValid) + [self validatePropertiesCache]; + return self->relationsUsedForFetch; +} + +- (NSArray *)attributesNamesUsedForInsert { + if (!flags.isPropertiesCacheValid) + [self validatePropertiesCache]; + return self->attributesNamesUsedForInsert; +} + +- (BOOL)setClassProperties:(NSArray *)properties { + int i, count = [properties count]; + + for(i = 0; i < count; i++) + if(![self isValidClassProperty:[properties objectAtIndex:i]]) + return NO; + + RELEASE(self->classProperties); self->classProperties = nil; + RELEASE(self->classPropertyNames); self->classPropertyNames = nil; + + if([properties isKindOfClass:[NSArray class]] + || [properties isKindOfClass:[NSMutableArray class]]) { + self->classProperties = [properties copyWithZone:[self zone]]; + } + else { + self->classProperties = [[NSArray allocWithZone:[self zone]] + initWithArray:properties]; + } + + self->classPropertyNames = [NSMutableArray arrayWithCapacity:count]; + for(i = 0; i < count; i++) { + id property = [properties objectAtIndex:i]; + [(NSMutableArray*)classPropertyNames addObject:[(EOAttribute*)property name]]; + } + self->classPropertyNames = [self->classPropertyNames copyWithZone:[self zone]]; + [self invalidatePropertiesCache]; + + return YES; +} + +- (BOOL)isValidClassProperty:(id)aProperty { + id thePropertyName = nil; + + if(!([aProperty isKindOfClass:[EOAttribute class]] + || [aProperty isKindOfClass:[EORelationship class]])) + return NO; + + thePropertyName = [(EOAttribute*)aProperty name]; + if([self->attributesByName objectForKey:thePropertyName] + || [self->relationshipsByName objectForKey:thePropertyName]) + return YES; + + return NO; +} + +- (NSArray *)relationshipsNamed:(NSString *)_relationshipPath { + if([_relationshipPath isNameOfARelationshipPath]) { + NSMutableArray *myRelationships = [[NSMutableArray alloc] init]; + NSArray *defArray = [_relationshipPath componentsSeparatedByString:@"."]; + int i, count = [defArray count] - 1; + EOEntity *currentEntity = self; + NSString *relName = nil; + id relation = nil; + + for(i = 0; i < count; i++) { + relName = [defArray objectAtIndex:i]; + + if([EOEntity isValidName:relName]) { + relation = [currentEntity relationshipNamed:relName]; + if(relation) { + [myRelationships addObject:relation]; + currentEntity = [relation destinationEntity]; + } + } + } + return AUTORELEASE(myRelationships); + } + return nil; +} + +- (id)propertyNamed:(NSString *)_name { + if([_name isNameOfARelationshipPath]) { + NSArray *defArray = [_name componentsSeparatedByString:@"."]; + EOEntity *currentEntity = self; + NSString *propertyName; + int i = 0, count = [defArray count]; + id property; + + for(; i < count - 1; i++) { + propertyName = [defArray objectAtIndex:i]; + if(![EOEntity isValidName:propertyName]) + return nil; + property = [currentEntity propertyNamed:propertyName]; + if(!property) + return nil; + + currentEntity = [property destinationEntity]; + } + propertyName = [defArray lastObject]; + property = [currentEntity attributeNamed:propertyName]; + return property; + } + else { + id attribute = nil; + id relationship = nil; + + attribute = [self->attributesByName objectForKey:_name]; + if(attribute) + return attribute; + + relationship = [self->relationshipsByName objectForKey:_name]; + if(relationship) + return relationship; + } + + return nil; +} + +- (BOOL)setAttributesUsedForLocking:(NSArray *)_attributes { + int i, count = [_attributes count]; + + for(i = 0; i < count; i++) + if(![self isValidAttributeUsedForLocking: + [_attributes objectAtIndex:i]]) + return NO; + + RELEASE(self->attributesUsedForLocking); + + if([_attributes isKindOfClass:[NSArray class]] + || [_attributes isKindOfClass:[NSMutableArray class]]) + self->attributesUsedForLocking = [_attributes copy]; + else + self->attributesUsedForLocking = [[NSArray alloc] initWithArray:_attributes]; + [self invalidatePropertiesCache]; + + return YES; +} + +- (BOOL)isValidAttributeUsedForLocking:(EOAttribute*)anAttribute { + if(!([anAttribute isKindOfClass:[EOAttribute class]] + && [self->attributesByName objectForKey:[anAttribute name]])) + return NO; + + if([anAttribute isDerived]) + return NO; + + return YES; +} + +- (void)setModel:(EOModel *)aModel { + self->model = aModel; /* non-retained */ +} +- (void)resetModel { + self->model = nil; +} +- (BOOL)hasModel { + return (self->model != nil) ? YES : NO; +} + +- (void)setClassName:(NSString *)_name { + if(!_name) _name = @"EOGenericRecord"; + ASSIGN(self->className, _name); +} + +- (void)setReadOnly:(BOOL)flag +{ + flags.isReadOnly = flag; +} + +- (BOOL)referencesProperty:(id)property { + id propertyName = [(EOAttribute*)property name]; + + if([self->attributesByName objectForKey:propertyName] + || [self->relationshipsByName objectForKey:propertyName]) + return YES; + return NO; +} + +- (EOSQLQualifier*)qualifier { + if (self->qualifier == nil) { + self->qualifier = [[EOSQLQualifier allocWithZone:[self zone]] + initWithEntity:self + qualifierFormat:nil]; + } + return self->qualifier; +} + +// accessors + +- (void)setExternalName:(NSString*)_name { + ASSIGN(externalName, _name); +} +- (NSString *)externalName { + return self->externalName; +} + +- (void)setExternalQuery:(NSString*)query { + ASSIGN(externalQuery, query); +} +- (NSString *)externalQuery { + return self->externalQuery; +} + +- (void)setUserDictionary:(NSDictionary*)dict { + ASSIGN(userDictionary, dict); +} +- (NSDictionary *)userDictionary { + return self->userDictionary; +} + +- (NSString *)name { + return self->name; +} +- (BOOL)isReadOnly { + return self->flags.isReadOnly; +} +- (NSString *)className { + return self->className; +} +- (NSArray *)attributesUsedForLocking { + return self->attributesUsedForLocking; +} +- (NSArray *)classPropertyNames { + return self->classPropertyNames; +} +- (NSArray *)classProperties { + return self->classProperties; +} +- (NSArray *)primaryKeyAttributes { + return self->primaryKeyAttributes; +} +- (NSArray *)primaryKeyAttributeNames { + return self->primaryKeyAttributeNames; +} +- (NSArray *)relationships { + return self->relationships; +} +- (EOModel *)model { + return self->model; +} +- (NSArray *)attributes { + return self->attributes; +} + +@end /* EOEntity */ + + +@implementation EOEntity (EOEntityCreation) + ++ (EOEntity *)entityFromPropertyList:(id)propertyList model:(EOModel *)_model { + EOEntity *entity; + NSArray *array; + NSEnumerator *enumerator; + id attributePList; + id relationshipPList; + + entity = AUTORELEASE([[EOEntity alloc] init]); + [entity setCreateMutableObjects:YES]; + + entity->name = RETAIN([propertyList objectForKey:@"name"]); + entity->className = RETAIN([propertyList objectForKey:@"className"]); + entity->externalName = RETAIN([propertyList objectForKey:@"externalName"]); + entity->externalQuery = RETAIN([propertyList objectForKey:@"externalQuery"]); + entity->userDictionary = RETAIN([propertyList objectForKey:@"userDictionary"]); + + array = [propertyList objectForKey:@"attributes"]; + enumerator = [array objectEnumerator]; + + while ((attributePList = [enumerator nextObject])) { + EOAttribute *attribute; + + attribute = [EOAttribute attributeFromPropertyList:attributePList]; + + if (![entity addAttribute:attribute]) { + NSLog(@"duplicate name for attribute '%@' in entity '%@'", + [attribute name], [entity name]); + [_model errorInReading]; + } + } + + entity->attributesUsedForLocking + = RETAIN([propertyList objectForKey:@"attributesUsedForLocking"]); + entity->classPropertyNames + = RETAIN([propertyList objectForKey:@"classProperties"]); + + if ((attributePList = [propertyList objectForKey:@"primaryKeyAttributes"])) { + entity->primaryKeyAttributeNames + = RETAIN([attributePList sortedArrayUsingSelector:@selector(compare:)]); + } + + else + if ((attributePList = [propertyList objectForKey:@"primaryKeyAttribute"])) + entity->primaryKeyAttributeNames + = RETAIN([NSArray arrayWithObject:attributePList]); + + array = [propertyList objectForKey:@"relationships"]; + enumerator = [array objectEnumerator]; + while((relationshipPList = [enumerator nextObject])) { + EORelationship *relationship + = [EORelationship relationshipFromPropertyList:relationshipPList + model:_model]; + + if(![entity addRelationship:relationship]) { + NSLog(@"duplicate name for relationship '%@' in entity '%@'", + [relationship name], [entity name]); + [_model errorInReading]; + } + } + + [entity setCreateMutableObjects:NO]; + + return entity; +} + +- (void)replaceStringsWithObjects { + NSEnumerator *enumerator = nil; + EOAttribute *attribute = nil; + NSString *attributeName = nil; + NSString *propertyName = nil; + NSMutableArray *array = nil; + int i, count; + + enumerator = [self->primaryKeyAttributeNames objectEnumerator]; + RELEASE(self->primaryKeyAttributes); + self->primaryKeyAttributes = AUTORELEASE([NSMutableArray new]); + + while ((attributeName = [enumerator nextObject])) { + attribute = [self attributeNamed:attributeName]; + + if((attribute == nil) || ![self isValidPrimaryKeyAttribute:attribute]) { + NSLog(@"invalid attribute name specified as primary key attribute " + @"'%s' in entity '%s'", + [attributeName cString], [name cString]); + [self->model errorInReading]; + } + else + [(NSMutableArray*)self->primaryKeyAttributes addObject:attribute]; + } + self->primaryKeyAttributes = [self->primaryKeyAttributes copy]; + + enumerator = [self->classPropertyNames objectEnumerator]; + RELEASE(self->classProperties); + self->classProperties = AUTORELEASE([NSMutableArray new]); + while((propertyName = [enumerator nextObject])) { + id property; + + property = [self propertyNamed:propertyName]; + if(!property || ![self isValidClassProperty:property]) { + NSLog(@"invalid property '%s' specified as class property in " + @"entity '%s'", + [propertyName cString], [name cString]); + [self->model errorInReading]; + } + else + [(NSMutableArray*)self->classProperties addObject:property]; + } + self->classProperties = [self->classProperties copy]; + + array = AUTORELEASE([NSMutableArray new]); + [array setArray:self->attributesUsedForLocking]; + RELEASE(self->attributesUsedForLocking); + count = [array count]; + for(i = 0; i < count; i++) { + attributeName = [array objectAtIndex:i]; + attribute = [self attributeNamed:attributeName]; + if(!attribute || ![self isValidAttributeUsedForLocking:attribute]) { + NSLog(@"invalid attribute specified as attribute used for " + @"locking '%@' in entity '%@'", attributeName, name); + [self->model errorInReading]; + } + else + [array replaceObjectAtIndex:i withObject:attribute]; + } + self->attributesUsedForLocking = [array copy]; +} + +- (id)propertyList +{ + id propertyList; + + propertyList = [NSMutableDictionary dictionary]; + [self encodeIntoPropertyList:propertyList]; + return propertyList; +} + +- (void)setCreateMutableObjects:(BOOL)flag { + if(self->flags.createsMutableObjects == flag) + return; + + self->flags.createsMutableObjects = flag; + + if(self->flags.createsMutableObjects) { + self->attributes = [AUTORELEASE(self->attributes) mutableCopy]; + self->relationships = [AUTORELEASE(self->relationships) mutableCopy]; + } + else { + self->attributes = [AUTORELEASE(self->attributes) copy]; + self->relationships = [AUTORELEASE(self->relationships) copy]; + } +} + +- (BOOL)createsMutableObjects { + return self->flags.createsMutableObjects; +} + +#if 0 +static inline void _printIds(NSArray *a, const char *pfx, const char *indent) { + int i; + if (pfx == NULL) pfx = ""; + if (indent == NULL) indent = " "; + printf("%s", pfx); + for (i = 0; i < [a count]; i++) + printf("%s0x%08X\n", indent, (unsigned)[a objectAtIndex:i]); +} +#endif + +static inline BOOL _containsObject(NSArray *a, id obj) { + id (*objAtIdx)(NSArray*, SEL, int idx); + register int i; + + objAtIdx = (void *)[a methodForSelector:@selector(objectAtIndex:)]; + for (i = [a count] - 1; i >= 0; i--) { + register id o; + + o = objAtIdx(a, @selector(objectAtIndex:), i); + if (o == obj) return YES; + } + return NO; +} + +- (void)validatePropertiesCache +{ + NSMutableArray *updAttr = [NSMutableArray new]; + NSMutableArray *updName = [NSMutableArray new]; + NSMutableArray *fetAttr = [NSMutableArray new]; + NSMutableArray *fetRels = [NSMutableArray new]; + + int i; + + [self invalidatePropertiesCache]; + +#ifdef DEBUG + NSAssert((updAttr != nil) && (updName != nil) && + (fetAttr != nil) && (fetRels != nil), + @"allocation of array failed !"); + + NSAssert(self->primaryKeyAttributes, @"no pkey attributes are set !"); + NSAssert(self->attributesUsedForLocking, @"no locking attrs are set !"); + NSAssert(self->classProperties, @"no class properties are set !"); +#endif + + //_printIds(self->attributes, "attrs:\n", " "); + //_printIds(self->attributesUsedForLocking, "lock:\n", " "); + + for (i = ([self->attributes count] - 1); i >= 0; i--) { + EOAttribute *attr = [self->attributes objectAtIndex:i]; + BOOL pk, lk, cp, sa; + + pk = _containsObject(self->primaryKeyAttributes, attr); + lk = _containsObject(self->attributesUsedForLocking, attr); + cp = _containsObject(self->classProperties, attr); + sa = (![attr isDerived] && ![attr isFlattened]); + + //NSLog(@"attribute %@ pk=%i lk=%i cp=%i sa=%i", [attr name], pk, lk, cp, sa); + + if ((pk || lk || cp) && (!_containsObject(fetAttr, attr))) + [fetAttr addObject:attr]; + + if ((pk || lk || cp) && (sa) && (!_containsObject(updAttr, attr))) { + [updAttr addObject:attr]; + [updName addObject:[attr name]]; + } + } + + for (i = [relationships count]-1; i >= 0; i--) { + id rel = [relationships objectAtIndex:i]; + + if (_containsObject(classProperties, rel)) + [fetRels addObject:rel]; + } + + RELEASE(self->attributesUsedForInsert); + self->attributesUsedForInsert = [[NSArray alloc] initWithArray:updAttr]; + RELEASE(self->relationsUsedForFetch); + self->relationsUsedForFetch = [[NSArray alloc] initWithArray:fetRels]; + RELEASE(self->attributesUsedForFetch); + self->attributesUsedForFetch = + [[NSArray alloc] initWithArray: + [fetAttr sortedArrayUsingFunction:_compareByName context:nil]]; + RELEASE(self->attributesNamesUsedForInsert); + attributesNamesUsedForInsert = [updName copy]; + + if ([self->attributesUsedForFetch count] == 0) { + NSLog(@"WARNING: entity %@ has no fetch attributes: " + @"attributes=%@ !", + self, + [[(id)self->attributes mappedArrayUsingSelector:@selector(name)] + componentsJoinedByString:@","]); + } + + RELEASE(updAttr); updAttr = nil; + RELEASE(fetAttr); fetAttr = nil; + RELEASE(fetRels); fetRels = nil; + RELEASE(updName); updName = nil; + + self->flags.isPropertiesCacheValid = YES; +} + +- (void)invalidatePropertiesCache { + if (flags.isPropertiesCacheValid) { + RELEASE(self->attributesUsedForInsert); + RELEASE(self->attributesUsedForFetch); + RELEASE(self->relationsUsedForFetch); + RELEASE(self->attributesNamesUsedForInsert); + + self->attributesUsedForInsert = nil; + self->attributesUsedForFetch = nil; + self->relationsUsedForFetch = nil; + self->attributesNamesUsedForInsert = nil; + + flags.isPropertiesCacheValid = NO; + } +} + +// description + +- (NSString *)description { + return [NSString stringWithFormat: + @"<%@[0x%08X]: name=%@ className=%@ tableName=%@ " + @"readOnly=%s>", + NSStringFromClass([self class]), self, + [self name], [self className], [self externalName], + [self isReadOnly] ? "YES" : "NO" + ]; +} + +@end /* EOEntity (EOEntityCreation) */ + + +@implementation EOEntity(ValuesConversion) + +- (NSDictionary *)convertValuesToModel:(NSDictionary *)aRow { + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + NSEnumerator *enumerator = [aRow keyEnumerator]; + NSString *key; + + while ((key = [enumerator nextObject])) { + id old = [aRow objectForKey:key]; + id new = [[self attributeNamed:key] convertValueToModel:old]; + + if (new) [dict setObject:new forKey:key]; + } + + return [dict count] ? dict : nil; +} + +static int _compareByName(id obj1, id obj2, void * context) { + return [[(EOAttribute*)obj1 name] compare:[(EOAttribute*)obj2 name]]; +} + +@end /* EOAttribute (ValuesConversion) */ + +@implementation EOEntity(EOF2Additions) + +- (BOOL)isAbstractEntity { + return NO; +} + +/* ids */ + +- (EOGlobalID *)globalIDForRow:(NSDictionary *)_row { + static Class EOKeyGlobalIDClass = Nil; + unsigned int keyCount = [self->primaryKeyAttributeNames count]; + id values[keyCount]; + unsigned int i; + + for (i = 0; i < keyCount; i++) { + NSString *attrName; + + attrName = [self->primaryKeyAttributeNames objectAtIndex:i]; + values[i] = [_row objectForKey:attrName]; + + if (values[i] == nil) + return nil; + } + if (EOKeyGlobalIDClass == Nil) EOKeyGlobalIDClass = [EOKeyGlobalID class]; + + return [EOKeyGlobalIDClass globalIDWithEntityName:self->name + keys:&(values[0]) + keyCount:keyCount + zone:[self zone]]; +} + +- (BOOL)isPrimaryKeyValidInObject:(id)_object { + unsigned int keyCount = [self->primaryKeyAttributeNames count]; + unsigned int i; + + if (_object == nil) return NO; + + for (i = 0; i < keyCount; i++) { + if ([_object valueForKey:[self->primaryKeyAttributeNames objectAtIndex:i]] + == nil) + return NO; + } + return YES; +} + +/* refs to other models */ + +- (NSArray *)externalModelsReferenced { + NSEnumerator *e; + EORelationship *relship; + NSMutableArray *result; + EOModel *thisModel; + + thisModel = [self model]; + result = nil; + + e = [self->relationships objectEnumerator]; + while ((relship = [e nextObject])) { + EOEntity *targetEntity; + EOModel *extModel; + + targetEntity = [relship destinationEntity]; + extModel = [targetEntity model]; + + if (extModel != thisModel) { + if (result == nil) result = [NSMutableArray array]; + [result addObject:extModel]; + } + } + return result ? result : [NSArray array]; +} + +/* fetch specs */ + +- (EOFetchSpecification *)fetchSpecificationNamed:(NSString *)_name { + return nil; +} +- (NSArray *)fetchSpecificationNames { + return nil; +} + +/* names */ + +- (void)beautifyName { + [self setName:[[self name] _beautifyEntityName]]; +} + +@end /* EOEntity(EOF2Additions) */ + +@implementation EOEntity(PropertyListCoding) + +static inline void _addToPropList(NSMutableDictionary *propertyList, + id _value, NSString *key) { + if (_value) [propertyList setObject:_value forKey:key]; +} + +- (void)encodeIntoPropertyList:(NSMutableDictionary *)_plist { + int i, count; + + _addToPropList(_plist, self->name, @"name"); + _addToPropList(_plist, self->className, @"className"); + _addToPropList(_plist, self->externalName, @"externalName"); + _addToPropList(_plist, self->externalQuery, @"externalQuery"); + _addToPropList(_plist, self->userDictionary, @"userDictionary"); + + if ((count = [self->attributes count])) { + id attributesPList; + + attributesPList = [NSMutableArray array]; + for (i = 0; i < count; i++) { + NSMutableDictionary *attributePList; + + attributePList = [[NSMutableDictionary alloc] init]; + [[self->attributes objectAtIndex:i] + encodeIntoPropertyList:attributePList]; + [attributesPList addObject:attributePList]; + RELEASE(attributePList); + } + + _addToPropList(_plist, attributesPList, @"attributes"); + } + + if ((count = [self->attributesUsedForLocking count])) { + id attributesUsedForLockingPList; + + attributesUsedForLockingPList = [NSMutableArray array]; + for (i = 0; i < count; i++) { + id attributePList; + + attributePList = + [(EOAttribute*)[self->attributesUsedForLocking objectAtIndex:i] name]; + [attributesUsedForLockingPList addObject:attributePList]; + } + _addToPropList(_plist, attributesUsedForLockingPList, + @"attributesUsedForLocking"); + } + + if ((count = [self->classProperties count])) { + id classPropertiesPList = nil; + + classPropertiesPList = [NSMutableArray array]; + for (i = 0; i < count; i++) { + id classPropertyPList; + + classPropertyPList = + [(EOAttribute*)[self->classProperties objectAtIndex:i] name]; + [classPropertiesPList addObject:classPropertyPList]; + } + _addToPropList(_plist, classPropertiesPList, @"classProperties"); + } + + if ((count = [self->primaryKeyAttributes count])) { + id primaryKeyAttributesPList; + + primaryKeyAttributesPList = [NSMutableArray array]; + for (i = 0; i < count; i++) { + id attributePList; + attributePList = + [(EOAttribute*)[self->primaryKeyAttributes objectAtIndex:i] name]; + [primaryKeyAttributesPList addObject:attributePList]; + } + _addToPropList(_plist, primaryKeyAttributesPList, @"primaryKeyAttributes"); + } + + if ((count = [self->relationships count])) { + id relationshipsPList; + + relationshipsPList = [NSMutableArray array]; + for (i = 0; i < count; i++) { + NSMutableDictionary *relationshipPList; + + relationshipPList = [NSMutableDictionary dictionary]; + + [[self->relationships objectAtIndex:i] + encodeIntoPropertyList:relationshipPList]; + [relationshipsPList addObject:relationshipPList]; + } + _addToPropList(_plist, relationshipsPList, @"relationships"); + } +} + +@end /* EOEntity(PropertyListCoding) */ + +@implementation NSString(EntityBeautify) + +- (NSString *)_beautifyEntityName { + if ([self length] == 0) + return @""; + else { + unsigned clen = 0; + char *s = NULL; + unsigned cnt, cnt2; + + clen = [self cStringLength]; +#if GNU_RUNTIME + s = objc_atomic_malloc(clen + 4); +#else + s = malloc(clen + 4); +#endif + + [self getCString:s maxLength:clen]; + + for (cnt = cnt2 = 0; cnt < clen; cnt++, cnt2++) { + if ((s[cnt] == '_') && (s[cnt + 1] != '\0')) { + s[cnt2] = toupper(s[cnt + 1]); + cnt++; + } + else if ((s[cnt] == '2') && (s[cnt + 1] != '\0')) { + s[cnt2] = s[cnt]; + cnt++; + cnt2++; + s[cnt2] = toupper(s[cnt]); + } + else + s[cnt2] = tolower(s[cnt]); + } + s[cnt2] = '\0'; + + s[0] = toupper(s[0]); + +#if !LIB_FOUNDATION_LIBRARY + { + NSString *os; + + os = [NSString stringWithCString:s]; + free(s); + return os; + } +#else + return [NSString stringWithCStringNoCopy:s freeWhenDone:YES]; +#endif + } +} + +@end diff --git a/sope-gdl1/GDLAccess/EOEntityClassDescription.m b/sope-gdl1/GDLAccess/EOEntityClassDescription.m new file mode 100644 index 00000000..e113f143 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOEntityClassDescription.m @@ -0,0 +1,237 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// $Id: EOEntityClassDescription.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#import "EOEntity.h" +#import "EOAttribute.h" +#import "EORelationship.h" +#import +#import + +@interface EOClassDescription(ClassDesc) +/* TODO: check, whether this can be removed */ ++ (NSClassDescription *)classDescriptionForEntityName:(NSString *)_entityName; +@end + +@implementation EOEntityClassDescription + +- (id)initWithEntity:(EOEntity *)_entity { + self->entity = RETAIN(_entity); + return self; +} + +- (void)dealloc { + RELEASE(self->entity); + [super dealloc]; +} + +/* creating instances */ + +- (id)createInstanceWithEditingContext:(id)_ec + globalID:(EOGlobalID *)_oid + zone:(NSZone *)_zone +{ + Class eoClass; + id eo; + + eoClass = NSClassFromString([self->entity className]); + eo = [eoClass allocWithZone:_zone]; + + if ([eo respondsToSelector: + @selector(initWithEditingContext:classDescription:globalID:)]) + eo = [eo initWithEditingContext:_ec classDescription:self globalID:_oid]; + else + eo = [eo init]; + + return AUTORELEASE(eo); +} + +/* accessors */ + +- (EOEntity *)entity { + return self->entity; +} + +/* model */ + +- (NSString *)entityName { + return [self->entity name]; +} + +- (NSArray *)attributeKeys { + NSArray *attrs = [self->entity attributes]; + unsigned int attrCount = [attrs count]; + id keys[attrCount]; + unsigned int i; + + for (i = 0; i < attrCount; i++) { + EOAttribute *attribute; + + attribute = [attrs objectAtIndex:i]; + keys[i] = [attribute name]; + } + + return [NSArray arrayWithObjects:keys count:attrCount]; +} + +- (NSArray *)toManyRelationshipKeys { + NSArray *relships = [self->entity relationships]; + unsigned int attrCount = [relships count]; + id keys[attrCount]; + unsigned int i, j; + + for (i = 0, j = 0; i < attrCount; i++) { + EORelationship *relship; + + relship = [relships objectAtIndex:i]; + if ([relship isToMany]) { + keys[j] = [relship name]; + } + } + return [NSArray arrayWithObjects:keys count:j]; +} + +- (NSArray *)toOneRelationshipKeys { + NSArray *relships = [self->entity relationships]; + unsigned int attrCount = [relships count]; + id keys[attrCount]; + unsigned int i, j; + + for (i = 0, j = 0; i < attrCount; i++) { + EORelationship *relship; + + relship = [relships objectAtIndex:i]; + if (![relship isToMany]) { + keys[j] = [relship name]; + } + } + return [NSArray arrayWithObjects:keys count:j]; +} + + +- (NSClassDescription *)classDescriptionForDestinationKey:(NSString *)_key { + /* TODO: is this used anywhere?, maybe remove? */ + EORelationship *relship; + NSString *targetEntityName; + + if ((relship = [self->entity relationshipNamed:_key]) == nil) + return nil; + + if ([relship isToMany]) + return nil; + + targetEntityName = [[relship entity] name]; + + return [EOClassDescription classDescriptionForEntityName:targetEntityName]; +} + +/* validation */ + +- (NSException *)validateObjectForSave:(id)_object { + NSMutableArray *exceptions; + NSArray *attrs; + unsigned int count, i; + + exceptions = nil; + + /* validate attributes */ + + attrs = [self->entity attributes]; + count = [attrs count]; + + for (i = 0; i < count; i++) { + EOAttribute *attribute; + NSException *exception; + id oldValue, newValue; + + attribute = [attrs objectAtIndex:i]; + oldValue = [_object storedValueForKey:[attribute name]]; + newValue = oldValue; + + if ((exception = [attribute validateValue:&newValue])) { + /* validation failed */ + if (exceptions == nil) exceptions = [NSMutableArray array]; + [exceptions addObject:exception]; + } + else if (oldValue != newValue) { + /* apply new value to object (value was changed by val-method) */ + [_object takeStoredValue:newValue forKey:[attribute name]]; + } + } + + /* validate relationships */ + + attrs = [self->entity relationships]; + count = [attrs count]; + + for (i = 0; i < count; i++) { + EORelationship *relationship; + NSException *exception; + id oldValue, newValue; + + relationship = [attrs objectAtIndex:i]; + oldValue = [_object storedValueForKey:[relationship name]]; + newValue = oldValue; + + if ((exception = [relationship validateValue:&newValue])) { + /* validation failed */ + if (exceptions == nil) exceptions = [NSMutableArray array]; + [exceptions addObject:exception]; + } + else if (oldValue != newValue) { + /* apply new value to object (value was changed by val-method) */ + [_object takeStoredValue:newValue forKey:[relationship name]]; + } + } + + /* process exceptions */ + + if ((count = [exceptions count]) == 0) + return nil; + + if (count == 1) + return [exceptions objectAtIndex:0]; + + { + NSException *master; + NSMutableDictionary *ui; + + master = [exceptions objectAtIndex:0]; + ui = [[master userInfo] mutableCopy]; + if (ui == nil) ui = [[NSMutableDictionary alloc] init]; + [ui setObject:exceptions forKey:@"EOAdditionalExceptions"]; + + master = [NSException exceptionWithName:[master name] + reason:[master reason] + userInfo:ui]; + [ui release]; ui = nil; + return master; + } +} + +@end /* EOEntityClassDescription */ diff --git a/sope-gdl1/GDLAccess/EOExpressionArray.m b/sope-gdl1/GDLAccess/EOExpressionArray.m new file mode 100644 index 00000000..cdd014bb --- /dev/null +++ b/sope-gdl1/GDLAccess/EOExpressionArray.m @@ -0,0 +1,318 @@ +/* + EOExpressionArray.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: September 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOExpressionArray.h" +#import "EOAttribute.h" +#import "EOEntity.h" +#import "EORelationship.h" + +@implementation EOExpressionArray + +- (id)init { + [super init]; + self->array = [[NSMutableArray allocWithZone:[self zone]] init]; + return self; +} + +- (id)initWithPrefix:(NSString *)_prefix + infix:(NSString *)_infix + suffix:(NSString *)_suffix +{ + [super init]; + ASSIGN(self->prefix, _prefix); + ASSIGN(self->infix, _infix); + ASSIGN(self->suffix, _suffix); + RELEASE(self->array); + self->array = [[NSMutableArray allocWithZone:[self zone]] init]; + return self; +} + +- (void)dealloc { + RELEASE(self->array); + RELEASE(self->prefix); + RELEASE(self->infix); + RELEASE(self->suffix); + [super dealloc]; +} + +- (BOOL)referencesObject:(id)anObject { + return [self indexOfObject:anObject] != NSNotFound; +} + +- (NSString *)expressionValueForContext:(id)ctx { + if(ctx && [self count] && + [[self objectAtIndex:0] isKindOfClass:[EORelationship class]]) + return [ctx expressionValueForAttributePath:self->array]; + else { + int i, count; + id result; + SEL sel; + IMP imp; + + count = [self count]; + result = [NSMutableString stringWithCapacity:256]; + sel = @selector(appendString:); + imp = [result methodForSelector:sel]; + + if (self->prefix) + [result appendString:self->prefix]; + + if (count) { + id o; + + o = [self objectAtIndex:0]; + + (*imp)(result, sel, [o expressionValueForContext:ctx]); + for (i = 1 ; i < count; i++) { + if (self->infix) + (*imp)(result, sel, self->infix); + + o = [self objectAtIndex:i]; + (*imp)(result, sel, [o expressionValueForContext:ctx]); + } + } + + if (self->suffix) + [result appendString:self->suffix]; + + return result; + } +} + +- (void)setPrefix:(NSString *)_prefix { + ASSIGN(self->prefix, _prefix); +} +- (void)setInfix:(NSString *)_infix { + ASSIGN(self->infix, _infix); +} +- (void)setSuffix:(NSString *)_suffix { + ASSIGN(self->suffix, _suffix); +} + +- (NSString *)prefix { + return self->prefix; +} +- (NSString *)infix { + return self->infix; +} +- (NSString *)suffix { + return self->suffix; +} + ++ (EOExpressionArray *)parseExpression:(NSString *)expression + entity:(EOEntity *)entity + replacePropertyReferences:(BOOL)replacePropertyReferences +{ + return [EOExpressionArray parseExpression:expression + entity:entity + replacePropertyReferences: + replacePropertyReferences + relationshipPaths:nil]; +} + ++ (EOExpressionArray *)parseExpression:(NSString *)expression + entity:(EOEntity *)entity + replacePropertyReferences:(BOOL)replacePropertyReferences + relationshipPaths:(NSMutableArray *)relationshipPaths +{ + EOExpressionArray *exprArray; + unsigned char buf[[expression cStringLength] + 4]; // TODO: not too good + const unsigned char *s, *start; + id objectToken; + NSAutoreleasePool *pool; + + exprArray = [[EOExpressionArray new] autorelease]; + pool = [[NSAutoreleasePool alloc] init]; + [expression getCString:buf]; + s = buf; + + /* Divide the expression string in alternating substrings that obey the + following simple grammar: + + I = [a-zA-Z0-9@_#]([a-zA-Z0-9@_.#$])+ + O = \'.*\' | \".*\" | [^a-zA-Z0-9@_#]+ + S -> I S | O S | nothing + */ + while(*s) { + /* Determines an I token. */ + if(isalnum((int)*s) || *s == '@' || *s == '_' || *s == '#') { + start = s; + for(++s; *s; s++) + if(!isalnum((int)*s) && *s != '@' && *s != '_' + && *s != '.' && *s != '#' && *s != '$') + break; + + objectToken = [NSString stringWithCString:start + length:(unsigned)(s - start)]; + if (replacePropertyReferences) { + id property = [entity propertyNamed:objectToken]; + if(property) { + if ([objectToken isNameOfARelationshipPath] && + relationshipPaths) { + [relationshipPaths addObject: + [entity relationshipsNamed: + objectToken]]; + } + objectToken = property; + } + } + [exprArray addObject:objectToken]; + } + + /* Determines an O token. */ + start = s; + for(; *s && !isalnum((int)*s) && *s != '@' && *s != '_' && *s != '#'; + s++) { + if(*s == '\'' || *s == '"') { + unsigned char quote = *s; + + for(++s; *s; s++) + if(*s == quote) + break; + else if(*s == '\\') + s++; /* Skip the escaped characters */ + if(!*s) { + [NSException raise:@"SyntaxErrorException" + format:@"unterminated character string"]; + } + } + } + if (s != start) { + objectToken = [NSString stringWithCString:start + length:(unsigned)(s - start)]; + [exprArray addObject:objectToken]; + } + } + + RELEASE(pool); + return exprArray; +} + +/* NSMutableCopying */ + +- (id)copyWithZone:(NSZone *)_zone { + return [self mutableCopyWithZone:_zone]; +} +- (id)mutableCopyWithZone:(NSZone *)_zone { + EOExpressionArray *new; + + new = [[EOExpressionArray allocWithZone:_zone] + initWithPrefix:self->prefix + infix:self->infix + suffix:self->suffix]; + RELEASE(new->array); new->array = nil; + new->array = [self->array mutableCopyWithZone:_zone]; + + return new; +} + +/* NSArray compatibility */ + +- (void)addObjectsFromExpressionArray:(EOExpressionArray *)_array { + [self->array addObjectsFromArray:_array->array]; +} + +- (void)insertObject:(id)_obj atIndex:(unsigned int)_idx { + [self->array insertObject:_obj atIndex:_idx]; +} +- (void)addObjectsFromArray:(NSArray *)_array { + [self->array addObjectsFromArray:_array]; +} + +- (void)addObject:(id)_object { + [self->array addObject:_object]; +} + +- (unsigned int)indexOfObject:(id)_object { + return [self->array indexOfObject:_object]; +} + +- (id)objectAtIndex:(unsigned int)_idx { + return [self->array objectAtIndex:_idx]; +} +- (id)lastObject { + return [self->array lastObject]; +} +- (unsigned int)count { + return [self->array count]; +} + +- (NSEnumerator *)objectEnumerator { + return [self->array objectEnumerator]; +} +- (NSEnumerator *)reverseObjectEnumerator { + return [self->array reverseObjectEnumerator]; +} + +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + + if (self->array) [ms appendFormat:@" array=%@", self->array]; + if (self->prefix) [ms appendFormat:@" prefix='%@'", self->prefix]; + if (self->infix) [ms appendFormat:@" infix='%@'", self->infix]; + if (self->suffix) [ms appendFormat:@" suffix='%@'", self->suffix]; + + [ms appendString:@">"]; + return ms; +} + +@end /* EOExpressionArray */ + +@implementation NSObject(EOExpression) + +- (NSString *)expressionValueForContext:(id)ctx { + if([self respondsToSelector:@selector(stringValue)]) + return [(id)self stringValue]; + + return [self description]; +} + +@end /* NSObject(EOExpression) */ + +@implementation NSString(EOExpression) + +/* + Avoid returning the description in case of NSString because if the string + contains whitespaces it will be quoted. Particular adaptors have to override + -formatValue:forAttribute: and they have to quote with the specific + database character the returned string. +*/ +- (NSString *)expressionValueForContext:(id)ctx { + return self; +} + +@end /* NSString(EOExpression) */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/EOFExceptions.m b/sope-gdl1/GDLAccess/EOFExceptions.m new file mode 100644 index 00000000..48bd267e --- /dev/null +++ b/sope-gdl1/GDLAccess/EOFExceptions.m @@ -0,0 +1,171 @@ +/* + EOFExceptions.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOFExceptions.h" +#import "EOEntity.h" +#import "EORelationship.h" + +@implementation EOFException +@end /* EOFException */ + + +@implementation ObjectNotAvailableException + +- initWithEntity:entity andPrimaryKey:key { + id _reason = [NSString stringWithFormat:@"A to-one relation could not be " + @"resolved for entity %@ and primary key %@", + [(EOEntity*)entity name], [key description]]; + + [self initWithName:@"NSObjectNotAvailableException" + reason:_reason userInfo:nil]; + return self; +} + +@end /* ObjectNotAvailableException */ + + +@implementation PropertyDefinitionException +@end /* PropertyDefinitionException */ + + +@implementation DestinationEntityDoesntMatchDefinitionException + +- initForDestination:(EOEntity*)destinationEntity + andDefinition:(NSString*)definition + relationship:(EORelationship*)relationship +{ + id _reason = [NSString stringWithFormat:@"destination entity '%@' does not" + @" match definition '%@' in relationship '%@'", + [destinationEntity name], + definition, + [relationship name]]; + [self initWithName:NSStringFromClass(isa) + reason:_reason userInfo:nil]; + return self; +} +@end /* DestinationEntityDoesntMatchDefinitionException */ + + +@implementation InvalidNameException +- initWithName:(NSString*)_name +{ + id _reason = [NSString stringWithFormat:@"invalid name: '%@'", _name]; + [self initWithName:NSStringFromClass(isa) reason:_reason userInfo:nil]; + return self; +} +@end /* InvalidNameException */ + + +@implementation InvalidPropertyException +- initWithName:propertyName entity:currentEntity +{ + id _reason = [NSString stringWithFormat:@"property '%@' does not exist in " + @"entity '%@'", propertyName, + [(EOEntity*)currentEntity name]]; + [self initWithName:NSStringFromClass(isa) + reason:_reason userInfo:nil]; + return self; +} +@end /* InvalidPropertyException */ + + +@implementation RelationshipMustBeToOneException +- initWithName:propertyName entity:currentEntity +{ + id _reason = [NSString stringWithFormat:@"property '%@' must be to one in " + @"entity '%@' to allow flattened attribute", + propertyName, [(EOEntity*)currentEntity name]]; + [self initWithName:NSStringFromClass(isa) + reason:_reason userInfo:nil]; + return self; +} +@end /* RelationshipMustBeToOneException */ + + +@implementation InvalidValueTypeException +- initWithType:type +{ + id _reason = [NSString stringWithFormat:@"unknow value type '%@'", type]; + [self initWithName:@"InvalidValueTypeException" + reason:_reason userInfo:nil]; + return self; +} +@end + + +@implementation InvalidAttributeException +@end /* InvalidAttributeException */ + + +@implementation InvalidQualifierException +@end /* InvalidQualifierException */ + + +@implementation EOAdaptorException +@end /* EOAdaptorException */ + + +@implementation CannotFindAdaptorBundleException +@end /* CannotFindAdaptorBundleException */ + + +@implementation InvalidAdaptorBundleException +@end /* InvalidAdaptorBundleException */ + + +@implementation InvalidAdaptorStateException ++ exceptionWithAdaptor:(id)_adaptor +{ + InvalidAdaptorStateException* exception = [self alloc]; + exception->adaptor = _adaptor; + return exception; +} +@end /* InvalidAdaptorStateException */ + + +@implementation DataTypeMappingNotSupportedException +@end /* DataTypeMappingNotSupportedException */ + + +@implementation ChannelIsNotOpenedException +@end /* ChannelIsNotOpenedException */ + + +@implementation AdaptorIsFetchingException +@end /* AdaptorIsFetchingException */ + + +@implementation AdaptorIsNotFetchingException +@end /* AdaptorIsNotFetchingException */ + + +@implementation NoTransactionInProgressException +@end /* NoTransactionInProgressException */ + + +@implementation TooManyOpenedChannelsException +@end /* TooManyOpenedChannelsException */ diff --git a/sope-gdl1/GDLAccess/EOFault.m b/sope-gdl1/GDLAccess/EOFault.m new file mode 100644 index 00000000..c15e077a --- /dev/null +++ b/sope-gdl1/GDLAccess/EOFault.m @@ -0,0 +1,376 @@ +/* + EOAttributeOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// $Id: EOFault.m 1 2004-08-20 10:38:46Z znek $ + +#include "EOFault.h" +#include "EOFaultHandler.h" +#include "common.h" + +#if NeXT_RUNTIME || APPLE_RUNTIME +# include +#endif + +typedef struct { + Class isa; +} *my_objc_object; + +#if GNU_RUNTIME +# define object_is_instance(object) \ + ((object!=nil)&&CLS_ISCLASS(((my_objc_object)object)->isa)) +#else +# warning TODO: implement for NeXT/Apple runtime! +# define object_is_instance(object) (object!=nil?YES:NO) +#endif + + +/* + * EOFault class + */ + +@implementation EOFault + ++ (void)makeObjectIntoFault:(id)_object withHandler:(EOFaultHandler *)_handler { + [_handler setTargetClass:[_object class] extraData:((id *)_object)[1]]; + + ((EOFault *)_object)->isa = self; + ((EOFault *)_object)->faultResolver = [_handler retain]; +} + ++ (EOFaultHandler *)handlerForFault:(id)_fault { + if (![self isFault:_fault]) + return nil; + + return ((EOFault *)_fault)->faultResolver; +} + +/* Fault class methods */ + ++ (void)clearFault:(id)fault { + EOFault *aFault = (EOFault*)fault; + int refs; + + /* check if fault */ + if (aFault->isa != self) + return; + + /* get fault instance reference count + 1 set in creation methods */ + refs = aFault->faultResolver->faultReferences; + + /* make clear instance */ + aFault->isa = [aFault->faultResolver targetClass]; + aFault->faultResolver = [aFault->faultResolver autorelease]; + aFault->faultResolver = [aFault->faultResolver extraData]; + + /* + set references to real instance so that + re-implemented retain/release mechanism take control + */ + while(refs-- > 0) + [aFault retain]; +} + ++ (BOOL)isFault:(id)fault { + static Class EOFaultClass = Nil; + Class clazz; + + if (fault == nil) return NO; + if (EOFaultClass == Nil) EOFaultClass = [EOFault class]; + + for (clazz = ((EOFault *)fault)->isa; clazz; clazz = clazz->super_class) { + if (clazz == EOFaultClass) + return YES; + } + return NO; +} ++ (BOOL)isFault { + return NO; // no class faults +} +- (BOOL)isFault { + return YES; +} + ++ (Class)targetClassForFault:(id)_fault { + EOFault *aFault = (EOFault*)_fault; + + // Check that argument is fault + if (aFault->isa != self) + return nil; + + return [aFault->faultResolver targetClass]; +} + +// Fault Instance methods + +- (Class)superclass { +#if GNU_RUNTIME + return (object_is_instance(self)) + ? [[self->faultResolver classForFault:self] superclass] + : class_get_super_class((Class)self); +#else +# warning TODO: add complete implementation for NeXT/Apple runtime! + return [[self->faultResolver classForFault:self] superclass]; +#endif +} + ++ (Class)class { + return self; +} +- (Class)class { + return [self->faultResolver classForFault:self]; +} + +- (BOOL)isKindOfClass:(Class)_class; { + return [self->faultResolver isKindOfClass:_class forFault:self]; +} +- (BOOL)isMemberOfClass:(Class)_class { + return [self->faultResolver isMemberOfClass:_class forFault:self]; +} + +- (BOOL)conformsToProtocol:(Protocol *)_protocol { + return [self->faultResolver conformsToProtocol:_protocol forFault:self]; +} + ++ (BOOL)respondsToSelector:(SEL)_selector { +#if GNU_RUNTIME + return class_get_instance_method(self, _selector) != NULL; +#else +# warning TODO: add complete implementation for Apple/NeXT runtime! + return NO; +#endif +} + +- (BOOL)respondsToSelector:(SEL)_selector { +#if GNU_RUNTIME + return (object_is_instance(self)) + ? [self->faultResolver respondsToSelector:_selector forFault:self] + : class_get_class_method(self->isa, _selector) != METHOD_NULL; +#else +# warning TODO: add complete implementation for Apple/NeXT runtime! + return [self->faultResolver respondsToSelector:_selector forFault:self]; +#endif +} + +// ******************** retain counting ******************** + ++ (id)retain { + return self; +} +- (id)retain { + self->faultResolver->faultReferences++; + return self; +} + ++ (oneway void)release { +} +- (oneway void)release { + if (faultResolver->faultReferences <= 0) + [self dealloc]; + else + faultResolver->faultReferences--; +} + ++ (unsigned)retainCount { + return 1; +} +- (unsigned)retainCount { + // For instance + return faultResolver->faultReferences+1; +} + ++ (id)autorelease { + return self; +} +- (id)autorelease { + [NSAutoreleasePool addObject:self]; + return self; +} + +- (NSZone *)zone { + return NSZoneFromPointer(self); +} + +- (BOOL)isProxy { + return NO; +} +- (BOOL)isGarbageCollectable { + return NO; +} + ++ (void)dealloc { + NSLog(@"WARNING: tried to deallocate EOFault class .."); +} +- (void)dealloc { + [self->isa clearFault:self]; + [self dealloc]; +} + +/* descriptions */ + +- (NSString *)description { + return [self->faultResolver descriptionForObject:self]; +} +- (NSString *)descriptionWithIndent:(unsigned)level { + return [self description]; +} +- (NSString *)stringRepresentation { + return [self description]; +} +- (NSString *)eoShallowDescription { + return [self description]; +} + +- (NSString *)propertyListStringWithLocale:(NSDictionary *)_locale + indent:(int)_i +{ + return [self description]; +} + +/* Forwarding stuff */ + ++ (void)initialize { + /* + Must be here as initialize is called for each root class + without asking if it responds to it ! + */ +} + +static inline void _resolveFault(EOFault *self) { + EOFaultHandler *handler; + + /* If in class */ + if (!object_is_instance(self)) { + [NSException raise:@"NSInvalidArgumentException" + format:@"used EOFault class in forward"]; + } + + handler = self->faultResolver; + [handler completeInitializationOfObject:self]; + + if (self->isa == [EOFault class]) { + [NSException raise:@"NSInvalidArgumentException" + format: + @"fault error: %@ was not cleared during fault fetching", + [handler descriptionForObject:self]]; + } +} + ++ (id)self { + _resolveFault(self); + return self; +} + +#if 0 + +- (void)setObject:(id)object forKey:(id)key { + _resolveFault(self); + [self setObject:object forKey:key]; +} +- (id)objectForKey:(id)key { + _resolveFault(self); + return [self objectForKey:key]; +} +- (void)removeObjectForKey:(id)key { + _resolveFault(self); + [self removeObjectForKey:key]; +} + +- (void)takeValuesFromDictionary:(NSDictionary *)dictionary { + _resolveFault(self); + [self takeValuesFromDictionary:dictionary]; +} +- (NSDictionary *)valuesForKeys:(NSArray *)keys { + _resolveFault(self); + return [self valuesForKeys:keys]; +} +- (BOOL)takeValue:(id)object forKey:(id)key { + _resolveFault(self); + return [self takeValue:object forKey:key]; +} +- (id)valueForKey:(id)key { + _resolveFault(self); + return [self valueForKey:key]; +} + +- (BOOL)kvcIsPreferredInKeyPath { + _resolveFault(self); + return YES; +} + +#endif /* 0 */ + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)_sel { + return [self->faultResolver methodSignatureForSelector:_sel forFault:self]; +} + +- (void)forwardInvocation:(NSInvocation *)_invocation { + if ([self->faultResolver shouldPerformInvocation:_invocation]) { + _resolveFault(self); + [_invocation invoke]; + } +} + +@end /* EOFault */ + +@implementation EOFault(RealForwarding) + +#if NeXT_Foundation_LIBRARY + +- (void)forwardInvocation:(NSInvocation *)_inv { + _resolveFault(self); + + [_inv setTarget:self]; + [_inv invoke]; +} + +#else + +- (retval_t)forward:(SEL)sel:(arglist_t)args { +#if 1 && !defined(__APPLE__) + Method_t forward; + + forward = class_get_instance_method(objc_lookup_class("NSObject"), _cmd); + return ((retval_t (*)(id, SEL, SEL, arglist_t))forward->method_imp) + (self, _cmd, sel, args); +#else + struct objc_method *m; + + _resolveFault(self); + + if ((m = class_get_instance_method(self->isa, sel)) == NULL) { + NSString *r; + + r = [NSString stringWithFormat: + @"fault error: resolved fault does not responds to selector %s", + sel_get_name(sel)]; + [NSException raise:@"NSInvalidArgumentException" reason:r userInfo:nil]; + } + return objc_msg_sendv(self, sel, args); +#endif +} +#endif + +@end /* EOFault(RealForwarding) */ diff --git a/sope-gdl1/GDLAccess/EOFaultHandler.m b/sope-gdl1/GDLAccess/EOFaultHandler.m new file mode 100644 index 00000000..a52a9c6e --- /dev/null +++ b/sope-gdl1/GDLAccess/EOFaultHandler.m @@ -0,0 +1,206 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOFaultHandler.m 1 2004-08-20 10:38:46Z znek $ + +#include "EOFaultHandler.h" +#include "EOFault.h" +#include "common.h" + +#if NeXT_RUNTIME +# if !defined(METHOD_NULL) +# define METHOD_NULL NULL +# endif +#endif + +@implementation EOFaultHandler + +- (void)setTargetClass:(Class)_class extraData:(void *)_extraData { + self->targetClass = _class; + self->extraData = _extraData; +} + +- (Class)targetClass; { + return self->targetClass; +} +- (void *)extraData { + return self->extraData; +} + +/* firing */ + +- (BOOL)shouldPerformInvocation:(NSInvocation *)_invocation { + return YES; +} + +- (void)faultWillFire:(EOFault *)_fault { +} + +- (void)completeInitializationOfObject:(id)_object { + [self doesNotRecognizeSelector:_cmd]; +} + +/* fault reflection */ + +- (Class)classForFault:(EOFault *)_fault { +#if GNU_RUNTIME + return (object_is_instance(_fault)) + ? [self targetClass] + : (*(Class *)_fault); +#else +# warning TODO: add complete implementation for Apple/NeXT runtime! + return [self targetClass]; +#endif +} + +- (BOOL)respondsToSelector:(SEL)_selector forFault:(EOFault *)_fault { + Class class; + + /* first check whether fault itself responds to selector */ +#if GNU_RUNTIME + if (class_get_instance_method(*(Class *)_fault, _selector) != METHOD_NULL) + return YES; +#else +# warning TODO: add implementation for NeXT/Apple runtime! +#endif + + /* then check whether the target class does */ + class = [self targetClass]; +#if GNU_RUNTIME + return (class_get_instance_method(class, _selector) != NULL) ? YES : NO; +#else +# warning TODO: use NeXT/Apple runtime function + return [class methodForSelector:_selector] ? YES : NO; +#endif +} + +- (BOOL)conformsToProtocol:(Protocol *)_protocol forFault:(EOFault *)_fault { + Class class, sClass; + +#if GNU_RUNTIME + struct objc_protocol_list* protos; + int i; + + class = object_is_instance(_fault) ? [self targetClass] : (Class)_fault; + for (protos = class->protocols; protos; protos = protos->next) { + for (i = 0; i < protos->count; i++) { + if ([protos->list[i] conformsTo:_protocol]) + return YES; + } + } +#else +# warning TODO: implement on NeXT/Apple runtime! + class = [self targetClass]; +#endif + + return ((sClass = [class superclass])) + ? [sClass conformsToProtocol:_protocol] + : NO; +} + +- (BOOL)isKindOfClass:(Class)_class forFault:(EOFault *)_fault { + Class class; + +#if GNU_RUNTIME + class = object_is_instance(_fault) ? [self targetClass] : (Class)_fault; + for (; class != Nil; class = class_get_super_class(class)) { + if (class == _class) + return YES; + } +#else +# warning TODO: add implementation for NeXT/Apple runtime! + class = [self targetClass]; +#endif + return NO; +} + +- (BOOL)isMemberOfClass:(Class)_class forFault:(EOFault *)_fault { + Class class; +#if GNU_RUNTIME + class = object_is_instance(_fault) ? [self targetClass] : (Class)_fault; +#else +# warning TODO: add implementation for NeXT/Apple runtime! + class = [self targetClass]; +#endif + return class == _class ? YES : NO; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)_selector + forFault:(EOFault *)_fault +{ +#if NeXT_Foundation_LIBRARY + // probably incorrect + return [_fault methodSignatureForSelector:_selector]; +#else + register const char *types = NULL; + + if (_selector == NULL) // invalid selector + return nil; + +#if GNU_RUNTIME && 0 + // GNU runtime selectors may be typed, a lookup may not be necessary + types = aSelector->sel_types; +#endif + + /* first check for EOFault's own methods */ + + if (types == NULL) { + // lookup method for selector + struct objc_method *mth; + mth = class_get_instance_method(*(Class *)_fault, _selector); + if (mth) types = mth->method_types; + } + + /* then check in target class methods */ + + if (types == NULL) { + // lookup method for selector + struct objc_method *mth; + mth = class_get_instance_method([self targetClass], _selector); + if (mth) types = mth->method_types; + } + +#if GNU_RUNTIME + // GNU runtime selectors may be typed, a lookup may not be necessary + if (types == NULL) + types = _selector->sel_types; +#endif + if (types == NULL) + return nil; + + return [NSMethodSignature signatureWithObjCTypes:types]; +#endif +} + +/* description */ + +- (NSString *)descriptionForObject:(id)_fault { + return [NSString stringWithFormat:@"<%@[0x%08X]: on=%@>", + NSStringFromClass(*(Class *)_fault), + _fault, + NSStringFromClass([self targetClass])]; +} + +@end /* EOFaultHandler */ diff --git a/sope-gdl1/GDLAccess/EOGenericRecord.m b/sope-gdl1/GDLAccess/EOGenericRecord.m new file mode 100644 index 00000000..79856f4a --- /dev/null +++ b/sope-gdl1/GDLAccess/EOGenericRecord.m @@ -0,0 +1,84 @@ +/* + EOGenericRecord.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#import +#import +#import +#import "common.h" +#import "EOEntity.h" +#import "EOGenericRecord.h" +#import "EODatabase.h" +#import +#import + +@interface EOClassDescription(ClassDesc) +/* TODO: check, whether this can be removed */ ++ (NSClassDescription *)classDescriptionForEntityName:(NSString *)_entityName; +@end + +@implementation EOGenericRecord(EOAccess) + +- (id)initWithPrimaryKey:(NSDictionary *)_key entity:(EOEntity *)_entity { + /* TODO: is this method ever used? Maybe remove */ + EOClassDescription *cd; + NSEnumerator *e; + NSString *key; + + if (_entity == nil) { + AUTORELEASE(self); + NSLog(@"WARNING: tried to create generic record with entity !"); + return nil; + } + + cd = (id)[EOClassDescription classDescriptionForEntityName:[_entity name]]; +#if DEBUG + NSAssert1(cd, @"did not find class description for entity %@", _entity); +#endif + + self = [self initWithEditingContext:nil + classDescription:cd + globalID:nil]; + + e = [_key keyEnumerator]; + + while ((key = [e nextObject])) + [self setObject:[_key objectForKey:key] forKey:key]; + + return self; +} + +- (void)_letDatabasesForget { + [EODatabase forgetObject:self]; +} + +/* model */ + +- (EOEntity *)entity { + return [(EOEntityClassDescription *)[self classDescription] entity]; +} + +@end /* EOGenericRecord(EOAccess) */ diff --git a/sope-gdl1/GDLAccess/EOKeyComparisonQualifier+SQL.m b/sope-gdl1/GDLAccess/EOKeyComparisonQualifier+SQL.m new file mode 100644 index 00000000..8b56c895 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOKeyComparisonQualifier+SQL.m @@ -0,0 +1,70 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOKeyComparisonQualifier+SQL.m 1 2004-08-20 10:38:46Z znek $ + +#import "EOSQLQualifier.h" +#include "common.h" + +#if NeXT_RUNTIME || APPLE_RUNTIME +# ifndef SEL_EQ +# define SEL_EQ(__A__,__B__) (__A__==__B__?YES:NO) +# endif +#endif + +@implementation EOKeyComparisonQualifier(SQLQualifier) + +/* SQL qualifier generation */ + +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity { + EOSQLQualifier *q; + NSString *format; + + if (SEL_EQ(self->operator, EOQualifierOperatorEqual)) + format = @"%A = %A"; + else if (SEL_EQ(self->operator, EOQualifierOperatorNotEqual)) + format = @"%A <> %A"; + else if (SEL_EQ(self->operator, EOQualifierOperatorLessThan)) + format = @"%A < %A"; + else if (SEL_EQ(self->operator, EOQualifierOperatorGreaterThan)) + format = @"%A > %A"; + else if (SEL_EQ(self->operator, EOQualifierOperatorLessThanOrEqualTo)) + format = @"%A <= %A"; + else if (SEL_EQ(self->operator, EOQualifierOperatorGreaterThanOrEqualTo)) + format = @"%A >= %A"; + else if (SEL_EQ(self->operator, EOQualifierOperatorLike)) + format = @"%A LIKE %A"; + else { + format = [NSString stringWithFormat:@"%%A %@ %%A", + NSStringFromSelector(self->operator)]; + } + + q = [[EOSQLQualifier alloc] + initWithEntity:_entity + qualifierFormat:format, self->leftKey, self->rightKey]; + return AUTORELEASE(q); +} + +@end /* EOKeyComparisonQualifier(SQLQualifier) */ diff --git a/sope-gdl1/GDLAccess/EOKeySortOrdering.m b/sope-gdl1/GDLAccess/EOKeySortOrdering.m new file mode 100644 index 00000000..dc2296f0 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOKeySortOrdering.m @@ -0,0 +1,144 @@ +/* + EOKeySortOrdering.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import +#import +#import +#import +#import "common.h" +#import "EOKeySortOrdering.h" +#import + +@implementation EOKeySortOrdering + ++ keyOrderingWithKey:(NSString*)aKey ordering:(NSComparisonResult)anOrdering +{ + return AUTORELEASE([[EOKeySortOrdering alloc] + initWithKey:aKey ordering:anOrdering]); +} + +- initWithKey:(NSString*)aKey ordering:(NSComparisonResult)anOrdering +{ + ASSIGN(key, aKey); + ordering = anOrdering; + return self; +} + +- (NSString*)key {return key;} +- (NSComparisonResult)ordering {return ordering;} + +@end + +// TODO : integrate this function in the two methods above and optimize +// object creation and method calls for objects that provide quick +// access to their values - do not use nested functions + +static NSComparisonResult _keySortCompare(id obj1, id obj2, NSArray* order) + __attribute__((unused)); + +static NSComparisonResult _keySortCompare(id obj1, id obj2, NSArray* order) { + int i, n; + + for (i = 0, n = [order count]; i < n; i++) { + id val1, val2, key, kar; + NSComparisonResult ord, vord; + EOKeySortOrdering* kso = [order objectAtIndex:i]; + + key = [kso key]; + ord = [kso ordering]; + kar = [NSArray arrayWithObject:key]; + + val1 = [[obj1 valuesForKeys:kar] objectForKey:key]; + val2 = [[obj2 valuesForKeys:kar] objectForKey:key]; + + if (!val1 && !val2) + continue; + + if (!val1 && val2) + return ord == NSOrderedAscending ? + NSOrderedAscending : NSOrderedDescending; + + if (val1 && !val2) + return ord == NSOrderedAscending ? + NSOrderedDescending : NSOrderedAscending; + + vord = [(NSString *)val1 compare:val2]; + + if (vord == NSOrderedSame) + continue; + + if (vord == NSOrderedAscending) + return ord == NSOrderedAscending ? + NSOrderedAscending : NSOrderedDescending; + else + return ord == NSOrderedAscending ? + NSOrderedDescending : NSOrderedAscending; + } + + return NSOrderedSame; +} + +#if 0 + +@implementation NSArray(EOKeyBasedSorting) + +- (NSArray*)sortedArrayUsingKeyOrderArray:(NSArray*)orderArray +{ + NSArray* arry; + CREATE_AUTORELEASE_POOL(pool); + + arry = [self sortedArrayUsingFunction: + (int(*)(id, id, void*))_keySortCompare + context:orderArray]; + RELEASE(pool); + return arry; +} + +@end + +@implementation NSMutableArray(EOKeyBasedSorting) + +- (void)sortUsingKeyOrderArray:(NSArray*)orderArray +{ + CREATE_AUTORELEASE_POOL(pool); + + [self sortUsingFunction: + (int(*)(id, id, void*))_keySortCompare + context:orderArray]; + RELEASE(pool); +} + +@end + +#endif + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ + diff --git a/sope-gdl1/GDLAccess/EOKeyValueQualifier+SQL.m b/sope-gdl1/GDLAccess/EOKeyValueQualifier+SQL.m new file mode 100644 index 00000000..e4e098ff --- /dev/null +++ b/sope-gdl1/GDLAccess/EOKeyValueQualifier+SQL.m @@ -0,0 +1,64 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOKeyValueQualifier+SQL.m 1 2004-08-20 10:38:46Z znek $ + +#import "EOSQLQualifier.h" +#include "common.h" + +@implementation EOKeyValueQualifier(SQLQualifier) + +/* SQL qualifier generation */ + +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity { + EOSQLQualifier *q; + NSString *format; + + if (SEL_EQ(self->operator, EOQualifierOperatorEqual)) + format = @"%A = %@"; + else if (SEL_EQ(self->operator, EOQualifierOperatorNotEqual)) + format = @"%A <> %@"; + else if (SEL_EQ(self->operator, EOQualifierOperatorLessThan)) + format = @"%A < %@"; + else if (SEL_EQ(self->operator, EOQualifierOperatorGreaterThan)) + format = @"%A > %@"; + else if (SEL_EQ(self->operator, EOQualifierOperatorLessThanOrEqualTo)) + format = @"%A <= %@"; + else if (SEL_EQ(self->operator, EOQualifierOperatorGreaterThanOrEqualTo)) + format = @"%A >= %@"; + else if (SEL_EQ(self->operator, EOQualifierOperatorLike)) + format = @"%A LIKE %@"; + else { + format = [NSString stringWithFormat:@"%%A %@ %%@", + NSStringFromSelector(self->operator)]; + } + + q = [[EOSQLQualifier alloc] + initWithEntity:_entity + qualifierFormat:format, self->key, self->value]; + return AUTORELEASE(q); +} + +@end /* EOKeyValueQualifier */ diff --git a/sope-gdl1/GDLAccess/EOModel.m b/sope-gdl1/GDLAccess/EOModel.m new file mode 100644 index 00000000..917c9ad2 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOModel.m @@ -0,0 +1,462 @@ +/* + EOModel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOModel.h" +#import "EOEntity.h" + +/* Include the code from EOKeyValueCoding.m and EOCustomValues.m here because + they contain categories to various classes from Foundation that don't get + linked into the client application since no one refers them. The NeXT linker + knows how to deal with this but all the other linkers don't... */ +#if 0 +# import "EOCustomValues.m" +#endif + +void EOModel_linkCategories(void) { + void EOAccess_EOCustomValues_link(void); + + EOAccess_EOCustomValues_link(); +} + +@implementation EOModel + +- (id)copyWithZone:(NSZone *)_zone { + return RETAIN(self); +} + ++ (NSString*)findPathForModelNamed:(NSString*)modelName { + int i; + NSBundle* bundle = [NSBundle mainBundle]; + NSString* modelPath = [bundle pathForResource:modelName ofType:@"eomodel"]; + NSString* paths[] = { @"~/Library/Models", + @"/LocalLibrary/Models", + @"/NextLibrary/Models", + nil }; + + if(modelPath) + return modelPath; + + for(i = 0; paths[i]; i++) { + bundle = [NSBundle bundleWithPath:paths[i]]; + modelPath = [bundle pathForResource:modelName ofType:@"eomodel"]; + if(modelPath) + return modelPath; + } + return nil; +} + +- (id)init { + if ((self = [super init])) { + NSNotificationCenter *nc; + + nc = [NSNotificationCenter defaultCenter]; + [nc addObserver:self selector:@selector(_requireClassDescriptionForClass:) + name:@"EOClassDescriptionNeededForClass" object:nil]; + [nc addObserver:self + selector:@selector(_requireClassDescriptionForEntityName:) + name:@"EOClassDescriptionNeededForEntityName" object:nil]; + + self->entities = [[NSArray alloc] init]; + self->entitiesByName = [[NSMutableDictionary alloc] initWithCapacity:4]; + self->entitiesByClassName = + [[NSMutableDictionary alloc] initWithCapacity:4]; + } + + return self; +} + +- (void)resetEntities { + [self->entities makeObjectsPerformSelector:@selector(resetModel)]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self resetEntities]; + RELEASE(self->entities); + RELEASE(self->entitiesByName); + RELEASE(self->entitiesByClassName); + RELEASE(self->name); + RELEASE(self->path); + RELEASE(self->adaptorName); + RELEASE(self->adaptorClassName); + RELEASE(self->connectionDictionary); + RELEASE(self->pkeyGeneratorDictionary); + RELEASE(self->userDictionary); + [super dealloc]; +} + +- (id)initWithContentsOfFile:(NSString*)filename +{ + NSDictionary *propList; + + propList = [[[NSDictionary alloc] + initWithContentsOfFile:filename] autorelease]; + if (propList == nil) { + [NSException raise:NSInvalidArgumentException + format:@"EOModel: Couldn't load model file: %@", filename]; + } + + if ((self = [self initWithPropertyList:propList])) { + self->path = [filename copy]; + self->name = [[[filename lastPathComponent] stringByDeletingPathExtension] + copy]; + } + return self; +} + +- (id)initWithPropertyList:(NSDictionary *)propertyList { + if ((self = [self init])) { + int i, count; + NSArray *propListEntities; + + if (propertyList == nil) { + [NSException raise:NSInvalidArgumentException + format: + @"EOModel: Argument of initWithPropertyList: must " + @"not be the nil object"]; + } + if (![propertyList isKindOfClass:[NSDictionary class]]) { + [NSException raise:NSInvalidArgumentException + format:@"EOModel: Argument of initWithPropertyList: must " + @"be kind of NSDictionary class"]; + } + + self->adaptorName = + [[propertyList objectForKey:@"adaptorName"] copy]; + self->adaptorClassName = + [[propertyList objectForKey:@"adaptorClassName"] copy]; + self->connectionDictionary = + [[propertyList objectForKey:@"connectionDictionary"] copy]; + self->pkeyGeneratorDictionary = + [[propertyList objectForKey:@"pkeyGeneratorDictionary"] copy]; + self->userDictionary = + [[propertyList objectForKey:@"userDictionary"] copy]; + + propListEntities = [propertyList objectForKey:@"entities"]; + + flags.errors = NO; + [self setCreateMutableObjects:YES]; + count = [propListEntities count]; + for (i = 0; i < count; i++) { + EOEntity *entity; + + entity = [EOEntity entityFromPropertyList: + [propListEntities objectAtIndex:i] + model:self]; + [self addEntity:entity]; + } + + count = [self->entities count]; + for (i = 0; i < count; i++) + [[self->entities objectAtIndex:i] replaceStringsWithObjects]; + + /* Init relationships */ + for (i = 0; i < count; i++) { + EOEntity *entity; + NSArray *rels; + + entity = [self->entities objectAtIndex:i]; + rels = [entity relationships]; + /* Replace all the strings in relationships. */ + [rels makeObjectsPerformSelector:@selector(replaceStringsWithObjects)]; + } + + /* Another pass to allow properly initialization of flattened + relationships. */ + for (i = 0; i < count; i++) { + EOEntity* entity = + [self->entities objectAtIndex:i]; + NSArray* rels = [entity relationships]; + + [rels makeObjectsPerformSelector:@selector(initFlattenedRelationship)]; + } + + /* Init attributes */ + for (i = 0; i < count; i++) { + EOEntity *entity = [self->entities objectAtIndex:i]; + NSArray *attrs = [entity attributes]; + + [attrs makeObjectsPerformSelector:@selector(replaceStringsWithObjects)]; + } + + [self setCreateMutableObjects:NO]; + } + return flags.errors ? (void)AUTORELEASE(self), (id)nil : self; +} + +- (id)initWithName:(NSString*)_name { + if ((self = [self init])) { + ASSIGN(self->name, _name); + } + return self; +} + +/* class-description notifications */ + +- (void)_requireClassDescriptionForEntityName:(NSNotification *)_notification { + NSString *entityName; + + if ((entityName = [_notification object])) { + EOEntity *entity; + + if ((entity = [self->entitiesByName objectForKey:entityName])) { + EOClassDescription *d; + + d = [[EOEntityClassDescription alloc] initWithEntity:entity]; + [EOClassDescription registerClassDescription:d + forClass:NSClassFromString([entity className])]; + RELEASE(d); d = nil; + } + } +} +- (void)_requireClassDescriptionForClass:(NSNotification *)_notification { + Class clazz; + NSString *className; + EOEntity *entity; + EOClassDescription *d; + + if ((clazz = [_notification object]) == nil) + return; + if ((className = NSStringFromClass(clazz)) == nil) + return; + if ((entity = [self->entitiesByClassName objectForKey:className]) == nil) + return; + + d = [[EOEntityClassDescription alloc] initWithEntity:entity]; + [EOClassDescription registerClassDescription:d forClass:clazz]; + [d release]; d = nil; +} + +/* property list */ + +- (id)modelAsPropertyList { + NSMutableDictionary *model = [NSMutableDictionary dictionaryWithCapacity:64]; + int i, count; + + [model setObject:[[NSNumber numberWithInt:[isa version]] stringValue] + forKey:@"EOModelVersion"]; + if (name) + [model setObject:name forKey:@"name"]; + if (adaptorName) + [model setObject:adaptorName forKey:@"adaptorName"]; + if (adaptorClassName) + [model setObject:adaptorClassName forKey:@"adaptorClassName"]; + if (connectionDictionary) + [model setObject:connectionDictionary forKey:@"connectionDictionary"]; + if (pkeyGeneratorDictionary) { + [model setObject:pkeyGeneratorDictionary + forKey:@"pkeyGeneratorDictionary"]; + } + if (userDictionary) + [model setObject:userDictionary forKey:@"userDictionary"]; + if (self->entities && (count = [self->entities count])) { + id entitiesArray = [NSMutableArray arrayWithCapacity:count]; + + [model setObject:entitiesArray forKey:@"entities"]; + for (i = 0; i < count; i++) { + [entitiesArray addObject: + [[entities objectAtIndex:i] propertyList]]; + } + } + + return model; +} + +- (BOOL)addEntity:(EOEntity *)entity { + NSString * entityName = [entity name]; + + if ([self->entitiesByName objectForKey:entityName]) + return NO; + + if ([self createsMutableObjects]) + [(NSMutableArray*)self->entities addObject:entity]; + else { + self->entities = + [[[self->entities autorelease] mutableCopy] autorelease]; + [(NSMutableArray *)self->entities addObject:entity]; + self->entities = [self->entities copy]; + } + + [self->entitiesByName setObject:entity forKey:entityName]; + [self->entitiesByClassName setObject:entity forKey:[entity className]]; + [entity setModel:self]; + return YES; +} + +- (void)removeEntityNamed:(NSString*)entityName { + id entity; + + if (entityName == nil) + return; + + entity = [self->entitiesByName objectForKey:entityName]; + + if ([self createsMutableObjects]) + [(NSMutableArray*)self->entities removeObject:entity]; + else { + self->entities = [AUTORELEASE(self->entities) mutableCopy]; + [(NSMutableArray*)self->entities removeObject:entity]; + self->entities = [AUTORELEASE(self->entities) copy]; + } + [self->entitiesByName removeObjectForKey:entityName]; + [entity resetModel]; +} + +- (EOEntity *)entityNamed:(NSString *)entityName { + return [self->entitiesByName objectForKey:entityName]; +} + +- (NSArray *)referencesToProperty:property { + [self notImplemented:_cmd]; + return 0; +} + +- (EOEntity *)entityForObject:object { + NSString *className; + + className = NSStringFromClass([object class]); + return [self->entitiesByClassName objectForKey:className]; +} + +- (BOOL)incorporateModel:(EOModel*)model { + [self notImplemented:_cmd]; + return 0; +} + +- (void)setAdaptorName:(NSString*)_adaptorName { + id tmp = self->adaptorName; + self->adaptorName = [_adaptorName copyWithZone:[self zone]]; + RELEASE(tmp); tmp = nil; +} +- (NSString *)adaptorName { + return self->adaptorName; +} + +- (void)setAdaptorClassName:(NSString*)_adaptorClassName { + id tmp = self->adaptorClassName; + self->adaptorClassName = [_adaptorClassName copyWithZone:[self zone]]; + RELEASE(tmp); tmp = nil; +} +- (NSString *)adaptorClassName { + return self->adaptorClassName; +} + +- (void)setConnectionDictionary:(NSDictionary*)_connectionDictionary { + ASSIGN(self->connectionDictionary, _connectionDictionary); +} +- (NSDictionary *)connectionDictionary { + return self->connectionDictionary; +} + +- (void)setPkeyGeneratorDictionary:(NSDictionary *)_dict { + ASSIGN(self->pkeyGeneratorDictionary, _dict); +} +- (NSDictionary *)pkeyGeneratorDictionary { + return self->pkeyGeneratorDictionary; +} + +- (void)setUserDictionary:(NSDictionary *)_userDictionary { + ASSIGN(self->userDictionary, _userDictionary); +} +- (NSDictionary *)userDictionary { + return self->userDictionary; +} + +- (NSString *)path { + return self->path; +} +- (NSString *)name { + return self->name; +} +- (NSArray *)entities { + NSMutableArray *ents; + int cnt, i; + + cnt = [self->entities count]; + ents = [NSMutableArray arrayWithCapacity:cnt]; + for (i = 0; i < cnt; i++) + [ents addObject:[self->entities objectAtIndex:i]]; + + return ents; +} + ++ (int)version { + return 1; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + NSString *s; + + ms = [NSMutableString stringWithCapacity:256]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + + if ((s = [self name])) [ms appendFormat:@" name=%@", s]; + if ((s = [self path])) [ms appendFormat:@" path=%@", s]; + if ((s = [self adaptorName])) [ms appendFormat:@" adaptor=%@", s]; + if ((s = [self adaptorClassName])) [ms appendFormat:@" adaptor-class=%@", s]; + + [ms appendFormat:@" #entities=%d", [self->entities count]]; + + [ms appendString:@">"]; + return ms; +} + +@end /* EOModel */ + + +@implementation EOModel (EOModelPrivate) + +- (void)setCreateMutableObjects:(BOOL)flag { + if(flags.createsMutableObjects == flag) + return; + + flags.createsMutableObjects = flag; + + if(flags.createsMutableObjects) + self->entities = [AUTORELEASE(self->entities) mutableCopy]; + else + self->entities = [AUTORELEASE(self->entities) copy]; +} + +- (BOOL)createsMutableObjects { + return flags.createsMutableObjects; +} +- (void)errorInReading { + flags.errors = YES; +} + +@end /* EOModel (EOModelPrivate) */ + +@implementation EOModel(NewInEOF2) + +- (void)loadAllModelObjects { +} + +@end diff --git a/sope-gdl1/GDLAccess/EOModelGroup.m b/sope-gdl1/GDLAccess/EOModelGroup.m new file mode 100644 index 00000000..64839b83 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOModelGroup.m @@ -0,0 +1,242 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOModelGroup.m 1 2004-08-20 10:38:46Z znek $ + +#include "EOModelGroup.h" +#include "EOModel.h" +#include "EOEntity.h" +#import +#include "common.h" + +@implementation EOModelGroup + +static EOModelGroup *defaultGroup = nil; +static id classDelegate = nil; + ++ (void)setDefaultGroup:(EOModelGroup *)_group { + ASSIGN(defaultGroup, _group); +} + ++ (EOModelGroup *)defaultGroup { + EOModelGroup *group; + + group = defaultGroup; + + if (group == nil) + group = [[self classDelegate] defaultModelGroup]; + + if (group == nil) + group = [self globalModelGroup]; + + return group; +} + ++ (EOModelGroup *)globalModelGroup { + static EOModelGroup *globalModelGroup = nil; + NSEnumerator *bundles; + NSBundle *bundle; + + if (globalModelGroup) + return globalModelGroup; + + globalModelGroup = [[EOModelGroup alloc] init]; + + bundles = [[NSBundle allBundles] objectEnumerator]; + while ((bundle = [bundles nextObject])) { + NSEnumerator *paths; + NSString *path; + + paths = [[bundle pathsForResourcesOfType:@"eomodel" inDirectory:nil] + objectEnumerator]; + + while ((path = [paths nextObject])) { + EOModel *model; + + model = [[EOModel alloc] initWithContentsOfFile:path]; + if (model == nil) { + NSLog(@"WARNING: couldn't load model %@", path); + } + else { + [globalModelGroup addModel:model]; + RELEASE(model); + } + } + } + return globalModelGroup; +} + ++ (void)setClassDelegate:(id)_delegate { + ASSIGN(classDelegate, _delegate); +} ++ (id)classDelegate { + return classDelegate; +} + +- (id)init { + self->nameToModel = [[NSMutableDictionary allocWithZone:[self zone]] init]; + return self; +} + +- (void)dealloc { + RELEASE(self->nameToModel); + [super dealloc]; +} + +/* instance delegate */ + +- (void)setDelegate:(id)_delegate { + self->delegate = _delegate; +} +- (id)delegate { + return self->delegate; +} + +/* accessors */ + +- (void)addModel:(EOModel *)_model { + NSString *name; + + name = [_model name]; + if (name == nil) name = [[_model path] lastPathComponent]; + + if ([self->nameToModel objectForKey:name]) { + [NSException raise:@"NSInvalidArgumentException" + format:@"model group %@ already contains model named %@", + self, name]; + } + + [self->nameToModel setObject:_model forKey:name]; + + [[NSNotificationCenter defaultCenter] + postNotificationName:@"EOModelAddedNotification" + object:_model]; +} + +- (void)removeModel:(EOModel *)_model { + NSArray *allNames; + + allNames = [self->nameToModel allKeysForObject:_model]; + [self->nameToModel removeObjectsForKeys:allNames]; + + [[NSNotificationCenter defaultCenter] + postNotificationName:@"EOModelInvalidatedNotification" + object:_model]; +} + +- (EOModel *)addModelWithFile:(NSString *)_path { + EOModel *model; + + model = [[EOModel alloc] initWithContentsOfFile:_path]; + if (model == nil) + return nil; + AUTORELEASE(model); + + [self addModel:model]; + + return model; +} + +- (EOModel *)modelNamed:(NSString *)_name { + return [self->nameToModel objectForKey:_name]; +} +- (EOModel *)modelWithPath:(NSString *)_path { + NSEnumerator *e; + EOModel *m; + NSString *p; + + p = [_path stringByStandardizingPath]; + if (p == nil) p = _path; + + e = [self->nameToModel objectEnumerator]; + while ((m = [e nextObject])) { + NSString *mp; + + mp = [[m path] stringByStandardizingPath]; + if (mp == nil) mp = [m path]; + + if ([p isEqual:mp]) + return m; + } + return m; +} + +- (NSArray *)modelNames { + return [self->nameToModel allKeys]; +} +- (NSArray *)models { + return [self->nameToModel allValues]; +} + +- (void)loadAllModelObjects { + [[self->nameToModel allValues] makeObjectsPerformSelector:_cmd]; +} + +/* entities */ + +- (EOEntity *)entityForObject:(id)_object { + NSEnumerator *e; + EOModel *m; + + e = [self->nameToModel objectEnumerator]; + while ((m = [e nextObject])) { + EOEntity *entity; + + if ((entity = [m entityForObject:_object])) + return entity; + } + return nil; +} + +- (EOEntity *)entityNamed:(NSString *)_name { + NSEnumerator *e; + EOModel *m; + + e = [self->nameToModel objectEnumerator]; + while ((m = [e nextObject])) { + EOEntity *entity; + + if ((entity = [m entityNamed:_name])) + return entity; + } + return nil; +} + +- (EOFetchSpecification *)fetchSpecificationNamed:(NSString *)_name + entityNamed:(NSString *)_entityName +{ + return [[self entityNamed:_entityName] fetchSpecificationNamed:_name]; +} + +/* description */ + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@[0x%08X]: models=%@>", + NSStringFromClass([self class]), + self, + [[self modelNames] componentsJoinedByString:@","]]; +} + +@end /* EOModelGroup */ diff --git a/sope-gdl1/GDLAccess/EONotQualifier+SQL.m b/sope-gdl1/GDLAccess/EONotQualifier+SQL.m new file mode 100644 index 00000000..18ecb41d --- /dev/null +++ b/sope-gdl1/GDLAccess/EONotQualifier+SQL.m @@ -0,0 +1,43 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EONotQualifier+SQL.m 1 2004-08-20 10:38:46Z znek $ + +#import "EOSQLQualifier.h" +#include "common.h" + +@implementation EONotQualifier(SQLQualifier) + +/* SQL qualifier generation */ + +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity { + EOSQLQualifier *q; + + q = [self->qualifier sqlQualifierForEntity:_entity]; + [q negate]; + return q; +} + +@end /* EONotQualifier */ diff --git a/sope-gdl1/GDLAccess/EOObjectUniquer.m b/sope-gdl1/GDLAccess/EOObjectUniquer.m new file mode 100644 index 00000000..e6057f6e --- /dev/null +++ b/sope-gdl1/GDLAccess/EOObjectUniquer.m @@ -0,0 +1,369 @@ +/* + EOObjectUniquer.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOEntity.h" +#import "EOObjectUniquer.h" +#import "EOPrimaryKeyDictionary.h" +#import "EODatabaseFault.h" +#import "EOGenericRecord.h" + +static unsigned uniquerHash(NSMapTable* table, EOUniquerRecord* rec) { + // efficient hash for dictionaries is done in the concrete + // dictionaries implementation; dictionaries are allocated + // from EOPrimaryKeyDictionary concrete subclasses + return ((unsigned)(rec->entity) >> 4) + + ((EOPrimaryKeyDictionary*)(rec->pkey))->fastHash; +} + +static BOOL uniquerCompare(NSMapTable *table, EOUniquerRecord *rec1, + EOUniquerRecord *rec2) { + // efficient compare between dictionaries is done in the concrete + // dictionaries implementation; dictionaries are allocated + // from EOPrimaryKeyDictionary concrete subclasses + return (rec1->entity == rec2->entity) && [rec1->pkey fastIsEqual:rec2->pkey]; +} + +static NSString* uniqDescription(NSMapTable *t, EOUniquerRecord* rec) { + return [NSString stringWithFormat: + @"<>", + rec->pkey, rec->entity, rec->object, rec->snapshot]; +} + +static void uniquerRetain(NSMapTable *table, EOUniquerRecord* rec) { + rec->refCount++; +} + +static void uniquerRelease(NSMapTable *table, EOUniquerRecord *rec) { + rec->refCount--; + + if (rec->refCount <= 0) { + RELEASE(rec->pkey); rec->pkey = NULL; + RELEASE(rec->entity); rec->entity = NULL; + RELEASE(rec->snapshot); rec->snapshot = NULL; + Free(rec); rec = NULL; + } +} + +static inline EOUniquerRecord *uniquerCreate(id pkey, id entity, id object, + id snapshot) { + EOUniquerRecord *rec = NULL; + + rec = (EOUniquerRecord *)Malloc(sizeof(EOUniquerRecord)); + rec->refCount = 0; + rec->pkey = RETAIN(pkey); + rec->entity = RETAIN(entity); + rec->object = object; + rec->snapshot = RETAIN(snapshot); + + return rec; +} + +static void uniquerNoAction(NSMapTable * t, const void *_object) { +} + +static NSMapTableKeyCallBacks uniquerKeyMapCallbacks = { + (unsigned(*)(NSMapTable *, const void *))uniquerHash, + (BOOL(*)(NSMapTable *, const void *, const void *))uniquerCompare, + (void (*)(NSMapTable *, const void *))uniquerNoAction, + (void (*)(NSMapTable *, void *))uniquerNoAction, + (NSString *(*)(NSMapTable *, const void *))uniqDescription, + (const void *)NULL +}; + +static NSMapTableValueCallBacks uniquerValueMapCallbacks = { + (void (*)(NSMapTable *, const void *))uniquerRetain, + (void (*)(NSMapTable *, void *))uniquerRelease, + (NSString *(*)(NSMapTable *, const void *))uniqDescription +}; + +static int initialHashSize = 1021; + +@implementation EOObjectUniquer + +static NSMutableArray *uniquerExtent = nil; +static NSRecursiveLock *lock = nil; + ++ (void)initialize { + static BOOL isInitialized = NO; + if (!isInitialized) { + isInitialized = YES; + + uniquerExtent = [[NSMutableArray alloc] initWithCapacity:16]; + // THREAD: lock = [[NSRecursiveLock alloc] init]; + } +} + +static inline void _addUniquerInstance(EOObjectUniquer *_uniquer) { + [lock lock]; + [uniquerExtent addObject:[NSValue valueWithNonretainedObject:_uniquer]]; + [lock unlock]; +} +static inline void _removeUniquerInstance(EOObjectUniquer *_uniquer) { + [lock lock]; + { + int i; + + for (i = [uniquerExtent count] - 1; i >= 0; i--) { + EOObjectUniquer *uniquer; + + uniquer = [[uniquerExtent objectAtIndex:i] nonretainedObjectValue]; + if (uniquer == _uniquer) { + [uniquerExtent removeObjectAtIndex:i]; + break; + } + } + } + [lock unlock]; +} + +// Initializing a uniquing dictionary + +- (id)init { + self->primaryKeyToRec = NSCreateMapTable(uniquerKeyMapCallbacks, + uniquerValueMapCallbacks, + initialHashSize); +#if LIB_FOUNDATION_LIBRARY + self->objectsToRec = NSCreateMapTableInvisibleKeysOrValues + (NSNonOwnedPointerMapKeyCallBacks, + uniquerValueMapCallbacks, initialHashSize, + YES, NO); +#else + self->objectsToRec = NSCreateMapTable + (NSNonOwnedPointerMapKeyCallBacks, + uniquerValueMapCallbacks, initialHashSize); +#endif + self->keyRecord = uniquerCreate(nil, nil, nil, nil); + + _addUniquerInstance(self); + + return self; +} + +- (void)dealloc { + [self forgetAllObjects]; + _removeUniquerInstance(self); + + NSFreeMapTable(self->objectsToRec); + NSFreeMapTable(self->primaryKeyToRec); + if (self->keyRecord) { + Free(self->keyRecord); + self->keyRecord = NULL; + } + [super dealloc]; +} + +// Transfer self to parent + +- (void)transferTo:(EOObjectUniquer *)_dest + objects:(BOOL)isKey andSnapshots:(BOOL)isSnap +{ + EOUniquerRecord *key = NULL; + EOUniquerRecord *rec = NULL; + NSMapEnumerator enumerator = NSEnumerateMapTable(primaryKeyToRec); + + while(NSNextMapEnumeratorPair(&enumerator, (void**)(&key), (void**)(&rec))) { + [_dest recordObject:rec->object + primaryKey: isKey ? rec->pkey : nil + entity: isKey ? rec->entity : nil + snapshot: isSnap ? rec->snapshot : nil]; + } + [self forgetAllObjects]; +} + +// Handling objects + +- (void)forgetObject:(id)_object { + EOUniquerRecord *rec = NULL; + + if (_object == nil) + return; + + rec = (EOUniquerRecord *)NSMapGet(self->objectsToRec, _object); + + if (rec == NULL) + return; + + /* + NSLog(@"Uniquer[0x%08X]: forget object 0x%08X<%s> entity=%@", + self, _object, class_get_class_name(*(Class *)_object), + [[_object entity] name]); + */ + + if (rec->pkey) + NSMapRemove(self->primaryKeyToRec, rec); + NSMapRemove(self->objectsToRec, _object); +} + +- (void)forgetAllObjects { + NSResetMapTable(self->primaryKeyToRec); + NSResetMapTable(self->objectsToRec); +} + +- (void)forgetAllSnapshots { + NSMapEnumerator enumerator; + EOUniquerRecord *rec = NULL; + id key = nil; + + NSLog(@"uniquer 0x%08X forgetAllSnapshots ..", self); + + enumerator = NSEnumerateMapTable(self->objectsToRec); + while (NSNextMapEnumeratorPair(&enumerator, (void**)(&key), (void**)(&rec))) { + RELEASE(rec->snapshot); + rec->snapshot = nil; + } +} + +- (id)objectForPrimaryKey:(NSDictionary *)_key entity:(EOEntity *)_entity { + EOUniquerRecord *rec; + + if (_key == nil || _entity == nil) + return nil; + + if (![_key isKindOfClass:[EOPrimaryKeyDictionary class]]) { + [NSException raise:NSInvalidArgumentException + format: + @"attempt to record object with non " + @" EOPrimaryKeyDictionary class in EOObjectUniquer." + @"This is a bug in EODatabase/Context/Channel."]; + } + + keyRecord->pkey = _key; + keyRecord->entity = _entity; + + rec = (EOUniquerRecord*)NSMapGet(primaryKeyToRec, keyRecord); + + return rec ? rec->object : nil; +} + +- (EOUniquerRecord *)recordForObject:(id)_object { + return (_object == nil) + ? (EOUniquerRecord *)NULL + : (EOUniquerRecord *)NSMapGet(self->objectsToRec, _object); +} + +- (void)recordObject:(id)_object + primaryKey:(NSDictionary *)_key + entity:(EOEntity *)_entity + snapshot:(NSDictionary *)_snapshot +{ + EOUniquerRecord *rec = NULL; + EOUniquerRecord *orc = NULL; + + if (_object == nil) + return; + + if ((_key == nil) || (_entity == nil)) { + _key = nil; + _entity = nil; + } + + if ((_key == nil) && (_snapshot == nil)) + return; + + if (_key && ![_key isKindOfClass:[EOPrimaryKeyDictionary class]]) { + [NSException raise:NSInvalidArgumentException + format: + @"attempt to record object with non " + @" EOPrimaryKeyDictionary class in EOObjectUniquer." + @"This is a bug in EODatabase/Context/Channel."]; + } + + keyRecord->pkey = _key; + keyRecord->entity = _entity; + + rec = (EOUniquerRecord*)NSMapGet(objectsToRec, _object); + if (rec) { + if (_key && uniquerCompare(NULL, rec, keyRecord)) { + ASSIGN(rec->snapshot, _snapshot); + return; + } + if (_key) { + orc = (EOUniquerRecord*)NSMapGet(primaryKeyToRec, keyRecord); + if (orc && orc != rec) { + if (orc->pkey) + NSMapRemove(primaryKeyToRec, orc); + + NSMapRemove(objectsToRec, orc->object); + } + NSMapRemove(primaryKeyToRec, rec); + } + ASSIGN(rec->pkey, _key); + ASSIGN(rec->entity, _entity); + ASSIGN(rec->snapshot, _snapshot); + + if (_key) + NSMapInsertKnownAbsent(primaryKeyToRec, rec, rec); + return; + } + + if (_key) + rec = (EOUniquerRecord*)NSMapGet(primaryKeyToRec, keyRecord); + if (rec) { + if (rec->object == _object) { + ASSIGN(rec->snapshot, _snapshot); + return; + } + + NSMapRemove(objectsToRec, rec->object); + + ASSIGN(rec->snapshot, _snapshot); + rec->object = _object; + NSMapInsertKnownAbsent(objectsToRec, _object, rec); + return; + } + + rec = uniquerCreate(_key, _entity, _object, _snapshot); + if (_key) + NSMapInsertKnownAbsent(primaryKeyToRec, rec, rec); + NSMapInsertKnownAbsent(objectsToRec, _object, rec); +} + + +/* This method is called by the Boehm's garbage collector when an object + is finalized */ +- (void)_objectWillFinalize:(id)_object { + // printf ("_objectWillFinalize: %p (%s)\n", + // _object, class_get_class_name ([_object class])); + [self forgetObject:_object]; +} + ++ (void)forgetObject:(id)_object { + [lock lock]; + { + int i; + + for (i = [uniquerExtent count] - 1; i >= 0; i--) { + EOObjectUniquer *uniquer; + + uniquer = [[uniquerExtent objectAtIndex:i] nonretainedObjectValue]; + [uniquer forgetObject:_object]; + } + } + [lock unlock]; +} + +@end /* EOObjectUniquer */ diff --git a/sope-gdl1/GDLAccess/EOOrQualifier+SQL.m b/sope-gdl1/GDLAccess/EOOrQualifier+SQL.m new file mode 100644 index 00000000..a2ced429 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOOrQualifier+SQL.m @@ -0,0 +1,69 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOOrQualifier+SQL.m 1 2004-08-20 10:38:46Z znek $ + +#import "EOSQLQualifier.h" +#include "common.h" + +@implementation EOOrQualifier(SQLQualifier) + +/* SQL qualifier generation */ + +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity { + unsigned cc = [self->qualifiers count]; + + if (cc == 0) + return nil; + else if (cc == 1) + return [[self->qualifiers objectAtIndex:0] sqlQualifierForEntity:_entity]; + else if (cc == 2) { + id left; + id right; + + left = [[self->qualifiers objectAtIndex:0] sqlQualifierForEntity:_entity]; + right = [[self->qualifiers objectAtIndex:1] sqlQualifierForEntity:_entity]; + [left disjoinWithQualifier:right]; + return left; + } + else { + EOSQLQualifier *masterQ; + unsigned i; + + for (i = 0, masterQ = nil; i < cc; i++) { + EOSQLQualifier *q; + + q = [[self->qualifiers objectAtIndex:i] + sqlQualifierForEntity:_entity]; + if (masterQ == nil) + masterQ = q; + else + [masterQ disjoinWithQualifier:q]; + } + return masterQ; + } +} + +@end /* EOOrQualifier */ diff --git a/sope-gdl1/GDLAccess/EOPrimaryKeyDictionary.m b/sope-gdl1/GDLAccess/EOPrimaryKeyDictionary.m new file mode 100644 index 00000000..6d4fb36d --- /dev/null +++ b/sope-gdl1/GDLAccess/EOPrimaryKeyDictionary.m @@ -0,0 +1,403 @@ +/* + EOPrimaryKeyDictionary.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Mircea Oancea + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOPrimaryKeyDictionary.h" +#import + +/* + * Concrete Classes declaration + */ + +@interface EOSinglePrimaryKeyDictionary : EOPrimaryKeyDictionary +{ + id key; + id value; +} +- (id)initWithObject:(id)anObject forKey:(id)aKey; +- (id)key; +@end + +@interface EOSinglePrimaryKeyDictionaryEnumerator : NSEnumerator +{ + id key; +} + +- (id)iniWithObject:(id)_key; + +@end + +@interface EOMultiplePrimaryKeyDictionary : EOPrimaryKeyDictionary +{ + int count; + NSArray *keys; + id values[0]; +} + ++ (id)allocWithZone:(NSZone *)_zone capacity:(int)_capacity; +- (id)initWithKeys:(NSArray *)_keys fromDictionary:(NSDictionary *)_dict; + +@end + +/* + * Single key dictionary + */ + +@implementation EOSinglePrimaryKeyDictionary + +- (id)initWithObject:(id)_object forKey:(id)_key { + NSAssert(_key, @"provided invalid key (is nil)"); + NSAssert1(_object, @"provided invalid value (is nil), key=%@", _key); + + if ([_object isKindOfClass:[EONull class]]) { + NSLog(@"value of primary key %@ is null ..", _key); + RELEASE(self); + return nil; + } + + NSAssert(![_object isKindOfClass:[EONull class]], + @"value of primary key may not be null !"); + + self->key = RETAIN(_key); + self->value = RETAIN(_object); + self->fastHash = [_object hash]; + return self; +} + +- (void)dealloc { + RELEASE(self->key); + RELEASE(self->value); + [super dealloc]; +} + +/* operations */ + +- (NSEnumerator *)keyEnumerator { + return AUTORELEASE([[EOSinglePrimaryKeyDictionaryEnumerator alloc] + iniWithObject:self->key]); +} + +- (id)objectForKey:(id)_key { + return [key isEqual:_key] ? value : nil; +} + +- (unsigned int)count { + return 1; +} + +- (unsigned int)hash { + return 1; +} + +- (id)key { + return self->key; +} + +- (NSArray *)allKeys { + return [NSArray arrayWithObject:key]; +} + +- (NSArray *)allValues { + return [NSArray arrayWithObject:value]; +} + +- (BOOL)isEqualToDictionary:(NSDictionary *)other { + if (self == (EOSinglePrimaryKeyDictionary*)other) + return YES; + if (self->isa == ((EOSinglePrimaryKeyDictionary*)other)->isa) { + if (fastHash == ((EOSinglePrimaryKeyDictionary*)other)->fastHash && + [key isEqual:((EOSinglePrimaryKeyDictionary*)other)->key] && + [value isEqual:((EOSinglePrimaryKeyDictionary*)other)->value]) + return YES; + else + return NO; + } + if ([other count] != 1) + return NO; + return [value isEqual:[other objectForKey:key]]; +} + +- (id)copyWithZone:(NSZone*)zone { + if ([self zone] == (zone ? zone : NSDefaultMallocZone())) + return RETAIN(self); + else + return [[[self class] allocWithZone:zone] + initWithObject:value forKey:key]; +} +- (id)copy { + return [self copyWithZone:NULL]; +} + +- (BOOL)fastIsEqual:(id)other { + if (self == other) + return YES; + if (self->isa == ((EOSinglePrimaryKeyDictionary*)other)->isa) { + if (fastHash == ((EOSinglePrimaryKeyDictionary*)other)->fastHash && + key == ((EOSinglePrimaryKeyDictionary*)other)->key && + [value isEqual:((EOSinglePrimaryKeyDictionary*)other)->value]) + return YES; + else + return NO; + } + [NSException raise:NSInvalidArgumentException + format: + @"fastIsEqual: compares only " + @"EOPrimaryKeyDictionary instances !"]; + return NO; +} + +@end /* EOSinglePrimaryKeyDictionary */ + +@implementation EOSinglePrimaryKeyDictionaryEnumerator + +- (id)iniWithObject:(id)aKey { + self->key = RETAIN(aKey); + return self; +} + +- (void)dealloc { + RELEASE(self->key); + [super dealloc]; +} + +/* operations */ + +- (id)nextObject { + id tmp = self->key; + self->key = nil; + return AUTORELEASE(tmp); +} + +@end /* EOSinglePrimaryKeyDictionaryEnumerator */ + +/* + * Multiple key dictionary is very time-memory efficient + */ + +@implementation EOMultiplePrimaryKeyDictionary + ++ (id)allocWithZone:(NSZone *)zone capacity:(int)capacity { + return NSAllocateObject(self, sizeof(id)*capacity, zone); +} + +- (id)initWithKeys:(NSArray*)theKeys fromDictionary:(NSDictionary*)dict; { + int i; + + self->count = [theKeys count]; + self->keys = RETAIN(theKeys); + self->fastHash = 0; + + for (i = 0; i < count; i++) { + self->values[i] = [dict objectForKey:[keys objectAtIndex:i]]; + RETAIN(self->values[i]); + + NSAssert(![values[i] isKindOfClass:[EONull class]], + @"primary key values may not be null !"); + + if (self->values[i] == nil) { + AUTORELEASE(self); + return nil; + } + self->fastHash += [self->values[i] hash]; + } + + return self; +} + +- (void)dealloc { + int i; + + for (i = 0; i < count; i++) + RELEASE(self->values[i]); + RELEASE(self->keys); + [super dealloc]; +} + +/* operations */ + +- (NSEnumerator *)keyEnumerator { + return [self->keys objectEnumerator]; +} + +- (id)objectForKey:(id)aKey { + int max, min, mid; + // Binary search for key's index + for (min = 0, max = count-1; min <= max; ) { + NSComparisonResult ord; + + mid = (min+max) >> 1; + ord = [(NSString*)aKey compare:(NSString*)[keys objectAtIndex:mid]]; + if (ord == NSOrderedSame) + return values[mid]; + if (ord == NSOrderedDescending) + min = mid+1; + else + max = mid-1; + } + return nil; +} + +- (unsigned int)count { + return self->count; +} + +- (unsigned int)hash { + return self->count; +} + +- (NSArray *)allKeys { + return self->keys; +} + +- (NSArray *)allValues { + return AUTORELEASE([[NSArray alloc] initWithObjects:values count:count]); +} + +- (BOOL)isEqualToDictionary:(NSDictionary *)other { + int i; + + if (self == (EOMultiplePrimaryKeyDictionary*)other) + return YES; + if ((unsigned)self->count != [other count]) + return NO; + for (i = 0; i < self->count; i++) { + if (![values[i] isEqual:[other objectForKey:[keys objectAtIndex:i]]]) + return NO; + } + return YES; +} + +- (id)copyWithZone:(NSZone *)zone { + if ([self zone] == (zone ? zone : NSDefaultMallocZone())) + return RETAIN(self); + else { + return [[[self class] + allocWithZone:zone capacity:count] + initWithKeys:keys fromDictionary:self]; + } +} +- (id)copy { + return [self copyWithZone:NULL]; +} + +- (unsigned)fastHash { + return self->fastHash; +} + +- (BOOL)fastIsEqual:(id)aDict { + int i; + + if (self->isa != ((EOMultiplePrimaryKeyDictionary*)aDict)->isa) { + [NSException raise:NSInvalidArgumentException + format:@"fastIsEqual: can compare only " + @"EOPrimaryKeyDictionary instances"]; + } + if (self->count != ((EOMultiplePrimaryKeyDictionary*)aDict)->count || + self->fastHash != ((EOMultiplePrimaryKeyDictionary*)aDict)->fastHash || + self->keys != ((EOMultiplePrimaryKeyDictionary*)aDict)->keys) + return NO; + + for (i = count - 1; i >= 0; i--) { + if (![values[i] isEqual: + ((EOMultiplePrimaryKeyDictionary*)aDict)->values[i]]) + return NO; + } + return YES; +} + +@end /* EOMultiplePrimaryKeyDictionary */ + +/* + * Cluster Abstract class + */ + +@implementation EOPrimaryKeyDictionary + ++ (id)allocWithZone:(NSZone *)_zone { + return NSAllocateObject(self, 0, _zone); +} + ++ (id)dictionaryWithKeys:(NSArray *)keys fromDictionary:(NSDictionary *)dict { + if ([dict count] == 0) + return nil; + + if ([keys count] == 1) { + id key = [keys objectAtIndex:0]; + id keyValue = [dict objectForKey:key]; + + NSAssert2(keyValue, @"dictionary %@ contained no value for key %@ ..", + dict, key); + + // Check if already an EOSinglePrimaryKeyDictionary from same entity + // return it since the new one will be identical to it; we have + // no problem regarding its correctness since it was built by this + // method ! + if ([dict isKindOfClass:[EOSinglePrimaryKeyDictionary class]]) { + if ([(EOSinglePrimaryKeyDictionary*)dict key]==key) + return dict; + } + + //HH: + // Check if the keyValue is EONull. If this is the case, return nil. + // Primary keys are always 'not null'. + if ([keyValue isKindOfClass:[EONull class]]) + return nil; + + // Alloc single key dictionary + return AUTORELEASE([[EOSinglePrimaryKeyDictionary alloc] + initWithObject:keyValue + forKey:key]); + } + else { + // Check if already an EOMultiplePrimaryKeyDictionary from same entity + // return it since the new one will be identical to it; we have + // no problem regarding its correctness since it was built by this + // method ! + if ([dict isKindOfClass:[EOMultiplePrimaryKeyDictionary class]] && + [dict allKeys] == keys) + return dict; + // Alloc multi-key dictionary + return AUTORELEASE([[EOMultiplePrimaryKeyDictionary + allocWithZone:NULL capacity:[keys count]] + initWithKeys:keys fromDictionary:dict]); + } +} + ++ (id)dictionaryWithObject:(id)object forKey:(id)key { + return AUTORELEASE([[EOSinglePrimaryKeyDictionary alloc] + initWithObject:object forKey:key]); +} + +- (unsigned)fastHash { + return self->fastHash; +} + +- (BOOL)fastIsEqual:aDict { + // TODO - request concrete implementation + return NO; +} + +@end /* EOPrimaryKeyDictionary */ diff --git a/sope-gdl1/GDLAccess/EOQualifier+SQL.m b/sope-gdl1/GDLAccess/EOQualifier+SQL.m new file mode 100644 index 00000000..30c0f4e8 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOQualifier+SQL.m @@ -0,0 +1,141 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOQualifier+SQL.m 1 2004-08-20 10:38:46Z znek $ + +#include "EOSQLExpression.h" +#include "EOSQLQualifier.h" +#include +#include "common.h" + +@implementation EOAndQualifier(SQLGeneration) + +- (NSString *)sqlStringForSQLExpression:(EOSQLExpression *)_sqlExpr { + return [_sqlExpr sqlStringForConjoinedQualifiers:[self qualifiers]]; +} + +- (EOQualifier *)schemaBasedQualifierWithRootEntity:(EOEntity *)_entity { + NSArray *array; + id objects[self->count + 1]; + unsigned i; + + IMP objAtIdx; + + objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)]; + + for (i = 0; i < self->count; i++) { + id q, newq; + + q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i); + newq = [q schemaBasedQualifierWithRootEntity:_entity]; + if (newq == nil) newq = q; + + objects[i] = newq; + } + + array = [NSArray arrayWithObjects:objects count:self->count]; + return [[[[self class] alloc] initWithQualifierArray:array] autorelease]; +} + +@end /* EOAndQualifier(SQLGeneration) */ + +@implementation EOOrQualifier(SQLGeneration) + +- (NSString *)sqlStringForSQLExpression:(EOSQLExpression *)_sqlExpr { + return [_sqlExpr sqlStringForDisjoinedQualifiers:[self qualifiers]]; +} + +- (EOQualifier *)schemaBasedQualifierWithRootEntity:(EOEntity *)_entity { + NSArray *array; + id objects[self->count + 1]; + unsigned i; + + IMP objAtIdx; + + objAtIdx = [self->qualifiers methodForSelector:@selector(objectAtIndex:)]; + + for (i = 0; i < self->count; i++) { + id q, newq; + + q = objAtIdx(self->qualifiers, @selector(objectAtIndex:), i); + newq = [q schemaBasedQualifierWithRootEntity:_entity]; + if (newq == nil) newq = q; + + objects[i] = newq; + } + + array = [NSArray arrayWithObjects:objects count:self->count]; + return [[[[self class] alloc] initWithQualifierArray:array] autorelease]; +} + +@end /* EOOrQualifier(SQLGeneration) */ + +@implementation EONotQualifier(SQLGeneration) + +- (NSString *)sqlStringForSQLExpression:(EOSQLExpression *)_sqlExpr { + return [_sqlExpr sqlStringForNegatedQualifier:[self qualifier]]; +} + +- (EOQualifier *)schemaBasedQualifierWithRootEntity:(EOEntity *)_entity { + EOQualifier *sq; + + sq = [(id)self->qualifier + schemaBasedQualifierWithRootEntity:_entity]; + if (sq == self->qualifier) + return self; + + sq = [[EONotQualifier alloc] initWithQualifier:sq]; + return [sq autorelease]; +} + +@end /* EONotQualifier(SQLGeneration) */ + +@implementation EOKeyValueQualifier(SQLGeneration) + +- (NSString *)sqlStringForSQLExpression:(EOSQLExpression *)_sqlExpr { + return [_sqlExpr sqlStringForKeyValueQualifier:self]; +} + +- (EOQualifier *)schemaBasedQualifierWithRootEntity:(EOEntity *)_entity { + NSLog(@"ERROR(%s): subclasses need to override this method!", + __PRETTY_FUNCTION__); + return nil; +} + +@end /* EOKeyValueQualifier(SQLGeneration) */ + +@implementation EOKeyComparisonQualifier(SQLGeneration) + +- (NSString *)sqlStringForSQLExpression:(EOSQLExpression *)_sqlExpr { + return [_sqlExpr sqlStringForKeyComparisonQualifier:self]; +} + +- (EOQualifier *)schemaBasedQualifierWithRootEntity:(EOEntity *)_entity { + NSLog(@"ERROR(%s): subclasses need to override this method!", + __PRETTY_FUNCTION__); + return nil; +} + +@end /* EOKeyComparisonQualifier(SQLGeneration) */ diff --git a/sope-gdl1/GDLAccess/EOQualifierScanner.m b/sope-gdl1/GDLAccess/EOQualifierScanner.m new file mode 100644 index 00000000..0286f316 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOQualifierScanner.m @@ -0,0 +1,194 @@ +/* + EOQualifierScanner.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Helge Hess + Date: September 1996 + November 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOQualifierScanner.m 1 2004-08-20 10:38:46Z znek $ + +#import "common.h" +#include "EOQualifierScanner.h" +#include "EOFExceptions.h" +#include "EOEntity.h" +#include "EOSQLQualifier.h" +#include + +#if LIB_FOUNDATION_LIBRARY +# import +# import +#else +# import "DefaultScannerHandler.h" +# import "PrintfFormatScanner.h" +#endif + +@implementation EOQualifierScannerHandler + +- (id)init { + [super init]; + + specHandler['d'] = [self methodForSelector:@selector(convertInt:scanner:)]; + specHandler['f'] + = [self methodForSelector:@selector(convertFloat:scanner:)]; + specHandler['s'] + = [self methodForSelector:@selector(convertCString:scanner:)]; + specHandler['A'] + = [self methodForSelector:@selector(convertProperty:scanner:)]; + specHandler['@'] + = [self methodForSelector:@selector(convertObject:scanner:)]; + return self; +} + +- (void)setEntity:(EOEntity *)_entity +{ + ASSIGN(self->entity, _entity); +} + +- (void)dealloc { + RELEASE(self->entity); + [super dealloc]; +} + +/* conversions */ + +- (NSString *)convertInt:(va_list *)pInt scanner:(FormatScanner*)scanner { + char buffer[256]; + sprintf(buffer, [scanner currentSpecifier], va_arg(*pInt, int)); + return [NSString stringWithCString:buffer]; +} + +- (NSString*)convertFloat:(va_list *)pFloat scanner:(FormatScanner*)scanner { + char buffer[256]; + sprintf(buffer, [scanner currentSpecifier], va_arg(*pFloat, double)); + return [NSString stringWithCString:buffer]; +} + +- (NSString*)convertCString:(va_list *)pString scanner:(FormatScanner*)scanner { + char *string; + string = va_arg(*pString, char*); + return string ? [NSString stringWithCString:string] : @""; +} + +- (NSString*)convertProperty:(va_list*)pString scanner:(FormatScanner*)scanner { + NSString *propertyName; + id property; + + propertyName = va_arg(*pString, id); + property = [entity propertyNamed:propertyName]; + + if(property == nil) { + [[[InvalidPropertyException alloc] + initWithName:propertyName entity:entity] raise]; + } + return propertyName; +} + +- (NSString *)convertObject:(va_list *)pId scanner:scanner { + id object = va_arg(*pId, id); + if (object == nil) object = [NSNull null]; + return [object expressionValueForContext:nil]; +} + +@end /* EOQualifierScannerHandler */ + +@implementation EOQualifierEnumScannerHandler + +- (id)init { + [super init]; + + specHandler['d'] = [self methodForSelector:@selector(convertInt:scanner:)]; + specHandler['f'] + = [self methodForSelector:@selector(convertFloat:scanner:)]; + specHandler['s'] + = [self methodForSelector:@selector(convertCString:scanner:)]; + specHandler['A'] + = [self methodForSelector:@selector(convertProperty:scanner:)]; + specHandler['@'] + = [self methodForSelector:@selector(convertObject:scanner:)]; + return self; +} + +- (void)setEntity:(EOEntity *)_entity { + ASSIGN(self->entity, _entity); +} + +- (void)dealloc { + RELEASE(self->entity); + [super dealloc]; +} + +- (NSString *)convertInt:(NSEnumerator **)pInt scanner:(FormatScanner*)scanner { + char buffer[256]; + sprintf(buffer, [scanner currentSpecifier], [[*pInt nextObject] intValue]); + return [NSString stringWithCString:buffer]; +} + +- (NSString *)convertFloat:(NSEnumerator **)pFloat + scanner:(FormatScanner *)scanner +{ + char buffer[256]; + sprintf(buffer, [scanner currentSpecifier], + [[*pFloat nextObject] doubleValue]); + return [NSString stringWithCString:buffer]; +} + +- (NSString *)convertCString:(NSEnumerator **)pString + scanner:(FormatScanner *)scanner +{ + id str; + + if ((str = [*pString nextObject]) == nil) + str = @""; + else if ([str isKindOfClass:[NSString class]]) + ; + else if ([str respondsToSelector:@selector(stringValue)]) + str = [str stringValue]; + else + str = [str description]; + + return (str == nil) ? @"" : str; +} + +- (NSString *)convertProperty:(NSEnumerator **)pString + scanner:(FormatScanner *)scanner +{ + NSString *propertyName; + id property; + + propertyName = [*pString nextObject]; + property = [entity propertyNamed:propertyName]; + + if(property == nil) { + [[[InvalidPropertyException alloc] + initWithName:propertyName entity:entity] raise]; + } + return propertyName; +} + +- (NSString *)convertObject:(NSEnumerator **)pId scanner:(id)scanner { + id object; + object = [*pId nextObject]; + return [object expressionValueForContext:nil]; +} + +@end /* EOQualifierEnumScannerHandler */ diff --git a/sope-gdl1/GDLAccess/EOQuotedExpression.m b/sope-gdl1/GDLAccess/EOQuotedExpression.m new file mode 100644 index 00000000..7a001282 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOQuotedExpression.m @@ -0,0 +1,81 @@ +/* + EOQuotedExpression.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import +#import +#import "common.h" +#import "EOQuotedExpression.h" + +@implementation EOQuotedExpression + +- (id)expressionValueForContext:(id)_context { + NSMutableString *result; + NSArray *components; + id expr; + + expr = [self->expression expressionValueForContext:_context]; + components = [expr componentsSeparatedByString:quote]; + result = [[NSMutableString alloc] initWithCapacity:[expr length] + 10]; + + [result appendString:quote]; + [result appendString:[components componentsJoinedByString:escape]]; + [result appendString:quote]; + + return AUTORELEASE(result); +} + +- (id)initWithExpression:(id)_expression + quote:(NSString *)_quote + escape:(NSString *)_escape +{ + if ((self = [super init])) { + ASSIGN(self->expression, _expression); + ASSIGN(self->quote, _quote); + ASSIGN(self->escape, _escape); + } + + return self; +} + +- (void)dealloc { + RELEASE(self->expression); + RELEASE(self->quote); + RELEASE(self->escape); + [super dealloc]; +} + +// NSCopying + +- (id)copyWithZone:(NSZone*)zone { + return [[[self class] + allocWithZone:zone] + initWithExpression:expression quote:quote escape:escape]; +} +- (id)copy { + return [self copyWithZone:NSDefaultMallocZone()]; +} + +@end /* EOQuotedExpression */ diff --git a/sope-gdl1/GDLAccess/EORecordDictionary.m b/sope-gdl1/GDLAccess/EORecordDictionary.m new file mode 100644 index 00000000..b839b118 --- /dev/null +++ b/sope-gdl1/GDLAccess/EORecordDictionary.m @@ -0,0 +1,231 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EORecordDictionary.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include + +#import +#import +#import +#import +#import + +#if LIB_FOUNDATION_LIBRARY +# include +# include +#else +# include +#endif + +#include "EORecordDictionary.h" + +@implementation EORecordDictionary + +static NSDictionary *emptyDict = nil; + +- (id)init { + RELEASE(self); + if (emptyDict == nil) emptyDict = [[NSDictionary alloc] init]; + return [emptyDict retain]; +} + +- (id)initWithObjects:(id *)_objects forKeys:(id *)_keys + count:(unsigned int)_count +{ + if (_count == 0) { + RELEASE(self); + if (emptyDict == nil) emptyDict = [[NSDictionary alloc] init]; + return [emptyDict retain]; + } + + if (_count == 1) { + RELEASE(self); + return [[NSDictionary alloc] + initWithObjects:_objects forKeys:_keys + count:_count]; + } + + self->count = _count; + while(_count--) { + if ((_keys[_count] == nil) || (_objects[_count] == nil)) { + [NSException raise:NSInvalidArgumentException + format:@"Nil object to be added in dictionary"]; + } + self->entries[_count].key = RETAIN(_keys[_count]); + self->entries[_count].hash = [_keys[_count] hash]; + self->entries[_count].value = RETAIN(_objects[_count]); + } + return self; +} + +- (id)initWithDictionary:(NSDictionary *)dictionary { + // TODO: who calls this method? + NSEnumerator *keys; + unsigned char i; + + keys = [dictionary keyEnumerator]; + self->count = [dictionary count]; + + for (i = 0; i < self->count; i++) { + id key = [keys nextObject]; + + self->entries[i].key = RETAIN(key); + self->entries[i].hash = [key hash]; + self->entries[i].value = RETAIN([dictionary objectForKey:key]); + } + return self; +} + +- (void)dealloc { + /* keys are always NSString keys?! */ +#if GNU_RUNTIME + static Class LastKeyClass = Nil; + static IMP keyRelease = 0; + static unsigned misses = 0, hits = 0; +#endif + register unsigned char i; + + for (i = 0; i < self->count; i++) { + register NSString *key = self->entries[i].key; +#if GNU_RUNTIME + if (*(id *)key != LastKeyClass) { + LastKeyClass = *(id *)key; + keyRelease = + method_get_imp(class_get_instance_method(LastKeyClass, + @selector(release))); + misses++; + } + else + hits++; + + keyRelease(key, NULL /* dangerous? */); + +#if PROF_METHOD_CACHE + if (hits % 1000 == 0 && hits != 0) + NSLog(@"%s: DB HITS: %d MISSES: %d", __PRETTY_FUNCTION__,hits, misses); +#endif +#else + [key release]; +#endif + + RELEASE(self->entries[i].value); + } + [super dealloc]; +} + +/* operations */ + +- (id)objectForKey:(id)aKey { + register EORecordDictionaryEntry *e = self->entries; + register signed char i; + register unsigned hash; +#if GNU_RUNTIME + static Class LastKeyClass = Nil; + static unsigned (*keyHash)(id,SEL) = 0; + static BOOL (*keyEq)(id,SEL,id) = 0; +#if PROF_METHOD_CACHE + static unsigned misses = 0, hits = 0; +#endif +#endif + +#if GNU_RUNTIME + if (aKey == nil) + return nil; + + if (*(id *)aKey != LastKeyClass) { + LastKeyClass = *(id *)aKey; + keyHash = (void *) + method_get_imp(class_get_instance_method(LastKeyClass, + @selector(hash))); + keyEq = (void *) + method_get_imp(class_get_instance_method(LastKeyClass, + @selector(isEqual:))); + } + + hash = keyHash(aKey, NULL /* dangerous? */); +#else + hash = [aKey hash]; +#endif + + for (i = (self->count - 1); i >= 0; i--, e++) { + if (e->hash != hash) + continue; + if (e->key == aKey) + return e->value; + +#if GNU_RUNTIME + if (keyEq(e->key, NULL /* dangerous? */, aKey)) + return e->value; +#else + if ([e->key isEqual:aKey]) + return e->value; +#endif + } + return nil; +} + +- (unsigned int)count { + return self->count; +} +- (NSEnumerator *)keyEnumerator { + return AUTORELEASE([[_EORecordDictionaryKeyEnumerator alloc] + initWithDictionary:self + firstEntry:self->entries count:self->count]); +} + +@end /* NSConcreteSmallDictionary */ + +@implementation _EORecordDictionaryKeyEnumerator + +- (id)initWithDictionary:(EORecordDictionary *)_dict + firstEntry:(EORecordDictionaryEntry *)_firstEntry + count:(unsigned char)_count +{ + self->dict = RETAIN(_dict); + self->currentEntry = _firstEntry; + self->count = _count; + return self; +} + +- (void)dealloc { + RELEASE(self->dict); + [super dealloc]; +} + +- (id)nextObject { + if (self->count > 0) { + id obj; + obj = self->currentEntry->key; + self->currentEntry++; + self->count--; + return obj; + } + + return nil; +} + +@end /* _NSConcreteSmallDictionaryKeyEnumerator */ diff --git a/sope-gdl1/GDLAccess/EORelationship.m b/sope-gdl1/GDLAccess/EORelationship.m new file mode 100644 index 00000000..8918554f --- /dev/null +++ b/sope-gdl1/GDLAccess/EORelationship.m @@ -0,0 +1,567 @@ +/* + EORelationship.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#import "common.h" +#import "EOModel.h" +#import "EOAttribute.h" +#import "EOEntity.h" +#import "EORelationship.h" +#import "EOExpressionArray.h" +#import "EOFExceptions.h" +#import + +static EONull *null = nil; + +@interface EOJoin : EORelationship // for adaptor compability +@end + +@implementation EORelationship + ++ (void)initialize { + if (null == nil) null = [[EONull null] retain]; +} + +- (id)init { + if ((self = [super init])) { + self->flags.createsMutableObjects = YES; + self->entity = nil; + self->destinationEntity = nil; + } + return self; +} + +- (id)initWithName:(NSString*)_name { + if ((self = [self init])) { + self->name = _name; + } + return self; +} + +- (void)dealloc { + RELEASE(self->name); + RELEASE(self->definition); + RELEASE(self->userDictionary); + self->entity = nil; + if ([self->destinationEntity isKindOfClass:[NSString class]]) + RELEASE(self->destinationEntity); + // else: non-retained EOEntity + self->destinationEntity = nil; + RELEASE(self->componentRelationships); + RELEASE(self->sourceAttribute); + RELEASE(self->destinationAttribute); + [super dealloc]; +} + +// These methods should be here to let the library work with NeXT foundation +- (id)copy { + return RETAIN(self); +} +- (id)copyWithZone:(NSZone *)_zone { + return RETAIN(self); +} + +// Is equal only if same name; used to make aliasing ordering stable +- (unsigned)hash { + return [self->name hash]; +} + ++ (BOOL)isValidName:(NSString*)_name { + return [EOEntity isValidName:_name]; +} + +- (void)setDefinition:(NSString *)def { + if (def == nil) { + [NSException raise:NSInvalidArgumentException + format:@"invalid (nil) definition argument ..."]; + } + + if ([def isNameOfARelationshipPath]) { + NSArray *defArray = nil; + int count; + + defArray = [def componentsSeparatedByString:@"."]; + count = [defArray count]; + + RELEASE(self->componentRelationships); + self->componentRelationships = + [[NSMutableArray alloc] initWithCapacity:count]; + + flags.isFlattened = YES; + + NS_DURING { + EOEntity *currentEntity = self->entity; + id relationship = nil; + int i; + + for (i = 0; i < count; i++) { + id relationshipName = [defArray objectAtIndex:i]; + + /* Take the address of `relationship' to force the compiler + to not allocate it into a register. */ + *(&relationship) = [currentEntity relationshipNamed: + relationshipName]; + if (!relationship) + [[[InvalidPropertyException alloc] + initWithName:relationshipName + entity:currentEntity] raise]; + [self->componentRelationships addObject:relationship]; + flags.isToMany |= [relationship isToMany]; + currentEntity = [relationship destinationEntity]; + } + if (self->destinationEntity && + ![self->destinationEntity isEqual:currentEntity]) + [[[DestinationEntityDoesntMatchDefinitionException alloc] + initForDestination:self->destinationEntity + andDefinition:def + relationship:self] raise]; + if ([self->destinationEntity isKindOfClass:[NSString class]]) + RELEASE(self->destinationEntity); + self->destinationEntity = currentEntity; /* non-retained */ + if ([self->destinationEntity isKindOfClass:[NSString class]]) + RETAIN(self->destinationEntity); + } + NS_HANDLER { + RELEASE(self->componentRelationships); + self->componentRelationships = nil; + [localException raise]; + } + NS_ENDHANDLER; + } + else + [[[InvalidNameException alloc] initWithName:def] raise]; + + ASSIGN(self->definition, def); +} + +- (BOOL)setToMany:(BOOL)_flag { + if ([self isFlattened]) return NO; + self->flags.isToMany = _flag; + return YES; +} +- (BOOL)isToMany { + return self->flags.isToMany; +} + +- (BOOL)setName:(NSString *)_name { + if ([self->entity referencesProperty:_name]) + return NO; + ASSIGN(self->name, _name); + return NO; +} +- (NSString *)name { + return self->name; +} + +- (BOOL)isCompound { + return NO; +} + +- (NSString *)expressionValueForContext:(id)_ctx { + return self->name; +} + +- (void)setEntity:(EOEntity *)_entity { + self->entity = _entity; /* non-retained */ +} +- (EOEntity *)entity { + return self->entity; +} +- (void)resetEntities { + self->entity = nil; + self->destinationEntity = nil; +} +- (BOOL)hasEntity { + return (self->entity != nil) ? YES : NO; +} +- (BOOL)hasDestinationEntity { + return (self->destinationEntity != nil) ? YES : NO; +} + +- (void)setUserDictionary:(NSDictionary *)dict { + ASSIGN(self->userDictionary, dict); +} +- (NSDictionary *)userDictionary { + return self->userDictionary; +} + +- (NSArray *)joins { + return self->sourceAttribute ? [NSArray arrayWithObject:self] : nil; +} + +- (NSString *)definition { + return self->definition; +} +- (NSArray *)sourceAttributes { + return [NSArray arrayWithObject:self->sourceAttribute]; +} +- (NSArray *)destinationAttributes { + return [NSArray arrayWithObject:self->destinationAttribute]; +} +- (EOEntity *)destinationEntity { + return self->destinationEntity; +} +- (BOOL)isFlattened { + return self->flags.isFlattened; +} +- (NSArray *)componentRelationships { + return self->componentRelationships; +} + +- (BOOL)referencesProperty:(id)_property { + if ([self->sourceAttribute isEqual:_property]) + return YES; + if ([self->destinationAttribute isEqual:_property]) + return YES; + + if ([self->componentRelationships indexOfObject:_property] != NSNotFound) + return YES; + return NO; +} + +- (NSDictionary *)foreignKeyForRow:(NSDictionary *)_row { + int j, i, n = [_row count]; + id keys[n], vals[n]; + + for (i = j = 0, n = 1; j < n; j++) { + EOAttribute *keyAttribute = self->sourceAttribute; + EOAttribute *fkeyAttribute = self->destinationAttribute; + NSString *key = nil; + NSString *fkey = nil; + id value = nil; + + key = [keyAttribute name]; + fkey = [fkeyAttribute name]; + value = [_row objectForKey:key]; + + if (value) { + vals[i] = value; + keys[i] = fkey; + i++; + } + else { + NSLog(@"%s: could not get value of key %@ (foreignKey=%@)", + __PRETTY_FUNCTION__, key, fkey); + } + } + + return AUTORELEASE([[NSDictionary alloc] + initWithObjects:vals + forKeys:keys count:i]); +} + +- (NSString *)description { + return [[self propertyList] description]; +} + +@end /* EORelationship */ + + +@implementation EORelationship (EORelationshipPrivate) + ++ (EORelationship *)relationshipFromPropertyList:(id)_plist + model:(EOModel *)model +{ + EORelationship *relationship = nil; + NSArray *array = nil; + NSEnumerator *enumerator = nil; + id joinPList = nil; + + relationship = AUTORELEASE([EORelationship new]); + [relationship setCreateMutableObjects:YES]; + [relationship setName:[_plist objectForKey:@"name"]]; + [relationship setUserDictionary: + [_plist objectForKey:@"userDictionary"]]; + + if ((array = [_plist objectForKey:@"joins"])) { + enumerator = [array objectEnumerator]; + + joinPList = [enumerator nextObject]; + [relationship loadJoinPropertyList:joinPList]; + joinPList = [enumerator nextObject]; + NSAssert(joinPList == nil, @"a relationship only supports one join !"); + } + else { + [relationship loadJoinPropertyList:_plist]; + } + + relationship->destinationEntity = + RETAIN([_plist objectForKey:@"destination"]); + // retained string + + relationship->flags.isToMany = + [[_plist objectForKey:@"isToMany"] isEqual:@"Y"]; + + relationship->flags.isMandatory = + [[_plist objectForKey:@"isMandatory"] isEqual:@"Y"]; + + /* Do not send here the -setDefinition: message because the relationships + are not yet created from the model file. */ + relationship->definition + = RETAIN([_plist objectForKey:@"definition"]); + + return relationship; +} + +- (void)replaceStringsWithObjects { + EOModel *model = [self->entity model]; + + if (self->destinationEntity) { + // now self->destinationEntity is NSString and retained !! + id destinationEntityName = AUTORELEASE(self->destinationEntity); + self->destinationEntity = [model entityNamed:destinationEntityName]; + // now hold entity non-retained + + if (self->destinationEntity == nil) { + NSLog(@"invalid entity name '%@' specified as destination entity " + @"for relationship '%@' in entity '%@'", + destinationEntityName, name, [self->entity name]); + [model errorInReading]; + } + } + + if (!(self->destinationEntity || self->definition)) { + NSLog(@"relationship '%@' in entity '%@' is incompletely specified: " + @"no destination entity or definition.", name, [self->entity name]); + [model errorInReading]; + } + + if (self->definition && (self->sourceAttribute != nil)) { + NSLog(@"relationship '%@' in entity '%@': flattened relationships " + @"cannot have joins", name, [self->entity name]); + [model errorInReading]; + } + + if (self->sourceAttribute) { + EOEntity *attributeEntity; + EOAttribute *attribute = nil; + +#if 0 + attributeEntity = self->flags.isToMany + ? self->destinationEntity + : self->entity; +#endif + attributeEntity = self->entity; + attribute = + [attributeEntity attributeNamed:(NSString*)self->sourceAttribute]; + + if (attribute) + [self setSourceAttribute:attribute]; + else { + [model errorInReading]; + NSLog(@"invalid attribute name '%@' specified as source attribute for " + @"join in relationship '%@' in entity '%@' (dest='%@')", + sourceAttribute, [self name], + [self->entity name], [self->destinationEntity name]); + } + +#if 0 + attributeEntity = self->flags.isToMany + ? self->entity + : self->destinationEntity; +#endif + attributeEntity = self->destinationEntity; + attribute = [attributeEntity attributeNamed:(NSString*)destinationAttribute]; + + if (attribute) + [self setDestinationAttribute:attribute]; + else { + [model errorInReading]; + NSLog(@"invalid attribute name '%@' specified as destination " + @"attribute for join in relationship '%@' in entity '%@' (dest='%@')", + destinationAttribute, [self name], + [self->entity name], [self->destinationEntity name]); + } + } + [self setCreateMutableObjects:NO]; +} + +- (void)initFlattenedRelationship { + if (self->definition) { + NS_DURING + [self setDefinition:self->definition]; + NS_HANDLER { + NSLog([localException reason]); + [[self->entity model] errorInReading]; + } + NS_ENDHANDLER; + } +} + +- (id)propertyList { + NSMutableDictionary *propertyList = nil; + + propertyList = [NSMutableDictionary dictionary]; + [self encodeIntoPropertyList:propertyList]; + return propertyList; +} + +- (void)setCreateMutableObjects:(BOOL)flag { + if (self->flags.createsMutableObjects == flag) + return; + + self->flags.createsMutableObjects = flag; +} + +- (BOOL)createsMutableObjects { + return self->flags.createsMutableObjects; +} + +- (int)compareByName:(EORelationship *)_other { + return [[(EORelationship *)self name] compare:[_other name]]; +} + +@end /* EORelationship (EORelationshipPrivate) */ + +@implementation EORelationship(EOJoin) + +- (void)loadJoinPropertyList:(id)propertyList { + NSString *joinOperatorPList; + NSString *joinSemanticPList; + id tmp; + + tmp = [propertyList objectForKey:@"sourceAttribute"]; + [self setSourceAttribute:tmp]; + tmp = [propertyList objectForKey:@"destinationAttribute"]; + [self setDestinationAttribute:tmp]; + + if ((joinOperatorPList = [propertyList objectForKey:@"joinOperator"])) { + NSAssert([joinOperatorPList isEqual:@"EOJoinEqualTo"], + @"only EOJoinEqualTo is supported as the join operator !"); + } + + if ((joinSemanticPList = [propertyList objectForKey:@"joinSemantic"])) { + NSAssert([joinSemanticPList isEqual:@"EOInnerJoin"], + @"only EOInnerJoin is supported as the join semantic !"); + } +} + +- (void)setDestinationAttribute:(EOAttribute*)attribute { + ASSIGN(self->destinationAttribute, attribute); +} +- (EOAttribute*)destinationAttribute { + return self->destinationAttribute; +} + +- (void)setSourceAttribute:(EOAttribute *)attribute { + ASSIGN(self->sourceAttribute, attribute); +} +- (EOAttribute*)sourceAttribute { + return self->sourceAttribute; +} + +- (EOJoinOperator)joinOperator { + return EOJoinEqualTo; +} +- (EOJoinSemantic)joinSemantic { + return EOInnerJoin; +} + +- (EORelationship*)relationship { + return self; +} + +// misc + +- (void)addJoin:(EOJoin *)_join { + [self setSourceAttribute:[_join sourceAttribute]]; + [self setDestinationAttribute:[_join destinationAttribute]]; +} + +@end /* EORelationship(EOJoin) */ + +@implementation EORelationship(PropertyListCoding) + +static inline void _addToPropList(NSMutableDictionary *_plist, + id _value, NSString *key) { + if (_value) [_plist setObject:_value forKey:key]; +} + +- (void)encodeIntoPropertyList:(NSMutableDictionary *)_plist { + _addToPropList(_plist, self->name, @"name"); + _addToPropList(_plist, self->definition, @"definition"); + _addToPropList(_plist, self->userDictionary, @"userDictionary"); + + if (self->sourceAttribute) { // has join ? + _addToPropList(_plist, [self->sourceAttribute name], @"sourceAttribute"); + _addToPropList(_plist, [self->destinationAttribute name], + @"destinationAttribute"); + _addToPropList(_plist, [[self->sourceAttribute entity] name], + @"destination"); + } + + if (![self isFlattened] && self->destinationEntity) { + _addToPropList(_plist, [self->destinationEntity name], @"destination"); + } + + if (![self isFlattened]) + _addToPropList(_plist, flags.isToMany ? @"Y" : @"N", @"isToMany"); + + if (![self isMandatory]) + _addToPropList(_plist, flags.isMandatory ? @"Y" : @"N", @"isMandatory"); +} + +@end /* EORelationship(PropertyListCoding) */ + +@implementation EORelationship(EOF2Additions) + +/* constraints */ + +- (void)setIsMandatory:(BOOL)_flag { + self->flags.isMandatory = _flag ? 1 : 0; +} +- (BOOL)isMandatory { + return self->flags.isMandatory ? YES : NO; +} + +- (NSException *)validateValue:(id *)_value { + if (_value == NULL) return nil; + + /* check 'mandatory' constraint */ + + if (self->flags.isMandatory) { + if (self->flags.isToMany) { + if ([*_value count] == 0) { + NSLog(@"WARNING(%s): tried to use value %@" + @"with mandatory toMany relationship %@", + __PRETTY_FUNCTION__, *_value, self); + } + } + else { + if ((*_value == nil) || (*_value == null)) { + NSLog(@"WARNING(%s): tried to use value %@" + @"with mandatory toOne relationship %@", + __PRETTY_FUNCTION__, *_value, self); + } + } + } + + return nil; +} + +@end /* EORelationship(EOF2Additions) */ + +@implementation EOJoin +@end /* EOJoin */ diff --git a/sope-gdl1/GDLAccess/EOSQLExpression.m b/sope-gdl1/GDLAccess/EOSQLExpression.m new file mode 100644 index 00000000..d273de63 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOSQLExpression.m @@ -0,0 +1,1446 @@ +/* + EOSQLExpression.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: September 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "EOSQLExpression.h" +#include "common.h" +#import "EOAdaptor.h" +#import "EOAdaptorChannel.h" +#import "EOAdaptorContext.h" +#import "EOAttribute.h" +#import "EOAttributeOrdering.h" +#import "EOEntity.h" +#import "EOFExceptions.h" +#import "EOSQLQualifier.h" +#import "EORelationship.h" +#import +#import +#import +#import + +#if LIB_FOUNDATION_LIBRARY +# include +# include +#else +# include "DefaultScannerHandler.h" +# include "PrintfFormatScanner.h" +#endif + +/* +A SQL command is generated for an entity when you fetch, insert, update or +delete an object from the database. The command includes all the attributes +from entity. + +The biggest problem in generation of SQL commands is the generation of SELECT +statements, because the tables have to be properly aliased. If an entity has +only simple attributes then you have a single table in the FROM clause. If the +entity has flattened attributes, then several tables appear in the FROM list; +each one with a different alias. + +The algorithm uses a dictionary that has as keys either entities or +relationships. The values in dictionary are aliases. + +For a simple attribute we insert in the above dictionary the attribute's entity +as key and an alias for it. + +For a flattened attribute with the following definition: `toEntity1.toEntity2. +... toEntityn.attribute', we have to assign to each toEntityi object an alias. + +Let's see how each component of the SELECT command is generated. The columns +list is generated by iterating over the attributes of entity. If the attribute +is simple, its entity is looked up in the aliases dictionary. If the attribute +is flattened, the alias of attribute is the alias of toEntityn. If the +attribute is derived, each component of it is generated applying the same +rules. + +The FROM list is generated like this. For each key in the aliases dictionary: +* if the key is an entity, its external name is written followed by the alias +corresponding to entity +* if the key is a relationship, the external name of its destination entity is +written followed by the alias corresponding to relationship. + +A little bit complicated is the WHERE clause. For each flattened attribute we +have to generate the logic expression that selects the attribute by expressing +the joins over several entities. The algorithm starts with the first +relationship. An additional variable, named context is used. Its initial value +is the current entity. The expression + +context-alias.source-attribute join-operator + relationship-alias.destination-attribute + +is added using the AND operator to the where clause. Then the context variable +is set to the current relationship. The algorithm continues with the next +relationship until there are no more relationships to process. + +*/ + +static EONull *null = nil; +NSString *EOBindVariableNameKey = @"name"; +NSString *EOBindVariablePlaceHolderKey = @"placeHolder"; +NSString *EOBindVariableAttributeKey = @"attribute"; +NSString *EOBindVariableValueKey = @"value"; + + +@interface EOInsertUpdateScannerHandler : DefaultScannerHandler +{ + NSString *value; + EOAttribute *attribute; + EOAdaptor *adaptor; +} + +- (void)setValue:(NSString*)value + attribute:(EOAttribute*)attribute + adaptor:(EOAdaptor*)adaptor; +@end + + +@implementation EOInsertUpdateScannerHandler + +- (id)init { + [super init]; + + specHandler['V'] + = [self methodForSelector:@selector(convertValue:scanner:)]; + return self; +} + +- (void)dealloc { + RELEASE(self->value); + RELEASE(self->attribute); + RELEASE(self->adaptor); + [super dealloc]; +} + +- (void)setValue:(NSString *)_value + attribute:(EOAttribute*)_attribute + adaptor:(EOAdaptor*)_adaptor +{ + ASSIGNCOPY(self->value, _value); + ASSIGN(self->attribute, _attribute); + ASSIGN(self->adaptor, _adaptor); +} + +- (NSString *)convertValue:(va_list *)pString scanner:(FormatScanner *)scanner{ + return (self->adaptor) + ? [self->adaptor formatValue:self->value?self->value:(id)null + forAttribute:attribute] + : self->value; +} + +@end /* EOInsertUpdateScannerHandler */ + + +@implementation EOSQLExpression + ++ (int)version { + return 1; +} + ++ (void)initialize { + if (null == nil) null = [[NSNull null] retain]; +} + +- (id)initWithEntity:(EOEntity *)_entity { + if ((self = [super init])) { + ASSIGN(self->entity, _entity); + } + return self; +} +- (id)init { + return [self initWithEntity:nil]; +} + ++ (id)deleteExpressionWithQualifier:(EOSQLQualifier*)qualifier + channel:(EOAdaptorChannel*)channel +{ + EOSQLExpression* sqlExpression + = AUTORELEASE([[self deleteExpressionClass] new]); + [sqlExpression deleteExpressionWithQualifier:qualifier channel:channel]; + return sqlExpression; +} ++ (id)insertExpressionForRow:(NSDictionary *)row + entity:(EOEntity*)_entity + channel:(EOAdaptorChannel*)channel +{ + EOSQLExpression* sqlExpression + = AUTORELEASE([[self insertExpressionClass] new]); + + [sqlExpression insertExpressionForRow:row entity:_entity channel:channel]; + return sqlExpression; +} + +- (id)deleteExpressionWithQualifier:(EOSQLQualifier *)qualifier + channel:(EOAdaptorChannel*)channel +{ + NSString *sql; + + self = [self initWithEntity:[qualifier entity]]; + + self->adaptor = RETAIN([[channel adaptorContext] adaptor]); + + sql = [self assembleDeleteStatementWithQualifier:qualifier + tableList:[entity externalName] + whereClause:[self whereClauseForQualifier:qualifier]]; + + self->content = [sql mutableCopy]; + [self finishBuildingExpression]; + + return self; +} + +- (id)insertExpressionForRow:(NSDictionary *)row + entity:(EOEntity*)_entity + channel:(EOAdaptorChannel*)channel +{ + NSString *sql; + + self = [self initWithEntity:_entity]; + + self->adaptor = RETAIN([[channel adaptorContext] adaptor]); + + sql = [self assembleInsertStatementWithRow:row + tableList:[entity externalName] + columnList:[self columnListForRow:row] + valueList:[self valueListForRow:row]]; + + self->content = [sql mutableCopy]; + + [self finishBuildingExpression]; + + return self; +} + ++ (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel +{ + EOSQLExpression* sqlExpression + = AUTORELEASE([[self selectExpressionClass] new]); + [sqlExpression selectExpressionForAttributes:attributes + lock:flag + qualifier:qualifier + fetchOrder:fetchOrder + channel:channel]; + return sqlExpression; +} + +- (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel +{ + NSArray *relationshipPaths; + NSString *sql; + + self = [self initWithEntity:[qualifier entity]]; + + self->adaptor = [[[channel adaptorContext] adaptor] retain]; + // self->content = [NSMutableString new]; // mh: BUG!!! + + relationshipPaths = [self relationshipPathsForAttributes:attributes + qualifier:qualifier + fetchOrder:fetchOrder]; + + sql = [self assembleSelectStatementWithAttributes:attributes + lock:flag + qualifier:qualifier + fetchOrder:fetchOrder + selectString: + [qualifier usesDistinct] ? @"SELECT DISTINCT" : @"SELECT" + columnList: + [self selectListWithAttributes:attributes + qualifier:qualifier] + tableList:[self fromClause] + whereClause:[self whereClauseForQualifier:qualifier] + joinClause: + [self joinExpressionForRelationshipPaths:relationshipPaths] + orderByClause:[self orderByClauseForFetchOrder:fetchOrder] + lockClause:flag ? [self lockClause] : nil]; + + self->content = [sql mutableCopy]; + + [self finishBuildingExpression]; + + return self; +} ++ (id)updateExpressionForRow:(NSDictionary *)row + qualifier:(EOSQLQualifier *)qualifier + channel:(EOAdaptorChannel *)channel +{ + EOSQLExpression* sqlExpression + = AUTORELEASE([[self updateExpressionClass] new]); + [sqlExpression updateExpressionForRow:row + qualifier:qualifier + channel:channel]; + return sqlExpression; +} + +- (id)updateExpressionForRow:(NSDictionary *)row + qualifier:(EOSQLQualifier *)qualifier + channel:(EOAdaptorChannel *)channel +{ + NSString *sql; + + self = [self initWithEntity:[qualifier entity]]; + if (self->entity == nil) { + [[[InvalidQualifierException alloc] + initWithFormat:@"entity for qualifier %@ is nil", + [qualifier expressionValueForContext:nil]] raise]; + } + + self->adaptor = [[[channel adaptorContext] adaptor] retain]; + self->content = [[NSMutableString alloc] init]; + + sql = [self assembleUpdateStatementWithRow:row + qualifier:qualifier + tableList:[entity externalName] + updateList:[self updateListForRow:row] + whereClause:[self whereClauseForQualifier:qualifier]]; + [self->content appendString:sql]; + + [self finishBuildingExpression]; + + return self; +} + +- (void)dealloc { + RELEASE(self->bindings); + RELEASE(self->listString); + RELEASE(self->whereClauseString); + RELEASE(self->entity); + RELEASE(self->adaptor); + RELEASE(self->entitiesAndPropertiesAliases); + RELEASE(self->fromListEntities); + RELEASE(self->content); + [super dealloc]; +} + +- (NSString *)selectListWithAttributes:(NSArray *)attributes + qualifier:(EOSQLQualifier *)qualifier +{ + NSMutableString *selectList; + NSEnumerator *enumerator; + BOOL first = YES; + EOAttribute *attribute; + BOOL isDistinct; + + selectList = [NSMutableString stringWithCapacity:128]; + isDistinct = [qualifier usesDistinct]; + + /* check whether DISTINCT is allowed */ + enumerator = [attributes objectEnumerator]; + while ((attribute = [enumerator nextObject])) { + if (self->adaptor) { + if (![self->adaptor attributeAllowedInDistinctSelects:attribute]) { +#if DEBUG && 0 + NSLog(@"WARNING: tried to select attribute type %@ with DISTINCT " + @"which is not allowed, disabling DISTINCT: %@", + [attribute externalType], [attribute name]); +#endif + isDistinct = NO; + break; + } + } + } + + enumerator = [attributes objectEnumerator]; + while ((attribute = [enumerator nextObject])) { + if(first) + first = NO; + else + [selectList appendString:@", "]; + + [selectList appendString:[self expressionValueForAttribute:attribute]]; + } + + return selectList; +} + +- (NSString *)fromClause { + NSMutableString *fromClause; + NSEnumerator *enumerator; + BOOL first = YES; + id key; + + fromClause = [NSMutableString stringWithCapacity:64]; + enumerator = [self->fromListEntities objectEnumerator]; + + /* Compute the FROM list from all the aliases found in + entitiesAndPropertiesAliases dictionary. Note that this dictionary + contains entities and relationships. The last ones are there for + flattened attributes over reflexive relationships. */ + while ((key = [enumerator nextObject])) { + if (first) + first = NO; + else + [fromClause appendString:@", "]; + + if ([key isKindOfClass:[EORelationship class]]) { + /* This key corresponds to a flattened attribute. */ + [fromClause appendFormat:@"%@ %@", + [[key destinationEntity] externalName], + [entitiesAndPropertiesAliases objectForKey:key]]; + } + else { + /* This is an EOEntity. */ + [fromClause appendFormat:@"%@ %@", + [key externalName], + [entitiesAndPropertiesAliases objectForKey:key]]; + } + } + + return fromClause; +} + +- (NSString *)whereClauseForQualifier:(EOSQLQualifier *)_qualifier { + return [_qualifier expressionValueForContext:self]; +} + +- (id)joinExpressionForRelationshipPaths:(NSArray *)relationshipPaths +{ + NSMutableString *expression = [NSMutableString stringWithCapacity:64]; + NSEnumerator *enumerator = [relationshipPaths objectEnumerator]; + NSMutableArray *rels = [NSMutableArray new]; + NSArray *relationshipPath; + EORelationship *relationship; + BOOL first = YES; + + while ((relationshipPath = [enumerator nextObject])) { + NSEnumerator *componentRelationshipsEnumerator; + id context; + + componentRelationshipsEnumerator = [relationshipPath objectEnumerator]; + context = entity; + + while((relationship = [componentRelationshipsEnumerator nextObject])) { + if (![rels containsObject:relationship]) { + id sourceAttribute, destinationAttribute; + + [rels addObject:relationship]; + + /* Compute the SQL expression string corresponding to each join in + the relationship. */ + sourceAttribute = [self expressionValueForAttribute: + [relationship sourceAttribute] + context:context]; + destinationAttribute = [self expressionValueForAttribute: + [relationship destinationAttribute] + context: + [relationship destinationEntity]]; + + //NSLog(@"sourceAttribute %@", sourceAttribute); + //NSLog(@"destinationAttribute %@", destinationAttribute); + + if (first) + first = NO; + else + [expression appendString:@" AND "]; + + [expression appendString:[sourceAttribute description]]; + [expression appendString:@" = "]; + [expression appendString:[destinationAttribute description]]; + } + /* Compute the next context which is the current relationship. */ + context = [relationship destinationEntity]; + } + } + [rels release]; + return expression; +} + +- (NSString *)orderByClauseForFetchOrder:(NSArray *)fetchOrder +{ + int i, count; + NSMutableString *orderBy; + + if ((count = [fetchOrder count]) == 0) + return @""; + + orderBy = (id)[NSMutableString stringWithCapacity:32]; + for(i = 0; i < count; i++) { + id eorder; + + eorder = [fetchOrder objectAtIndex:i]; + + if (i != 0) [orderBy appendString:@", "]; + + if ([eorder isKindOfClass:[EOSortOrdering class]]) { + EOSortOrdering *order; + EOAttribute *attribute; + SEL ordering; + NSString *fmt; + + order = eorder; + ordering = [order selector]; + attribute = [self->entity attributeNamed:[order key]]; + + if (sel_eq(ordering, EOCompareCaseInsensitiveAscending) || + sel_eq(ordering, EOCompareCaseInsensitiveDescending)) + fmt = @"LOWER(%@)"; + else + fmt = @"%@"; + + [orderBy appendFormat:fmt, [self expressionValueForAttribute:attribute]]; + + if (sel_eq(ordering, EOCompareCaseInsensitiveAscending) || + sel_eq(ordering, EOCompareAscending)) { + [orderBy appendString:@" ASC"]; + } + else if (sel_eq(ordering, EOCompareCaseInsensitiveDescending) || + sel_eq(ordering, EOCompareDescending)) { + [orderBy appendString:@" DESC"]; + } + } + else { + EOAttributeOrdering *order; + EOOrdering ordering; + + order = eorder; + ordering = [order ordering]; + + [orderBy appendFormat:@"%@", + [self expressionValueForAttribute:[order attribute]]]; + if (ordering != EOAnyOrder) + [orderBy appendString: + ([order ordering] == EOAscendingOrder ? @" ASC" : @" DESC")]; + } + } + + return orderBy; +} + +- (NSString *)literalForAttribute:(EOAttribute *)_attribute + withValue:(id)_value fromRow:(NSDictionary *)_row +{ + return (self->adaptor) + ? [self->adaptor formatValue:_value?_value:null forAttribute:_attribute] + : [_value stringValue]; +} + +- (id)updateListForRow:(NSDictionary *)row { + PrintfFormatScanner *formatScanner = nil; + EOInsertUpdateScannerHandler *scannerHandler = nil; + NSMutableString *expression = nil; + NSEnumerator *enumerator; + NSString *attributeName = nil; + BOOL first = YES; + + enumerator = [row keyEnumerator]; + expression = [NSMutableString stringWithCapacity:256]; + + formatScanner = [[PrintfFormatScanner alloc] init]; + AUTORELEASE(formatScanner); + scannerHandler = [[EOInsertUpdateScannerHandler alloc] init]; + AUTORELEASE(scannerHandler); + + [formatScanner setAllowOnlySpecifier:YES]; + [formatScanner setFormatScannerHandler:scannerHandler]; + + while((attributeName = [enumerator nextObject])) { + EOAttribute *attribute; + NSString *updateFormat; + NSString *columnName = nil; + id value = nil; + + attribute = [entity attributeNamed:attributeName]; + updateFormat = [attribute updateFormat]; + + NSAssert1(attribute, @"attribute %@ should be non nil", attributeName); + columnName = adaptor + ? [adaptor formatAttribute:attribute] + : [attribute columnName]; + + value = [row objectForKey:attributeName]; + + if (updateFormat) { + [scannerHandler setValue:value + attribute:attribute + adaptor:adaptor]; +#if defined(__s390__) + value = [formatScanner performSelector: + @selector(stringWithFormat:arguments:) + withObject:updateFormat + withObject:nil]; +#else + value = [formatScanner stringWithFormat:updateFormat + arguments:NULL]; +#endif + } + else { + value = [self literalForAttribute:attribute + withValue:value fromRow:row]; + } + + if(first) first = NO; + else [expression appendString:@", "]; + + [expression appendString:columnName]; + [expression appendString:@" = "]; + [expression appendString:value]; + } + + return expression; +} + +- (id)columnListForRow:(NSDictionary *)row { + NSMutableString *expression; + NSEnumerator *enumerator; + NSString *attributeName = nil; + BOOL first = YES; + + expression = [NSMutableString stringWithCapacity:128]; + enumerator = [row keyEnumerator]; + + while ((attributeName = [enumerator nextObject])) { + EOAttribute *attribute; + NSString *columnName; + + attribute = [entity attributeNamed:attributeName]; + + NSAssert1(attribute, @"attribute %@ should be non nil", attributeName); + columnName = adaptor + ? [adaptor formatAttribute:attribute] + : [attribute columnName]; + + if (first) first = NO; + else [expression appendString:@", "]; + + [expression appendString:columnName]; + } + + return expression; +} + +- (id)valueListForRow:(NSDictionary *)row { + EOInsertUpdateScannerHandler *scannerHandler; + PrintfFormatScanner *formatScanner; + NSEnumerator *enumerator; + NSString *attributeName = nil; + NSMutableString *expression = nil; + BOOL first = YES; + + formatScanner = [[PrintfFormatScanner alloc] init]; + AUTORELEASE(formatScanner); + scannerHandler = [[EOInsertUpdateScannerHandler alloc] init]; + AUTORELEASE(scannerHandler); + + expression = [NSMutableString stringWithCapacity:256]; + enumerator = [row keyEnumerator]; + + [formatScanner setAllowOnlySpecifier:YES]; + [formatScanner setFormatScannerHandler:scannerHandler]; + + while ((attributeName = [enumerator nextObject])) { + EOAttribute *attribute; + NSString *insertFormat; + id value; + + attribute = [entity attributeNamed:attributeName]; + insertFormat = [attribute insertFormat]; + value = [row objectForKey:attributeName]; + + NSAssert1(attribute, @"attribute %@ should be non nil", attributeName); + if (insertFormat) { + [scannerHandler setValue:value + attribute:attribute + adaptor:self->adaptor]; +#if defined(__s390__) + value = [formatScanner performSelector: + @selector(stringWithFormat:arguments:) + withObject:insertFormat + withObject:nil]; +#else + value = [formatScanner stringWithFormat:insertFormat + arguments:NULL]; +#endif + } + else { + value = [self literalForAttribute:attribute + withValue:value fromRow:row]; + } + + if(first) first = NO; + else [expression appendString:@", "]; + + [expression appendString:value]; + } + + return expression; +} + +- (NSArray *)relationshipPathsForAttributes:(NSArray *)attributes + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder +{ + int i, count; + NSMutableSet *entities; + NSMutableSet *relationshipPaths; + NSEnumerator *enumerator; + id entityOrRelationship; + + entities = [NSMutableSet set]; + relationshipPaths = [NSMutableSet set]; + + NSAssert3(self->entity, + @"entity should be non nil (attrs=%@, qual=%@, order=%@)", + attributes, qualifier, fetchOrder); + + for (i = 0, count = [attributes count]; i < count; i++) { + EOAttribute *attribute; + + attribute = [attributes objectAtIndex:i]; + + if ([attribute entity] != entity) { + [[[InvalidAttributeException alloc] + initWithFormat:@"all attributes must be from the same " + @"entity (attribute '%@' is not in '%@')", + [attribute name], + [entity name]] raise]; + } + if ([attribute isFlattened]) { + id definitionArray = [attribute definitionArray]; + NSRange range = { 0, [definitionArray count] - 1 }; + id relationshipPath = [definitionArray subarrayWithRange:range]; + + [relationshipPaths addObject:relationshipPath]; + [entities addObjectsFromArray:relationshipPath]; + } + else { + /* attribute is normal. */ + [entities addObject:[attribute entity]]; + } + } + + [relationshipPaths unionSet:[qualifier relationshipPaths]]; + [entities unionSet:[qualifier additionalEntities]]; + + for (i = 0, count = [fetchOrder count]; i < count; i++) { + EOAttribute *attribute; + id eorder; + + eorder = [fetchOrder objectAtIndex:i]; + + attribute = ([eorder isKindOfClass:[EOSortOrdering class]]) + ? [self->entity attributeNamed:[(EOSortOrdering *)eorder key]] + : [(EOAttributeOrdering *)eorder attribute]; + + if ([attribute entity] != entity) { + [[[InvalidAttributeException alloc] + initWithFormat:@"all attributes must be from the same " + @"entity (attribute '%@' is not in '%@')", + [attribute name], + [entity name]] raise]; + } + if ([attribute isFlattened]) { + id definitionArray = [attribute definitionArray]; + NSRange range = { 0, [definitionArray count] - 1 }; + id relationshipPath = [definitionArray subarrayWithRange:range]; + + [relationshipPaths addObject:relationshipPath]; + [entities addObjectsFromArray:relationshipPath]; + } + } + + entitiesAndPropertiesAliases = [NSMutableDictionary new]; + fromListEntities = [NSMutableArray new]; + enumerator = [entities objectEnumerator]; + i = 1; + while ((entityOrRelationship = [enumerator nextObject])) { + NSString* alias = [NSString stringWithFormat:@"t%d", i++]; + + [entitiesAndPropertiesAliases setObject:alias + forKey:entityOrRelationship]; + [fromListEntities addObject:entityOrRelationship]; + } + + return [relationshipPaths allObjects]; +} + +- (EOEntity *)entity { + return self->entity; +} +- (id)finishBuildingExpression { + return self; +} +- (NSString *)lockClause { + return @""; +} + +- (NSString *)expressionValueForAttribute:(EOAttribute *)attribute + context:(id)context +{ + NSString *alias = [entitiesAndPropertiesAliases objectForKey:context]; + NSString *columnName = nil; + + columnName = adaptor + ? [adaptor formatAttribute:attribute] + : [attribute columnName]; + + return alias + ? [NSString stringWithFormat:@"%@.%@", alias, columnName] + : columnName; +} + +- (NSString *)expressionValueForAttribute:(EOAttribute *)attribute { + if([attribute isFlattened]) + return [self expressionValueForAttributePath: + [attribute definitionArray]]; + else if([attribute isDerived]) + return [[attribute definitionArray] expressionValueForContext:self]; + + /* attribute is a normal attribute. Its alias is the alias + of its entity. */ + return [self expressionValueForAttribute:attribute + context:[attribute entity]]; +} + +- (NSString *)expressionValueForAttributePath:(NSArray *)definitionArray { + /* Take the alias of the last relationship. */ + id relationship; + NSString *alias; + + relationship + = [definitionArray objectAtIndex:([definitionArray count] - 2)]; + alias = [entitiesAndPropertiesAliases objectForKey:relationship]; + + return AUTORELEASE(([[NSString alloc] + initWithFormat:@"%@.%@", + alias, [[definitionArray lastObject] columnName]])); +} + +- (NSString *)expressionValueForContext:(id)context { + return self->content; +} + ++ (Class)selectExpressionClass { + return [EOSelectSQLExpression class]; +} ++ (Class)insertExpressionClass { + return [EOInsertSQLExpression class]; +} ++ (Class)deleteExpressionClass { + return [EODeleteSQLExpression class]; +} ++ (Class)updateExpressionClass { + return [EOUpdateSQLExpression class]; +} + +- (EOAdaptor *)adaptor { + return self->adaptor; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]:\n", self, NSStringFromClass([self class])]; + + if (self->entity) [ms appendFormat:@" entity=%@\n", self->entity]; + if (self->adaptor) [ms appendFormat:@" adaptor=%@\n", self->adaptor]; + if (self->content) [ms appendFormat:@" content='%@\n'", self->content]; + + if (self->entitiesAndPropertiesAliases) + [ms appendFormat:@" aliases=%@\n", self->entitiesAndPropertiesAliases]; + if (self->fromListEntities) + [ms appendFormat:@" from-entities=%@\n", self->fromListEntities]; + + if (self->whereClauseString) + [ms appendFormat:@" where=%@\n", self->whereClauseString]; + + if (self->listString) [ms appendFormat:@" list=%@\n", self->listString]; + if (self->bindings) [ms appendFormat:@" bindings=%@\n", self->bindings]; + + [ms appendString:@">"]; + return ms; +} + +@end /* EOSQLExpression */ + + +@implementation EOInsertSQLExpression +@end /* EOInsertSQLExpression */ + +@implementation EOUpdateSQLExpression +@end /* EOUpdateSQLExpression */ + +@implementation EODeleteSQLExpression +@end /* EODeleteSQLExpression */ + +@implementation EOSQLExpression(NewInEOF2) + ++ (EOSQLExpression *)selectStatementForAttributes:(NSArray *)_attributes + lock:(BOOL)_flag + fetchSpecification:(EOFetchSpecification *)_fspec + entity:(EOEntity *)_entity +{ + if (_fspec == nil) { + [NSException raise:NSInvalidArgumentException + format:@"missing fetch specification argument .."]; + } + if ([_attributes count] == 0) { + [NSException raise:NSInvalidArgumentException + format:@"missing attributes for select .."]; + } + + return [self selectExpressionForAttributes:_attributes + lock:_flag + qualifier:[[_fspec qualifier] sqlQualifierForEntity:_entity] + fetchOrder:[_fspec sortOrderings] + channel:nil]; +} + ++ (EOSQLExpression *)expressionForString:(NSString *)_sql { + EOSQLExpression *se; + + se = [[EOSQLExpression alloc] init]; + [se setStatement:_sql]; + return AUTORELEASE(se); +} + +/* accessors */ + +- (void)setStatement:(NSString *)_stmt { + id tmp; + tmp = self->content; + self->content = [_stmt mutableCopy]; + RELEASE(tmp); +} +- (NSString *)statement { + return self->content; +} + +- (NSString *)whereClauseString { + return self->whereClauseString; +} + +/* tables */ + +- (NSString *)tableListWithRootEntity:(EOEntity *)_entity { + return ([self->fromListEntities count] > 0) + ? [self fromClause] + : [_entity externalName]; +} + +/* assembly */ + +- (NSString *)assembleDeleteStatementWithQualifier:(EOQualifier *)_qualifier + tableList:(NSString *)_tableList + whereClause:(NSString *)_whereClause +{ + NSMutableString *s; + + s = [NSMutableString stringWithCapacity:64]; + [s appendString:@"DELETE FROM "]; + [s appendString:_tableList]; + [s appendString:@" WHERE "]; + [s appendString:_whereClause]; + return s; +} + +- (NSString *)assembleInsertStatementWithRow:(NSDictionary *)_row + tableList:(NSString *)_tables + columnList:(NSString *)_columns + valueList:(NSString *)_values +{ + NSMutableString *s; + + s = [NSMutableString stringWithCapacity:256]; + [s appendString:@"INSERT INTO "]; + [s appendString:_tables]; + [s appendString:@" ("]; + [s appendString:_columns]; + [s appendString:@") VALUES ("]; + [s appendString:_values]; + [s appendString:@")"]; + return s; +} + +- (NSString *)assembleSelectStatementWithAttributes:(NSArray *)_attributes + lock:(BOOL)_lock + qualifier:(EOQualifier *)_qualifier + fetchOrder:(NSArray *)_fetchOrder + selectString:(NSString *)_selectString + columnList:(NSString *)_columns + tableList:(NSString *)_tables + whereClause:(NSString *)_whereClause + joinClause:(NSString *)_joinClause + orderByClause:(NSString *)_orderByClause + lockClause:(NSString *)_lockClause +{ + NSMutableString *s; + unsigned wlen, jlen; + +#if 0 +#warning DEBUG LOG, REMOVE! + [self logWithFormat:@"%s: '%@': %@", __PRETTY_FUNCTION__, _whereClause,self]; +#endif + + s = [NSMutableString stringWithCapacity:256]; + + [s appendString:_selectString ? _selectString : @"SELECT"]; + [s appendString:@" "]; + [s appendString:_columns]; + [s appendString:@" FROM "]; + [s appendString:_tables]; + + if ([_lockClause length] > 0) { + [s appendString:@" "]; + [s appendString:_lockClause]; + } + + wlen = [_whereClause length]; + jlen = [_joinClause length]; + + if ((wlen > 0) || (jlen > 0)) + [s appendString:@" WHERE "]; + + if (wlen > 0) + [s appendString:_whereClause]; + + if ((wlen > 0) && (jlen > 0)) + [s appendString:@" AND "]; + + if (jlen > 0) + [s appendString:_joinClause]; + + if ([_orderByClause length] > 0) { + [s appendString:@" ORDER BY "]; + [s appendString:_orderByClause]; + } + + return s; +} + +- (NSString *)assembleUpdateStatementWithRow:(NSDictionary *)_row + qualifier:(EOQualifier *)_qualifier + tableList:(NSString *)_tables + updateList:(NSString *)_updates + whereClause:(NSString *)_whereClause +{ + NSMutableString *s; + + s = [NSMutableString stringWithCapacity:256]; + + [s appendString:@"UPDATE "]; + [s appendString:_tables]; + [s appendString:@" SET "]; + [s appendString:_updates]; + [s appendString:@" WHERE "]; + [s appendString:_whereClause]; + + return s; +} + +- (NSString *)assembleJoinClauseWithLeftName:(NSString *)_leftName + rightName:(NSString *)_rightName + joinSemantic:(EOJoinSemantic)_semantic +{ + NSMutableString *s; + + s = [NSMutableString stringWithCapacity:64]; + [s appendString:_leftName]; + switch (_semantic) { + case EOInnerJoin: + [s appendString:@" = "]; + break; + case EOFullOuterJoin: + [s appendString:@" *=* "]; + break; + case EOLeftOuterJoin: + [s appendString:@" *= "]; + break; + case EORightOuterJoin: + [s appendString:@" =* "]; + break; + } + [s appendString:_rightName]; + return s; +} + +/* attributes */ + +- (NSString *)sqlStringForAttribute:(EOAttribute *)_attribute { + NSLog(@"ERROR(%s): subclasses need to override this method!", + __PRETTY_FUNCTION__); + return nil; +} + +- (NSString *)sqlStringForAttributePath:(NSString *)_attrPath { + NSLog(@"ERROR(%s): subclasses need to override this method!", + __PRETTY_FUNCTION__); + return nil; +} + +- (NSString *)sqlStringForAttributeNamed:(NSString *)_attrName { + EOAttribute *a; + + if ((a = [[self entity] attributeNamed:_attrName])) + return [self sqlStringForAttribute:a]; + + return [self sqlStringForAttributePath:_attrName]; +} + +/* bind variables */ + ++ (BOOL)useBindVariables { + return NO; +} +- (BOOL)mustUseBindVariableForAttribute:(EOAttribute *)_attr { + return NO; +} +- (BOOL)shouldUseBindVariableForAttribute:(EOAttribute *)_attr { + return NO; +} + +- (NSMutableDictionary *)bindVariableDictionaryForAttribute:(EOAttribute *)_attr + value:(id)_value +{ + NSMutableDictionary *d; + + d = [NSMutableDictionary dictionaryWithCapacity:8]; + [d setObject:_attr forKey:EOBindVariableAttributeKey]; + [d setObject:_value ? _value : null forKey:EOBindVariableValueKey]; + return d; +} + +- (void)addBindVariableDictionary:(NSMutableDictionary *)_dictionary { + if (self->bindings == nil) + self->bindings = [[NSMutableArray alloc] init]; +} +- (NSArray *)bindVariableDictionaries { + return self->bindings; +} + +/* values */ + ++ (NSString *)formatValue:(id)_value forAttribute:(EOAttribute *)_attribute { + return _value ? _value : null; +} + +- (NSString *)sqlStringForValue:(id)_value attributeNamed:(NSString *)_attrName { + NSMutableDictionary *bindVars; + EOAttribute *attribute; + + attribute = [[self entity] attributeNamed:_attrName]; + + if ([self mustUseBindVariableForAttribute:attribute]) + bindVars = [self bindVariableDictionaryForAttribute:attribute value:_value]; + else if ([[self class] useBindVariables] && + [self shouldUseBindVariableForAttribute:attribute]) { + bindVars = [self bindVariableDictionaryForAttribute:attribute value:_value]; + } + else + bindVars = nil; + + if (bindVars) { + [self addBindVariableDictionary:bindVars]; + return [bindVars objectForKey:EOBindVariablePlaceHolderKey]; + } + + return [[self class] formatValue:_value?_value:null forAttribute:attribute]; +} + ++ (NSString *)sqlPatternFromShellPattern:(NSString *)_pattern { + unsigned len; + + if ((len = [_pattern length]) > 0) { + unsigned cstrLen = [_pattern cStringLength]; + char cstrBuf[cstrLen + 1]; + const char *cstr; + char buf[len * 3 + 1]; + unsigned i; + BOOL didSomething = NO; + + [_pattern getCString:cstrBuf]; + cstr = cstrBuf; + + for (i = 0; *cstr; cstr++) { + switch (*cstr) { + case '*': + buf[i] = '%'; i++; didSomething = YES; + break; + case '?': + buf[i] = '_'; i++; didSomething = YES; + break; + + case '%': + buf[i] = '['; i++; + buf[i] = '%'; i++; + buf[i] = ']'; i++; + didSomething = YES; + break; + + case '_': + buf[i] = '['; i++; + buf[i] = '_'; i++; + buf[i] = ']'; i++; + didSomething = YES; + break; + + default: + buf[i] = *cstr; + i++; + break; + } + } + buf[i] = '\0'; + + return (didSomething) + ? [NSString stringWithCString:buf length:i] + : _pattern; + } + return _pattern; +} + +/* SQL formats */ + ++ (NSString *)formatSQLString:(NSString *)_sqlString format:(NSString *)_fmt { + return _sqlString; +} + +/* qualifier operators */ + +- (NSString *)sqlStringForSelector:(SEL)_selector value:(id)_value { + if ((_value == null) || (_value == nil)) { + if (sel_eq(_selector, EOQualifierOperatorEqual)) + return @"is"; + else if (sel_eq(_selector, EOQualifierOperatorNotEqual)) + return @"is not"; + } + else { + if (sel_eq(_selector, EOQualifierOperatorEqual)) + return @"="; + else if (sel_eq(_selector, EOQualifierOperatorNotEqual)) + return @"<>"; + } + + if (sel_eq(_selector, EOQualifierOperatorLessThan)) + return @"<"; + else if (sel_eq(_selector, EOQualifierOperatorGreaterThan)) + return @">"; + else if (sel_eq(_selector, EOQualifierOperatorLessThanOrEqualTo)) + return @"<="; + else if (sel_eq(_selector, EOQualifierOperatorGreaterThanOrEqualTo)) + return @">="; + else if (sel_eq(_selector, EOQualifierOperatorLike)) + return @"LIKE"; + else { + return [NSString stringWithFormat:@"UNKNOWN<%@>", + NSStringFromSelector(_selector)]; + } +} + +/* qualifiers */ + +- (NSString *)sqlStringForKeyComparisonQualifier:(EOKeyComparisonQualifier *)_q { + NSMutableString *s; + NSString *sql; + EOAttribute *a; + + s = [NSMutableString stringWithCapacity:64]; + + sql = [self sqlStringForAttributeNamed:[_q leftKey]]; + a = [[self entity] attributeNamed:[_q leftKey]]; /* relationships ? */ + sql = [[self class] formatSQLString:sql format:[a readFormat]]; + [s appendString:sql]; + + [s appendString:@" "]; + [s appendString:[self sqlStringForSelector:[_q selector] value:nil]]; + [s appendString:@" "]; + + sql = [self sqlStringForAttributeNamed:[_q rightKey]]; + a = [[self entity] attributeNamed:[_q rightKey]]; /* relationships ? */ + sql = [[self class] formatSQLString:sql format:[a readFormat]]; + [s appendString:sql]; + + return s; +} + +- (NSString *)sqlStringForKeyValueQualifier:(EOKeyValueQualifier *)_q { + NSMutableString *s; + NSString *sql; + EOAttribute *a; + id v; + + v = [_q value]; + s = [NSMutableString stringWithCapacity:64]; + + sql = [self sqlStringForAttributeNamed:[_q key]]; + a = [[self entity] attributeNamed:[_q key]]; /* relationships ? */ + sql = [[self class] formatSQLString:sql format:[a readFormat]]; + [s appendString:sql]; + + [s appendString:@" "]; + sql = [self sqlStringForSelector:[_q selector] value:v]; + [s appendString:sql]; + [s appendString:@" "]; + + if (([_q selector] == EOQualifierOperatorLike) || + ([_q selector] == EOQualifierOperatorCaseInsensitiveLike)) + v = [[self class] sqlPatternFromShellPattern:v]; + + sql = [self sqlStringForValue:v attributeNamed:[_q key]]; + [s appendString:sql]; + return s; +} + +- (NSString *)sqlStringForNegatedQualifier:(EOQualifier *)_q { + NSMutableString *s; + NSString *sql; + + sql = [(id)_q sqlStringForSQLExpression:self]; + s = [NSMutableString stringWithCapacity:[sql length] + 8]; + [s appendString:@"NOT ("]; + [s appendString:sql]; + [s appendString:@")"]; + return s; +} + +- (NSString *)sqlStringForConjoinedQualifiers:(NSArray *)_qs { + NSMutableString *s; + unsigned i, count; + id (*objAtIdx)(id,SEL,unsigned); + + objAtIdx = (void *)[_qs methodForSelector:@selector(objectAtIndex:)]; + for (i = 0, count = [_qs count], s = nil; i < count; i++) { + id q; + + q = objAtIdx(self, @selector(objectAtIndex:), i); + + if (s == nil) + s = [NSMutableString stringWithCapacity:128]; + else + [s appendString:@" AND "]; + + [s appendString:[q sqlStringForSQLExpression:self]]; + } + return s; +} + +- (NSString *)sqlStringForDisjoinedQualifiers:(NSArray *)_qs { + NSMutableString *s; + unsigned i, count; + id (*objAtIdx)(id,SEL,unsigned); + + objAtIdx = (void *)[_qs methodForSelector:@selector(objectAtIndex:)]; + for (i = 0, count = [_qs count], s = nil; i < count; i++) { + id q; + + q = objAtIdx(self, @selector(objectAtIndex:), i); + + if (s == nil) + s = [NSMutableString stringWithCapacity:128]; + else + [s appendString:@" OR "]; + + [s appendString:[q sqlStringForSQLExpression:self]]; + } + return s; +} + +/* list strings */ + +- (NSMutableString *)listString { + if (self->listString == nil) + self->listString = [[NSMutableString alloc] initWithCapacity:128]; + return self->listString; +} + +- (void)appendItem:(NSString *)_itemString toListString:(NSMutableString *)_ls { + if ([_ls length] > 0) + [_ls appendString:@","]; + [_ls appendString:_itemString]; +} + +/* deletes */ + +- (void)prepareDeleteExpressionForQualifier:(EOQualifier *)_qual { + NSString *tableList, *sql; + + self->whereClauseString = + [[(id)_qual sqlStringForSQLExpression:self] copy]; + + tableList = [self tableListWithRootEntity:[self entity]]; + + sql = [self assembleDeleteStatementWithQualifier:_qual + tableList:tableList + whereClause:[self whereClauseString]]; + + [self setStatement:sql]; +} + +/* updates */ + +- (void)addUpdateListAttribute:(EOAttribute *)_attr value:(NSString *)_value { + NSMutableString *s; + + s = [[NSMutableString alloc] initWithCapacity:32]; + [s appendString:[_attr columnName]]; + [s appendString:@"="]; + _value = [[self class] formatSQLString:_value format:[_attr writeFormat]]; + [s appendString:_value]; + + [self appendItem:s toListString:[self listString]]; + RELEASE(s); +} + +- (void)prepareUpdateExpressionWithRow:(NSDictionary *)_row + qualifier:(EOQualifier *)_qual +{ + NSEnumerator *keys; + NSString *key; + NSString *tableList, *sql; + + keys = [_row keyEnumerator]; + while ((key = [keys nextObject])) { + EOAttribute *attribute; + id value; + + attribute = [self->entity attributeNamed:key]; + value = [_row objectForKey:key]; + + [self addUpdateListAttribute:attribute value:value]; + } + + self->whereClauseString = + [[(id)_qual sqlStringForSQLExpression:self] copy]; + + tableList = [self tableListWithRootEntity:[self entity]]; + + sql = [self assembleUpdateStatementWithRow:_row + qualifier:_qual + tableList:tableList + updateList:[self listString] + whereClause:[self whereClauseString]]; + + [self setStatement:sql]; +} + +@end /* EOSQLExpression(NewInEOF2) */ diff --git a/sope-gdl1/GDLAccess/EOSQLQualifier.m b/sope-gdl1/GDLAccess/EOSQLQualifier.m new file mode 100644 index 00000000..50425bb1 --- /dev/null +++ b/sope-gdl1/GDLAccess/EOSQLQualifier.m @@ -0,0 +1,592 @@ +/* + EOSQLQualifier.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Helge Hess + Date: September 1996 + November 1999 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#import "common.h" +#import "EOSQLQualifier.h" +#import "EOAdaptor.h" +#import "EOAttribute.h" +#import "EOEntity.h" +#import "EOExpressionArray.h" +#import "EOFExceptions.h" +#import "EORelationship.h" +#import "EOSQLExpression.h" +#include +#include +#import "EOQualifierScanner.h" + +#if LIB_FOUNDATION_LIBRARY +# include +# include +#else +# include "DefaultScannerHandler.h" +# include "PrintfFormatScanner.h" +#endif + +@interface EOQualifierJoinHolder : NSObject +{ + id source; + id destination; +} ++ (id)valueForSource:(id)source destination:(id)destination; +- (NSString*)expressionValueForContext:(EOSQLExpression*)context; +- (id)source; +- (id)destination; +@end + +@implementation EOQualifierJoinHolder + +static Class AttributeClass = Nil; +static EONull *null = nil; + ++ (void)initialize { + AttributeClass = [EOAttribute class]; + null = [[NSNull null] retain]; +} + ++ (id)valueForSource:(id)_source destination:(id)_destination { + EOQualifierJoinHolder *value; + + value = [[[self alloc] init] autorelease]; + value->source = [_source retain]; + value->destination = [_destination retain]; + return value; +} + +- (NSString *)expressionValueForContext:(EOSQLExpression *)context { + NSMutableString *result = nil; + EOAdaptor *adaptor = nil; + NSString *formattedLeft = nil; + NSString *formattedRight = nil; + BOOL checkNull = NO; + + adaptor = [context adaptor]; + + if ([source isKindOfClass:AttributeClass]) { + formattedLeft = [source expressionValueForContext:context]; + } + else { + NSAssert([destination isKindOfClass:AttributeClass], + @"either one of source or destination should be EOAttribute"); + if ([source isEqual:null] || (source == nil)) + checkNull = YES; + + formattedLeft = [adaptor formatValue:source?source:null + forAttribute:destination]; + } + + if ([destination isKindOfClass:AttributeClass]) { + NSString *tmp = formattedLeft; + + formattedLeft = [destination expressionValueForContext:context]; + formattedRight = tmp; + } + else { + NSAssert([source isKindOfClass:AttributeClass], + @"either one of source or destination should be EOAttribute"); + + if ([destination isEqual:null] || (destination == nil)) + checkNull = YES; + + formattedRight = [adaptor formatValue:destination?destination:null + forAttribute:source]; + } + + result = [NSMutableString stringWithCapacity:64]; + [result appendString:formattedLeft]; + [result appendString:checkNull ? @" IS " : @"="]; + [result appendString:formattedRight]; + return result; +} + +- (id)source { + return self->source; +} +- (id)destination { + return self->destination; +} + +@end /* EOQualifierJoinHolder */ + + +@implementation EOSQLQualifier + ++ (EOSQLQualifier*)qualifierForRow:(NSDictionary*)row + entity:(EOEntity*)_entity +{ + EOSQLQualifier *qualifier = nil; + NSEnumerator *enumerator = nil; + NSString *attributeName = nil; + EOAttribute *attribute = nil; + id value = nil; + BOOL first = YES; + + enumerator = [row keyEnumerator]; + qualifier = [[[EOSQLQualifier alloc] init] autorelease]; + + while ((attributeName = [enumerator nextObject])) { + attribute = [_entity attributeNamed:attributeName]; + value = [row objectForKey:attributeName]; + + if ((value == nil) || (attribute == nil)) + /* return nil when is unable to build a qualifier for all keys + in the given row + */ + return nil; + + if (first) + first = NO; + else + [qualifier->content addObject:@" AND "]; + + [qualifier->content addObject: + [EOQualifierJoinHolder valueForSource:attribute destination:value]]; + } + + qualifier->entity = RETAIN(_entity); + [qualifier _computeRelationshipPaths]; + + return qualifier; +} + ++ (EOSQLQualifier*)qualifierForPrimaryKey:(NSDictionary*)dictionary + entity:(EOEntity*)_entity +{ + NSDictionary *pkey = nil; + + pkey = [_entity primaryKeyForRow:dictionary]; + /* return nil when is unable to build a complete qualifier + for all primary key attributes + */ + return pkey ? [self qualifierForRow:pkey entity:_entity] : nil; +} + ++ (EOSQLQualifier*)qualifierForRow:(NSDictionary*)row + relationship:(EORelationship*)relationship +{ + NSArray *componentRelationships = nil; + EOSQLQualifier *qualifier = nil; + NSArray *sourceAttributes = nil; + id tmpRelationship = nil; + EOAttribute *sourceAttribute = nil; + EOAttribute *destinationAttribute = nil; + id value = nil; + int j = 0; + int count2 = 0; + + componentRelationships = [relationship componentRelationships]; + tmpRelationship = relationship; + qualifier = [[[EOSQLQualifier alloc] init] autorelease]; + + /* Make a qualifier string in the following manner. If the relationship is + not flattened we must join using the join operator the values from `row' + and the foreign keys taken from the destination entity of relatioship. + If the relationship is flattend we must append then joins between the + components of relationship. */ + + if (componentRelationships) { + tmpRelationship = [componentRelationships objectAtIndex:0]; + + sourceAttributes = + [NSArray arrayWithObject:[tmpRelationship sourceAttribute]]; + } + else { + sourceAttributes = + [NSArray arrayWithObject:[relationship sourceAttribute]]; + } + + sourceAttribute = [tmpRelationship sourceAttribute]; + value = [row objectForKey:[sourceAttribute name]]; + if (value == nil) + /* Returns nil if `row' does not contain all the values needed to + create a complete qualifier + */ + return nil; + + destinationAttribute = [tmpRelationship destinationAttribute]; + [qualifier->content addObject: + [EOQualifierJoinHolder valueForSource:destinationAttribute + destination:value]]; + + if (componentRelationships) { + EOEntity *tempEntity = [tmpRelationship destinationEntity]; + + /* The relationship is flattened. Iterate over the components and + add joins that `link' the components between them. + */ + count2 = [componentRelationships count]; + for (j = 1; j < count2; j++) { + relationship = [componentRelationships objectAtIndex:j]; + + if ([relationship sourceAttribute]) { + [qualifier->content addObject:@" AND "]; + [qualifier->content addObject: + [EOQualifierJoinHolder valueForSource: + [relationship sourceAttribute] + destination: + [relationship destinationAttribute]]]; + } + } + + /* Here we make a hack because later we need to use this qualifier in + a SELECT expression in which the qualifier's entity should be the + final destination entity of the flattened relationship. In addition + we need in the FROM clause all the entities corresponding to the + components of the relationship to be able to insert the joins + between the values given in row and the final attributes from the + destination entity of the last component of relationship. */ + ASSIGN(qualifier->entity, tempEntity); + [qualifier _computeRelationshipPaths]; + ASSIGN(qualifier->entity, [relationship destinationEntity]); + return qualifier; + } + else { + ASSIGN(qualifier->entity, [relationship destinationEntity]); + return qualifier; + } +} + ++ (EOSQLQualifier *)qualifierForObject:sourceObject + relationship:(EORelationship *)relationship +{ + return [self qualifierForRow: + [sourceObject valueForKey:[[relationship sourceAttribute] name]] + relationship:relationship]; +} + +- (id)init { + NSZone *z = [self zone]; + + RELEASE(self->content); self->content = nil; + RELEASE(self->relationshipPaths); self->relationshipPaths = nil; + RELEASE(self->additionalEntities); self->additionalEntities = nil; + + self->content = [[EOExpressionArray allocWithZone:z] init]; + self->relationshipPaths = [[NSMutableSet allocWithZone:z] init]; + self->additionalEntities = [[NSMutableSet allocWithZone:z] init]; + return self; +} + +- (id)initWithEntity:(EOEntity *)_entity + qualifierFormat:(NSString *)_qualifierFormat + argumentsArray:(NSArray *)_args +{ + PrintfFormatScanner *formatScanner = nil; + EOQualifierEnumScannerHandler *scannerHandler = nil; + NSString *qualifierString = nil; + NSMutableArray *myRelationshipPaths = nil; + NSEnumerator *args = nil; + + myRelationshipPaths = [[NSMutableArray allocWithZone:[self zone]] init]; + + [self init]; + ASSIGN(self->entity, _entity); + + if (_qualifierFormat == nil) + return self; + + formatScanner = [[PrintfFormatScanner alloc] init]; + scannerHandler = [[EOQualifierEnumScannerHandler alloc] init]; + [formatScanner setAllowOnlySpecifier:YES]; + + args = [_args objectEnumerator]; + [scannerHandler setEntity:_entity]; + + [formatScanner setFormatScannerHandler:scannerHandler]; + /* + Note: This is an ugly hack. Arguments is supposed to be a va_args + structure, but an NSArray is passed in. + It works because the value is casted to -parseFormatString:context: + which gives control to the scannerHandler which casts the va_args + back to an array (the EOQualifierEnumScannerHandler does that). + Works on ix86, but *NOT* on iSeries or zServer !! + */ +#if defined(__s390__) + qualifierString = + [formatScanner performSelector:@selector(stringWithFormat:arguments:) + withObject:_qualifierFormat + withObject:args]; +#else + qualifierString = + [formatScanner stringWithFormat:_qualifierFormat + arguments:args]; +#endif + + [formatScanner release]; formatScanner = nil; + [scannerHandler release]; scannerHandler = nil; + + [self->content release]; self->content = nil; + self->content = + [[EOExpressionArray parseExpression:qualifierString + entity:entity + replacePropertyReferences:YES + relationshipPaths:myRelationshipPaths] + retain]; + [self _computeRelationshipPaths:myRelationshipPaths]; + [myRelationshipPaths release]; myRelationshipPaths = nil; + return self; +} + +- (id)initWithEntity:(EOEntity*)_entity + qualifierFormat:(NSString *)qualifierFormat, ... +{ + va_list ap; + id formatScanner = nil; + id scannerHandler = nil; + NSString *qualifierString = nil; + NSMutableArray *myRelationshipPaths = nil; + + if ((self = [self init]) == nil) + return nil; + + myRelationshipPaths = [[NSMutableArray alloc] init]; + ASSIGN(self->entity, _entity); + + if (qualifierFormat == nil) { + return self; + } + + formatScanner = [[PrintfFormatScanner alloc] init]; + scannerHandler = [[EOQualifierScannerHandler alloc] init]; + [formatScanner setAllowOnlySpecifier:YES]; + + va_start(ap, qualifierFormat); + [scannerHandler setEntity:_entity]; + [formatScanner setFormatScannerHandler:scannerHandler]; + qualifierString = [formatScanner stringWithFormat:qualifierFormat + arguments:ap]; + va_end(ap); + + [formatScanner release]; + [scannerHandler release]; + + [self->content release]; self->content = nil; + self->content = + [[EOExpressionArray parseExpression:qualifierString + entity:entity + replacePropertyReferences:YES + relationshipPaths:myRelationshipPaths] retain]; + [self _computeRelationshipPaths:myRelationshipPaths]; + [myRelationshipPaths release]; myRelationshipPaths = nil; + return self; +} + +- (void)_computeRelationshipPaths { + [self _computeRelationshipPaths:nil]; +} + +static void +handle_attribute(EOSQLQualifier *self, id object, id _relationshipPaths) +{ + if ([object isFlattened]) { + id definitionArray = nil; + id relsArray = nil; + NSRange range; + + definitionArray = [object definitionArray]; + range = NSMakeRange(0, [definitionArray count] - 1); + relsArray = [definitionArray subarrayWithRange:range]; + + [self->relationshipPaths addObject:relsArray]; + [self->additionalEntities addObjectsFromArray:relsArray]; + } + else { + [self->additionalEntities addObject:[object entity]]; + } +} + +- (void)_computeRelationshipPaths:(NSArray *)_relationshipPaths { + int i, count; + + [relationshipPaths removeAllObjects]; + + if (_relationshipPaths) { + NSEnumerator *pathEnum = [_relationshipPaths objectEnumerator]; + NSArray *relPath = nil; + + while ((relPath = [pathEnum nextObject])) { + NSEnumerator *relEnum = nil; + EORelationship *rel = nil; + + relEnum = [relPath objectEnumerator]; + + while ((rel = [relEnum nextObject])) { + [additionalEntities addObject:[rel destinationEntity]]; + } + } + [relationshipPaths addObjectsFromArray:_relationshipPaths]; + } + for (i = 0, count = [content count]; i < count; i++) { + id object = [content objectAtIndex:i]; + + /* The objects from content can only be NSString, values or + EOAttribute. */ + if ([object isKindOfClass:[EOAttribute class]]) { + handle_attribute (self, object, _relationshipPaths); + } + else if ([object isKindOfClass:[EOQualifierJoinHolder class]]) { + id source = nil; + id destination = nil; + + source = [object source]; + destination = [object destination]; + + if ([source isKindOfClass:[EOAttribute class]]) + handle_attribute (self, source, _relationshipPaths); + if ([destination isKindOfClass:[EOAttribute class]]) + handle_attribute (self, destination, _relationshipPaths); + } + else if ([object isKindOfClass:[EORelationship class]]) { + [[[InvalidPropertyException alloc] + initWithFormat:@"cannot refer a EORelat" + @"ionship in a EOSQLQualifier: '%@'", + [(EORelationship*)object name]] raise]; + } + } +} + +- (void)dealloc { + RELEASE(self->relationshipPaths); + RELEASE(self->additionalEntities); + + RELEASE(self->entity); + RELEASE(self->content); + [super dealloc]; +} + +- (id)copy { + return [self copyWithZone:NSDefaultMallocZone()]; +} + +- (id)copyWithZone:(NSZone*)zone { + EOSQLQualifier* copy = nil; + + copy = [[self->isa allocWithZone:zone] init]; + copy->entity = RETAIN(self->entity); + copy->content = [self->content mutableCopyWithZone:zone]; + copy->relationshipPaths = [self->relationshipPaths mutableCopyWithZone:zone]; + copy->usesDistinct = self->usesDistinct; + return copy; +} + +- (void)negate { + [self->content insertObject:@"NOT (" atIndex:0]; + [self->content addObject:@")"]; +} + +- (void)conjoinWithQualifier:(EOSQLQualifier*)qualifier { + if (![qualifier isKindOfClass:[EOSQLQualifier class]]) { + [NSException raise:NSInvalidArgumentException + format:@"argument of conjoinWithQualifier: method must " + @"be EOSQLQualifier"]; + } + + if (self->entity != qualifier->entity) { + [NSException raise:NSInvalidArgumentException + format:@"qualifier argument of conjoinWithQualifier: " + @"must have the same entity as receiver"]; + } + + [self->content insertObject:@"(" atIndex:0]; + [self->content addObject:@") AND ("]; + [self->content addObjectsFromExpressionArray:qualifier->content]; + [self->content addObject:@")"]; + [self->relationshipPaths unionSet:qualifier->relationshipPaths]; +} + +- (void)disjoinWithQualifier:(EOSQLQualifier*)qualifier { + if (![qualifier isKindOfClass:[EOSQLQualifier class]]) { + [NSException raise:NSInvalidArgumentException + format:@"argument of disjoinWithQualifier: method must " + @"be EOSQLQualifier"]; + } + + if (self->entity != qualifier->entity) { + [NSException raise:NSInvalidArgumentException + format:@"qualifier argument of disjoinWithQualifier: " + @"must have the same entity as receiver"]; + } + + [self->content insertObject:@"(" atIndex:0]; + [self->content addObject:@") OR ("]; + [self->content addObjectsFromExpressionArray:qualifier->content]; + [self->content addObject:@")"]; + [self->relationshipPaths unionSet:qualifier->relationshipPaths]; +} + +- (EOEntity*)entity { + return self->entity; +} +- (BOOL)isEmpty { + return (self->entity == nil) ? YES : NO; +} +- (void)setUsesDistinct:(BOOL)flag { + self->usesDistinct = flag; +} +- (BOOL)usesDistinct { + return self->usesDistinct; +} +- (NSMutableSet*)relationshipPaths { + return self->relationshipPaths; +} +- (NSMutableSet*)additionalEntities { + return self->additionalEntities; +} + +- (NSString*)expressionValueForContext:(id)ctx { + return [self->content expressionValueForContext:ctx]; +} + +- (EOSQLQualifier *)sqlQualifierForEntity:(EOEntity *)_entity { + NSAssert3(self->entity == _entity, + @"passed invalid entity to %@ (contains %@, got %@)", + self, self->entity, _entity); + return (EOSQLQualifier *)self; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]:\n", self, NSStringFromClass([self class])]; + + [ms appendFormat:@" entity=%@", [self->entity name]]; + + if (self->content) + [ms appendFormat:@" content=%@", self->content]; + + if (self->usesDistinct) + [ms appendString:@" distinct"]; + + [ms appendString:@">"]; + return ms; +} + +@end /* EOSQLQualifier */ diff --git a/sope-gdl1/GDLAccess/EOSelectSQLExpression.m b/sope-gdl1/GDLAccess/EOSelectSQLExpression.m new file mode 100644 index 00000000..2c750a3d --- /dev/null +++ b/sope-gdl1/GDLAccess/EOSelectSQLExpression.m @@ -0,0 +1,147 @@ +/* + EOSQLExpression.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: September 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "EOSQLExpression.h" +#include "EOAttribute.h" +#include "EOAdaptor.h" +#include "common.h" + +#if LIB_FOUNDATION_LIBRARY +# include +# include +#else +# include "DefaultScannerHandler.h" +# include "PrintfFormatScanner.h" +#endif + +@interface EOSelectScannerHandler : DefaultScannerHandler +{ + EOAttribute *attribute; + EOAdaptor *adaptor; + NSString *alias; +} + +- (void)setAttribute:(EOAttribute*)attribute + adaptor:(EOAdaptor*)adaptor + alias:(NSString*)alias; + +@end + +@implementation EOSelectSQLExpression + +- (NSString *)expressionValueForAttribute:(EOAttribute *)attribute + context:(id)context +{ + NSString *alias; + NSString *columnName; + NSString *selectFormat; + + alias = [entitiesAndPropertiesAliases objectForKey:context]; + selectFormat = [attribute selectFormat]; + + //NSLog(@"entitiesAndPropertiesAliases: %@", entitiesAndPropertiesAliases); + + if (selectFormat) { + PrintfFormatScanner *formatScanner; + EOSelectScannerHandler *scannerHandler; + + formatScanner = + [[[[PrintfFormatScanner alloc] init] setAllowOnlySpecifier:YES] + autorelease]; + scannerHandler = + [[[EOSelectScannerHandler alloc] init] autorelease]; + + [scannerHandler setAttribute:attribute adaptor:adaptor alias:alias]; + [formatScanner setFormatScannerHandler:scannerHandler]; +#if defined(__s390__) + return [formatScanner performSelector: + @selector(stringWithFormat:arguments:) + withObject:selectFormat + withObject:nil]; +#else + return [formatScanner stringWithFormat:selectFormat arguments:NULL]; +#endif + } + else { + columnName = adaptor + ? [adaptor formatAttribute:attribute] + : [attribute columnName]; + + if (alias) { + return [([[NSString alloc] initWithFormat:@"%@.%@", + alias, columnName]) autorelease]; + } + + return columnName; + } +} + +@end /* EOSelectSQLExpression */ + +@implementation EOSelectScannerHandler + +- (id)init +{ + [super init]; + + specHandler['A'] + = [self methodForSelector:@selector(convertAttribute:scanner:)]; + return self; +} + +- (void)dealloc +{ + RELEASE(self->attribute); + RELEASE(self->adaptor); + RELEASE(self->alias); + [super dealloc]; +} + +- (void)setAttribute:(EOAttribute*)_attribute + adaptor:(EOAdaptor*)_adaptor + alias:(NSString*)_alias +{ + ASSIGN(self->attribute, _attribute); + ASSIGN(self->adaptor, _adaptor); + ASSIGN(self->alias, _alias); +} + +- (NSString *)convertAttribute:(va_list *)pString + scanner:(FormatScanner *)scanner +{ + NSString *columnName; + + columnName = (adaptor) + ? [adaptor formatAttribute:self->attribute] + : [self->attribute columnName]; + + if (alias) + return [NSString stringWithFormat:@"%@.%@", alias, columnName]; + + return columnName; +} + +@end /* EOSelectScannerHandler */ diff --git a/sope-gdl1/GDLAccess/English.lproj/InfoPlist.strings b/sope-gdl1/GDLAccess/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..38e0c36d Binary files /dev/null and b/sope-gdl1/GDLAccess/English.lproj/InfoPlist.strings differ diff --git a/sope-gdl1/GDLAccess/FoundationExt/COPYING b/sope-gdl1/GDLAccess/FoundationExt/COPYING new file mode 100644 index 00000000..ea951871 --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/COPYING @@ -0,0 +1,18 @@ + +Copyright (C) 1995, 1996, 1997, 1998 Ovidiu Predescu and Mircea Oancea. +All rights reserved. + +Permission to use, copy, modify, and distribute this software and its +documentation for ANY purpose and without fee is hereby granted, provided +that the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. This software may be included in any commercial product +provided that its distribution contain the libFoundation copyright notice +and this permission notice. + +We disclaim all warranties with regard to this software, including all +implied warranties of merchantability and fitness, in no event shall +we be liable for any special, indirect or consequential damages or any +damages whatsoever resulting from loss of use, data or profits, whether in +an action of contract, negligence or other tortious action, arising out of +or in connection with the use or performance of this software. diff --git a/sope-gdl1/GDLAccess/FoundationExt/COPYRIGHT b/sope-gdl1/GDLAccess/FoundationExt/COPYRIGHT new file mode 100644 index 00000000..60438d54 --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/COPYRIGHT @@ -0,0 +1,5 @@ + Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. + All rights reserved. + + Author: Ovidiu Predescu + Helge Hess diff --git a/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.h b/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.h new file mode 100644 index 00000000..a6346689 --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.h @@ -0,0 +1,62 @@ +/* + DefaultScannerHandler.h + + Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. + All rights reserved. + + Author: Ovidiu Predescu + + This file is part of libFoundation. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + We disclaim all warranties with regard to this software, including all + implied warranties of merchantability and fitness, in no event shall + we be liable for any special, indirect or consequential damages or any + damages whatsoever resulting from loss of use, data or profits, whether in + an action of contract, negligence or other tortious action, arising out of + or in connection with the use or performance of this software. +*/ + +#ifndef __DefaultScannerHandler_h__ +#define __DefaultScannerHandler_h__ + +#include + +@class NSString; +@class FormatScanner; + +@interface DefaultScannerHandler : NSObject +{ + IMP specHandler[256]; +} + +- (NSString *)stringForArgument:(void *)arg scanner:(id)aFormatScanner; +- (NSString *)unknownSpecifier:(void *)arg scanner:(id)scanner; + +@end + +@class NSEnumerator; + +@interface DefaultEnumScannerHandler : NSObject +{ + IMP specHandler[256]; +} + +- (NSString *)stringForArgument:(void *)arg scanner:(id)aFormatScanner; +- (NSString *)unknownSpecifier:(void *)arg scanner:(id)scanner; + +@end + +#endif /* __DefaultScannerHandler_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.m b/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.m new file mode 100644 index 00000000..dad679f2 --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.m @@ -0,0 +1,90 @@ +/* + DefaultScannerHandler.m + + Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. + All rights reserved. + + Author: Ovidiu Predescu + Helge Hess + + This file is part of libFoundation. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + We disclaim all warranties with regard to this software, including all + implied warranties of merchantability and fitness, in no event shall + we be liable for any special, indirect or consequential damages or any + damages whatsoever resulting from loss of use, data or profits, whether in + an action of contract, negligence or other tortious action, arising out of + or in connection with the use or performance of this software. +*/ + +#import +#include "FormatScanner.h" +#include "DefaultScannerHandler.h" + +@implementation DefaultScannerHandler + +- (id)init { + int i; + IMP unknownSpecifierIMP + = [self methodForSelector:@selector(unknownSpecifier:scanner:)]; + + for(i = 0; i < 256; i++) + specHandler[i] = unknownSpecifierIMP; + return self; +} + +- (NSString *)unknownSpecifier:(void *)arg scanner:scanner +{ + char str[] = { [scanner characterSpecifier], 0 }; + return [NSString stringWithCString:str]; +} + +- (NSString *)stringForArgument:(void *)arg scanner:scanner +{ + return (*specHandler[(int)[scanner characterSpecifier]]) + (self, _cmd, arg, scanner); +} + +@end /* DefaultScannerHandler */ + +@implementation DefaultEnumScannerHandler + +- (id)init +{ + int i; + IMP unknownSpecifierIMP; + + unknownSpecifierIMP = + [self methodForSelector:@selector(unknownSpecifier:scanner:)]; + + for(i = 0; i < 256; i++) + self->specHandler[i] = unknownSpecifierIMP; + return self; +} + +- (NSString *)unknownSpecifier:(void *)arg scanner:scanner +{ + char str[] = { [scanner characterSpecifier], 0 }; + return [NSString stringWithCString:str]; +} + +- (NSString *)stringForArgument:(void *)arg scanner:scanner +{ + return (*specHandler[(int)[scanner characterSpecifier]]) + (self, _cmd, arg, scanner); +} + +@end /* DefaultEnumScannerHandler */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/FoundationExt/FormatScanner.h b/sope-gdl1/GDLAccess/FoundationExt/FormatScanner.h new file mode 100644 index 00000000..efa75edf --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/FormatScanner.h @@ -0,0 +1,127 @@ +/* + FormatScanner.h + + Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. + All rights reserved. + + Author: Ovidiu Predescu + + This file is part of libFoundation. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + We disclaim all warranties with regard to this software, including all + implied warranties of merchantability and fitness, in no event shall + we be liable for any special, indirect or consequential damages or any + damages whatsoever resulting from loss of use, data or profits, whether in + an action of contract, negligence or other tortious action, arising out of + or in connection with the use or performance of this software. +*/ + +#ifndef __FormatScanner_h__ +#define __FormatScanner_h__ + +#include +#include + +@class NSString; + +/* + * A FormatScanner scans a NSString format. When it reaches a specifier + * similar to printf(3S), it calls a handler object previously registered to + * it. The handler object is usually inherited from the DefaultScannerHandler + * class. The handler object maintains a mapping between format characters and + * selectors that have to be called when a specifier is found in the format + * string. The selector must have exactly two arguments: the first one is a + * pointer to a va_list and the second one is the format scanner. It is the + * responsability of handler to increase the pointer to the va_list with the + * size of the object it handles. During the execution of the method the + * scanner calls, the handler can ask the scanner about the flags, width, + * precision, modifiers and the specifier character. The method should return a + * NSString object that represents the converted object. + * + * FormatScanner is an abstract class. Use the PrintfFormatScanner class that + * is used to write printf-like functions. Additional classes can be inherited + * to write scanf-like functions. + */ + +typedef enum { + FS_ALTERNATE_FORM = 1, + FS_ZERO = 2, + FS_MINUS_SIGN = 4, + FS_PLUS_SIGN = 8, + FS_BLANK = 16 +} FormatScannerFlags; + +@interface FormatScanner : NSObject +{ + int specifierLen, specifierSize; + char *currentSpecifier; + id handler; + unsigned flags; + int width; + int precision; + char modifier; + char characterSpecifier; + BOOL allowFlags:1; + BOOL allowWidth:1; + BOOL allowPeriod:1; + BOOL allowPrecision:1; + BOOL allowModifier:1; +} + +/* This method start the searching of specifiers in `format'. `context' is + passed in handleFormatSpecifierWithContext: unmodified. */ +- (BOOL)parseFormatString:(NSString*)format context:(void*)context; + +/* This method is called whenever a string between two specifiers is found. + Rewrite it in subclasses to perform whatever action you want (for example + to collect them in a result string if you're doing printf). The method + should return NO if the scanning of format should stop. */ +- (BOOL)handleOrdinaryString:(NSString*)string; + +/* This method is called whenever a format specifier is found in `format'. + Again, rewrite this method in subclasses to perform whatever action you + want. The method should return NO if the scanning of the format should stop. +*/ +- (BOOL)handleFormatSpecifierWithContext:(void*)context; + +- (void)setFormatScannerHandler:(id)anObject; +- (id)formatScannerHandler; + +- (unsigned int)flags; +- (int)width; +- (int)precision; +- (char)modifier; +- (char)characterSpecifier; +- (const char*)currentSpecifier; + +- (id)setAllowFlags:(BOOL)flag; +- (id)setAllowWidth:(BOOL)flag; +- (id)setAllowPeriod:(BOOL)flag; +- (id)setAllowPrecision:(BOOL)flag; +- (id)setAllowModifier:(BOOL)flag; + +/* A shorthand for sending all -setAllow* messages with !flag as argument */ +- (id)setAllowOnlySpecifier:(BOOL)flag; + +- (BOOL)allowFlags; +- (BOOL)allowWidth; +- (BOOL)allowPeriod; +- (BOOL)allowPrecision; +- (BOOL)allowModifier; + +@end + +#endif /* __FormatScanner_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/FoundationExt/FormatScanner.m b/sope-gdl1/GDLAccess/FoundationExt/FormatScanner.m new file mode 100644 index 00000000..5f2026e4 --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/FormatScanner.m @@ -0,0 +1,341 @@ +/* + FormatScanner.m + + Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. + All rights reserved. + + Author: Ovidiu Predescu + + This file is part of libFoundation. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + We disclaim all warranties with regard to this software, including all + implied warranties of merchantability and fitness, in no event shall + we be liable for any special, indirect or consequential damages or any + damages whatsoever resulting from loss of use, data or profits, whether in + an action of contract, negligence or other tortious action, arising out of + or in connection with the use or performance of this software. +*/ + +#include + +#include "common.h" + +#import +#import +#import +#import + +//#include +#include "FormatScanner.h" + +@implementation FormatScanner + +enum { SPECIFIER_SIZE = 1000 }; /* This value should be sufficient */ + +- (id)init { + specifierSize = SPECIFIER_SIZE; + currentSpecifier = MallocAtomic(specifierSize); + allowFlags = YES; + allowWidth = YES; + allowPeriod = YES; + allowPrecision = YES; + allowModifier = YES; + return self; +} + +- (void)dealloc { + if (self->currentSpecifier) free(currentSpecifier); + RELEASE(self->handler); + [super dealloc]; +} + +- (void)setFormatScannerHandler:(id)anObject { + ASSIGN(self->handler, anObject); +} + +- (id)setAllowOnlySpecifier:(BOOL)flag { + allowFlags = !flag; + allowWidth = !flag; + allowPeriod = !flag; + allowPrecision = !flag; + allowModifier = !flag; + return self; +} + +- (id)setAllowFlags:(BOOL)flag { + allowFlags = flag; + return self; +} +- (BOOL)allowFlags { + return allowFlags; +} + +- (id)setAllowWidth:(BOOL)flag { + allowWidth = flag; + return self; +} +- (BOOL)allowWidth { + return allowWidth; +} + +- (id)setAllowPeriod:(BOOL)flag { + allowPeriod = flag; + return self; +} +- (BOOL)allowPeriod { + return allowPeriod; +} + +- (id)setAllowPrecision:(BOOL)flag { + allowPrecision = flag; + return self; +} +- (BOOL)allowPrecision { + return allowPrecision; +} + +- (id)setAllowModifier:(BOOL)flag { + allowModifier = flag; + return self; +} +- (BOOL)allowModifier { + return allowModifier; +} + +- (id)formatScannerHandler { + return handler; +} + +- (unsigned int)flags { + return self->flags; +} +- (int)width { + return self->width; +} +- (int)precision { + return self->precision; +} +- (char)modifier { + return self->modifier; +} +- (char)characterSpecifier { + return self->characterSpecifier; +} +- (const char *)currentSpecifier { + return self->currentSpecifier; +} + +#define CHECK_END \ + if(i >= length) { \ + /* An unterminated specifier. Break the loop. */ \ + [self handleOrdinaryString: \ + [NSString stringWithCString:currentSpecifier]]; \ + goto _return; \ + } + +/* Scans the format string looking after specifiers. Doesn't handle '*' as a + valid width or precision. */ +- (BOOL)parseFormatString:(NSString*)format context:(void *)context { + NSRange searchRange, foundRange; + int i, length; + unichar ch; + NSCharacterSet *decimals; + + i = 0; + length = [format length]; + decimals = [NSCharacterSet decimalDigitCharacterSet]; + + *currentSpecifier = 0; + specifierLen = 0; + + while (i < length) { + searchRange.location = i; + searchRange.length = length - i; + + foundRange = [format rangeOfString:@"%" options:0 range:searchRange]; + if (foundRange.length == 0) + foundRange.location = length; + searchRange.length = foundRange.location - searchRange.location; + + if (searchRange.length) { + if (![self handleOrdinaryString: + [format substringWithRange:searchRange]]) + return NO; + } + + i = foundRange.location; + CHECK_END + + i++; + strcpy(currentSpecifier, "%"); + specifierLen = 1; + CHECK_END + + flags = width = precision = modifier = characterSpecifier = 0; + + /* Check for flags. */ + if (self->allowFlags) { + for (; i < length; i++) { + ch = [format characterAtIndex:i]; + switch(ch) { + case '#': strcat(currentSpecifier, "#"); + flags |= FS_ALTERNATE_FORM; + break; + case '0': strcat(currentSpecifier, "0"); + flags |= FS_ZERO; + break; + case '-': strcat(currentSpecifier, "-"); + flags |= FS_MINUS_SIGN; + break; + case '+': strcat(currentSpecifier, "+"); + flags |= FS_PLUS_SIGN; + break; + case ' ': strcat(currentSpecifier, " "); + flags |= FS_BLANK; + break; + default: goto quit; + } + if (++specifierLen == specifierSize) { + currentSpecifier = + Realloc(currentSpecifier, + specifierSize += SPECIFIER_SIZE); + } + } + quit: + CHECK_END + } + + /* Check for width. */ + if (self->allowWidth) { + for(; i < length; i++) { + char str[2] = { 0, 0 }; + + ch = [format characterAtIndex:i]; + if (![decimals characterIsMember:ch]) + break; + str[0] = ch; + + strcat(currentSpecifier, str); + if(++specifierLen == specifierSize) { + currentSpecifier = + Realloc(currentSpecifier, + specifierSize += SPECIFIER_SIZE); + } + + width = 10 * width + (ch - '0'); + } + CHECK_END + } + + /* Check for period. */ + if (self->allowPeriod) { + ch = [format characterAtIndex:i]; + if(ch == '.') { + char str[2] = { ch, 0 }; + + strcat(currentSpecifier, str); + if(++specifierLen == specifierSize) { + currentSpecifier = + Realloc(currentSpecifier, + specifierSize += SPECIFIER_SIZE); + } + + i++; + CHECK_END + } + } + + /* Check for precision. */ + if (self->allowPrecision) { + for(; i < length; i++) { + char str[2] = { 0, 0 }; + + ch = [format characterAtIndex:i]; + if (![decimals characterIsMember:ch]) + break; + str[0] = ch; + + strcat(currentSpecifier, str); + if(++specifierLen == specifierSize) { + currentSpecifier = + Realloc(currentSpecifier, + specifierSize += SPECIFIER_SIZE); + } + precision = 10 * precision + (ch - '0'); + } + CHECK_END + } + + /* Check for data-width modifier. */ + if (allowModifier) { + ch = [format characterAtIndex:i]; + if (ch == 'h' || ch == 'l') { + char str[2] = { ch, 0 }; + + strcat(currentSpecifier, str); + if (++specifierLen == specifierSize) { + currentSpecifier = + Realloc(currentSpecifier, + specifierSize += SPECIFIER_SIZE); + } + + modifier = ch; + i++; + CHECK_END + } + } + + /* Finally, the conversion character. */ + { + char str[2] = { 0, 0 }; + ch = [format characterAtIndex:i]; + str[0] = ch; + + strcat(currentSpecifier, str); + if(++specifierLen == specifierSize) { + currentSpecifier = + Realloc(currentSpecifier, + specifierSize += SPECIFIER_SIZE); + } + + characterSpecifier = ch; + } + + if (![self handleFormatSpecifierWithContext:context]) + return NO; + + i++; + *currentSpecifier = 0; + specifierLen = 0; + + CHECK_END + } + +_return: + return YES; +} + +- (BOOL)handleOrdinaryString:(NSString*)string +{ + return YES; +} + +- (BOOL)handleFormatSpecifierWithContext:(void*)context +{ + return YES; +} + +@end /* FormatScanner */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/FoundationExt/GNUmakefile b/sope-gdl1/GDLAccess/FoundationExt/GNUmakefile new file mode 100644 index 00000000..ca095b53 --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/GNUmakefile @@ -0,0 +1,14 @@ +# $Id: GNUmakefile 1 2004-08-20 10:38:46Z znek $ + +include $(GNUSTEP_MAKEFILES)/common.make + +SUBPROJECT_NAME = FoundationExt + +FoundationExt_OBJC_FILES = \ + DefaultScannerHandler.m \ + PrintfFormatScanner.m \ + FormatScanner.m \ + +ADDITIONAL_INCLUDE_DIRS += -I. -I.. + +include $(GNUSTEP_MAKEFILES)/subproject.make diff --git a/sope-gdl1/GDLAccess/FoundationExt/LICENSE b/sope-gdl1/GDLAccess/FoundationExt/LICENSE new file mode 100644 index 00000000..dcdb6dad --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/LICENSE @@ -0,0 +1,12 @@ + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + We disclaim all warranties with regard to this software, including all + implied warranties of merchantability and fitness, in no event shall + we be liable for any special, indirect or consequential damages or any + damages whatsoever resulting from loss of use, data or profits, whether in + an action of contract, negligence or other tortious action, arising out of + or in connection with the use or performance of this software. diff --git a/sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.h b/sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.h new file mode 100644 index 00000000..cc373f26 --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.h @@ -0,0 +1,52 @@ +/* + PrintfFormatScanner.h + + Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. + All rights reserved. + + Author: Ovidiu Predescu + + This file is part of libFoundation. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + We disclaim all warranties with regard to this software, including all + implied warranties of merchantability and fitness, in no event shall + we be liable for any special, indirect or consequential damages or any + damages whatsoever resulting from loss of use, data or profits, whether in + an action of contract, negligence or other tortious action, arising out of + or in connection with the use or performance of this software. +*/ + +#ifndef __PrintfFormatScanner_h__ +#define __PrintfFormatScanner_h__ + +#if XCODE_SELF_COMPILE +# include "FormatScanner.h" +#else +# include +#endif + +@class NSMutableString; + +@interface PrintfFormatScanner : FormatScanner +{ + NSMutableString *result; +} + +- (NSString *)stringWithFormat:(NSString *)format arguments:(va_list)args; + +@end + +#endif /* __PrintfFormatScanner_h__ */ + +/* + Local Variables: + c-basic-offset: 4 + tab-width: 8 + End: +*/ diff --git a/sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.m b/sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.m new file mode 100644 index 00000000..fe7c7e8d --- /dev/null +++ b/sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.m @@ -0,0 +1,55 @@ +/* + PrintfFormatScanner.m + + Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea. + All rights reserved. + + Author: Ovidiu Predescu + + This file is part of libFoundation. + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + We disclaim all warranties with regard to this software, including all + implied warranties of merchantability and fitness, in no event shall + we be liable for any special, indirect or consequential damages or any + damages whatsoever resulting from loss of use, data or profits, whether in + an action of contract, negligence or other tortious action, arising out of + or in connection with the use or performance of this software. +*/ + +#import +#include "PrintfFormatScanner.h" +#include "DefaultScannerHandler.h" + +@implementation PrintfFormatScanner + +- (NSString *)stringWithFormat:(NSString *)format arguments:(va_list)args { + va_list va; + +#ifdef __va_copy + __va_copy(va, args); +#else + va = args; +#endif + + self->result = [NSMutableString stringWithCapacity:[format cStringLength]]; + [self parseFormatString:format context:&va]; + return [[self->result copy] autorelease]; +} + +- (BOOL)handleOrdinaryString:(NSString *)string { + [self->result appendString:string]; + return YES; +} + +- (BOOL)handleFormatSpecifierWithContext:(void *)context { + [self->result appendString:[handler stringForArgument:context scanner:self]]; + return YES; +} + +@end /* PrintfFormatScanner */ diff --git a/sope-gdl1/GDLAccess/GDLAccess-Info.plist b/sope-gdl1/GDLAccess/GDLAccess-Info.plist new file mode 100644 index 00000000..84843553 --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLAccess-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + GDLAccess + CFBundleGetInfoString + + CFBundleIdentifier + org.opengroupware.gnustep-db + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleShortVersionString + + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/sope-gdl1/GDLAccess/GDLExtensions/ChangeLog b/sope-gdl1/GDLAccess/GDLExtensions/ChangeLog new file mode 100644 index 00000000..05bae17b --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/ChangeLog @@ -0,0 +1,44 @@ +2004-06-28 Helge Hess + + * GNUmakefile.preamble: fixed link pathes (v4.2.28) + +2002-08-15 Helge Hess + + * GNUmakefile: fixed Version imports (now v4.2.3) + +Mon Apr 2 22:02:05 2001 Helge Hess + + * GDLExtensions.m: fixed linking problem + +Tue Feb 29 19:06:44 2000 Helge Hess + + * MOF3 import + +Mon Apr 26 14:00:01 1999 Helge Hess + + * added kit class GDLExtensions + + * use #include instead of #import + +Mon Dec 21 19:02:16 1998 Helge Hess + + * NSObject+EONullInit.m: added -stringValue to EONull + +Mon Dec 21 16:19:18 1998 Helge Hess + + * EOGenericRecord+KeyValueCoding2.m: updated for new EOGenericRecord + classes (which uses NSMapTable instead of a dictionary). + +Fri Dec 11 16:48:10 1998 Helge Hess + + * NSObject+EONullInit.m: added method '-isNull' to EONull, NSObject + +Fri Nov 27 19:55:21 1998 Helge Hess + + * added PB.project + +Fri Nov 27 19:55:12 1998 Helge Hess + + * created ChangeLog + + diff --git a/sope-gdl1/GDLAccess/GDLExtensions/EOEntity+Factory.h b/sope-gdl1/GDLAccess/GDLExtensions/EOEntity+Factory.h new file mode 100644 index 00000000..193faa6b --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/EOEntity+Factory.h @@ -0,0 +1,8 @@ +// $Id: EOEntity+Factory.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __GDLExtensions_EOEntity_Factory_P_H__ +#define __GDLExtensions_EOEntity_Factory_P_H__ + +#include + +#endif /* __GDLExtensions_EOEntity_Factory_H__ */ diff --git a/sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.h b/sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.h new file mode 100644 index 00000000..63eb7aa3 --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.h @@ -0,0 +1,21 @@ +// $Id: GDLExtensions.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __GDLExtensions_H__ +#define __GDLExtensions_H__ + +#if NeXT_Foundation_LIBRARY || COCOA_Foundation_LIBRARY +# include +# include +#else +# include +# include +#endif + +// kit class + +@interface GDLExtensions : NSObject +@end + +#define LINK_GDLExtensions + +#endif /* __GDLExtensions_H__ */ diff --git a/sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.m b/sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.m new file mode 100644 index 00000000..c40ff42a --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.m @@ -0,0 +1,13 @@ +// $Id: GDLExtensions.m 1 2004-08-20 10:38:46Z znek $ + +#include "GDLExtensions.h" + +@implementation GDLExtensions + +- (void)_staticLinkClasses { +} + +- (void)_staticLinkModules { +} + +@end diff --git a/sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile b/sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile new file mode 100644 index 00000000..c025379e --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile @@ -0,0 +1,25 @@ +# $Id: GNUmakefile 1 2004-08-20 10:38:46Z znek $ + +SKYROOT=../.. + +include $(GNUSTEP_MAKEFILES)/common.make +include $(SKYROOT)/Version +-include ../Version +-include ./Version + +LIBRARY_NAME = libGDLExtensions + +libGDLExtensions_HEADER_FILES = \ + GDLExtensions.h \ + EOEntity+Factory.h \ + NSObject+EONullInit.h \ + +libGDLExtensions_OBJC_FILES = GDLExtensions.m + +libGDLExtensions_HEADER_FILES_DIR = . +libGDLExtensions_HEADER_FILES_INSTALL_DIR = /GDLExtensions +libGDLExtensions_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) + +-include GNUmakefile.preamble +include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/library.make +-include GNUmakefile.postamble diff --git a/sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile.preamble b/sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile.preamble new file mode 100644 index 00000000..e1f75432 --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile.preamble @@ -0,0 +1,16 @@ +# $Id: GNUmakefile.preamble 1 2004-08-20 10:38:46Z znek $ + +libGDLExtensions_INCLUDE_DIRS += \ + -I.. -I../GDLAccess -I../.. + +ADDITIONAL_LIB_DIRS += \ + -L../$(GNUSTEP_OBJ_DIR) \ + -L../../../../SOPE/skyrix-core/EOControl/$(GNUSTEP_OBJ_DIR) + +libGDLExtensions_LIBRARIES_DEPEND_UPON += \ + -lGDLAccess \ + -lEOControl + +ifeq ($(GNUSTEP_TARGET_OS),mingw32) +libGDLExtensions_LIBRARIES_DEPEND_UPON += -lobjc +endif diff --git a/sope-gdl1/GDLAccess/GDLExtensions/NSObject+EONullInit.h b/sope-gdl1/GDLAccess/GDLExtensions/NSObject+EONullInit.h new file mode 100644 index 00000000..894e6bec --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/NSObject+EONullInit.h @@ -0,0 +1,8 @@ +// $Id: NSObject+EONullInit.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __GDLExtensions_NSObject_EONull_P_H__ +#define __GDLExtensions_NSObject_EONull_P_H__ + +#include + +#endif /* __GDLExtensions_NSObject_EONull_H__ */ diff --git a/sope-gdl1/GDLAccess/GDLExtensions/common.h b/sope-gdl1/GDLAccess/GDLExtensions/common.h new file mode 100644 index 00000000..0938f70e --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/common.h @@ -0,0 +1,10 @@ +// $Id: common.h 1 2004-08-20 10:38:46Z znek $ + +// common include files + +#import +#import + +#if NeXT_Foundation_LIBRARY +# import +#endif diff --git a/sope-gdl1/GDLAccess/GDLExtensions/libGDLExtensions.def b/sope-gdl1/GDLAccess/GDLExtensions/libGDLExtensions.def new file mode 100644 index 00000000..875da0a3 --- /dev/null +++ b/sope-gdl1/GDLAccess/GDLExtensions/libGDLExtensions.def @@ -0,0 +1,2 @@ +EXPORTS + __objc_class_name_GDLExtensions; diff --git a/sope-gdl1/GDLAccess/GNUmakefile b/sope-gdl1/GDLAccess/GNUmakefile new file mode 100644 index 00000000..63633199 --- /dev/null +++ b/sope-gdl1/GDLAccess/GNUmakefile @@ -0,0 +1,130 @@ +# $Id: GNUmakefile 1 2004-08-20 10:38:46Z znek $ + +include ../common.make +-include ./Version + +GNUSTEP_INSTALLATION_DIR = ${GNUSTEP_LOCAL_ROOT} + +LIBRARY_NAME = libGDLAccess +libGDLAccess_SOVERSION=$(MAJOR_VERSION).$(MINOR_VERSION) + +libGDLAccess_DLL_DEF = libGDLAccess.def + +libGDLAccess_HEADER_FILES = \ + GDLAccess.h \ + EOAccess.h \ + EODelegateResponse.h \ + EOJoinTypes.h \ + EOAdaptor.h \ + EOAdaptorChannel.h \ + EOAdaptorContext.h \ + EOArrayProxy.h \ + EOAttribute.h \ + EOAttributeOrdering.h \ + EOCustomValues.h \ + EODatabase.h \ + EODatabaseChannel.h \ + EODatabaseContext.h \ + EOEntity.h \ + EOExpressionArray.h \ + EOFExceptions.h \ + EODatabaseFault.h \ + EODatabaseFaultResolver.h \ + EOModel.h \ + EOObjectUniquer.h \ + EOPrimaryKeyDictionary.h \ + EOSQLQualifier.h \ + EOQuotedExpression.h \ + EORelationship.h \ + EOSQLExpression.h \ + EOGenericRecord.h \ + EOModelGroup.h \ + EONull.h \ + EOKeySortOrdering.h \ + EOAdaptorDataSource.h \ + EOAdaptorChannel+Attributes.h \ + EOAdaptorOperation.h \ + EOAdaptorGlobalID.h \ + NSObject+EONullInit.h \ + EOEntity+Factory.h \ + EORecordDictionary.h \ + EOFault.h \ + EOFaultHandler.h \ + +libGDLAccess_OBJC_FILES = \ + eoaccess.m \ + EOAdaptor.m \ + EOAdaptorChannel.m \ + EOAdaptorContext.m \ + EOArrayProxy.m \ + EOAttribute.m \ + EOAttributeOrdering.m \ + EOCustomValues.m \ + EODatabase.m \ + EODatabaseChannel.m \ + EODatabaseContext.m \ + EOEntity.m \ + EOExpressionArray.m \ + EOFExceptions.m \ + EODatabaseFault.m \ + EODatabaseFaultResolver.m \ + EOKeySortOrdering.m \ + EOModel.m \ + EOObjectUniquer.m \ + EOPrimaryKeyDictionary.m \ + EORelationship.m \ + EOGenericRecord.m \ + EOModelGroup.m \ + EOEntityClassDescription.m \ + EOAdaptorDataSource.m \ + EOAdaptorChannel+Attributes.m \ + EOAdaptorOperation.m \ + EOAdaptorGlobalID.m \ + NSObject+EONullInit.m \ + EOEntity+Factory.m \ + EORecordDictionary.m \ + EOFault.m \ + EOFaultHandler.m \ + \ + EOAndQualifier+SQL.m \ + EOKeyComparisonQualifier+SQL.m \ + EOKeyValueQualifier+SQL.m \ + EONotQualifier+SQL.m \ + EOOrQualifier+SQL.m \ + EOQualifier+SQL.m \ + \ + EOSQLQualifier.m \ + EOSQLExpression.m \ + EOSelectSQLExpression.m \ + EOQuotedExpression.m \ + EOQualifierScanner.m \ + +ifneq ($(FOUNDATION_LIB),fd) +libGDLAccess_SUBPROJECTS += FoundationExt +endif + +libGDLAccess_HEADER_FILES_DIR = EOAccess +libGDLAccess_HEADER_FILES_INSTALL_DIR = /GDLAccess + +# GDLExtensions + +SUBPROJECTS += GDLExtensions + +# adaptor load test + +TOOL_NAME = load-EOAdaptor connect-EOAdaptor + +load-EOAdaptor_OBJC_FILES = load-EOAdaptor.m +load-EOAdaptor_LIB_DIRS += -L./$(GNUSTEP_OBJ_DIR) +load-EOAdaptor_TOOL_LIBS += -lGDLAccess -lEOControl + +connect-EOAdaptor_OBJC_FILES = connect-EOAdaptor.m +connect-EOAdaptor_LIB_DIRS += -L./$(GNUSTEP_OBJ_DIR) +connect-EOAdaptor_TOOL_LIBS += -lGDLAccess -lEOControl + + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/library.make +include $(GNUSTEP_MAKEFILES)/aggregate.make +include $(GNUSTEP_MAKEFILES)/tool.make +-include GNUmakefile.postamble diff --git a/sope-gdl1/GDLAccess/GNUmakefile.postamble b/sope-gdl1/GDLAccess/GNUmakefile.postamble new file mode 100644 index 00000000..70457d3a --- /dev/null +++ b/sope-gdl1/GDLAccess/GNUmakefile.postamble @@ -0,0 +1,23 @@ +# $Id: GNUmakefile.postamble 1 2004-08-20 10:38:46Z znek $ + +ifneq ($(GNUSTEP_TARGET_OS),cygwin32) + +before-all :: + $(LN_S) -f EOAccess GDLAccess + +after-install :: + cp -rf \ + $(GNUSTEP_HEADERS)$(libGDLAccess_HEADER_FILES_INSTALL_DIR) \ + $(GNUSTEP_HEADERS)/EOAccess + +endif + +ifneq ($(FOUNDATION_LIB),nx) +# case sensitivity issues on HFS ... + +after-install :: + cp -rf \ + $(GNUSTEP_HEADERS)$(libGDLAccess_HEADER_FILES_INSTALL_DIR) \ + $(GNUSTEP_HEADERS)/eoaccess + +endif diff --git a/sope-gdl1/GDLAccess/GNUmakefile.preamble b/sope-gdl1/GDLAccess/GNUmakefile.preamble new file mode 100644 index 00000000..44407937 --- /dev/null +++ b/sope-gdl1/GDLAccess/GNUmakefile.preamble @@ -0,0 +1,22 @@ +# $Id: GNUmakefile.preamble 1 2004-08-20 10:38:46Z znek $ + +libGDLAccess_LIBRARIES_DEPEND_UPON = \ + -lEOControl + +libGDLAccess_LIB_DIRS += \ + -L../../../SOPE/skyrix-core/EOControl/$(GNUSTEP_OBJ_DIR) + +ifeq ($(GNUSTEP_TARGET_OS),mingw32) +libGDLAccess_LIBRARIES_DEPEND_UPON += -lobjc +endif + +ifeq ($(GNUSTEP_TARGET_OS),cygwin32) +libGDLAccess_LIBRARIES_DEPEND_UPON += -lobjc +endif + +libGDLAccess_INCLUDE_DIRS += \ + -I. \ + -I./$(libGDLAccess_HEADER_FILES_DIR) \ + -I.. \ + -I../../../SOPE/skyrix-core/ \ + -IFoundationExt diff --git a/sope-gdl1/GDLAccess/NSObject+EONullInit.m b/sope-gdl1/GDLAccess/NSObject+EONullInit.m new file mode 100644 index 00000000..72cf5e2b --- /dev/null +++ b/sope-gdl1/GDLAccess/NSObject+EONullInit.m @@ -0,0 +1,48 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: NSObject+EONullInit.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include +#include "common.h" + +@interface NSObject(Entity) +- (EOEntity *)entity; +@end + +@implementation NSObject(EONullInit) + +- (void)setAllAttributesToEONull:(EOEntity *)_entity { + NSAssert(_entity != nil, @"invalid entity parameter"); + [_entity setAttributesOfObjectToEONull:self]; +} + +- (void)setAllAttributesToEONull { + // assume the object respondsTo: entity + [self setAllAttributesToEONull:[self entity]]; +} + +@end /* NSObject(EONullInit) */ diff --git a/sope-gdl1/GDLAccess/README b/sope-gdl1/GDLAccess/README new file mode 100644 index 00000000..9e54000b --- /dev/null +++ b/sope-gdl1/GDLAccess/README @@ -0,0 +1,194 @@ +# $Id: README 1 2004-08-20 10:38:46Z znek $ + +NOTE: this file is heavily outdated + +GNU Database Library Access Layer - MDlink patch Version + + Contained code is derived from gdl - GNU Database Library and is therefore + LGPL license. Copyright for gdl has the Free Software Foundation. + + Changes + + There are no EOJoin's anymore (only for compability). EORelationships cannot + be compound and store source and destination themselves. + + No compound primary keys are allowed. + + Uniquing is always enabled. + + Static Linking + + uncomment '#imports' in EOModel.m + + Intro + + The GNUstep Database Library is a hierarchy of Objective-C classes + that provide a three-tiered architecture for developing database + applications. + + The three-tier architecture is a flexible paradigm for building + robust and scalable client/server applications; the three tiers refer + to the database, the Application Objects, and the user interface. The + separation of the database from the user interface through intermediary + Application Objects allows the data to be distributed appropriately + across database servers and still have the user interface display data + cohesively for the end-user. Business logic, as implemented in the + Application Objects, provides the mechanism for consistency and + reusability across all your business applications. + + Entity-relationship modelling is used for describing the Application + Objects and how they are mapped to database fields. The GNUstep + Database Library represents these models as plain ASCII text files; this + allows external programs to be used for constructing and maintaining the + models separate from the applications which use them. + + Differences to GNUstep gdl + + Datasource objects are missing. + + ToDo + + EOQualifier: + `isValidQualifierType' from EOAdaptor is not used now. This method + is supposed to verify, when a qualifier is constructed, if an + attribute can appear inside an expression. + + Make the relationshipPaths of type GCMutableSet. + + EOSQLExpresion + There is no support now for specifying properties for the tables + that appear in the FROM clause; I am thinking specifically at the + OUTER specifier required by some servers when you use outer joins. + + Optimize the generated WHERE clause when the same relationship + appears more than one time in the entity. + + The external query from EOEntity is not used when a fetch + operation is unrestricted, i.e. it fetches all the records from + the table + + Class Hierachy + + NSObject + DefaultScannerHandler + EOInsertUpdateScannerHandler + EOQualifierScannerHandler + EOSelectScannerHandler + EOAdaptor + EOAdaptorChannel + EOAdaptorContext + EOAttributeOrdering + EODatabase + EODatabaseChannel + EODatabaseContext + EOFaultResolver + EOArrayFault + EOObjectFault + EOGenericRecord + EOKeySortOrdering + EONull < NSCopying > + EOObjectUniquer + EOQualifierJoinHolder + EOQuotedExpression < NSCopying > + EOSQLExpression < EOExpressionContext > + EODeleteSQLExpression + EOInsertSQLExpression + EOSelectSQLExpression + EOUpdateSQLExpression + NSDictionary + EOPrimaryKeyDictionary + EOSinglePrimaryKeyDictionary + EOMultiplePrimaryKeyDictionary + NSEnumerator + EOSinglePrimaryKeyDictionaryEnumerator + EOAttribute + EOEntity + EOModel + EOQualifier + EOSQLQualifier < NSCopying > + EORelationship + EOExpressionArray + + GCObject + GCMutableArray + + EOFault + + NSException + EOFException + DestinationEntityDoesntMatchDefinitionException + EOAdaptorException + InvalidAttributeException + InvalidQualifierException + ObjectNotAvailableException + PropertyDefinitionException + PropertyDefinitionException + InvalidNameException + InvalidPropertyException + InvalidValueTypeException + RelationshipMustBeToOneException + EOAdaptorException + CannotFindAdaptorBundleException + DataTypeMappingNotSupportedException + InvalidAdaptorBundleException + InvalidAdaptorStateException + InvalidAdaptorStateException + AdaptorIsFetchingException + AdaptorIsNotFetchingException + ChannelIsNotOpenedException + NoTransactionInProgressException + TooManyOpenedChannelsException + + Categories + + EOAdaptor+Private + EOAdaptorContext+Private + EOAttribute+EOAttributePrivate + EOAttribute+ValuesConversion + EODatabase+Private + EODatabaseChannel+Private + EODatabaseContext+Private + EOEntity+EOEntityPrivate + EOEntity+ValuesConversion + EOJoin+EOJoinPrivate + EOModel+EOModelPrivate + EORelationship+EORelationshipPrivate + NSArray+EOKeyBasedSorting + NSData+EOCustomValues + NSDictionary+EOKeyValueCoding + NSMutableArray+EOKeyBasedSorting + NSMutableDictionary+EOKeyValueCoding + NSNumber+EOCustomValues + NSObject+EOExpression + NSObject+EOAdaptorChannelDelegation + NSObject+EOAdaptorContextDelegate + NSObject+EOAdaptorDelegate + NSObject+EOCustomValues + NSObject+EODatabaseChannelDelegateProtocol + NSObject+EODatabaseChannelNotification + NSObject+EODatabaseCustomValues + NSObject+EOGenericRecord + NSObject+EOKeyValueCoding + NSObject+EOKeyValueCodingEONull + NSObject+EOUnableToFaultToOne + NSString+EOAttributeTypeCheck + NSString+EOCustomValues + + Protocols + + EOExpressionContext + + Informal Protocols + + EOClassMapping + EOCustomValues + EODatabaseChannelNotification + EODatabaseCustomValues + EOExpression + EOKeyValueCoding + EOKeyValueCodingEONull + EOUnableToFaultToOne + +-- +Helge Hess (helge@mdlink.de) +MDlink online service center, 1998-11-01 diff --git a/sope-gdl1/GDLAccess/TODO b/sope-gdl1/GDLAccess/TODO new file mode 100644 index 00000000..fb5aa76e --- /dev/null +++ b/sope-gdl1/GDLAccess/TODO @@ -0,0 +1,15 @@ +# $Id: TODO 1 2004-08-20 10:38:46Z znek $ + +TODO +==== + +- remove all things not required for OGo + +MacOSX +====== + +- replace all InvalidArgumentExceptions with proper Foundation replacements + +- remove dependency on FoundationExt + - currently the dependency is formed by the libFoundation scanner handlers + and format processors diff --git a/sope-gdl1/GDLAccess/Version b/sope-gdl1/GDLAccess/Version new file mode 100644 index 00000000..92391da2 --- /dev/null +++ b/sope-gdl1/GDLAccess/Version @@ -0,0 +1,3 @@ +# $Id: Version 1 2004-08-20 10:38:46Z znek $ + +SUBMINOR_VERSION:=32 diff --git a/sope-gdl1/GDLAccess/common.h b/sope-gdl1/GDLAccess/common.h new file mode 100644 index 00000000..e9274af2 --- /dev/null +++ b/sope-gdl1/GDLAccess/common.h @@ -0,0 +1,246 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: common.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef __common_h__ +#define __common_h__ + +#include +#include + +#ifndef __WIN32__ +# include +# include +#endif + +#include +#include +#include + +#import +#import +#import +#import + +#if NeXT_RUNTIME || APPLE_RUNTIME +# define sel_eq(sela,selb) (sela==selb?YES:NO) +#endif + +#if LIB_FOUNDATION_LIBRARY +# import +# import +#else +# include +# include +#endif + + +// ******************** common functions ******************** + +static inline void *Malloc(int) __attribute__((unused)); +static inline void *Calloc(int, int) __attribute__((unused)); +static inline void *Realloc(void*, int) __attribute__((unused)); +static inline void Free(void*) __attribute__((unused)); + +static inline int Strlen(const char*) __attribute__((unused)); +static inline char* Strdup(const char*) __attribute__((unused)); +static inline char* Strcpy (char*, const char*) __attribute__((unused)); +static inline char* Strncpy (char*, const char*, unsigned) + __attribute__((unused)); +static inline char* Strcat (char*, const char*) __attribute__((unused)); +static inline char* Strncat (char*, const char*, unsigned) + __attribute__((unused)); +static inline int Strcmp(const char*, const char*) __attribute__((unused)); +static inline int Strncmp(const char*, const char*, unsigned) + __attribute__((unused)); +static inline int Atoi(const char*) __attribute__((unused)); +static inline long Atol(const char*) __attribute__((unused)); + +static inline void *Malloc(int size) { + return malloc(size); +} + +static inline void *MallocAtomic(int size) { + return malloc(size); +} + +static inline void Free(void* p) { + if (p) free(p); +} + +static inline void *Calloc(int elem, int size) { + return calloc(elem, size); +} + +static inline void *CallocAtomic(int elem, int size) { + return calloc(elem, size); +} + +static inline void *Realloc(void* p, int size) { + return realloc(p, size); +} + +static inline int Strlen(const char* s) { + return s ? strlen(s) : 0; +} + +static inline char* Strdup(const char* s) { + return s ? strcpy(Malloc(strlen(s) + 1), s) : NULL; +} + +static inline char* Strcpy (char* d, const char* s) { + return s && d ? strcpy(d, s) : d; +} + +static inline char* Strncpy (char* d, const char* s, unsigned size) { + return s && d ? strncpy(d, s, size) : d; +} + +static inline char* Strcat (char* d, const char* s) { + return s && d ? strcat(d, s) : d; +} + +static inline char* Strncat (char* d, const char* s , unsigned size) { + return s && d ? strncat(d, s , size) : d; +} + +static inline int Strcmp(const char* p, const char* q) { + if(!p) { + if(!q) + return 0; + else return -1; + } + else { + if(!q) + return 1; + else return strcmp(p, q); + } +} + +static inline int Strncmp(const char* p, const char* q, unsigned size) { + if(!p) { + if(!q) + return 0; + else return -1; + } + else { + if(!q) + return 1; + else return strncmp(p, q, size); + } +} + +static inline int Atoi(const char* str) +{ + return str ? atoi(str) : 0; +} + +static inline long Atol(const char *str) +{ + return str ? atol(str) : 0; +} + +#ifndef MAX +#define MAX(a, b) \ + ({typedef _ta = (a), _tb = (b); \ + _ta _a = (a); _tb _b = (b); \ + _a > _b ? _a : _b; }) +#endif + +#ifndef MIN +#define MIN(a, b) \ + ({typedef _ta = (a), _tb = (b); \ + _ta _a = (a); _tb _b = (b); \ + _a < _b ? _a : _b; }) +#endif + +#if !LIB_FOUNDATION_LIBRARY + +#ifndef CREATE_AUTORELEASE_POOL +#define CREATE_AUTORELEASE_POOL(pool) \ + id pool = [[NSAutoreleasePool alloc] init] +#endif + +#endif /* ! LIB_FOUNDATION_LIBRARY */ + + +#if !LIB_FOUNDATION_LIBRARY + +static inline char *Ltoa(long nr, char *str, int base) +{ + char buff[34], rest, is_negative; + int ptr; + + ptr = 32; + buff[33] = '\0'; + if(nr < 0) { + is_negative = 1; + nr = -nr; + } + else + is_negative = 0; + + while(nr != 0) { + rest = nr % base; + if(rest > 9) + rest += 'A' - 10; + else + rest += '0'; + buff[ptr--] = rest; + nr /= base; + } + if(ptr == 32) + buff[ptr--] = '0'; + if(is_negative) + buff[ptr--] = '-'; + + Strcpy(str, &buff[ptr+1]); + + return(str); +} +#endif + +#if !LIB_FOUNDATION_LIBRARY + +@interface NSObject(FoundationExtGDLAccess) +- (void)subclassResponsibility:(SEL)sel; +- (void)notImplemented:(SEL)sel; +@end + +#endif + +#if !GNU_RUNTIME +# ifndef SEL_EQ +# define SEL_EQ(__A__,__B__) (__A__==__B__ ? YES : NO) +# endif +#else +# ifndef SEL_EQ +# include +# define SEL_EQ(__A__,__B__) sel_eq(__A__,__B__) +# endif +#endif + +#endif /* __common_h__ */ diff --git a/sope-gdl1/GDLAccess/connect-EOAdaptor.m b/sope-gdl1/GDLAccess/connect-EOAdaptor.m new file mode 100644 index 00000000..c52b9873 --- /dev/null +++ b/sope-gdl1/GDLAccess/connect-EOAdaptor.m @@ -0,0 +1,125 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: connect-EOAdaptor.m 1 2004-08-20 10:38:46Z znek $ + +#import +#include +#include +#include +#include + +int main(int argc, char **argv, char **env) { + NSAutoreleasePool *pool; + NSArray *args; + NSString *adaptorName; + NSString *condictstr; + NSDictionary *condict; + EOAdaptor *adaptor; + EOAdaptorContext *adctx; + EOAdaptorChannel *adch; + BOOL ok; + + pool = [[NSAutoreleasePool alloc] init]; +#if LIB_FOUNDATION_LIBRARY + [NSProcessInfo initializeWithArguments:argv count:argc environment:env]; +#endif + + args = [[NSProcessInfo processInfo] arguments]; + if ([args count] < 3) { + fprintf(stderr, "usage: %s adaptorname condict\n", argv[0]); + exit(10); + } + + adaptorName = [args objectAtIndex:1]; + condictstr = [args objectAtIndex:2]; + + /* load adaptor */ + + NS_DURING { + adaptor = [EOAdaptor adaptorWithName:adaptorName]; + } + NS_HANDLER { + fprintf(stderr, "ERROR: %s: %s\n", + [[localException name] cString], + [[localException reason] cString]); + adaptor = nil; + } + NS_ENDHANDLER; + + if (adaptor == nil) { + fprintf(stderr, "ERROR: failed to load adaptor '%s'.\n", + [adaptorName cString]); + exit(1); + } + + printf("did load adaptor: %s\n", [[adaptor name] cString]); + + /* setup connection dictionary */ + + if ((condict = [condictstr propertyList]) == nil) { + fprintf(stderr, "ERROR: invalid connection dictionary '%s'.\n", + [condictstr cString]); + exit(2); + } + [adaptor setConnectionDictionary:condict]; + + /* setup connection */ + + if ((adctx = [adaptor createAdaptorContext]) == nil) { + fprintf(stderr, "ERROR: could not create adaptor context."); + exit(3); + } + if ((adch = [adctx createAdaptorChannel]) == nil) { + fprintf(stderr, "ERROR: could not create adaptor channel."); + exit(4); + } + + /* connect */ + + ok = NO; + NS_DURING { + ok = [adch openChannel]; + } + NS_HANDLER { + fprintf(stderr, "ERROR: could not connect to database %s: %s\n", + [[localException name] cString], + [[localException reason] cString]); + exit(5); + } + NS_ENDHANDLER; + + if (!ok) { + fprintf(stderr, "ERROR: could not connect to database.\n"); + exit(6); + } + else + printf("connection could be established.\n"); + + [adch closeChannel]; + + exit(0); + return 0; +} diff --git a/sope-gdl1/GDLAccess/eoaccess.m b/sope-gdl1/GDLAccess/eoaccess.m new file mode 100644 index 00000000..b6a9bfee --- /dev/null +++ b/sope-gdl1/GDLAccess/eoaccess.m @@ -0,0 +1,85 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: eoaccess.m 1 2004-08-20 10:38:46Z znek $ + +#include "EOAccess.h" +#include "EOArrayProxy.h" + +@implementation GDLAccess + +- (void)_staticLinkClasses { + [EOAdaptor class]; + [EOAdaptorChannel class]; + [EOAdaptorContext class]; + [EOArrayProxy class]; + [EOAttribute class]; + [EOAttributeOrdering class]; + [EODatabase class]; + [EODatabaseChannel class]; + [EODatabaseContext class]; + [EOEntity class]; + [EOFException class]; + [ObjectNotAvailableException class]; + [PropertyDefinitionException class]; + [DestinationEntityDoesntMatchDefinitionException class]; + [InvalidNameException class]; + [InvalidPropertyException class]; + [RelationshipMustBeToOneException class]; + [InvalidValueTypeException class]; + [InvalidAttributeException class]; + [InvalidQualifierException class]; + [EOAdaptorException class]; + [CannotFindAdaptorBundleException class]; + [InvalidAdaptorBundleException class]; + [InvalidAdaptorStateException class]; + [DataTypeMappingNotSupportedException class]; + [ChannelIsNotOpenedException class]; + [AdaptorIsFetchingException class]; + [AdaptorIsNotFetchingException class]; + [NoTransactionInProgressException class]; + [TooManyOpenedChannelsException class]; + [EOModel class]; + [EOObjectUniquer class]; + [EOPrimaryKeyDictionary class]; + [EOSQLQualifier class]; + [EOQuotedExpression class]; + [EORelationship class]; + [EOSQLExpression class]; +#if 0 + [EOSelectSQLExpression class]; + [EOInsertSQLExpression class]; + [EOUpdateSQLExpression class]; + [EODeleteSQLExpression class]; +#endif +} + +- (void)_staticLinkCategories { +} + +- (void)_staticLinkModules { +} + +@end /* GDLAccess */ diff --git a/sope-gdl1/GDLAccess/libGDLAccess.def b/sope-gdl1/GDLAccess/libGDLAccess.def new file mode 100644 index 00000000..74854c44 --- /dev/null +++ b/sope-gdl1/GDLAccess/libGDLAccess.def @@ -0,0 +1,60 @@ +EXPORTS + __objc_class_name_EOAdaptor; + __objc_class_name_EOAdaptorChannel; + __objc_class_name_EOAdaptorContext; + __objc_class_name_EOArrayProxy; + __objc_class_name_EOAttribute; + __objc_class_name_EOAttributeOrdering; + __objc_class_name_EODatabase; + __objc_class_name_EODatabaseChannel; + __objc_class_name_EODatabaseContext; + __objc_class_name_EODatabaseFault; + __objc_class_name_EODatabaseFaultResolver; + __objc_class_name_EOArrayFault; + __objc_class_name_EOObjectFault; + __objc_class_name_EOEntity; + __objc_class_name_EOEntityClassDescription; + __objc_class_name_EOExpressionArray; + __objc_class_name_EOFException; + __objc_class_name_ObjectNotAvailableException; + __objc_class_name_PropertyDefinitionException; + __objc_class_name_DestinationEntityDoesntMatchDefinitionException; + __objc_class_name_InvalidNameException; + __objc_class_name_InvalidPropertyException; + __objc_class_name_RelationshipMustBeToOneException; + __objc_class_name_InvalidValueTypeException; + __objc_class_name_InvalidAttributeException; + __objc_class_name_InvalidQualifierException; + __objc_class_name_EOAdaptorException; + __objc_class_name_CannotFindAdaptorBundleException; + __objc_class_name_InvalidAdaptorBundleException; + __objc_class_name_InvalidAdaptorStateException; + __objc_class_name_DataTypeMappingNotSupportedException; + __objc_class_name_ChannelIsNotOpenedException; + __objc_class_name_AdaptorIsFetchingException; + __objc_class_name_AdaptorIsNotFetchingException; + __objc_class_name_NoTransactionInProgressException; + __objc_class_name_TooManyOpenedChannelsException; + __objc_class_name_EOKeySortOrdering; + __objc_class_name_EOModel; + __objc_class_name_EOModelGroup; + __objc_class_name_EOObjectUniquer; + __objc_class_name_EOSinglePrimaryKeyDictionary; + __objc_class_name_EOSinglePrimaryKeyDictionaryEnumerator; + __objc_class_name_EOMultiplePrimaryKeyDictionary; + __objc_class_name_EOPrimaryKeyDictionary; + __objc_class_name_EOQualifierScannerHandler; + __objc_class_name_EOQualifierEnumScannerHandler; + __objc_class_name_EOQuotedExpression; + __objc_class_name_EORelationship; + __objc_class_name_EOJoin; + __objc_class_name_EOSelectScannerHandler; + __objc_class_name_EOInsertUpdateScannerHandler; + __objc_class_name_EOSQLExpression; + __objc_class_name_EOSelectSQLExpression; + __objc_class_name_EOInsertSQLExpression; + __objc_class_name_EOUpdateSQLExpression; + __objc_class_name_EODeleteSQLExpression; + __objc_class_name_EOQualifierJoinHolder; + __objc_class_name_EOSQLQualifier; + __objc_class_name_eoaccess; diff --git a/sope-gdl1/GDLAccess/load-EOAdaptor.m b/sope-gdl1/GDLAccess/load-EOAdaptor.m new file mode 100644 index 00000000..4fa4f4f7 --- /dev/null +++ b/sope-gdl1/GDLAccess/load-EOAdaptor.m @@ -0,0 +1,72 @@ +/* + EOAdaptorChannel.m + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: October 1996 + + This file is part of the GNUstep Database Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: load-EOAdaptor.m 1 2004-08-20 10:38:46Z znek $ + +#import +#include +#include + +int main(int argc, char **argv, char **env) { + NSAutoreleasePool *pool; + NSArray *args; + NSString *adaptorName; + EOAdaptor *adaptor; + + pool = [[NSAutoreleasePool alloc] init]; +#if LIB_FOUNDATION_LIBRARY + [NSProcessInfo initializeWithArguments:argv count:argc environment:env]; +#endif + + args = [[NSProcessInfo processInfo] arguments]; + if ([args count] < 2) { + fprintf(stderr, "usage: %s adaptorname\n", argv[0]); + exit(10); + } + + adaptorName = [args objectAtIndex:1]; + + NS_DURING { + adaptor = [EOAdaptor adaptorWithName:adaptorName]; + } + NS_HANDLER { + fprintf(stderr, "ERROR: %s: %s\n", + [[localException name] cString], + [[localException reason] cString]); + adaptor = nil; + } + NS_ENDHANDLER; + + if (adaptor) { + printf("did load adaptor: %s\n", [[adaptor name] cString]); + exit(0); + } + + fprintf(stderr, "ERROR: failed to load adaptor '%s'.\n", + [adaptorName cString]); + + exit (1); + return 1; +} diff --git a/sope-gdl1/GDLAccess/test.py b/sope-gdl1/GDLAccess/test.py new file mode 100755 index 00000000..c8ab2c32 --- /dev/null +++ b/sope-gdl1/GDLAccess/test.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +# $Id: test.py 2 2004-08-20 10:48:47Z znek $ +from sys import * +from Foundation import * +from eoaccess import * +from EOControl import * +from NGExtensions import * +from GDLExtensions import * +import resource; + +defaults = NSUserDefaults(); + +connDict = defaults["LSConnectionDictionary"]; +if connDict is None: + print "missing connection dictionary\n"; + exit(1); + +primKeyGenDict = defaults["pkeyGeneratorDictionary"]; +print primKeyGenDict; +if primKeyGenDict is None: + print "missing pkeyGeneratorDictionary\n"; + exit(1); + + +print "ConnectionDictionary: "; +print connDict.description(); + +adaptorName = defaults["LSAdaptor"]; +if adaptorName is None: + adaptorName = "Sybase10"; + +adaptor = EOAdaptor(adaptorName); +adaptor.setConnectionDictionary(connDict); +adaptor.setPkeyGeneratorDictionary(primKeyGenDict); + +adContext = adaptor.createAdaptorContext(); +adChannel = adContext.createAdaptorChannel(); + +def test_database_channel(): + print "adChannel " + adChannel.description() + "\n"; + print "channel "; + print "attributesForTableName doc"; + print adChannel.invoke1("attributesForTableName:", "doc"); + print "primaryKeyAttributesForTableName document _______________________________________\n"; + print adChannel.invoke1("primaryKeyAttributesForTableName:", "document"); + print "primaryKeyAttributesForTableName:, doc _______________________________________\n"; + print adChannel.invoke1("primaryKeyAttributesForTableName:", "doc"); + print "primaryKeyAttributesForTableName company _______________________________________\n"; + print adChannel.invoke1("primaryKeyAttributesForTableName:", "company"); + print "primaryKeyAttributesForTableName person_______________________________________\n"; + print adChannel.invoke1("primaryKeyAttributesForTableName:", "person"); + print "_______________________________________\n"; + +def test_adaptor_data_source(): + adaptor = adChannel.adaptorContext().adaptor(); + dict = NSMutableDictionary(); + dict["login"] = "jan_1"; + dict["name"] = "JR"; + dict["firstname"] = "jan"; + dict["is_person"] = 1; + dict["number"] = "12345_1"; + dict["birthday"] = NSCalendarDate('1999-09-21 13:23', '%Y-%m-%d %H:%M'); + dict["middlename"] = "Ein Unnuetzer middlename"; + + + dataSource = EOAdaptorDataSource(adChannel); + hints = NSMutableDictionary(); + pks = NSMutableArray(); + pks.addObject("company_id"); + hints.setObjectForKey(pks, "EOPrimaryKeyAttributeNamesHint") + + fetchSpec = EOFetchSpecification(); + fetchSpec.setEntityName("company"); + fetchSpec.setHints(hints); + + dataSource.setFetchSpecification(fetchSpec); + print "-------------------- {insert ---------------------\n"; + dataSource.insertObject(dict); + print "-------------------- insert} ---------------------\n"; + + print "-------------------- {select with hints ---------------------\n"; + qualifier = EOQualifier("login = %@", ("jan_1", )) + fetchSpec = EOFetchSpecification(); + fetchSpec.setQualifier(qualifier); + fetchSpec.setEntityName("company"); + + hints = NSMutableDictionary(); + pks.addObject("company_id"); + hints.setObjectForKey(NSTimeZone('MET'), "EOFetchResultTimeZoneHint") + fetchSpec.setHints(hints); + + sortOrderings = NSMutableArray(); + sortOrderings.addObject(EOSortOrdering("login", "compareCaseInsensitiveAscending:")); + sortOrderings.addObject(EOSortOrdering("company_id", "compareCaseInsensitiveDescending:")); + fetchSpec.setSortOrderings(sortOrderings); + dataSource = EOAdaptorDataSource(adChannel); + dataSource.setFetchSpecification(fetchSpec); + objs = dataSource.fetchObjects(); + print objs; + print "-------------------- select} ---------------------\n"; + obj = objs[0]; + + print "-------------------- {update ---------------------\n"; + print obj; + obj["login"] = "jan_1_1"; + obj["middlename"] = EONull(); + dataSource.updateObject(obj); + print "-------------------- update} ---------------------\n"; + + qualifier = EOQualifier("login caseInsensitiveLike %@", ("jan_1_*", )) + fetchSpec.setQualifier(qualifier); + dataSource.setFetchSpecification(fetchSpec); + + print "-------------------- {select ---------------------\n"; + objs = dataSource.fetchObjects(); + print objs; + print "-------------------- select} ---------------------\n"; + + print "-------------------- {delete ---------------------\n"; + obj = objs[0]; + dataSource.deleteObject(obj); + print "-------------------- delete} ---------------------\n"; + + print "-------------------- {select ---------------------\n"; + objs = dataSource.fetchObjects(); + print objs; + print "-------------------- select} ---------------------\n"; + + +def test_cascaded_datasources(): + + adaptor = adChannel.adaptorContext().adaptor(); + dict = NSMutableDictionary(); + dict["login"] = "jan_1"; + dict["name"] = "JR"; + dict["firstname"] = "jan"; + dict["is_person"] = 1; + dict["number"] = "12345_1"; + + dataSource = EOAdaptorDataSource(adChannel); + fetchSpec = EOFetchSpecification(); + fetchSpec.setEntityName("company"); + qualifier = EOQualifier("login like %@", ("j%", )) + fetchSpec = EOFetchSpecification(); + fetchSpec.setQualifier(qualifier); + fetchSpec.setEntityName("company"); + sortOrderings = NSMutableArray(); + sortOrderings.addObject(EOSortOrdering("login", "compareCaseInsensitiveAscending:")); + fetchSpec.setSortOrderings(sortOrderings); + hints = NSMutableDictionary(); + pks = NSMutableArray(); + pks.addObject("company_id"); + hints.setObjectForKey(pks, "EOPrimaryKeyAttributeNamesHint") + + fetchSpec.setHints(hints); + + dataSource.setFetchSpecification(fetchSpec); + cacheDataSource = EOCacheDataSource(dataSource); + objs = dataSource.fetchObjects(); + print objs; + print cacheDataSource.fetchObjects(); + print "-----------------------------\n"; + print cacheDataSource.fetchObjects(); + dataSource.insertObject(dict); + print "++++++++++++++++++++++++++++\n"; + + fetchSpec = EOFetchSpecification(); + fetchSpec.setEntityName("company"); + qualifier = EOQualifier("login = %@", ("jan_1", )) + fetchSpec = EOFetchSpecification(); + fetchSpec.setQualifier(qualifier); + fetchSpec.setEntityName("company"); + dataSource.setFetchSpecification(fetchSpec); + cacheDataSource = EOCacheDataSource(dataSource); + objs = dataSource.fetchObjects(); + obj = objs[0]; + print objs; + print "-----------------------------\n"; + print cacheDataSource.deleteObject(obj); + print "++++++++++++++++++++++++++++\n"; + print cacheDataSource.fetchObjects(); + +def echo_logins(objs): + for o in objs: + print o['login']; + +def test_sort_datasource(): + dataSource = EOAdaptorDataSource(adChannel); + + fetchSpec = EOFetchSpecification(); + fetchSpec.setEntityName("company"); + qualifier = EOQualifier("login like %@", ("%a%", )) + fetchSpec.setQualifier(qualifier); + + dataSource.setFetchSpecification(fetchSpec); + echo_logins(dataSource.fetchObjects()); + + sortOrderings = NSMutableArray(); + sO = EOSortOrdering("login", "compareDescending:"); + sortOrderings.addObject(sO); + fetchSpec.setSortOrderings(sortOrderings); + dataSource.setFetchSpecification(fetchSpec); + + echo_logins(dataSource.fetchObjects()); + +print resource.getrlimit(resource.RLIMIT_CORE); +if adChannel.openChannel(): + print "open channel ok"; +else: + print "open channel failed"; + exit(1); +print "adChannel ", adChannel; + + +#test_database_channel(); +test_adaptor_data_source(); +#test_cascaded_datasources(); +#test_sort_datasource(); diff --git a/sope-gdl1/GNUmakefile b/sope-gdl1/GNUmakefile new file mode 100644 index 00000000..ff278d23 --- /dev/null +++ b/sope-gdl1/GNUmakefile @@ -0,0 +1,14 @@ +# $Id: GNUmakefile 1 2004-08-20 10:38:46Z znek $ + +include $(GNUSTEP_MAKEFILES)/common.make + +PACKAGE_NAME=sope-gdl1 +VERSION=4.3.0 + +SUBPROJECTS += \ + GDLAccess \ + PostgreSQL72 \ + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/aggregate.make +-include GNUmakefile.postamble diff --git a/sope-gdl1/PostgreSQL72/COPYING b/sope-gdl1/PostgreSQL72/COPYING new file mode 100644 index 00000000..a43ea212 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/sope-gdl1/PostgreSQL72/COPYING.LIB b/sope-gdl1/PostgreSQL72/COPYING.LIB new file mode 100644 index 00000000..eb685a5e --- /dev/null +++ b/sope-gdl1/PostgreSQL72/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/sope-gdl1/PostgreSQL72/ChangeLog b/sope-gdl1/PostgreSQL72/ChangeLog new file mode 100644 index 00000000..f4488afe --- /dev/null +++ b/sope-gdl1/PostgreSQL72/ChangeLog @@ -0,0 +1,250 @@ +2004-08-20 Helge Hess + + * moved from ThirdParty to SOPE/sope-gdl1 (v1.0.33) + +2004-07-06 Helge Hess + + * PostgreSQL72Channel.m: ensure that the port is passed to the + connection as a string object (v1.0.32) + +2004-06-29 Helge Hess + + * GNUmakefile.preamble: added include path to SOPE/skyrix-core for + "inline" compilation (v1.0.31) + +2004-06-28 Helge Hess + + * PostgreSQL72Channel.m: do not raise errors in handler methods, but + return them for processing by the new X methods (v1.0.30) + + * PostgreSQL72Channel.m: implement a specific -evaluateExpressionX:, + use that in -primaryKeyForNewRowWithEntity: (v1.0.29) + +2004-06-22 Helge Hess + + * v1.0.28 + + * PostgreSQL72Adaptor.m: some code cleanups + + * PostgreSQL72Channel+Model.m: fixed a gstep-base warning + + * NSNumber+PGVal.m ([NSNumber -stringValueForPostgreSQLType:attribute:]): + fixed rendering of bool numbers for gstep-base (-stringValue of + bool numbers return 'YES'/'NO' on gstep-base while 1 or 0 on Cocoa + and libFoundation) + +2004-06-21 Helge Hess + + * EOAttribute+PostgreSQL72.m: added "cardinal_number", "character_data" + as known types (v1.0.27) + + * PostgreSQL72Channel+Model.m: code cleanups (v1.0.26) + +2004-06-16 Helge Hess + + * NSString+PGVal.m, PGConnection.m: fixed some gcc 3.4 warnings + (v1.0.25) + +2004-06-16 Helge Hess + + * v1.0.24 + + * PostgreSQL72Channel: rewrote to use PGResultSet. Removed processing + of oid-status which apparently was completely broken before! + + * PGConnection.m: added new PGResultSet object + +2004-06-15 Helge Hess + + * v1.0.23 + + * PostgreSQL72Channel+Model.m: added -describeDatabaseNames and + -describeUserNames methods + + * PostgreSQL72Adaptor.m: minor code cleanups + + * v1.0.22 + + * various files: fixed warnings on MacOSX with gstep-make + + * PostgreSQL72Channel.h: rewritten to use PGConnection object + + * started PGConnection object to remove low-level libpq things from + the channel (which can then concentrate on implementing the API) + +2004-06-06 Helge Hess + + * fixed some MacOSX compilation warnings (v1.0.21) + +2004-05-04 Helge Hess + + * GNUmakefile.preamble (PostgreSQL72_BUNDLE_LIBS): added missing libs + for current Panther PostgreSQL compilation (v1.0.20) + +2004-03-01 Helge Hess + + * GNUmakefile.preamble: fixed makefile for "inline" compilation + (v1.0.19) + +2004-02-12 Helge Hess + + * v1.0.18 + + * EOAttribute+PostgreSQL72.m: fixed exception for MacOSX + + * GNUmakefile.preamble: added yet another special case to locate the + PostgreSQL header files ... + +2004-02-10 Helge Hess + + * PostgreSQL72Channel.m: only set client encoding when being compiled + with PostgreSQL 7.3+ (seems to have problems with umlauts on Debian + 7.2) (v1.0.17) + +2004-02-08 Helge Hess + + * PostgreSQL72Channel.m: explicitly set connection encoding to Latin1 + to avoid problems with databases created as Unicode (v1.0.16) + +2004-01-07 Helge Hess + + * PostgreSQL72Exception.m: minor cleanup, include stdarg.h for varargs + processing (might fix compilation on Solaris) (v1.0.15) + +2004-01-07 Helge Hess + + * PostgreSQL72Channel.m: do cache attribute name field indices during + invocations, minor performance optimization to fetch method (which + requires that the attributes argument is constant!) (v1.0.14) + + * PostgreSQL72Channel.m: raise default value for max-connection count + to 50, various cleanups and minor fixes (v1.0.13) + +2003-12-26 Helge Hess + + * NSData+PGVal.m ([NSData -stringValueForPostgreSQLType:attribute:]): + fixed a bug in the data=>string conversion. Types like + "VARCHAR(4000)" where not properly converted, eg a long obj_property + value (v1.0.12) + +2003-12-13 Helge Hess + + * GNUmakefile.preamble: fixed include flags, so that GDLAccess must not + be installed prior compiling the adaptor (v1.0.11) + +2003-12-11 Helge Hess + + * GNUmakefile (BUNDLE_INSTALL_DIR): install into + GNUSTEP_INSTALLATION_DIR instead of GNUSTEP_SYSTEM_ROOT (v1.0.10) + +2003-09-03 Helge Hess + + * GNUmakefile.preamble: added /usr/include/postgresql as an include + search path - this is the position of the headers under Debian + (v1.0.9) + +2003-07-30 Helge Hess + + * NSCalendarDate+PGVal.m: added support for 4 digit timezone offsets + (eg +09:30) when parsing PG date values (v1.0.8) + +2003-07-28 Helge Hess + + * NSCalendarDate+PGVal.m: fixed two more bugs introduced in 1.0.5 ... + (v1.0.7) + +2003-07-28 Bjoern Stierand + + * NSCalendarDate+PGVal.m: fixed release bug introduced in 1.0.5, wrong + variable was returned leading to a memory error (v1.0.6) + +2003-07-27 Helge Hess + + * PostgreSQL72Values.m: split up into separate files, added several + performance optimizations to base value creation code (v1.0.5) + +2003-07-23 Helge Hess + + * more fixes to the include pathes, do not include using + but always using (v1.0.4) + +2003-07-21 Helge Hess + + * some include cleanups for FreeBSD (reported by Mirko Viviani), + fixed some warnings (v1.0.3) + +Wed May 14 11:27:21 2003 Jan Reichmann + + * PostgreSQL72Values.m: use lowercase type to determine sql type + (bug 126) (v1.0.2) + +2003-05-07 Helge Hess + + * v1.0.1 + + * PostgreSQL72Channel.m: small cleanups, speed improvement on attrname + creation (used no autorelease pools ...) + + * GNUmakefile (PostgreSQL72_RESOURCE_FILES): added a Version file + +Mon May 5 16:27:40 2003 Jan Reichmann + + * PostgreSQL72Values.m: implement valueFromCString, valueFromBytes, + stringValueForPostgreSQLType for NSData+PostgreSQL72Values (bug 126) + +Mon Dec 23 18:20:13 2002 Helge Hess + + * ported to MacOSX 10.2.3 (do not use + + * EOAttribute+PostgreSQL72.m: add timestamptz type + +Tue Nov 5 10:02:45 2002 Jan Reichmann + + * PostgreSQLChannel.m: add PGMaxOpenConnectionCount - Default to + set the max number of open postgres connections + +Fri Oct 18 19:15:15 2002 Jan Reichmann + + * EOAttribute+PostgreSQL72.m: add postgres types + +Thu Aug 22 11:08:35 2002 Jan Reichmann + + * PostgreSQL72Channel.m, PostgreSQL72Values.m: + -fixed bug (attributes with the same name were not fetched + (both attrs. where set to the first attr.-value) + -fixed escape-bug + +Thu Jun 13 14:57:10 2002 Jan41 Reichmann + + * PostgreSQL72Values.m: remove Logs + +Tue Jun 11 14:43:14 2002 Jan41 Reichmann + + * PostgreSQL72Context.m: remove abort() :( + +Mon Mar 18 12:53:42 CET 2002 Jan41 Reichmann + + * PostgreSQLValues.m, *Channel.*: add caches for attributes/ + add get primary key infos + +Mon Mar 11 12:02:24 2002 Jan41 Reichmann + + * PostgreSQLValues.m: fixed CAL-FORMAT Entry + +Thu Aug 16 14:13:10 2001 Martin Hoerning + + * PostgreSQLChannel.m: fixed RETAIN-BUGS, removed LOGS + +Fri Jul 27 17:32:17 2001 Jan Reichmann + + * EOAttribute+PostgreSQL.m: fixed timezone bugs + +Thu Jul 5 14:08:11 2001 Helge Hess + + * reactivated for SkyDev41 + +Tue Feb 2 09:01:10 1999 Helge Hess + + * created ChangeLog diff --git a/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.h b/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.h new file mode 100644 index 00000000..07ca6890 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.h @@ -0,0 +1,47 @@ +/* + EOAttribute+PostgreSQL72.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAttribute+PostgreSQL72.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_EOAttribute_H___ +#define ___PostgreSQL72_EOAttribute_H___ + +#import +#include + +@class NSString; + +@interface EOAttribute(PostgreSQL72AttributeAdditions) + +- (void)loadValueClassAndTypeUsingPostgreSQLType:(Oid)_type + size:(int)_size + modification:(int)_modification + binary:(BOOL)_isBinary; + +- (void)loadValueClassForExternalPostgreSQLType:(NSString *)_type; + +@end + +#endif /* ___PostgreSQL72_EOAttribute_H___ */ diff --git a/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.m b/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.m new file mode 100644 index 00000000..0a68fb36 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.m @@ -0,0 +1,232 @@ +/* + EOAttribute+PostgreSQL72.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: EOAttribute+PostgreSQL72.m 1 2004-08-20 10:38:46Z znek $ + +#include "common.h" +#import "EOAttribute+PostgreSQL72.h" + +#if 0 +#include +#else +#include +#endif +#include + +// Sybase dateformat: (need to be corrected for PostgreSQL) +static NSString *PGSQL_DATETIME_FORMAT = @"%b %d %Y %I:%M:%S:000%p"; +static NSString *PGSQL_TIMESTAMP_FORMAT = @"%Y-%m-%d %H:%M:%S%z"; + +@implementation EOAttribute(PostgreSQL72AttributeAdditions) + +- (void)loadValueClassAndTypeUsingPostgreSQLType:(Oid)_type + size:(int)_size + modification:(int)_modification + binary:(BOOL)_isBinary +{ + if (_isBinary) + [self setValueClassName:@"NSData"]; + + switch (_type) { + /* where in the PostgreSQL72 headers are these OIDs defined ??? */ + case BOOLOID: + [self setExternalType:@"bool"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + return; + case NAMEOID: + [self setExternalType:@"name"]; + [self setValueClassName:@"NSString"]; + return; + case TEXTOID: + [self setExternalType:@"textoid"]; + [self setValueClassName:@"NSString"]; + return; + case INT2OID: + [self setExternalType:@"int2"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + return; + case INT4OID: + [self setExternalType:@"int4"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + return; + case INT8OID: + [self setExternalType:@"int8"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + return; + + case CHAROID: + [self setExternalType:@"char"]; + [self setValueClassName:@"NSString"]; + break; + case VARCHAROID: + [self setExternalType:@"varchar"]; + [self setValueClassName:@"NSString"]; + break; + case NUMERICOID: + [self setExternalType:@"numeric"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + break; + case FLOAT4OID: + [self setExternalType:@"float4"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"f"]; + break; + case FLOAT8OID: + [self setExternalType:@"float8"]; + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"f"]; + break; + + case DATEOID: + [self setExternalType:@"datetime"]; + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:PGSQL_DATETIME_FORMAT]; + break; + case TIMEOID: + [self setExternalType:@"time"]; + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:PGSQL_DATETIME_FORMAT]; + break; + case TIMESTAMPOID: + [self setExternalType:@"timestamp"]; + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:PGSQL_DATETIME_FORMAT]; + break; + case TIMESTAMPTZOID: + [self setExternalType:@"timestamptz"]; + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:PGSQL_DATETIME_FORMAT]; + break; + case BITOID: + [self setExternalType:@"bit"]; + break; + default: + NSLog(@"What is PGSQL Oid %i ???", _type); + break; + } +} + +- (void)loadValueClassForExternalPostgreSQLType:(NSString *)_type { + if ([_type isEqualToString:@"bool"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + } + else if ([_type isEqualToString:@"int2"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + } + else if ([_type isEqualToString:@"int4"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"i"]; + } + else if ([_type isEqualToString:@"float4"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"f"]; + } + else if ([_type isEqualToString:@"float8"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + } + else if ([_type isEqualToString:@"decimal"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + } + else if ([_type isEqualToString:@"numeric"]) { + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + } + else if ([_type isEqualToString:@"cardinal_number"]) { + // TODO: not sure whether this is correct (comes from sql_features table) + [self setValueClassName:@"NSNumber"]; + [self setValueType:@"d"]; + } + else if ([_type isEqualToString:@"name"]) { + [self setExternalType:@"name"]; + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"varchar"]) { + [self setExternalType:@"varchar"]; + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"char"]) { + [self setExternalType:@"char"]; + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"character_data"]) { + // TODO: not sure whether this is correct (comes from sql_features table) + [self setExternalType:@"character_data"]; + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"timestamp"]) { + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:PGSQL_TIMESTAMP_FORMAT]; + } + else if ([_type isEqualToString:@"timestamptz"]) { + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:PGSQL_TIMESTAMP_FORMAT]; + } + else if ([_type isEqualToString:@"datetime"]) { + [self setValueClassName:@"NSCalendarDate"]; + [self setCalendarFormat:PGSQL_DATETIME_FORMAT]; + } + else if ([_type isEqualToString:@"date"]) { + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"time"]) { + [self setValueClassName:@"NSString"]; + } + else if ([_type isEqualToString:@"text"]) { + [self setValueClassName:@"NSString"]; + } + else { + NSLog(@"%s: invalid argument %@", __PRETTY_FUNCTION__, _type); + +#if LIB_FOUNDATION_LIBRARY + [InvalidArgumentException raise:@"InvalidArgumentException" + format: + @"invalid PostgreSQL72 type %@ passed to " + @"-loadValueClassForExternalPostgreSQLType:", + _type]; +#else + [NSException raise:@"InvalidArgumentException" + format: + @"invalid PostgreSQL72 type %@ passed to " + @"-loadValueClassForExternalPostgreSQLType:", + _type]; +#endif + } +} + +@end /* EOAttribute(PostgreSQL72) */ + +void __link_EOAttributePostgreSQL72() { + // used to force linking of object file + __link_EOAttributePostgreSQL72(); +} diff --git a/sope-gdl1/PostgreSQL72/GNUmakefile b/sope-gdl1/PostgreSQL72/GNUmakefile new file mode 100644 index 00000000..f73bb891 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/GNUmakefile @@ -0,0 +1,66 @@ +# +# GNUmakefile +# +# Copyright (C) 2004 SKYRIX Software AG +# +# Author: Helge Hess (helge.hess@skyrix.com) +# +# This file is part of the PostgreSQL Adaptor Library +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; see the file COPYING.LIB. +# If not, write to the Free Software Foundation, +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# $Id: GNUmakefile 1 2004-08-20 10:38:46Z znek $ + +include $(GNUSTEP_MAKEFILES)/common.make + +BUNDLE_NAME = PostgreSQL72 + +PostgreSQL72_OBJC_FILES = \ + PGConnection.m \ + PostgreSQL72Expression.m \ + PostgreSQL72Adaptor.m \ + PostgreSQL72Context.m \ + PostgreSQL72Channel.m \ + PostgreSQL72Channel+Model.m \ + PostgreSQL72Exception.m \ + PostgreSQL72Values.m \ + NSString+PostgreSQL72.m \ + EOAttribute+PostgreSQL72.m \ + NSString+PGVal.m \ + NSData+PGVal.m \ + NSCalendarDate+PGVal.m \ + NSNumber+PGVal.m \ + +PostgreSQL72_PRINCIPAL_CLASS = PostgreSQL72Adaptor + +BUNDLE_INSTALL = PostgreSQL72 +BUNDLE_INSTALL_DIR = $(GNUSTEP_INSTALLATION_DIR)/Libraries/Adaptors + +# Use .gdladaptor as the bundle extension +BUNDLE_EXTENSION = .gdladaptor + +PostgreSQL72_RESOURCE_FILES += Version + +# tool + +TOOL_NAME = gdltest + +gdltest_OBJC_FILES = gdltest.m + +-include GNUmakefile.preamble +include $(GNUSTEP_MAKEFILES)/bundle.make +#include $(GNUSTEP_MAKEFILES)/tool.make +-include GNUmakefile.postamble diff --git a/sope-gdl1/PostgreSQL72/GNUmakefile.preamble b/sope-gdl1/PostgreSQL72/GNUmakefile.preamble new file mode 100644 index 00000000..6607d48e --- /dev/null +++ b/sope-gdl1/PostgreSQL72/GNUmakefile.preamble @@ -0,0 +1,61 @@ +# +# GNUmakefile +# +# Copyright (C) 2003-2004 SKYRIX Software AG +# +# Author: Helge Hess (helge.hess@skyrix.com) +# +# This file is part of the PostgreSQL Adaptor Library +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; see the file COPYING.LIB. +# If not, write to the Free Software Foundation, +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# $Id: GNUmakefile.preamble 1 2004-08-20 10:38:46Z znek $ + +PostgreSQL72_BUNDLE_LIBS += -lpq +PostgreSQL72_BUNDLE_LIBS += -lGDLAccess -lEOControl + +gdltest_TOOL_LIBS += -lGDLAccess + +# set compile flags and go + +ADDITIONAL_INCLUDE_DIRS += \ + -I../GDLAccess -I.. + +ADDITIONAL_INCLUDE_DIRS += \ + -I$(PGSQL)/include/pgsql \ + -I$(PGSQL)/include \ + -I.. -I../.. \ + -I../../../SOPE/skyrix-core/ \ + -I/usr/local/include/pgsql \ + -I/usr/local/include \ + -I/usr/local/pgsql/include \ + -I/usr/include/pgsql \ + -I/usr/include/postgresql \ + -I/usr/include \ + -I/Library/PostgreSQL/include/ \ + +ADDITIONAL_LIB_DIRS += \ + -L../GDLAccess/$(GNUSTEP_OBJ_DIR)\ + -L$(PGSQL)/lib \ + -L/usr/local/lib \ + -L/usr/local/pgsql/lib/ \ + -L/usr/lib + +ifeq ($(FOUNDATION_LIB),apple) + +PostgreSQL72_BUNDLE_LIBS += -lssl -lcrypto + +endif diff --git a/sope-gdl1/PostgreSQL72/NSCalendarDate+PGVal.m b/sope-gdl1/PostgreSQL72/NSCalendarDate+PGVal.m new file mode 100644 index 00000000..0774841b --- /dev/null +++ b/sope-gdl1/PostgreSQL72/NSCalendarDate+PGVal.m @@ -0,0 +1,179 @@ +// $Id: NSCalendarDate+PGVal.m 1 2004-08-20 10:38:46Z znek $ + +#import +#include "PostgreSQL72Channel.h" +#include "common.h" + +// Sybase Date: Oct 21 1997 9:52:26:000PM +static NSString *PGSQL_DATETIME_FORMAT = @"%b %d %Y %I:%M:%S:000%p"; + +@implementation NSCalendarDate(PostgreSQL72Values) + +/* + Format: '2001-07-26 14:00:00+02' (len 22) + '2001-07-26 14:00:00+09:30' (len 25) + 0123456789012345678901234 + + Matthew: "07/25/2003 06:00:00 CDT". +*/ + +static Class NSCalDateClass = Nil; +static NSTimeZone *DefServerTimezone = nil; +static NSTimeZone *gmt = nil; +static NSTimeZone *gmt01 = nil; +static NSTimeZone *gmt02 = nil; + ++ (id)valueFromCString:(const char *)_cstr length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ + static unsigned char buf[28]; // reused buffer + unsigned char *p; + NSTimeZone *attrTZ; + NSCalendarDate *date; + int year, month, day, hour, min, sec, tzOffset = 0; + + if (_length == 0) + return nil; + + if (_length != 22 && _length != 25) { + // TODO: add support for "2001-07-26 14:00:00" (len=19) + NSLog(@"ERROR(%s): unexpected string '%s' for date type '%@', returning " + @"now (expected format: '2001-07-26 14:00:00+02')", + __PRETTY_FUNCTION__, + _cstr, _type); + return [NSCalendarDate date]; + } + strncpy(buf, _cstr, 25); + buf[25] = '\0'; + + /* perform on reverse, so that we don't overwrite with null-terminators */ + + if (_length == 22) { + p = &(buf[19]); + tzOffset = atoi(p) * 60; + } + else if (_length >= 25) { + int mins; + p = &(buf[23]); + mins = atoi(p); + buf[22] = '\0'; // the ':' + p = &(buf[19]); + tzOffset = atoi(p) * 60; + tzOffset = tzOffset > 0 ? (tzOffset + mins) : (tzOffset - mins); + } + + p = &(buf[17]); buf[19] = '\0'; sec = atoi(p); + p = &(buf[14]); buf[16] = '\0'; min = atoi(p); + p = &(buf[11]); buf[13] = '\0'; hour = atoi(p); + p = &(buf[8]); buf[10] = '\0'; day = atoi(p); + p = &(buf[5]); buf[7] = '\0'; month = atoi(p); + p = &(buf[0]); buf[4] = '\0'; year = atoi(p); + + /* TODO: cache all timezones (just 26 ;-) */ + switch (tzOffset) { + case 0: + if (gmt == nil) { + gmt = [[NSTimeZone timeZoneForSecondsFromGMT:0] retain]; + NSAssert(gmt, @"could not create GMT timezone?!"); + } + attrTZ = gmt; + break; + case 60: + if (gmt01 == nil) { + gmt01 = [[NSTimeZone timeZoneForSecondsFromGMT:3600] retain]; + NSAssert(gmt01, @"could not create GMT+01 timezone?!"); + } + attrTZ = gmt01; + break; + case 120: + if (gmt02 == nil) { + gmt02 = [[NSTimeZone timeZoneForSecondsFromGMT:7200] retain]; + NSAssert(gmt02, @"could not create GMT+02 timezone?!"); + } + attrTZ = gmt02; + break; + + default: { + /* cache the first, "alternative" timezone */ + static int firstTZOffset = 0; // can use 0 since GMT is a separate case + static NSTimeZone *firstTZ = nil; + if (firstTZOffset == 0) { + firstTZOffset = tzOffset; + firstTZ = [[NSTimeZone timeZoneForSecondsFromGMT:(tzOffset*60)] retain]; + } + + attrTZ = (firstTZOffset == tzOffset) + ? firstTZ + : [NSTimeZone timeZoneForSecondsFromGMT:(tzOffset * 60)]; + break; + } + } + + if (NSCalDateClass == Nil) NSCalDateClass = [[NSCalendarDate class] retain]; + date = [NSCalDateClass dateWithYear:year month:month day:day + hour:hour minute:min second:sec + timeZone:attrTZ]; + if (date == nil) { + NSLog(@"ERROR(%s): could not construct date from string '%s': " + @"year=%i,month=%i,day=%i,hour=%i,minute=%i,second=%i, tz=%@", + __PRETTY_FUNCTION__, _cstr, + year, month, day, hour, min, sec, attrTZ); + } + return date; +} + ++ (id)valueFromBytes:(const void *)_bytes length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ +#if COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY + NSLog(@"%s: not implemented!", __PRETTY_FUNCTION__); + return nil; +#else + return [self notImplemented:_cmd]; +#endif +} + +- (NSString *)stringValueForPostgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute +{ +#if 0 + NSString *format; +#endif + EOQuotedExpression *expr; + NSTimeZone *serverTimeZone; + NSString *format; + NSString *val; + + if ((serverTimeZone = [_attribute serverTimeZone]) == nil ) { + if (DefServerTimezone == nil) { + DefServerTimezone = [[NSTimeZone localTimeZone] retain]; + NSLog(@"Note: PostgreSQL72 adaptor using timezone '%@' as default", + DefServerTimezone); + } + serverTimeZone = DefServerTimezone; + } + +#if 0 + format = [_attribute calendarFormat]; +#else /* hm, why is that? */ + format = @"%Y-%m-%d %H:%M:%S%z"; +#endif + if (format == nil) + format = PGSQL_DATETIME_FORMAT; + + [self setTimeZone:serverTimeZone]; + + val = [self descriptionWithCalendarFormat:format]; + expr = [[EOQuotedExpression alloc] initWithExpression:val + quote:@"\'" escape:@"\\'"]; + val = [[expr expressionValueForContext:nil] retain]; + [expr release]; + + return [val autorelease]; +} + +@end /* NSCalendarDate(PostgreSQL72Values) */ diff --git a/sope-gdl1/PostgreSQL72/NSData+PGVal.m b/sope-gdl1/PostgreSQL72/NSData+PGVal.m new file mode 100644 index 00000000..a0095f4f --- /dev/null +++ b/sope-gdl1/PostgreSQL72/NSData+PGVal.m @@ -0,0 +1,97 @@ +// $Id: NSData+PGVal.m 1 2004-08-20 10:38:46Z znek $ + +#import +#include "PostgreSQL72Values.h" +#include "PostgreSQL72Channel.h" +#include "common.h" + +@implementation NSData(PostgreSQL72Values) + +static BOOL doDebug = NO; +static NSData *EmptyData = nil; + ++ (id)valueFromCString:(const char *)_cstr length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ + if (_length == 0) { + if (EmptyData == nil) EmptyData = [[NSData alloc] init]; + return EmptyData; + } + return [[[self alloc] initWithBytes:_cstr length:_length] autorelease]; +} + ++ (id)valueFromBytes:(const void *)_bytes length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ + if (_length == 0) { + if (EmptyData == nil) EmptyData = [[NSData alloc] init]; + return EmptyData; + } + return [[[self alloc] initWithBytes:_bytes length:_length] autorelease]; +} + +- (NSString *)stringValueForPostgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute +{ + // TODO: UNICODE + // TODO: this method looks slow + // example type: "VARCHAR(4000)" + static NSStringEncoding enc = 0; + NSString *str, *t; + unsigned len; + unichar c1; + + if ((len = [self length]) == 0) + return @""; + + if (enc == 0) { + enc = [NSString defaultCStringEncoding]; + NSLog(@"Note: PostgreSQL72 adaptor using '%@' encoding for data=>string " + @"conversion.", + [NSString localizedNameOfStringEncoding:enc]); + } + + str = [[NSString alloc] initWithData:self encoding:enc]; + + if (doDebug) { + NSLog(@"Note: made string (len=%i) for data (len=%i), type %@", + [str length], [self length], _type); + } + + if ((len = [_type length]) == 0) { + NSLog(@"WARNING(%s): missing type for data=>string conversion!", + __PRETTY_FUNCTION__); + return [str autorelease]; + } + + c1 = [_type characterAtIndex:0]; + switch (c1) { + case 'c': case 'C': // char + case 'v': case 'V': // varchar + case 'm': case 'M': // money + case 't': case 'T': // text + t = [_type lowercaseString]; + if ([t hasPrefix:@"char"] || + [t hasPrefix:@"varchar"] || + [t hasPrefix:@"money"] || + [t hasPrefix:@"text"]) { + if (doDebug) NSLog(@" converting type: %@", t); + t = [[str stringValueForPostgreSQLType:_type + attribute:_attribute] copy]; + [str release]; + if (doDebug) NSLog(@" result len %i", [t length]); + return [t autorelease]; + } + } + + NSLog(@"WARNING(%s): no processing of type '%@' for " + @"data=>string conversion!", + __PRETTY_FUNCTION__, _type); + return [str autorelease];; +} + +@end /* NSData(PostgreSQL72Values) */ diff --git a/sope-gdl1/PostgreSQL72/NSNumber+PGVal.m b/sope-gdl1/PostgreSQL72/NSNumber+PGVal.m new file mode 100644 index 00000000..49728183 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/NSNumber+PGVal.m @@ -0,0 +1,156 @@ +// $Id: NSNumber+PGVal.m 1 2004-08-20 10:38:46Z znek $ + +#import +#include "PostgreSQL72Channel.h" +#include "common.h" + +@implementation NSNumber(PostgreSQL72Values) + +static BOOL debugOn = NO; +static Class NSNumberClass = Nil; +static NSNumber *yesNum = nil; +static NSNumber *noNum = nil; + ++ (id)valueFromCString:(const char *)_cstr length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ + // TODO: can we avoid the lowercaseString? + unsigned len; + unichar c1; + + if ((len = [_type length]) == 0) + return nil; + + if (NSNumberClass == Nil) NSNumberClass = [NSNumber class]; + + c1 = [_type characterAtIndex:0]; + switch (c1) { + case 'f': case 'F': { + if (len < 5) + break; + if ([[_type lowercaseString] hasPrefix:@"float"]) + return [NSNumberClass numberWithDouble:atof(_cstr)]; + break; + } + case 's': case 'S': { + if (len < 8) + break; + if ([[_type lowercaseString] hasPrefix:@"smallint"]) + return [NSNumberClass numberWithShort:atoi(_cstr)]; + break; + } + case 'i': case 'I': { + if (len < 3) + break; + if ([[_type lowercaseString] hasPrefix:@"int"]) + return [NSNumberClass numberWithInt:atoi(_cstr)]; + } + case 'b': case 'B': { + if (len < 4) + break; + if (![[_type lowercaseString] hasPrefix:@"bool"]) + break; + + if (yesNum == nil) yesNum = [[NSNumberClass numberWithBool:YES] retain]; + if (noNum == nil) noNum = [[NSNumberClass numberWithBool:NO] retain]; + + if (_length == 0) + return noNum; + + switch (*_cstr) { + case 't': case 'T': + case 'y': case 'Y': + case '1': + return yesNum; + default: + return noNum; + } + } + } + return nil; +} + ++ (id)valueFromBytes:(const void *)_bytes length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ +#if COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY + NSLog(@"%s: not implemented!", __PRETTY_FUNCTION__); + return nil; +#else + return [self notImplemented:_cmd]; +#endif +} + +- (NSString *)stringValueForPostgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute +{ + // TODO: can we avoid the lowercaseString? + unsigned len; + unichar c1; + + if (debugOn) + NSLog(@"%s(type=%@,attr=%@)", __PRETTY_FUNCTION__, _type, _attribute); + + if ((len = [_type length]) == 0) { + if (debugOn) NSLog(@" no type, return string"); + return [self stringValue]; + } + if (len < 4) { /* apparently this is 'INT'? */ + if (debugOn) NSLog(@" type len < 4 (%@), return string", _type); +#if GNUSTEP_BASE_LIBRARY + /* + on gstep-base -stringValue of bool's return YES or NO, which seems to + be different on Cocoa and liBFoundation. + */ + { + Class BoolClass = Nil; + + if (BoolClass == Nil) BoolClass = NSClassFromString(@"NSBoolNumber"); + if ([self isKindOfClass:BoolClass]) + return [self boolValue] ? @"1" : @"0"; + } +#endif + return [self stringValue]; + } + + c1 = [_type characterAtIndex:0]; + if (debugOn) NSLog(@" typecode '%c' ...", c1); + switch (c1) { + case 'b': case 'B': + if (![[_type lowercaseString] hasPrefix:@"bool"]) + break; + return [self boolValue] ? @"true" : @"false"; + + case 'm': case 'M': { + if (![[_type lowercaseString] hasPrefix:@"money"]) + break; + return [@"$" stringByAppendingString:[self stringValue]]; + } + + case 'c': case 'C': + case 't': case 'T': + case 'v': case 'V': { + static NSMutableString *ms = nil; // reuse mstring, THREAD + + _type = [_type lowercaseString]; + if (!([_type hasPrefix:@"char"] || + [_type hasPrefix:@"varchar"] || + [_type hasPrefix:@"text"])) + break; + + // TODO: can we get this faster?! + if (ms == nil) ms = [[NSMutableString alloc] initWithCapacity:256]; + [ms setString:@"'"]; + [ms appendString:[self stringValue]]; + [ms appendString:@"'"]; + return [[ms copy] autorelease]; + } + } + return [self stringValue]; +} + +@end /* NSNumber(PostgreSQL72Values) */ diff --git a/sope-gdl1/PostgreSQL72/NSString+PGVal.m b/sope-gdl1/PostgreSQL72/NSString+PGVal.m new file mode 100644 index 00000000..28839990 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/NSString+PGVal.m @@ -0,0 +1,88 @@ +// $Id: NSString+PGVal.m 1 2004-08-20 10:38:46Z znek $ + +#import +#include "PostgreSQL72Channel.h" +#include +#include "common.h" + +@implementation NSString(PostgreSQL72Values) + +static Class NSStringClass = Nil; +static Class EOExprClass = Nil; + ++ (id)valueFromCString:(const char *)_cstr length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ + if (_cstr == NULL) return nil; + if (*_cstr == '\0') return @""; + if (NSStringClass == Nil) NSStringClass = [NSString class]; + + // TODO: cache IMP of selector + return [NSStringClass stringWithCString:_cstr]; +} + ++ (id)valueFromBytes:(const void *)_bytes length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel +{ +#if COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY + NSLog(@"%s: not implemented!", __PRETTY_FUNCTION__); + return nil; +#else + return [self notImplemented:_cmd]; +#endif +} + +- (NSString *)stringValueForPostgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute +{ + // TODO: all this looks slow ... + unsigned len; + unichar c1; + + if ((len = [_type length]) == 0) + return self; + + c1 = [_type characterAtIndex:0]; + switch (c1) { + case 'c': case 'C': + case 'v': case 'V': + case 't': case 'T': { + NSString *s; + EOQuotedExpression *expr; + + if (len < 4) + return self; + + _type = [_type lowercaseString]; + + if (!([_type hasPrefix:@"char"] || + [_type hasPrefix:@"varchar"] || + [_type hasPrefix:@"text"])) + break; + + /* TODO: creates too many autoreleased strings :-( */ + + s = [self stringByReplacingString:@"\\" withString:@"\\\\"]; + + if (EOExprClass == Nil) EOExprClass = [EOQuotedExpression class]; + expr = [[EOExprClass alloc] initWithExpression:s quote:@"'" escape:@"\\'"]; + s = [[expr expressionValueForContext:nil] retain]; + [expr release]; + return [s autorelease]; + } + case 'm': case 'M': { + if (len < 5) { + if ([[_type lowercaseString] hasPrefix:@"money"]) + return [@"$" stringByAppendingString:self]; + } + break; + } + } + return self; +} + +@end /* NSString(PostgreSQL72Values) */ diff --git a/sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.h b/sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.h new file mode 100644 index 00000000..ae5ed909 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.h @@ -0,0 +1,41 @@ +/* + NSString+PostgreSQL72.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: NSString+PostgreSQL72.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_NSString_H___ +#define ___PostgreSQL72_NSString_H___ + +#import + +@interface NSString(PostgreSQL72MiscStrings) + +- (NSString *)_pgModelMakeInstanceVarName; +- (NSString *)_pgModelMakeClassName; +- (NSString *)_pgStringWithCapitalizedFirstChar; +- (NSString *)_pgStripEndSpaces; + +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.m b/sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.m new file mode 100644 index 00000000..dfcbb519 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.m @@ -0,0 +1,162 @@ +/* + NSString+PostgreSQL72.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: NSString+PostgreSQL72.m 1 2004-08-20 10:38:46Z znek $ + +#if LIB_FOUNDATION_BOEHM_GC +# include +#endif + +#import +#include "common.h" +#import "NSString+PostgreSQL72.h" + +@implementation NSString(PostgreSQL72MiscStrings) + +- (NSString *)_pgModelMakeInstanceVarName { + if ([self length] == 0) + return @""; + else { + unsigned clen = 0; + char *s = NULL; + int cnt, cnt2; + + clen = [self cStringLength]; + s = malloc(clen + 10); + + [self getCString:s maxLength:clen]; + + for (cnt = cnt2 = 0; cnt < clen; cnt++, cnt2++) { + if ((s[cnt] == '_') && (s[cnt + 1] != '\0')) { + s[cnt2] = toupper(s[cnt + 1]); + cnt++; + } + else if ((s[cnt] == '2') && (s[cnt + 1] != '\0')) { + s[cnt2] = s[cnt]; + cnt++; + cnt2++; + s[cnt2] = toupper(s[cnt]); + } + else + s[cnt2] = tolower(s[cnt]); + } + s[cnt2] = '\0'; + + return [[[NSString alloc] + initWithCStringNoCopy:s length:strlen(s) freeWhenDone:YES] + autorelease]; + } +} + +- (NSString *)_pgModelMakeClassName { + if ([self length] == 0) + return @""; + else { + unsigned clen = 0; + char *s = NULL; + int cnt, cnt2; + + clen = [self cStringLength]; + s = malloc(clen + 10); + + [self getCString:s maxLength:clen]; + + for (cnt = cnt2 = 0; cnt < clen; cnt++, cnt2++) { + if ((s[cnt] == '_') && (s[cnt + 1] != '\0')) { + s[cnt2] = toupper(s[cnt + 1]); + cnt++; + } + else if ((s[cnt] == '2') && (s[cnt + 1] != '\0')) { + s[cnt2] = s[cnt]; + cnt++; + cnt2++; + s[cnt2] = toupper(s[cnt]); + } + else + s[cnt2] = tolower(s[cnt]); + } + s[cnt2] = '\0'; + + s[0] = toupper(s[0]); + + return [[[NSString alloc] + initWithCStringNoCopy:s length:strlen(s) + freeWhenDone:YES] + autorelease]; + } +} + +- (NSString *)_pgStringWithCapitalizedFirstChar { + NSCharacterSet *upperSet = [NSCharacterSet uppercaseLetterCharacterSet]; + + if ([self length] == 0) + return @""; + else if ([upperSet characterIsMember:[self characterAtIndex:0]]) + return [[self copy] autorelease]; + else { + NSMutableString *str = [NSMutableString stringWithCapacity:[self length]]; + + [str appendString:[[self substringToIndex:1] uppercaseString]]; + [str appendString:[self substringFromIndex:1]]; + + return [[str copy] autorelease]; + } +} + +- (NSString *)_pgStripEndSpaces { + if ([self length] > 0) { + NSCharacterSet *spaceSet = [NSCharacterSet whitespaceCharacterSet]; + NSMutableString *str = [NSMutableString stringWithCapacity:[self length]]; + IMP charAtIndex; + NSRange range; + + charAtIndex = [self methodForSelector:@selector(characterAtIndex:)]; + range.length = 0; + + for (range.location = ([self length] - 1); + range.location >= 0; + range.location++, range.length++) { + unichar c; + + c = (unichar)(int)charAtIndex(self, @selector(characterAtIndex:), + range.location); + if (![spaceSet characterIsMember:c]) + break; + } + + if (range.length > 0) { + [str appendString:self]; + [str deleteCharactersInRange:range]; + return AUTORELEASE([str copy]); + } + } + return AUTORELEASE([self copy]); +} + +@end + +void __link_NSStringPostgreSQL72() { + // used to force linking of object file + __link_NSStringPostgreSQL72(); +} diff --git a/sope-gdl1/PostgreSQL72/PGConnection.h b/sope-gdl1/PostgreSQL72/PGConnection.h new file mode 100644 index 00000000..ebc81566 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PGConnection.h @@ -0,0 +1,123 @@ +/* + PGConnection.h + + Copyright (C) 2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PGConnection.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_PGConnection_H___ +#define ___PostgreSQL72_PGConnection_H___ + +#import + +@class NSString, NSException; +@class PGResultSet; + +@interface PGConnection : NSObject +{ +@public + void *_connection; +} + +- (id)initWithHostName:(NSString *)_host port:(NSString *)_port + options:(NSString *)_options tty:(NSString *)_tty + database:(NSString *)_dbname + login:(NSString *)_login password:(NSString *)_pwd; + +/* accessors */ + +- (BOOL)isValid; + +/* connect operations */ + +- (NSException *)startConnectWithInfo:(NSString *)_conninfo; // async + +- (NSException *)connectWithInfo:(NSString *)_conninfo; +- (NSException *)connectWithHostName:(NSString *)_host port:(NSString *)_port + options:(NSString *)_options tty:(NSString *)_tty + database:(NSString *)_dbname + login:(NSString *)_login password:(NSString *)_pwd; + +- (void)finish; + +- (BOOL)isConnectionOK; + +/* message callbacks */ + +- (BOOL)setNoticeProcessor:(void *)_callback context:(void *)_ctx; + +/* settings */ + +- (BOOL)setClientEncoding:(NSString *)_encoding; + +/* errors */ + +- (NSString *)errorMessage; + +/* queries */ + +- (void *)rawExecute:(NSString *)_sql; +- (void)clearRawResults:(void *)_ptr; +- (PGResultSet *)execute:(NSString *)_sql; + +@end + +@interface PGResultSet : NSObject +{ +@protected + PGConnection *connection; +@public + void *results; +} + +- (id)initWithConnection:(PGConnection *)_con handle:(void *)_handle; + +/* accessors */ + +- (BOOL)isValid; + +- (BOOL)containsBinaryTuples; +- (NSString *)commandStatus; +- (NSString *)commandTuples; + +/* fields */ + +- (unsigned)fieldCount; +- (NSString *)fieldNameAtIndex:(unsigned int)_idx; +- (int)indexOfFieldNamed:(NSString *)_name; +- (int)fieldSizeAtIndex:(unsigned int)_idx; +- (int)modifierAtIndex:(unsigned int)_idx; + +/* tuples */ + +- (unsigned int)tupleCount; +- (BOOL)isNullTuple:(int)_tuple atIndex:(unsigned int)_idx; +- (void *)rawValueOfTuple:(int)_tuple atIndex:(unsigned int)_idx; +- (int)lengthOfTuple:(int)_tuple atIndex:(unsigned int)_idx; + +/* operations */ + +- (void)clear; + +@end + +#endif /* ___PostgreSQL72_PGConnection_H___ */ diff --git a/sope-gdl1/PostgreSQL72/PGConnection.m b/sope-gdl1/PostgreSQL72/PGConnection.m new file mode 100644 index 00000000..78812601 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PGConnection.m @@ -0,0 +1,339 @@ +/* + PGConnection.m + + Copyright (C) 2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PGConnection.m 1 2004-08-20 10:38:46Z znek $ + +#include "PGConnection.h" +#include "common.h" +#include + +#if PG_MAJOR_VERSION >= 6 && PG_MINOR_VERSION > 3 +# define NG_HAS_NOTICE_PROCESSOR 1 +# define NG_HAS_BINARY_TUPLES 1 +# define NG_HAS_FMOD 1 +#endif + +#if PG_MAJOR_VERSION >= 7 && PG_MINOR_VERSION > 3 +# define NG_SET_CLIENT_ENCODING 1 +#endif + +@implementation PGConnection + +static BOOL debugOn = NO; + +- (id)initWithHostName:(NSString *)_host port:(NSString *)_port + options:(NSString *)_options tty:(NSString *)_tty + database:(NSString *)_dbname + login:(NSString *)_login password:(NSString *)_pwd +{ + if ((self = [self init])) { + NSException *error; + + error = [self connectWithHostName:_host port:_port options:_options + tty:_tty database:_dbname login:_login password:_pwd]; + if (error != nil) { + if (debugOn) + NSLog(@"%s: could not connect: %@", __PRETTY_FUNCTION__, error); + [self release]; + return nil; + } + } + return self; +} + +- (void)dealloc { + [self finish]; + [super dealloc]; +} + +/* support */ + +- (const char *)_cstrFromString:(NSString *)_s { + // TODO: fix API, check what the API string encoding is + return [_s cString]; +} +- (NSString *)_stringFromCString:(const char *)_cstr { + return [NSString stringWithCString:_cstr]; +} + +/* accessors */ + +- (BOOL)isValid { + return self->_connection != NULL ? YES : NO; +} + +/* errors */ + +- (NSException *)_makeConnectException:(const char *)_func { + return [NSException exceptionWithName:@"PGConnectFailed" + reason:[NSString stringWithCString:_func] + userInfo:nil]; +} + +/* connect operations */ + +- (void)_disconnect { + if (self->_connection != NULL) + [self finish]; +} + +- (NSException *)startConnectWithInfo:(NSString *)_conninfo { + [self _disconnect]; + + self->_connection = PQconnectStart([self _cstrFromString:_conninfo]); + if (self->_connection == NULL) + return [self _makeConnectException:__PRETTY_FUNCTION__]; + return nil; +} +// TODO: add method for polling connect status + +- (NSException *)connectWithInfo:(NSString *)_conninfo { + [self _disconnect]; + + self->_connection = PQconnectdb([self _cstrFromString:_conninfo]); + if (self->_connection == NULL) + return [self _makeConnectException:__PRETTY_FUNCTION__]; + return nil; +} + +- (NSException *)connectWithHostName:(NSString *)_host port:(NSString *)_port + options:(NSString *)_options tty:(NSString *)_tty + database:(NSString *)_dbname + login:(NSString *)_login password:(NSString *)_pwd +{ + [self _disconnect]; + + self->_connection = PQsetdbLogin([self _cstrFromString:_host], + [self _cstrFromString:_port], + [self _cstrFromString:_options], + [self _cstrFromString:_tty], + [self _cstrFromString:_dbname], + [self _cstrFromString:_login], + [self _cstrFromString:_pwd]); + if (self->_connection == NULL) + return [self _makeConnectException:__PRETTY_FUNCTION__]; + return nil; +} + +- (void)finish { + if (self->_connection != NULL) { + PQfinish(self->_connection); + self->_connection = NULL; + } +} + +- (BOOL)isConnectionOK { + if (![self isValid]) + return NO; + return PQstatus(self->_connection) == CONNECTION_OK ? YES : NO; +} + +/* message callbacks */ + +- (BOOL)setNoticeProcessor:(void *)_callback context:(void *)_ctx { +#if NG_HAS_NOTICE_PROCESSOR + PQsetNoticeProcessor(self->_connection, _callback, _ctx); + return YES; // TODO: improve error handling +#else + return NO; +#endif +} + +/* settings */ + +- (BOOL)setClientEncoding:(NSString *)_encoding { + return PQsetClientEncoding(self->_connection, + [self _cstrFromString:_encoding]) == 0 ? YES : NO; +} + +/* errors */ + +- (NSString *)errorMessage { + if (![self isValid]) + return nil; + + return [self _stringFromCString:PQerrorMessage(self->_connection)]; +} + +/* queries */ + +- (void *)rawExecute:(NSString *)_sql { + return PQexec(self->_connection, [self _cstrFromString:_sql]); +} +- (void)clearRawResults:(void *)_ptr { + if (_ptr == NULL) return; + PQclear(_ptr); +} + +- (PGResultSet *)execute:(NSString *)_sql { + void *handle; + + if ((handle = [self rawExecute:_sql]) == NULL) + return nil; + + return [[[PGResultSet alloc] initWithConnection:self handle:handle] + autorelease]; +} + +/* debugging */ + +- (BOOL)isDebuggingEnabled { + return debugOn; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]: ", self, NSStringFromClass([self class])]; + if ([self isValid]) + [ms appendFormat:@" connection=0x%08X", self->_connection]; + else + [ms appendString:@" not-connected"]; + [ms appendString:@">"]; + return ms; +} + +@end /* PGConnection */ + +@implementation PGResultSet + +/* wraps PGresult */ + +- (id)initWithConnection:(PGConnection *)_con handle:(void *)_handle { + if (_handle == NULL) { + [self release]; + return nil; + } + if ((self = [super init])) { + self->connection = [_con retain]; + self->results = _handle; + } + return self; +} + +- (void)dealloc { + [self clear]; + [self->connection release]; + [super dealloc]; +} + +/* accessors */ + +- (BOOL)isValid { + return self->results != NULL ? YES : NO; +} + +- (BOOL)containsBinaryTuples { +#if NG_HAS_BINARY_TUPLES + if (self->results == NULL) return NO; + return PQbinaryTuples(self->results) ? YES : NO; +#else + return NO; +#endif +} + +- (NSString *)commandStatus { + char *cstr; + + if (self->results == NULL) + return nil; + if ((cstr = PQcmdStatus(self->results)) == NULL) + return nil; + return [NSString stringWithCString:cstr]; +} + +- (NSString *)commandTuples { + char *cstr; + + if (self->results == NULL) + return nil; + if ((cstr = PQcmdTuples(self->results)) == NULL) + return nil; + return [NSString stringWithCString:cstr]; +} + +/* fields */ + +- (unsigned)fieldCount { + return self->results != NULL ? PQnfields(self->results) : 0; +} + +- (NSString *)fieldNameAtIndex:(unsigned int)_idx { + // TODO: charset + if (self->results == NULL) return nil; + return [NSString stringWithCString:PQfname(self->results, _idx)]; +} + +- (int)indexOfFieldNamed:(NSString *)_name { + return PQfnumber(self->results, [_name cString]); +} + +- (int)fieldSizeAtIndex:(unsigned int)_idx { + if (self->results == NULL) return 0; + return PQfsize(self->results, _idx); +} + +- (int)modifierAtIndex:(unsigned int)_idx { + if (self->results == NULL) return 0; +#if NG_HAS_FMOD + return PQfmod(self->results, _idx); +#else + return 0; +#endif +} + +/* tuples */ + +- (unsigned int)tupleCount { + if (self->results == NULL) return 0; + return PQntuples(self->results); +} + +- (BOOL)isNullTuple:(int)_tuple atIndex:(unsigned int)_idx { + if (self->results == NULL) return NO; + return PQgetisnull(self->results, _tuple, _idx) ? YES : NO; +} + +- (void *)rawValueOfTuple:(int)_tuple atIndex:(unsigned int)_idx { + if (self->results == NULL) return NULL; + return PQgetvalue(self->results, _tuple, _idx); +} + +- (int)lengthOfTuple:(int)_tuple atIndex:(unsigned int)_idx { + if (self->results == NULL) return 0; + return PQgetlength(self->results, _tuple, _idx); +} + +/* operations */ + +- (void)clear { + if (self->results == NULL) return; + PQclear(self->results); + self->results = NULL; +} + +@end /* PGResultSet */ diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72-Info.plist b/sope-gdl1/PostgreSQL72/PostgreSQL72-Info.plist new file mode 100644 index 00000000..792cb7a4 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72-Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + PostgreSQL72 + CFBundleGetInfoString + + CFBundleIconFile + + CFBundleIdentifier + org.opengroupware.gnustep-db.PostgreSQL72 + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.h new file mode 100644 index 00000000..e0289366 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.h @@ -0,0 +1,89 @@ +/* + PostgreSQL72Adaptor.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Adaptor.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_Adaptor_H___ +#define ___PostgreSQL72_Adaptor_H___ + +/* + The PostgreSQL72 adaptor. + + The connection dictionary of this adaptor understands these keys: + hostName + port + options + tty + userName + password + databaseName + + The adaptor is based on libpq. +*/ + +#import +#import +#import + +@class NSString, NSMutableDictionary, NSArray; + +@interface PostgreSQL72Adaptor : EOAdaptor +{ +} + +- (id)initWithName:(NSString *)_name; + +/* connection management */ + +- (NSString *)serverName; +- (NSString *)loginName; +- (NSString *)loginPassword; +- (NSString *)databaseName; +- (NSString *)port; +- (NSString *)options; +- (NSString *)tty; +- (NSString *)newKeyExpression; + +/* sequence for primary key generation */ + +- (NSString *)primaryKeySequenceName; + +/* value formatting */ + +- (id)formatValue:(id)value forAttribute:(EOAttribute *)attribute; + +/* attribute typing */ + +- (BOOL)attributeAllowedInDistinctSelects:(EOAttribute *)_attr; + +/* classes used */ + +- (Class)adaptorContextClass; // PostgreSQL72Context +- (Class)adaptorChannelClass; // PostgreSQL72Channel +- (Class)expressionClass; // PostgreSQL72Expression + +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.m b/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.m new file mode 100644 index 00000000..18fd8f8b --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.m @@ -0,0 +1,181 @@ +/* + PostgreSQL72Adaptor.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Adaptor.m 1 2004-08-20 10:38:46Z znek $ + +#include "common.h" +#include "PostgreSQL72Adaptor.h" +#include "PostgreSQL72Context.h" +#include "PostgreSQL72Channel.h" +#include "PostgreSQL72Expression.h" +#include "PostgreSQL72Values.h" +#include "PGConnection.h" + +@implementation PostgreSQL72Adaptor + +static BOOL debugOn = NO; + +- (id)initWithName:(NSString *)_name { + if ((self = [super initWithName:_name])) { + } + return self; +} + +- (void)gcFinalize { +} + +- (void)dealloc { + // NSLog(@"%s", __PRETTY_FUNCTION__); + [self gcFinalize]; + [super dealloc]; +} + +/* NSCopying methods */ + +- (id)copyWithZone:(NSZone *)_zone { + return [self retain]; +} + +/* connections */ + +- (NSString *)_copyOfConDictString:(NSString *)_key { + return [[[[self connectionDictionary] objectForKey:_key] copy] autorelease]; +} + +- (NSString *)serverName { + NSString *serverName; + + serverName = [[self connectionDictionary] objectForKey:@"hostName"]; + + if (serverName == nil) { // lookup env-variable + serverName = + [[[NSProcessInfo processInfo] environment] objectForKey:@"PGHOST"]; + } + + return [[serverName copy] autorelease]; +} +- (NSString *)loginName { + return [self _copyOfConDictString:@"userName"]; +} +- (NSString *)loginPassword { + return [self _copyOfConDictString:@"password"]; +} +- (NSString *)databaseName { + return [self _copyOfConDictString:@"databaseName"]; +} + +- (NSString *)port { + return [self _copyOfConDictString:@"port"]; +} +- (NSString *)options { + return [self _copyOfConDictString:@"options"]; +} +- (NSString *)tty { + return [self _copyOfConDictString:@"tty"]; +} + +/* sequence for primary key generation */ + +- (NSString *)primaryKeySequenceName { + NSString *seqName; + + seqName = + [[self pkeyGeneratorDictionary] objectForKey:@"primaryKeySequenceName"]; + return [[seqName copy] autorelease]; +} + +- (NSString *)newKeyExpression { + NSString *newKeyExpr; + + newKeyExpr = + [[self pkeyGeneratorDictionary] objectForKey:@"newKeyExpression"]; + return [[newKeyExpr copy] autorelease]; +} + +/* formatting */ + +- (NSString *)charConvertExpressionForAttributeNamed:(NSString *)_attrName { + return _attrName; +} + +- (id)formatValue:(id)value forAttribute:(EOAttribute *)attribute { + /* + This formats values into SQL constants, eg: + @"blah" will be converted to 'blah' + */ + NSString *result; + + result = [value stringValueForPostgreSQLType:[attribute externalType] + attribute:attribute]; + if (debugOn) { + NSLog(@"formatting value '%@'(%@) result '%@'", + value, NSStringFromClass([value class]), result); + NSLog(@" value class %@ attr %@ attr type %@", + [value class], attribute, [attribute externalType]); + } + return result; +} + +- (BOOL)attributeAllowedInDistinctSelects:(EOAttribute *)_attr { + return YES; +} + +/* types */ + +- (BOOL)isValidQualifierType:(NSString *)_typeName { + return YES; +} + +/* adaptor info */ + +- (Class)adaptorContextClass { + return [PostgreSQL72Context class]; +} +- (Class)adaptorChannelClass { + return [PostgreSQL72Channel class]; +} + +- (Class)expressionClass { + return [PostgreSQL72Expression class]; +} + +@end /* PostgreSQL72Adaptor */ + +void __linkPostgreSQL72Adaptor(void) { + extern void __link_EOAttributePostgreSQL72(); + extern void __link_NSStringPostgreSQL72(); + extern void __link_PostgreSQL72ChannelModel(); + extern void __link_PostgreSQL72Values(); + ; + [PostgreSQL72Channel class]; + [PostgreSQL72Context class]; + [PostgreSQL72Exception class]; + [PostgreSQL72Expression class]; + __link_EOAttributePostgreSQL72(); + __link_NSStringPostgreSQL72(); + //__link_PostgreSQL72ChannelModel(); + __link_PostgreSQL72Values(); + __linkPostgreSQL72Adaptor(); +} diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.h new file mode 100644 index 00000000..9f44474c --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.h @@ -0,0 +1,45 @@ +/* + PostgreSQL72Channel+Model.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Channel+Model.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_ModelFetching_H___ +#define ___PostgreSQL72_ModelFetching_H___ + +#import "PostgreSQL72Channel.h" + +@class NSArray; +@class EOModel; + +@interface PostgreSQL72Channel(ModelFetching) + +- (EOModel *)describeModelWithTableNames:(NSArray *)_tableNames; +- (NSArray *)describeUserNames; +- (NSArray *)describeTableNames; +- (NSArray *)describeDatabaseNames; + +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.m b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.m new file mode 100644 index 00000000..80d974d6 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.m @@ -0,0 +1,363 @@ +/* + PostgreSQL72Channel+Model.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Channel+Model.m 1 2004-08-20 10:38:46Z znek $ + +#include "PostgreSQL72Channel.h" +#include "NSString+PostgreSQL72.h" +#include "EOAttribute+PostgreSQL72.h" +#import "common.h" + +@interface EORelationship(FixMe) +- (void)addJoin:(id)_join; +@end + +@implementation PostgreSQL72Channel(ModelFetching) + +static BOOL debugOn = NO; + +- (NSArray *)_attributesForTableName:(NSString *)_tableName { + NSMutableArray *attributes; + NSString *sqlExpr; + NSArray *resultDescription; + NSDictionary *row; + + if (![_tableName length]) + return nil; + + attributes = [self->_attributesForTableName objectForKey:_tableName]; + if (attributes != nil) + return attributes; + + sqlExpr = + @"SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull " + @"FROM pg_class c, pg_attribute a, pg_type t " + @"WHERE c.relname='%@' AND a.attnum>0 AND a.attrelid=c.oid AND " + @"a.atttypid=t.oid " + @"ORDER BY attnum;"; + sqlExpr = [NSString stringWithFormat:sqlExpr, _tableName]; + + if (![self evaluateExpression:sqlExpr]) { + fprintf(stderr, + "Could not evaluate column-describe '%s' on table '%s'\n", + [sqlExpr cString], [_tableName cString]); + return nil; + } + + resultDescription = [self describeResults]; + attributes = [NSMutableArray arrayWithCapacity:16]; + + while ((row = [self fetchAttributes:resultDescription withZone:NULL])) { + EOAttribute *attribute; + NSString *columnName, *externalType, *attrName; + + columnName = [[row objectForKey:@"attname"] stringValue]; + attrName = [columnName _pgModelMakeInstanceVarName]; + externalType = [[row objectForKey:@"typname"] stringValue]; + + attribute = [[EOAttribute alloc] init]; + [attribute setColumnName:columnName]; + [attribute setName:attrName]; + [attribute setExternalType:externalType]; + [attribute loadValueClassForExternalPostgreSQLType:externalType]; + [attributes addObject:attribute]; + [attribute release]; attribute = nil; + } + [self->_attributesForTableName setObject:attributes forKey:_tableName]; + if (debugOn) NSLog(@"%s: got attrs: %@", __PRETTY_FUNCTION__, attributes); + return attributes; +} + +- (NSArray *)_primaryKeysNamesForTableName:(NSString *)_tableName { + NSArray *pkNameForTableName = nil; + NSMutableArray *primaryKeys = nil; + NSString *selectExpression; + NSArray *resultDescription = nil; + NSString *columnNameKey = nil; + NSDictionary *row = nil; + + if ([_tableName length] == 0) + return nil; + + pkNameForTableName = + [self->_primaryKeysNamesForTableName objectForKey:_tableName]; + + if (pkNameForTableName != nil) + return pkNameForTableName; + + selectExpression = [NSString stringWithFormat: + @"SELECT attname FROM pg_attribute WHERE " + @"attrelid IN (SELECT a.indexrelid FROM " + @"pg_index a, pg_class b WHERE " + @"a.indexrelid = b.oid AND " + @"b.relname in (SELECT indexname FROM " + @"pg_indexes WHERE " + @"tablename = '%@') " + @"AND a.indisprimary)", _tableName]; + + if (![self evaluateExpression:selectExpression]) + return nil; + + resultDescription = [self describeResults]; + columnNameKey = [(EOAttribute *)[resultDescription objectAtIndex:0] name]; + primaryKeys = [NSMutableArray arrayWithCapacity:4]; + + while ((row = [self fetchAttributes:resultDescription withZone:NULL])) + [primaryKeys addObject:[row objectForKey:columnNameKey]]; + + pkNameForTableName = primaryKeys; + [self->_primaryKeysNamesForTableName setObject:pkNameForTableName + forKey:_tableName]; + return pkNameForTableName; +} + +- (NSArray *)_foreignKeysForTableName:(NSString *)_tableName { + return nil; +} + +- (EOModel *)describeModelWithTableNames:(NSArray *)_tableNames { + NSMutableArray *buildRelShips = [NSMutableArray arrayWithCapacity:64]; + EOModel *model = AUTORELEASE([EOModel new]); + int cnt, tc = [_tableNames count]; + + for (cnt = 0; cnt < tc; cnt++) { + NSMutableDictionary *relNamesUsed; + NSMutableArray *classProperties; + NSMutableArray *primaryKeyAttributes; + NSString *tableName; + NSArray *attributes; + NSArray *pkeys; + NSArray *fkeys; + EOEntity *entity; + int cnt2, ac, fkc; + + relNamesUsed = [NSMutableDictionary dictionaryWithCapacity:4]; + classProperties = [NSMutableArray arrayWithCapacity:16]; + primaryKeyAttributes = [NSMutableArray arrayWithCapacity:2]; + + tableName = [_tableNames objectAtIndex:cnt]; + attributes = [self _attributesForTableName:tableName]; + pkeys = [self _primaryKeysNamesForTableName:tableName]; + fkeys = [self _foreignKeysForTableName:tableName]; + entity = [[EOEntity new] autorelease]; + ac = [attributes count]; + fkc = [fkeys count]; + + [entity setName:[tableName _pgModelMakeClassName]]; + [entity setClassName: + [@"EO" stringByAppendingString: + [tableName _pgModelMakeClassName]]]; + [entity setExternalName:tableName]; + [classProperties addObjectsFromArray:[entity classProperties]]; + [primaryKeyAttributes addObjectsFromArray:[entity primaryKeyAttributes]]; + [model addEntity:entity]; + + for (cnt2 = 0; cnt2 < ac; cnt2++) { + EOAttribute *attribute = [attributes objectAtIndex:cnt2]; + NSString *columnName = [attribute columnName]; + + attribute = [attributes objectAtIndex:cnt2]; + columnName = [attribute columnName]; + + [entity addAttribute:attribute]; + [classProperties addObject:attribute]; + + if ([pkeys containsObject:columnName]) + [primaryKeyAttributes addObject:attribute]; + } + [entity setClassProperties:classProperties]; + [entity setPrimaryKeyAttributes:primaryKeyAttributes]; + + for (cnt2 = 0; cnt2 < fkc; cnt2++) { + NSDictionary *fkey; + NSMutableArray *classProperties; + NSString *sa, *da, *dt; + EORelationship *rel; + EOJoin *join; + NSString *relName = nil; + + fkey = [fkeys objectAtIndex:cnt2]; + classProperties = [NSMutableArray arrayWithCapacity:16]; + sa = [fkey objectForKey:@"sourceAttr"]; + da = [fkey objectForKey:@"targetAttr"]; + dt = [fkey objectForKey:@"targetTable"]; + rel = [[[EORelationship alloc] init] autorelease]; + join = [[[EOJoin alloc] init] autorelease]; + + if ([pkeys containsObject:sa]) + relName = [@"to" stringByAppendingString:[dt _pgModelMakeClassName]]; + else { + relName = [@"to" stringByAppendingString: + [[sa _pgModelMakeInstanceVarName] + _pgStringWithCapitalizedFirstChar]]; + if ([relName hasSuffix:@"Id"]) { + int cLength = [relName cStringLength]; + + relName = [relName substringToIndex:cLength - 2]; + } + } + if ([relNamesUsed objectForKey:relName] != nil) { + int useCount = [[relNamesUsed objectForKey:relName] intValue]; + + [relNamesUsed setObject:[NSNumber numberWithInt:(useCount++)] + forKey:relName]; + relName = [NSString stringWithFormat:@"%s%d", + [relName cString], useCount]; + } + else + [relNamesUsed setObject:[NSNumber numberWithInt:0] forKey:relName]; + + [rel setName:relName]; + //[rel setDestinationEntity:(EOEntity *)[dt _pgModelMakeClassName]]; + [rel setToMany:NO]; + + // TODO: EOJoin is removed, fix this ... + [(id)join setSourceAttribute: + (EOAttribute *)[sa _pgModelMakeInstanceVarName]]; + [(id)join setDestinationAttribute: + (EOAttribute *)[da _pgModelMakeInstanceVarName]]; + [rel addJoin:join]; + + [entity addRelationship:rel]; + [classProperties addObjectsFromArray:[entity classProperties]]; + [classProperties addObject:rel]; + [entity setClassProperties:classProperties]; + [buildRelShips addObject:rel]; + } + + [entity setAttributesUsedForLocking:[entity attributes]]; + } + + [buildRelShips makeObjectsPerformSelector: + @selector(replaceStringsWithObjects)]; + /* + // make reverse relations + { + int cnt, rc = [buildRelShips count]; + + for (cnt = 0; cnt < rc; cnt++) { + EORelationship *rel = [buildRelShips objectAtIndex:cnt]; + NSMutableArray *classProperties = [NSMutableArray new]; + EORelationship *reverse = [rel reversedRelationShip]; + EOEntity *entity = [rel destinationEntity]; + NSArray *pkeys = [entity primaryKeyAttributes]; + BOOL isToMany = [reverse isToMany]; + EOAttribute *sa = [[[reverse joins] lastObject] sourceAttribute]; + NSString *relName = nil; + + if ([pkeys containsObject:sa] + || isToMany) + relName = [@"to" stringByAppendingString: + [(EOEntity *)[reverse destinationEntity] name]]; + else { + relName = [@"to" stringByAppendingString: + [[[sa name] _pgModelMakeInstanceVarName] + _pgStringWithCapitalizedFirstChar]]; + if ([relName hasSuffix:@"Id"]) { + int cLength = [relName cStringLength]; + + relName = [relName substringToIndex:cLength - 2]; + } + } + + if ([entity relationshipNamed:relName]) { + int cnt = 1; + NSString *numName; + + numName = [NSString stringWithFormat:@"%s%d", [relName cString], cnt]; + while ([entity relationshipNamed:numName]) { + cnt++; + numName = [NSString stringWithFormat:@"%s%d", [relName cString], cnt]; + } + + relName = numName; + } + + [reverse setName:relName]; + + [entity addRelationship:reverse]; + + [classProperties addObjectsFromArray:[entity classProperties]]; + [classProperties addObject:reverse]; + [entity setClassProperties:classProperties]; + } + } + */ + [model setAdaptorName:@"PostgreSQL72"]; + [model setAdaptorClassName:@"PostgreSQL72Adaptor"]; + [model setConnectionDictionary: + [[adaptorContext adaptor] connectionDictionary]]; + + return model; +} + +- (NSArray *)_runSingleColumnQuery:(NSString *)_query { + NSMutableArray *names; + NSArray *resultDescription; + NSString *attributeName; + NSDictionary *row; + + if (![self evaluateExpression:_query]) { + fprintf(stderr, "Could not evaluate expression: '%s'\n", [_query cString]); + return nil; + } + + resultDescription = [self describeResults]; + attributeName = [(EOAttribute *)[resultDescription objectAtIndex:0] name]; + names = [NSMutableArray arrayWithCapacity:16]; + + while ((row = [self fetchAttributes:resultDescription withZone:NULL])) + [names addObject:[row objectForKey:attributeName]]; + + return names; +} + +- (NSArray *)describeTableNames { + NSString *sql; + + sql = + @"SELECT relname " + @"FROM pg_class " + @"WHERE (relkind='r') AND (relname !~ '^pg_') AND " + @"(relname !~ '^xinv[0-9]+') " + @"ORDER BY relname"; + return [self _runSingleColumnQuery:sql]; +} + +- (NSArray *)describeDatabaseNames { + return [self _runSingleColumnQuery: + @"SELECT datname FROM pg_database ORDER BY datname"]; +} + +- (NSArray *)describeUserNames { + return [self _runSingleColumnQuery:@"SELECT usename FROM pg_user"]; +} + +@end /* PostgreSQL72Channel(ModelFetching) */ + +void __link_PostgreSQL72ChannelModel() { + // used to force linking of object file + __link_PostgreSQL72ChannelModel(); +} diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Channel.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel.h new file mode 100644 index 00000000..06598fbd --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel.h @@ -0,0 +1,102 @@ +/* + PostgreSQL72Channel.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Channel.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_Channel_H___ +#define ___PostgreSQL72_Channel_H___ + +#import +#include + +@class NSArray, NSString, NSMutableDictionary; +@class PGConnection, PGResultSet; + +typedef struct { + const char *name; + Oid type; + int size; + int modification; +} PostgreSQL72FieldInfo; + +@interface PostgreSQL72Channel : EOAdaptorChannel +{ + // connection is valid after an openChannel call + PGConnection *connection; + + // valid during -evaluateExpression: + PGResultSet *resultSet; + int tupleCount; + int fieldCount; + BOOL containsBinaryData; + PostgreSQL72FieldInfo *fieldInfo; + NSString *cmdStatus; + NSString *cmdTuples; + int currentTuple; + + // turns on/off channel debugging + BOOL isDebuggingEnabled; + + NSMutableDictionary *_attributesForTableName; + NSMutableDictionary *_primaryKeysNamesForTableName; + + int *fieldIndices; + NSString **fieldKeys; + id *fieldValues; +} + +- (void)setDebugEnabled:(BOOL)_flag; +- (BOOL)isDebugEnabled; + +- (BOOL)isOpen; +- (BOOL)openChannel; +- (void)closeChannel; + +- (NSMutableDictionary *)primaryFetchAttributes:(NSArray *)_attributes + withZone:(NSZone *)_zone; + +- (BOOL)evaluateExpression:(NSString *)_expression; + +// cancelFetch is always called to terminate a fetch +// (even by primaryFetchAttributes) +// it frees all fetch-local variables +- (void)cancelFetch; + +// uses dataFormat type information to create EOAttribute objects +- (NSArray *)describeResults; + +@end + +@interface NSObject(Sybase10ChannelDelegate) + +- (NSArray*)postgreSQLChannel:(PostgreSQL72Channel *)channel + willFetchAttributes:(NSArray *)attributes; + +- (BOOL)postgreSQLChannel:(PostgreSQL72Channel *)channel + willReturnRow:(NSDictionary *)row; + +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Channel.m b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel.m new file mode 100644 index 00000000..fc7dbc57 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Channel.m @@ -0,0 +1,789 @@ +/* + PostgreSQL72Channel.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Channel.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include +#include +#import "common.h" +#import "PostgreSQL72Channel.h" +#import "PostgreSQL72Adaptor.h" +#import "PostgreSQL72Exception.h" +#import "NSString+PostgreSQL72.h" +#import "PostgreSQL72Values.h" +#import "EOAttribute+PostgreSQL72.h" +#include "PGConnection.h" + +#ifndef MIN +# define MIN(x, y) ((x > y) ? y : x) +#endif + +#if PG_MAJOR_VERSION >= 6 && PG_MINOR_VERSION > 3 +# define NG_HAS_NOTICE_PROCESSOR 1 +# define NG_HAS_BINARY_TUPLES 1 +# define NG_HAS_FMOD 1 +#endif + +#if PG_MAJOR_VERSION >= 7 && PG_MINOR_VERSION > 3 +# define NG_SET_CLIENT_ENCODING 1 +#endif + +#define MAX_CHAR_BUF 16384 + +@interface PostgreSQL72Channel(Privates) +- (void)_resetEvaluationState; +@end + +@implementation PostgreSQL72Channel + +#if NG_SET_CLIENT_ENCODING +static NSString *PGClientEncoding = @"Latin1"; +#endif +static int MaxOpenConnectionCount = -1; +static BOOL debugOn = NO; +static NSNull *null = nil; +static NSNumber *yesObj = nil; +static Class StringClass = Nil; +static Class MDictClass = Nil; + ++ (void)initialize { + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + + if (null == nil) null = [[NSNull null] retain]; + if (yesObj == nil) yesObj = [[NSNumber numberWithBool:YES] retain]; + + StringClass = [NSString class]; + MDictClass = [NSMutableDictionary class]; + + MaxOpenConnectionCount = [ud integerForKey:@"PGMaxOpenConnectionCount"]; + if (MaxOpenConnectionCount < 2) + MaxOpenConnectionCount = 50; + + debugOn = [ud boolForKey:@"PGDebugEnabled"]; +} + +- (id)initWithAdaptorContext:(EOAdaptorContext*)_adaptorContext { + if ((self = [super initWithAdaptorContext:_adaptorContext])) { + [self setDebugEnabled:debugOn]; + + self->_attributesForTableName = [[MDictClass alloc] initWithCapacity:16]; + self->_primaryKeysNamesForTableName = + [[MDictClass alloc] initWithCapacity:16]; + } + return self; +} + +/* collection */ + +- (void)dealloc { + [self _resetEvaluationState]; + + if ([self isOpen]) + [self closeChannel]; + + [self->_attributesForTableName release]; + [self->_primaryKeysNamesForTableName release]; + [super dealloc]; +} + +/* NSCopying methods */ + +- (id)copyWithZone:(NSZone *)zone { + return [self retain]; +} + +/* debugging */ + +- (void)setDebugEnabled:(BOOL)_flag { + self->isDebuggingEnabled = _flag; +} +- (BOOL)isDebugEnabled { + return self->isDebuggingEnabled; +} + +- (void)receivedMessage:(NSString *)_message { + NSLog(@"%@: message: %@", self, _message); +} + +static void _pgMessageProcessor(void *_channel, const char *_msg) + __attribute__((unused)); + +static void _pgMessageProcessor(void *_channel, const char *_msg) { + [(id)_channel receivedMessage: + _msg ? [StringClass stringWithCString:_msg] : nil]; +} + +/* cleanup */ + +- (void)_resetResults { + [self->resultSet clear]; + [self->resultSet release]; + self->resultSet = nil; +} + +/* open/close */ + +static int openConnectionCount = 0; + +- (BOOL)isOpen { + return [self->connection isValid]; +} + +- (BOOL)openChannel { + PostgreSQL72Adaptor *adaptor; + + if ([self->connection isValid]) { + NSLog(@"%s: Connection already open !!!", __PRETTY_FUNCTION__); + return NO; + } + + adaptor = (PostgreSQL72Adaptor *)[adaptorContext adaptor]; + + if (![super openChannel]) + return NO; + +#if HEAVY_DEBUG + NSLog(@"+++++++++ %s: openConnectionCount %d", __PRETTY_FUNCTION__, + openConnectionCount); +#endif + + if (openConnectionCount > MaxOpenConnectionCount) { + [PostgreSQL72CouldNotOpenChannelException raise:@"NoMoreConnections" + format: + @"cannot open a additional connection !"]; + return NO; + } + + self->connection = + [[PGConnection alloc] initWithHostName:[adaptor serverName] + port:[(id)[adaptor port] stringValue] + options:[adaptor options] + tty:[adaptor tty] database:[adaptor databaseName] + login:[adaptor loginName] + password:[adaptor loginPassword]]; + + if (![self->connection isValid]) { + // could not login .. + NSLog(@"WARNING: could not open pgsql channel to %@@%@ host %@:%@", + [adaptor loginName], + [adaptor databaseName], [adaptor serverName], [adaptor port]); + return NO; + } + + /* PQstatus */ + if (![self->connection isConnectionOK]) { + NSLog(@"could not open channel to %@@%@", + [adaptor databaseName], [adaptor serverName]); + [self->connection finish]; + [self->connection release]; + self->connection = nil; + return NO; + } + + /* set message callback */ + [self->connection setNoticeProcessor:_pgMessageProcessor context:self]; + + /* set client encoding */ +#if NG_SET_CLIENT_ENCODING + if (![self->connection setClientEncoding:PGClientEncoding]) { + NSLog(@"WARNING: could not set client encoding to: '%s'", + PGClientEncoding); + } +#endif + + /* log */ + + if (isDebuggingEnabled) + NSLog(@"PostgreSQL72 connection established: %@", self->connection); + +#if HEAVY_DEBUG + NSLog(@"---------- %s: %@ opens channel count[%d]", __PRETTY_FUNCTION__, + self, openConnectionCount); +#endif + + openConnectionCount++; + + if (isDebuggingEnabled) { + NSLog(@"PostgreSQL72 channel 0x%08X opened (connection=%@)", + (unsigned)self, self->connection); + } + return YES; +} + +- (void)primaryCloseChannel { + self->tupleCount = 0; + self->fieldCount = 0; + self->containsBinaryData = NO; + + if (self->fieldInfo) { + free(self->fieldInfo); + self->fieldInfo = NULL; + } + + [self _resetResults]; + + [self->cmdStatus release]; self->cmdStatus = nil; + [self->cmdTuples release]; self->cmdTuples = nil; + + if (self->connection) { + [self->connection finish]; +#if HEAVY_DEBUG + NSLog(@"---------- %s: %@ close channel count[%d]", __PRETTY_FUNCTION__, + self, openConnectionCount); +#endif + openConnectionCount--; + + if (isDebuggingEnabled) { + fprintf(stderr, + "PostgreSQL72 connection dropped 0x%08X (channel=0x%08X)\n", + (unsigned)self->connection, (unsigned)self); + } + [self->connection release]; + self->connection = nil; + } +} + +- (void)closeChannel { + [super closeChannel]; + [self primaryCloseChannel]; +} + +/* fetching rows */ + +- (void)cancelFetch { + if (![self isOpen]) { + [PostgreSQL72Exception raise:@"ChannelNotOpenException" + format:@"No fetch in progress, connection is not open" + @" (channel=%@)", self]; + } + +#if HEAVY_DEBUG + NSLog(@"canceling fetch (%i tuples remaining).", + (self->tupleCount - self->currentTuple)); +#endif + + self->tupleCount = 0; + self->currentTuple = 0; + self->fieldCount = 0; + self->containsBinaryData = NO; + + if (self->fieldInfo) { + free(self->fieldInfo); + self->fieldInfo = NULL; + } + [self _resetResults]; + + [self->cmdStatus release]; self->cmdStatus = nil; + [self->cmdTuples release]; self->cmdTuples = nil; + + /* new caches which require a constant _attributes argument */ + if (self->fieldIndices) free(self->fieldIndices); self->fieldIndices = NULL; + if (self->fieldKeys) free(self->fieldKeys); self->fieldKeys = NULL; + if (self->fieldValues) free(self->fieldValues); self->fieldValues = NULL; + + [super cancelFetch]; +} + +- (NSArray *)describeResults { + int cnt; + NSMutableArray *result = nil; + NSMutableDictionary *usedNames = nil; + + if (![self isFetchInProgress]) { + [PostgreSQL72Exception raise:@"NoFetchInProgress" + format:@"No fetch in progress (channel=%@)", self]; + } + + result = [[NSMutableArray alloc] initWithCapacity:self->fieldCount]; + usedNames = [[MDictClass alloc] initWithCapacity:self->fieldCount]; + + for (cnt = 0; cnt < self->fieldCount; cnt++) { + EOAttribute *attribute = nil; + NSString *columnName; + NSString *attrName; + + columnName = + [[StringClass alloc] initWithCString:self->fieldInfo[cnt].name]; + attrName = [columnName _pgModelMakeInstanceVarName]; + + if ([[usedNames objectForKey:attrName] boolValue]) { + // TODO: move name generation code to different method! + int cnt2 = 0; + char buf[64]; + NSString *newAttrName = nil; + + for (cnt2 = 2; cnt2 < 100; cnt2++) { + NSString *s; + + sprintf(buf, "%i", cnt2); + + s = [[StringClass alloc] initWithCString:buf]; + newAttrName = [attrName stringByAppendingString:s]; + [s release]; s= nil; + + if (![[usedNames objectForKey:newAttrName] boolValue]) { + attrName = newAttrName; + break; + } + } + } + [usedNames setObject:yesObj forKey:attrName]; + + attribute = [[EOAttribute alloc] init]; + [attribute setName:attrName]; + [attribute setColumnName:columnName]; + + //NSLog(@"column: %@", columnName); + + [attribute loadValueClassAndTypeUsingPostgreSQLType: + self->fieldInfo[cnt].type + size:self->fieldInfo[cnt].size + modification:self->fieldInfo[cnt].modification + binary:self->containsBinaryData]; + + [result addObject:attribute]; + + [columnName release]; columnName = nil; + [attribute release]; attribute = nil; + } + + [usedNames release]; + usedNames = nil; + + return [result autorelease]; +} + +- (void)_fillFieldNamesForAttributes:(NSArray *)_attributes + count:(unsigned)attrCount +{ + // Note: this optimization requires that the "_attributes" array does + // note change between invocations! + // TODO: should add a sanity check for that! + NSMutableArray *fieldNames; + unsigned nFields, i; + unsigned cnt; + + if (self->fieldIndices) + return; + + self->fieldIndices = calloc(attrCount + 2, sizeof(int)); + + // TODO: we could probably cache the field-name array for much more speed ! + fieldNames = [[NSMutableArray alloc] initWithCapacity:32]; + nFields = [self->resultSet fieldCount]; + for (i = 0; i < nFields; i++) + [fieldNames addObject:[self->resultSet fieldNameAtIndex:i]]; + + for (cnt = 0; cnt < attrCount; cnt++) { + EOAttribute *attribute; + + attribute = [_attributes objectAtIndex:cnt]; +#if GDL_USE_PQFNUMBER_INDEX + self->fieldIndices[cnt] = + [self->resultSet indexOfFieldNamed:[attribute columnName]]; +#else + self->fieldIndices[cnt] = + [fieldNames indexOfObject:[attribute columnName]]; +#endif + + if (self->fieldIndices[cnt] == NSNotFound) { + [PostgreSQL72Exception raiseWithFormat: + @"attribute %@ not covered by query", + attribute]; + } + [fieldNames replaceObjectAtIndex:self->fieldIndices[cnt] withObject:null]; + } + [fieldNames release]; fieldNames = nil; +} + +- (NSMutableDictionary *)primaryFetchAttributes:(NSArray *)_attributes + withZone:(NSZone *)_zone +{ + NSMutableDictionary *row; + unsigned attrCount; + int *indices; + unsigned cnt, fieldDictCount; + + if (self->currentTuple == self->tupleCount) { + if (self->resultSet != nil) [self cancelFetch]; + return nil; + } + + attrCount = [_attributes count]; + [self _fillFieldNamesForAttributes:_attributes count:attrCount]; + indices = self->fieldIndices; + + if (self->fieldKeys == NULL) + self->fieldKeys = calloc(attrCount + 1, sizeof(NSString *)); + if (self->fieldValues == NULL) + self->fieldValues = calloc(attrCount + 1, sizeof(id)); + fieldDictCount = 0; + + for (cnt = 0; cnt < attrCount; cnt++) { + EOAttribute *attribute; + NSString *attrName; + id value = nil; + Class valueClass = Nil; + const char *pvalue; + int vallen; + + attribute = [_attributes objectAtIndex:cnt]; + attrName = [attribute name]; + + if ([self->resultSet isNullTuple:self->currentTuple atIndex:indices[cnt]]){ + self->fieldKeys[fieldDictCount] = attrName; + self->fieldValues[fieldDictCount] = null; + fieldDictCount++; + continue; + } + + valueClass = NSClassFromString([attribute valueClassName]); + if (valueClass == Nil) { + NSLog(@"ERROR(%s): %@: got no value class for column:\n" + @" attribute=%@\n type=%@", + __PRETTY_FUNCTION__, self, + attrName, [attribute externalType]); + continue; + } + + pvalue = [self->resultSet rawValueOfTuple:self->currentTuple + atIndex:indices[cnt]]; + vallen = [self->resultSet lengthOfTuple:self->currentTuple + atIndex:indices[cnt]]; + + if (self->containsBinaryData) { + // pvalue is stored in internal representation + + value = [valueClass valueFromBytes:pvalue length:vallen + postgreSQLType:[attribute externalType] + attribute:attribute + adaptorChannel:self]; + } + else { + // pvalue is ascii string + + value = [valueClass valueFromCString:pvalue length:vallen + postgreSQLType:[attribute externalType] + attribute:attribute + adaptorChannel:self]; + } + if (value == nil) { + NSLog(@"ERROR(%s): %@: got no value for column:\n" + @" attribute=%@\n valueClass=%@\n type=%@", + __PRETTY_FUNCTION__, self, + attrName, NSStringFromClass(valueClass), + [attribute externalType]); + continue; + } + + /* add to dictionary */ + self->fieldKeys[fieldDictCount] = attrName; + self->fieldValues[fieldDictCount] = value; + fieldDictCount++; + } + + self->currentTuple++; + + // TODO: we would need to have a copy on write dict here, ideally with + // the keys being reused for each fetch-loop + row = [[MDictClass alloc] initWithObjects:self->fieldValues + forKeys:self->fieldKeys + count:fieldDictCount]; + return [row autorelease]; +} + +/* sending sql to server */ + +- (void)_resetEvaluationState { + self->isFetchInProgress = NO; + self->tupleCount = 0; + self->fieldCount = 0; + self->currentTuple = 0; + self->containsBinaryData = NO; + if (self->fieldInfo) { + free(self->fieldInfo); + self->fieldInfo = NULL; + } + + /* new caches which require a constant _attributes argument */ + if (self->fieldIndices) free(self->fieldIndices); self->fieldIndices = NULL; + if (self->fieldKeys) free(self->fieldKeys); self->fieldKeys = NULL; + if (self->fieldValues) free(self->fieldValues); self->fieldValues = NULL; +} + +- (NSException *)_processEvaluationTuplesOKForExpression:(NSString *)_sql { + int i; + + self->isFetchInProgress = YES; + + self->tupleCount = [self->resultSet tupleCount]; + self->fieldCount = [self->resultSet fieldCount]; + self->containsBinaryData = [self->resultSet containsBinaryTuples]; + + self->fieldInfo = + calloc(self->fieldCount + 1, sizeof(PostgreSQL72FieldInfo)); + for (i = 0; i < self->fieldCount; i++) { + self->fieldInfo[i].name = PQfname(self->resultSet->results, i); + self->fieldInfo[i].type = PQftype(self->resultSet->results, i); + self->fieldInfo[i].size = [self->resultSet fieldSizeAtIndex:i]; + self->fieldInfo[i].modification = [self->resultSet modifierAtIndex:i]; + } + + self->cmdStatus = [[self->resultSet commandStatus] copy]; + self->cmdTuples = [[self->resultSet commandTuples] copy]; + + if (delegateRespondsTo.didEvaluateExpression) + [delegate adaptorChannel:self didEvaluateExpression:_sql]; + +#if HEAVY_DEBUG + NSLog(@"tuples %i fields %i status %@", + self->tupleCount, self->fieldCount, self->cmdStatus); +#endif + return nil; +} + +- (NSException *)_handleBadResponseError { + NSString *s; + + [self _resetResults]; + + s = [NSString stringWithFormat:@"bad pgsql response (channel=%@): %@", + self, [self->connection errorMessage]]; + return [PostgreSQL72Exception exceptionWithName:@"PostgreSQL72BadResponse" + reason:s userInfo:nil]; +} +- (NSException *)_handleNonFatalEvaluationError { + NSString *s; + + [self _resetResults]; + + s = [NSString stringWithFormat:@"pgsql error (channel=%@): %@", + self, [self->connection errorMessage]]; + return [PostgreSQL72Exception exceptionWithName:@"PostgreSQL72Error" + reason:s userInfo:nil]; +} +- (NSException *)_handleFatalEvaluationError { + NSString *s; + + [self _resetResults]; + + s = [NSString stringWithFormat:@"fatal pgsql error (channel=%@): %@", + self, [self->connection errorMessage]]; + return [PostgreSQL72Exception exceptionWithName:@"PostgreSQL72FatalError" + reason:s userInfo:nil]; +} + +- (NSException *)evaluateExpressionX:(NSString *)_expression { + BOOL result; + + *(&result) = YES; + + if (_expression == nil) { + return [NSException exceptionWithName:NSInvalidArgumentException + reason:@"parameter for evaluateExpression: " + @"must not be null" + userInfo:nil]; + } + + *(&_expression) = [[_expression mutableCopy] autorelease]; + + if (delegateRespondsTo.willEvaluateExpression) { + EODelegateResponse response; + + response = [delegate adaptorChannel:self + willEvaluateExpression: + (NSMutableString *)_expression]; + + if (response == EODelegateRejects) { + return [NSException exceptionWithName:@"EODelegateRejects" + reason:@"delegate rejected insert" + userInfo:nil]; + } + if (response == EODelegateOverrides) + return nil; + } + + if (![self isOpen]) { + return [PostgreSQL72Exception exceptionWithName:@"ChannelNotOpenException" + reason: + @"PostgreSQL72 connection is not open" + userInfo:nil]; + } + if (self->resultSet != nil) { + return [PostgreSQL72Exception exceptionWithName: + @"CommandInProgressException" + reason:@"an evaluation is in progress" + userInfo:nil]; + } + + if (isDebuggingEnabled) + NSLog(@"PG0x%08X SQL: %@", (unsigned)self, _expression); + + [self _resetEvaluationState]; + + self->resultSet = [[self->connection execute:_expression] retain]; + if (self->resultSet == nil) { + return [PostgreSQL72Exception exceptionWithName:@"ExecutionFailed" + reason:@"the PQexec() failed" + userInfo:nil]; + } + + /* process results */ + + switch (PQresultStatus(self->resultSet->results)) { + case PGRES_EMPTY_QUERY: + case PGRES_COMMAND_OK: + [self _resetResults]; + + if (delegateRespondsTo.didEvaluateExpression) + [delegate adaptorChannel:self didEvaluateExpression:_expression]; + return nil; + + case PGRES_TUPLES_OK: + return [self _processEvaluationTuplesOKForExpression:_expression]; + + case PGRES_COPY_OUT: + case PGRES_COPY_IN: + [self _resetResults]; + return [PostgreSQL72Exception exceptionWithName:@"UnsupportedOperation" + reason:@"copy(out|in) not supported" + userInfo:nil]; + + case PGRES_BAD_RESPONSE: + return [self _handleBadResponseError]; + case PGRES_NONFATAL_ERROR: + return [self _handleNonFatalEvaluationError]; + case PGRES_FATAL_ERROR: + return [self _handleFatalEvaluationError]; + + default: + return [NSException exceptionWithName:@"PostgreSQLEvalFailed" + reason:@"generic reason" + userInfo:nil]; + } +} +- (BOOL)evaluateExpression:(NSString *)_sql { + NSException *e; + NSString *n; + + if ((e = [self evaluateExpressionX:_sql]) == nil) + return YES; + + /* for compatibility with non-X methods, translate some errors to a bool */ + n = [e name]; + if ([n isEqualToString:@"EOEvaluationError"]) + return NO; + if ([n isEqualToString:@"EODelegateRejects"]) + return NO; + + [e raise]; + return NO; +} + +/* description */ + +- (NSString *)description { + NSMutableString *ms; + + ms = [NSMutableString stringWithCapacity:128]; + [ms appendFormat:@"<0x%08X[%@]:", self, NSStringFromClass([self class])]; + if (self->connection) + [ms appendFormat:@" connection=%@", self->connection]; + else + [ms appendString:@" not-connected"]; + [ms appendString:@">"]; + return ms; +} + +@end /* PostgreSQL72Channel */ + +@implementation PostgreSQL72Channel(PrimaryKeyGeneration) + +- (NSDictionary *)primaryKeyForNewRowWithEntity:(EOEntity *)_entity { + NSArray *pkeys; + PostgreSQL72Adaptor *adaptor; + NSString *seqName, *seq; + NSDictionary *pkey; + + pkeys = [_entity primaryKeyAttributeNames]; + adaptor = (id)[[self adaptorContext] adaptor]; + seqName = [adaptor primaryKeySequenceName]; + pkey = nil; + seq = nil; + + seq = [seqName length] > 0 + ? [StringClass stringWithFormat:@"SELECT NEXTVAL ('%@')", seqName] + : [adaptor newKeyExpression]; + + // TODO: since we use evaluateExpressionX, we should not see exceptions? + NS_DURING { + if ([self evaluateExpressionX:seq] == nil) { + id key = nil; + + if (self->tupleCount > 0) { + if ([self->resultSet isNullTuple:0 atIndex:0]) + key = [null retain]; + else { + const char *pvalue; + int vallen; + + if (self->containsBinaryData) { +#if COCOA_Foundation_LIBRARY || NeXT_Foundation_LIBRARY + NSLog(@"%s: binary data not implemented!", __PRETTY_FUNCTION__); +#else + [self notImplemented:_cmd]; +#endif + } + + pvalue = [self->resultSet rawValueOfTuple:0 atIndex:0]; + vallen = [self->resultSet lengthOfTuple:0 atIndex:0]; + + if (pvalue) + key = [[NSNumber alloc] initWithInt:atoi(pvalue)]; + } + } + [self cancelFetch]; + + if (key) { + pkey = [NSDictionary dictionaryWithObject:key + forKey:[pkeys objectAtIndex:0]]; + [key release]; key = nil; + } + } + } + NS_HANDLER + pkey = nil; + NS_ENDHANDLER; + + return pkey; +} + +@end /* PostgreSQL72Channel(PrimaryKeyGeneration) */ + +void __link_PostgreSQL72Channel() { + // used to force linking of object file + __link_PostgreSQL72Channel(); +} diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Context.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Context.h new file mode 100644 index 00000000..d3c794d7 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Context.h @@ -0,0 +1,40 @@ +/* + PostgreSQL72Context.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Context.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_Context_H___ +#define ___PostgreSQL72_Context_H___ + +#import + +@interface PostgreSQL72Context : EOAdaptorContext + +- (BOOL)primaryBeginTransaction; +- (BOOL)primaryCommitTransaction; +- (BOOL)primaryRollbackTransaction; + +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Context.m b/sope-gdl1/PostgreSQL72/PostgreSQL72Context.m new file mode 100644 index 00000000..551e505e --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Context.m @@ -0,0 +1,85 @@ +/* + PostgreSQL72Context.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Context.m 1 2004-08-20 10:38:46Z znek $ + +#import "PostgreSQL72Context.h" +#import "PostgreSQL72Channel.h" +#include "common.h" + +@implementation PostgreSQL72Context + +- (void)channelDidInit:_channel { + if ([channels count] > 0) { + [NSException raise:@"TooManyOpenChannelsException" + format:@"SybaseAdaptor10 only supports one channel per context"]; + } + [super channelDidInit:_channel]; +} + +- (BOOL)primaryBeginTransaction { + BOOL result; + + result = [[[channels lastObject] + nonretainedObjectValue] + evaluateExpression:@"BEGIN TRANSACTION"]; + + return result; +} + +- (BOOL)primaryCommitTransaction { + BOOL result; + + result = [[[channels lastObject] + nonretainedObjectValue] + evaluateExpression:@"COMMIT TRANSACTION"]; + + return result; +} + +- (BOOL)primaryRollbackTransaction { + BOOL result; + + result = [[[channels lastObject] + nonretainedObjectValue] + evaluateExpression:@"ROLLBACK TRANSACTION"]; + return result; +} + +- (BOOL)canNestTransactions { + return NO; +} + +// NSCopying methods + +- (id)copyWithZone:(NSZone *)zone { + return [self retain]; +} + +@end /* PostgreSQL72Context */ + +void __link_PostgreSQL72Context() { + // used to force linking of object file + __link_PostgreSQL72Context(); +} diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Exception.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Exception.h new file mode 100644 index 00000000..e062c7e4 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Exception.h @@ -0,0 +1,55 @@ +/* + PostgreSQL72Exception.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Exception.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_Exception_H___ +#define ___PostgreSQL72_Exception_H___ + +#import + +@interface PostgreSQL72Exception : NSException +{ +} + ++ (void)raiseWithFormat:(NSString *)_format, ...; + +@end + +@interface PostgreSQL72CouldNotOpenChannelException : PostgreSQL72Exception +{ +} +@end + +@interface PostgreSQL72CouldNotConnectException : PostgreSQL72CouldNotOpenChannelException +{ +} +@end + +@interface PostgreSQL72CouldNotBindException : PostgreSQL72Exception +{ +} +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Exception.m b/sope-gdl1/PostgreSQL72/PostgreSQL72Exception.m new file mode 100644 index 00000000..dd39f0be --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Exception.m @@ -0,0 +1,63 @@ +/* + PostgreSQL72Exception.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Exception.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include "PostgreSQL72Exception.h" +#include "common.h" +#include + +@implementation PostgreSQL72Exception + ++ (void)raiseWithFormat:(NSString *)_format, ... { + NSString *tmp = nil; + va_list ap; + + va_start(ap, _format); + tmp = [[NSString alloc] initWithFormat:_format arguments:ap]; + va_end(ap); + + [tmp autorelease]; + + [[[self alloc] initWithName:NSStringFromClass([self class]) + reason:tmp userInfo:nil] + raise]; +} + +@end /* PostgreSQL72Exception */ + +@implementation PostgreSQL72CouldNotOpenChannelException +@end + +@implementation PostgreSQL72CouldNotConnectException +@end + +@implementation PostgreSQL72CouldNotBindException +@end + +void __link_PostgreSQL72Exception() { + // used to force linking of object file + __link_PostgreSQL72Exception(); +} diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Expression.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Expression.h new file mode 100644 index 00000000..94785ec3 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Expression.h @@ -0,0 +1,56 @@ +/* + PostgreSQL72Expression.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Expression.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___Postgre_SQLExpression_H___ +#define ___Postgre_SQLExpression_H___ + +#include + +@class NSString, NSArray; +@class EOSQLQualifier, EOAdaptorChannel; + +@interface PostgreSQL72Expression : EOSQLExpression + ++ (Class)selectExpressionClass; + +@end + +@interface PostgreSQL72SelectSQLExpression : EOSelectSQLExpression +{ + BOOL lock; +} + +- (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel; + +- (NSString *)fromClause; + +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Expression.m b/sope-gdl1/PostgreSQL72/PostgreSQL72Expression.m new file mode 100644 index 00000000..9eade07f --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Expression.m @@ -0,0 +1,93 @@ +/* + PostgreSQL72Expression.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Expression.m 1 2004-08-20 10:38:46Z znek $ + +#include +#include +#include "PostgreSQL72Expression.h" + +@implementation PostgreSQL72Expression + ++ (Class)selectExpressionClass { + return [PostgreSQL72SelectSQLExpression class]; +} + +@end + +@implementation PostgreSQL72SelectSQLExpression + +- (id)selectExpressionForAttributes:(NSArray *)attributes + lock:(BOOL)flag + qualifier:(EOSQLQualifier *)qualifier + fetchOrder:(NSArray *)fetchOrder + channel:(EOAdaptorChannel *)channel { + + lock = flag; + [super selectExpressionForAttributes:attributes + lock:flag + qualifier:qualifier + fetchOrder:fetchOrder + channel:channel]; + return self; +} + +- (NSString *)fromClause { + NSMutableString *fromClause; + NSEnumerator *enumerator; + BOOL first = YES; + id key; + + fromClause = [NSMutableString stringWithCString:" "]; + enumerator = [fromListEntities objectEnumerator]; + + // Compute the FROM list from all the aliases found in + // entitiesAndPropertiesAliases dictionary. Note that this dictionary + // contains entities and relationships. The last ones are there for + // flattened attributes over reflexive relationships. + + while((key = [enumerator nextObject])) { + if(first) first = NO; + else [fromClause appendString:@", "]; + + [fromClause appendFormat:@"%@ %@", + [key isKindOfClass:[EORelationship class]] + ? [[key destinationEntity] externalName] // flattened attribute + : [key externalName], // EOEntity + [entitiesAndPropertiesAliases objectForKey:key]]; + +#if 0 + if (lock) [fromClause appendString:@" HOLDLOCK"]; +#endif + } + + return fromClause; +} + +@end + +void __link_PostgreSQL72Expression() { + // used to force linking of object file + __link_PostgreSQL72Expression(); +} diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Values.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Values.h new file mode 100644 index 00000000..4396b82a --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Values.h @@ -0,0 +1,85 @@ +/* + PostgreSQL72Values.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Values.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL72_Values_H___ +#define ___PostgreSQL72_Values_H___ + +#import +#import +#import +#import +#import +#import "PostgreSQL72Exception.h" + +@class EOAttribute; +@class PostgreSQL72Channel; + +@interface PostgreSQL72DataTypeMappingException : PostgreSQL72Exception + +- (id)initWithObject:(id)_obj + forAttribute:(EOAttribute *)_attr + andPostgreSQLType:(NSString *)_dt + inChannel:(PostgreSQL72Channel *)_channel; + +@end + +@protocol PostgreSQL72Values + ++ (id)valueFromCString:(const char *)_cstr length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel; + ++ (id)valueFromBytes:(const void *)_bytes length:(int)_length + postgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute + adaptorChannel:(PostgreSQL72Channel *)_channel; + +- (NSString *)stringValueForPostgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute; + +@end + +@interface NSString(PostgreSQL72Values) < PostgreSQL72Values > +@end + +@interface NSNumber(PostgreSQL72Values) < PostgreSQL72Values > +@end + +@interface NSData(PostgreSQL72Values) < PostgreSQL72Values > +@end + +@interface NSCalendarDate(PostgreSQL72Values) < PostgreSQL72Values > +@end + +@interface EONull(PostgreSQL72Values) + +- (NSString *)stringValueForPostgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute; + +@end + +#endif diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Values.m b/sope-gdl1/PostgreSQL72/PostgreSQL72Values.m new file mode 100644 index 00000000..8ee3ce7d --- /dev/null +++ b/sope-gdl1/PostgreSQL72/PostgreSQL72Values.m @@ -0,0 +1,85 @@ +/* + PostgreSQL72Values.m + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + + Author: Helge Hess (helge@mdlink.de) + + This file is part of the PostgreSQL72 Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: PostgreSQL72Values.m 1 2004-08-20 10:38:46Z znek $ + +#import "PostgreSQL72Values.h" +#import "common.h" + +#if !LIB_FOUNDATION_LIBRARY +@interface PostgreSQL72DataTypeMappingException(Privates) +- (void)setName:(NSString *)_name; +- (void)setReason:(NSString *)_reason; +- (void)setUserInfo:(NSDictionary *)_ui; +@end +#endif + +@implementation PostgreSQL72DataTypeMappingException + +- (id)initWithObject:(id)_obj + forAttribute:(EOAttribute *)_attr + andPostgreSQLType:(NSString *)_dt + inChannel:(PostgreSQL72Channel *)_channel; +{ + NSString *typeName = nil; + + typeName = _dt; + + if (typeName == nil) + typeName = [NSString stringWithFormat:@"Oid[%i]", _dt]; + + // TODO: fix for Cocoa/gstep Foundation? + [self setName:@"DataTypeMappingNotSupported"]; + [self setReason:[NSString stringWithFormat: + @"mapping between %@ and " + @"postgres type %@ is not supported", + [_obj description], + NSStringFromClass([_obj class]), + typeName]]; + + [self setUserInfo:[NSDictionary dictionaryWithObjectsAndKeys: + _attr, @"attribute", + _channel, @"channel", + _obj, @"object", + nil]]; + return self; +} + +@end /* PostgreSQL72DataTypeMappingException */ + +@implementation NSNull(PostgreSQL72Values) + +- (NSString *)stringValueForPostgreSQLType:(NSString *)_type + attribute:(EOAttribute *)_attribute +{ + return @"null"; +} + +@end /* NSNull(PostgreSQL72Values) */ + + +void __link_PostgreSQL72Values() { + // used to force linking of object file + __link_PostgreSQL72Values(); +} diff --git a/sope-gdl1/PostgreSQL72/README b/sope-gdl1/PostgreSQL72/README new file mode 100644 index 00000000..33367bfc --- /dev/null +++ b/sope-gdl1/PostgreSQL72/README @@ -0,0 +1,70 @@ +# $Id: README 1 2004-08-20 10:38:46Z znek $ + +Install PostgreSQL: + + cd /INTERNET/suse72/dvd/ + cd ap3 + rpm -Uvh postgresql.rpm + cd ap2 + rpm -Uvh postgresql-lib.rpm + rpm -Uvh postgresql-server.rpm + rpm -Uvh postgresql-devel.rpm + +Configure PostgreSQL: + + su - postgres + vi .bashrc + -> export PGDATA=/var/lib/pgsql/data + source .bashrc + initdb + + su - root + /etc/rc.d/postgresql start + + su - postgres + createdb OpenGroupware + createuser ogo + + vi data/pg_hba.conf + > add line: "host all 192.168.0.1 255.255.255.0 trust" + +PostgreSQL starten: + /etc/rc.d/postgresql restart + +Configure the Adaptor + PGDebugEnabled + + +NOTES +===== + +Querying the tables of a database +--------------------------------- + +SELECT relname + FROM pg_class + WHERE ( relkind = 'r') AND relname !~ '^pg_' + AND relname !~ '^xinv[0-9]+' + ORDER BY relname; + +und die infos dazu mit: + +SELECT a.attnum, a.attname, t.typname, a.attlen, a.attnotnull + FROM pg_class c, pg_attribute a, pg_type t + WHERE c.relname = 'TABELLENNAME_HERE' AND + a.attnum > 0 AND a.attrelid = c.oid + AND a.atttypid = t.oid + ORDER BY attnum; + +Quering the databases of a server +--------------------------------- + + SELECT * FROM pg_database + +You need a database to connect PostgreSQL using libpq, but 'template1' should +always be available. + +Fetch DB-names and their DBA: + SELECT DISTINCT dbs.datname, users.usename + FROM pg_database dbs, pg_user users + WHERE dbs.datdba=users.usesysid diff --git a/sope-gdl1/PostgreSQL72/TODO b/sope-gdl1/PostgreSQL72/TODO new file mode 100644 index 00000000..5d265ce1 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/TODO @@ -0,0 +1,3 @@ +# $Id: TODO 1 2004-08-20 10:38:46Z znek $ + +- cache field-names in PostgreSQL72Channel -primaryFetch (see TODO) diff --git a/sope-gdl1/PostgreSQL72/Version b/sope-gdl1/PostgreSQL72/Version new file mode 100644 index 00000000..2544f203 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/Version @@ -0,0 +1,3 @@ +# $Id: Version 1 2004-08-20 10:38:46Z znek $ + +SUBMINOR_VERSION:=33 diff --git a/sope-gdl1/PostgreSQL72/common.h b/sope-gdl1/PostgreSQL72/common.h new file mode 100644 index 00000000..0b8abb07 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/common.h @@ -0,0 +1,53 @@ +/* + common.h + + Copyright (C) 1999 MDlink online service center GmbH and Helge Hess + Copyright (C) 2000-2004 SKYRIX Software AG and Helge Hess + + Author: Helge Hess (helge.hess@opengroupware.org) + + This file is part of the PostgreSQL Adaptor Library + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +// $Id: common.h 1 2004-08-20 10:38:46Z znek $ + +#ifndef ___PostgreSQL_common_H___ +#define ___PostgreSQL_common_H___ + +#import + +#if LIB_FOUNDATION_BOEHM_GC +# include +# include +# include +#endif + +#include +#include +#include + +#import + +#if LIB_FOUNDATION_LIBRARY +# import +#else +# include +#endif + +#import + +#endif /* ___PostgreSQL_common_H___ */ diff --git a/sope-gdl1/PostgreSQL72/condict.plist b/sope-gdl1/PostgreSQL72/condict.plist new file mode 100644 index 00000000..1e9d44a5 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/condict.plist @@ -0,0 +1,7 @@ +{ + hostName = "localhost"; + userName = "helge"; + password = "helgehelge"; + databaseName = "hhtest1"; + port = 5432; +} diff --git a/sope-gdl1/PostgreSQL72/gdltest.m b/sope-gdl1/PostgreSQL72/gdltest.m new file mode 100644 index 00000000..dc95aeb5 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/gdltest.m @@ -0,0 +1,165 @@ +// $Id: gdltest.m 1 2004-08-20 10:38:46Z znek $ + +#import +#import +#include + +int main(int argc, char **argv, char **env) { + EOModel *m = nil; + EOAdaptor *a; + EOAdaptorContext *ctx; + EOAdaptorChannel *ch; + NSDictionary *conDict; + NSString *expr; + + [NSProcessInfo initializeWithArguments:argv count:argc environment:env]; + + NS_DURING { + + conDict = [NSDictionary dictionaryWithContentsOfFile:@"condict.plist"]; + NSLog(@"condict is %@", conDict); + + if ((a = [EOAdaptor adaptorWithName:@"PostgreSQL"]) == nil) { + NSLog(@"found no PostgreSQL adaptor .."); + exit(1); + } + + NSLog(@"got adaptor %@", a); + [a setConnectionDictionary:conDict]; + NSLog(@"got adaptor with condict %@", a); + + ctx = [a createAdaptorContext]; + ch = [ctx createAdaptorChannel]; + +#if 1 + m = AUTORELEASE([[EOModel alloc] initWithContentsOfFile:@"test.eomodel"]); + if (m) { + [a setModel:m]; + [a setConnectionDictionary:conDict]; + } +#endif + + expr = [[NSUserDefaults standardUserDefaults] stringForKey:@"sql"]; + + NSLog(@"opening channel .."); + + [ch setDebugEnabled:YES]; + + if ([ch openChannel]) { + NSLog(@"channel is open"); + + if ([ctx beginTransaction]) { + NSLog(@"began tx .."); + + /* do something */ + { + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + EOEntity *e; + EOSQLQualifier *q; + NSArray *attrs; + +#if 1 + /* fetch some expr */ + + if (expr) { + if ([ch evaluateExpression:expr]) { + NSDictionary *record; + + attrs = [ch describeResults]; + NSLog(@"results: %@", attrs); + + while ((record = [ch fetchAttributes:attrs withZone:nil])) + NSLog(@"fetched %@", record); + } + } +#endif + /* fetch some doof records */ + + e = [m entityNamed:@"Doof"]; + NSLog(@"entity: %@", e); + if (e == nil) + exit(1); + + q = [e qualifier]; + attrs = [e attributes]; + + if ([ch selectAttributes:attrs + describedByQualifier:q + fetchOrder:nil + lock:NO]) { + NSDictionary *record; + + while ((record = [ch fetchAttributes:attrs withZone:nil])) { + NSLog(@"fetched %@ birthday %@", + [record valueForKey:@"pkey"], + [record valueForKey:@"companyId"]); + } + } + else + NSLog(@"Could not select .."); + + /* fetch some team records */ + + if ((e = [m entityNamed:@"Team"])) { + q = [e qualifier]; + attrs = [e attributes]; + + if ([ch selectAttributes:attrs + describedByQualifier:q + fetchOrder:nil + lock:NO]) { + NSDictionary *record; + + while ((record = [ch fetchAttributes:attrs withZone:nil])) { + NSLog(@"fetched %@ birthday %@", + [record valueForKey:@"description"], + [record valueForKey:@"companyId"]); + } + } + else + NSLog(@"Could not select .."); + } + + /* do some update */ + + if ((e = [m entityNamed:@"Person"])) { + attrs = [e attributes]; + q = [[EOSQLQualifier alloc] + initWithEntity:e + qualifierFormat:@"%A='helge'", @"login"]; + AUTORELEASE(q); + + if ([ch selectAttributes:attrs + describedByQualifier:q + fetchOrder:nil + lock:NO]) { + NSDictionary *record; + + record = [ch fetchAttributes:attrs withZone:nil]; + } + else + NSLog(@"Could not select .."); + } + + RELEASE(pool); + } + + NSLog(@"committing tx .."); + if ([ctx commitTransaction]) + NSLog(@" could commit."); + else + NSLog(@" commit failed."); + } + + NSLog(@"closing channel .."); + [ch closeChannel]; + } + } + NS_HANDLER { + fprintf(stderr, "exception: %s\n", [[localException description] cString]); + abort(); + } + NS_ENDHANDLER; + + return 0; +} diff --git a/sope-gdl1/PostgreSQL72/postgres_types.h b/sope-gdl1/PostgreSQL72/postgres_types.h new file mode 100644 index 00000000..76c1727e --- /dev/null +++ b/sope-gdl1/PostgreSQL72/postgres_types.h @@ -0,0 +1,45 @@ +#define BOOLOID 16 +#define BYTEAOID 17 +#define CHAROID 18 +#define NAMEOID 19 +#define INT8OID 20 +#define INT2OID 21 +#define INT2VECTOROID 22 +#define INT4OID 23 +#define REGPROCOID 24 +#define TEXTOID 25 +#define OIDOID 26 +#define TIDOID 27 +#define XIDOID 28 +#define CIDOID 29 +#define OIDVECTOROID 30 +#define POINTOID 600 +#define LSEGOID 601 +#define PATHOID 602 +#define BOXOID 603 +#define POLYGONOID 604 +#define LINEOID 628 +#define FLOAT4OID 700 +#define FLOAT8OID 701 +#define ABSTIMEOID 702 +#define RELTIMEOID 703 +#define TINTERVALOID 704 +#define UNKNOWNOID 705 +#define CIRCLEOID 718 +#define CASHOID 790 +#define MACADDROID 829 +#define INETOID 869 +#define CIDROID 650 +#define ACLITEMSIZE 8 +#define BPCHAROID 1042 +#define VARCHAROID 1043 +#define DATEOID 1082 +#define TIMEOID 1083 +#define TIMESTAMPOID 1114 +#define TIMESTAMPTZOID 1184 +#define INTERVALOID 1186 +#define TIMETZOID 1266 +#define BITOID 1560 +#define VARBITOID 1562 +#define NUMERICOID 1700 +#define REFCURSOROID 1790 diff --git a/sope-gdl1/PostgreSQL72/test.eomodel b/sope-gdl1/PostgreSQL72/test.eomodel new file mode 100644 index 00000000..f17df573 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/test.eomodel @@ -0,0 +1,25 @@ +{ + EOModelVersion = 1; + adaptorClassName = PostgreSQLAdaptor; + adaptorName = PostgreSQL; + + entities = ( + { + name = Doof; + externalName = doof; + className = EOGenericRecord; + primaryKeyAttributes = ( pkey ); + attributesUsedForLocking = ( pkey ); + classProperties = ( pkey ); + attributes = ( + { + valueClassName = NSNumber; + columnName = pkey; + name = pkey; + valueType = i; + externalType = INT; // t_id + }, + ); + } + ); +} diff --git a/sope-gdl1/PostgreSQL72/types.psql b/sope-gdl1/PostgreSQL72/types.psql new file mode 100644 index 00000000..0f70ce45 --- /dev/null +++ b/sope-gdl1/PostgreSQL72/types.psql @@ -0,0 +1,13 @@ + +# type test table + +create table pgtypetest ( + t_int2 int2, + t_int4 int4, + t_int8 int8, + t_int int, + t_varchar255 varchar(255), + t_datetime datetime, + t_timestamp timestamp, + t_timestamp_wtz timestamp with time zone +); diff --git a/sope-gdl1/Version b/sope-gdl1/Version new file mode 100644 index 00000000..eef107a7 --- /dev/null +++ b/sope-gdl1/Version @@ -0,0 +1,8 @@ +# $Id: Version 1 2004-08-20 10:38:46Z znek $ +# +# This file is included by library makefiles to set the version information +# of the executable. + +MAJOR_VERSION=1 +MINOR_VERSION=0 +# the SUBMINOR_VERSION is set by the Version file inside of a library project diff --git a/sope-gdl1/common.make b/sope-gdl1/common.make new file mode 100644 index 00000000..5e17e3a7 --- /dev/null +++ b/sope-gdl1/common.make @@ -0,0 +1,27 @@ +# $Id: common.make 1 2004-08-20 10:38:46Z znek $ + +SKYROOT=.. + +include $(GNUSTEP_MAKEFILES)/common.make +include $(SKYROOT)/Version +-include ./Version + +GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_LOCAL_ROOT) + +ADDITIONAL_CPPFLAGS += -pipe -Wall -Wno-protocol + +SOPEDIR="../../../SOPE" + +ADDITIONAL_INCLUDE_DIRS += \ + -I.. \ + -I$(SOPEDIR)/skyrix-xml \ + -I$(SOPEDIR)/skyrix-core \ + -I$(SOPEDIR)/skyrix-core/NGExtensions \ + +ADDITIONAL_LIB_DIRS += \ + -L./$(GNUSTEP_OBJ_DIR) \ + -L$(SOPEDIR)/skyrix-xml/SaxObjC/$(GNUSTEP_OBJ_DIR) \ + -L$(SOPEDIR)/skyrix-xml/DOM/$(GNUSTEP_OBJ_DIR) \ + -L$(SOPEDIR)/skyrix-core/EOControl/$(GNUSTEP_OBJ_DIR) \ + -L$(SOPEDIR)/skyrix-core/NGExtensions/$(GNUSTEP_OBJ_DIR) + diff --git a/sope-gdl1/gnustep-db.xcode/project.pbxproj b/sope-gdl1/gnustep-db.xcode/project.pbxproj new file mode 100644 index 00000000..c726e0a1 --- /dev/null +++ b/sope-gdl1/gnustep-db.xcode/project.pbxproj @@ -0,0 +1,3002 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + E890B00E055AB18B004301A0 = { + children = ( + E890B01B055AB194004301A0, + E890B01D055AB1A0004301A0, + E890B01C055AB19B004301A0, + E8AC8D0905ABCA5E008C206D, + E890B028055AB1B8004301A0, + E8AC8D4E05ABCB39008C206D, + ); + isa = PBXGroup; + refType = 4; + sourceTree = ""; + }; + E890B010055AB18B004301A0 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + }; + isa = PBXBuildStyle; + name = Development; + }; + E890B011055AB18B004301A0 = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = YES; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + E890B012055AB18B004301A0 = { + buildSettings = { + }; + buildStyles = ( + E890B010055AB18B004301A0, + E890B011055AB18B004301A0, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = E890B00E055AB18B004301A0; + productRefGroup = E890B028055AB1B8004301A0; + projectDirPath = ""; + targets = ( + E890B026055AB1B8004301A0, + E8AC8D4C05ABCB39008C206D, + E8AC8DDC05ABCBC9008C206D, + ); + }; + E890B01B055AB194004301A0 = { + children = ( + E8AC8BEC05ABC13E008C206D, + E8AC8C2005ABC13E008C206D, + E8AC8C2205ABC13E008C206D, + E8AC8C2305ABC13E008C206D, + E8AC8BEF05ABC13E008C206D, + E8AC8C5F05ABC179008C206D, + E8AC8C6005ABC18A008C206D, + E890B02A055AB1C0004301A0, + E890B029055AB1BC004301A0, + E8AC8CF405ABC67E008C206D, + ); + isa = PBXGroup; + name = GDLAccess; + refType = 4; + sourceTree = ""; + }; + E890B01C055AB19B004301A0 = { + children = ( + ); + isa = PBXGroup; + name = FrontBase2; + refType = 4; + sourceTree = ""; + }; + E890B01D055AB1A0004301A0 = { + children = ( + E8AC8D1F05ABCAB9008C206D, + E8AC8D2205ABCAB9008C206D, + E8AC8D2305ABCAB9008C206D, + E8AC8D3E05ABCAB9008C206D, + E8AC8D4005ABCAB9008C206D, + E8AC8D4205ABCAB9008C206D, + E8AC8D4505ABCAEA008C206D, + E8AC8D4605ABCAFF008C206D, + E8AC8D4705ABCB1B008C206D, + ); + isa = PBXGroup; + name = PostgreSQL; + refType = 4; + sourceTree = ""; + }; + E890B022055AB1B8004301A0 = { + buildActionMask = 2147483647; + files = ( + E8AC8C2505ABC13E008C206D, + E8AC8C8E05ABC218008C206D, + E8AC8C8F05ABC218008C206D, + E8AC8C9005ABC218008C206D, + E8AC8C9105ABC218008C206D, + E8AC8C9205ABC218008C206D, + E8AC8C9305ABC218008C206D, + E8AC8C9405ABC218008C206D, + E8AC8C9505ABC218008C206D, + E8AC8C9605ABC218008C206D, + E8AC8C9705ABC218008C206D, + E8AC8C9805ABC218008C206D, + E8AC8C9905ABC218008C206D, + E8AC8C9A05ABC218008C206D, + E8AC8C9B05ABC218008C206D, + E8AC8C9C05ABC218008C206D, + E8AC8C9D05ABC218008C206D, + E8AC8C9E05ABC218008C206D, + E8AC8C9F05ABC218008C206D, + E8AC8CA005ABC218008C206D, + E8AC8CA105ABC218008C206D, + E8AC8CA205ABC218008C206D, + E8AC8CA305ABC218008C206D, + E8AC8CA405ABC218008C206D, + E8AC8CA505ABC218008C206D, + E8AC8CA605ABC218008C206D, + E8AC8CA705ABC218008C206D, + E8AC8CA805ABC218008C206D, + E8AC8CA905ABC218008C206D, + E8AC8CAA05ABC218008C206D, + E8AC8CAB05ABC218008C206D, + E8AC8CAC05ABC218008C206D, + E8AC8CAD05ABC218008C206D, + E8AC8CAE05ABC218008C206D, + E8AC8CAF05ABC218008C206D, + E8AC8CB005ABC218008C206D, + E8AC8CB105ABC218008C206D, + E8AC8CB205ABC218008C206D, + E8AC8CB305ABC218008C206D, + E8AC8CB405ABC218008C206D, + E8AC8CB505ABC218008C206D, + E8AC8D0105ABC6AE008C206D, + E8AC8D0305ABC6AE008C206D, + E8AC8D0705ABC6AE008C206D, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E890B023055AB1B8004301A0 = { + buildActionMask = 2147483647; + files = ( + E8AC8C2405ABC13E008C206D, + E8AC8C2705ABC13E008C206D, + E8AC8C5205ABC13E008C206D, + E8AC8C5305ABC13E008C206D, + E8AC8C5405ABC13E008C206D, + E8AC8C5505ABC13E008C206D, + E8AC8C5805ABC13E008C206D, + E8AC8C5905ABC13E008C206D, + E8AC8C5A05ABC13E008C206D, + E8AC8C5B05ABC13E008C206D, + E8AC8CFF05ABC6AE008C206D, + E8AC8D0005ABC6AE008C206D, + E8AC8D0505ABC6AE008C206D, + E8AC8D0605ABC6AE008C206D, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E890B024055AB1B8004301A0 = { + buildActionMask = 2147483647; + files = ( + E8AC8C2805ABC13E008C206D, + E8AC8C2905ABC13E008C206D, + E8AC8C2A05ABC13E008C206D, + E8AC8C2B05ABC13E008C206D, + E8AC8C2C05ABC13E008C206D, + E8AC8C2D05ABC13E008C206D, + E8AC8C2E05ABC13E008C206D, + E8AC8C2F05ABC13E008C206D, + E8AC8C3005ABC13E008C206D, + E8AC8C3105ABC13E008C206D, + E8AC8C3205ABC13E008C206D, + E8AC8C3305ABC13E008C206D, + E8AC8C3405ABC13E008C206D, + E8AC8C3505ABC13E008C206D, + E8AC8C3605ABC13E008C206D, + E8AC8C3705ABC13E008C206D, + E8AC8C3805ABC13E008C206D, + E8AC8C3905ABC13E008C206D, + E8AC8C3A05ABC13E008C206D, + E8AC8C3B05ABC13E008C206D, + E8AC8C3C05ABC13E008C206D, + E8AC8C3D05ABC13E008C206D, + E8AC8C3E05ABC13E008C206D, + E8AC8C3F05ABC13E008C206D, + E8AC8C4005ABC13E008C206D, + E8AC8C4105ABC13E008C206D, + E8AC8C4205ABC13E008C206D, + E8AC8C4305ABC13E008C206D, + E8AC8C4405ABC13E008C206D, + E8AC8C4505ABC13E008C206D, + E8AC8C4605ABC13E008C206D, + E8AC8C4705ABC13E008C206D, + E8AC8C4805ABC13E008C206D, + E8AC8C4905ABC13E008C206D, + E8AC8C4A05ABC13E008C206D, + E8AC8C4B05ABC13E008C206D, + E8AC8C4C05ABC13E008C206D, + E8AC8C4D05ABC13E008C206D, + E8AC8C4E05ABC13E008C206D, + E8AC8C4F05ABC13E008C206D, + E8AC8C5005ABC13E008C206D, + E8AC8C5105ABC13E008C206D, + E8AC8C5605ABC13E008C206D, + E8AC8C5705ABC13E008C206D, + E8AC8D0205ABC6AE008C206D, + E8AC8D0405ABC6AE008C206D, + E8AC8D0805ABC6AE008C206D, + E8D0A07E0605B8D10084DA47, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E890B025055AB1B8004301A0 = { + buildActionMask = 2147483647; + files = ( + E8AC8D0B05ABCA7A008C206D, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E890B026055AB1B8004301A0 = { + buildPhases = ( + E890B022055AB1B8004301A0, + E890B023055AB1B8004301A0, + E890B024055AB1B8004301A0, + E890B025055AB1B8004301A0, + ); + buildRules = ( + ); + buildSettings = { + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = /Users/helge/build; + FRAMEWORK_VERSION = A; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Foundation.framework/Headers/Foundation.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + HEADER_SEARCH_PATHS = "/Users/helge/OGo/OpenGroupware.org/ThirdParty/gnustep-db/GDLAccess/"; + INFOPLIST_FILE = "GDLAccess/GDLAccess-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + OTHER_CFLAGS = "-DAPPLE_RUNTIME=1 -DNeXT_RUNTIME=1 -DCOCOA_Foundation_LIBRARY=1 -DNeXT_Foundation_LIBRARY=1 -DXCODE_SELF_COMPILE=1"; + OTHER_LDFLAGS = "-framework Foundation"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = GDLAccess; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = GDLAccess; + productName = GDLAccess; + productReference = E890B027055AB1B8004301A0; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + GDLAccess + CFBundleGetInfoString + + CFBundleIdentifier + com.MySoftwareCompany.GDLAccess + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleShortVersionString + + CFBundleSignature + ???? + CFBundleVersion + 1.0.0d1 + + +"; + productType = "com.apple.product-type.framework"; + }; + E890B027055AB1B8004301A0 = { + explicitFileType = wrapper.framework; + includeInIndex = 0; + isa = PBXFileReference; + path = GDLAccess.framework; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E890B028055AB1B8004301A0 = { + children = ( + E890B027055AB1B8004301A0, + E8AC8D4D05ABCB39008C206D, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; + E890B029055AB1BC004301A0 = { + children = ( + E8AC8BED05ABC13E008C206D, + E8AC8BF005ABC13E008C206D, + E8AC8C6205ABC19C008C206D, + E8AC8C6305ABC1B2008C206D, + E8AC8C6405ABC1CB008C206D, + E8AC8C6505ABC1DB008C206D, + E8AC8BF905ABC13E008C206D, + E8AC8BFC05ABC13E008C206D, + E8AC8C0505ABC13E008C206D, + E8AC8C0605ABC13E008C206D, + E8AC8C0705ABC13E008C206D, + E8AC8C0805ABC13E008C206D, + E8AC8C0905ABC13E008C206D, + E8AC8C0B05ABC13E008C206D, + E8AC8C1005ABC13E008C206D, + E8AC8C1205ABC13E008C206D, + E8AC8C1605ABC13E008C206D, + E8AC8C1F05ABC13E008C206D, + ); + isa = PBXGroup; + name = Classes; + refType = 4; + sourceTree = ""; + }; + E890B02A055AB1C0004301A0 = { + children = ( + E8AC8C6605ABC218008C206D, + E8AC8C6705ABC218008C206D, + E8AC8C6805ABC218008C206D, + E8AC8C6905ABC218008C206D, + E8AC8C6A05ABC218008C206D, + E8AC8C6B05ABC218008C206D, + E8AC8C6C05ABC218008C206D, + E8AC8C6D05ABC218008C206D, + E8AC8C6E05ABC218008C206D, + E8AC8C6F05ABC218008C206D, + E8AC8C7005ABC218008C206D, + E8AC8C7105ABC218008C206D, + E8AC8C7205ABC218008C206D, + E8AC8C7305ABC218008C206D, + E8AC8C7405ABC218008C206D, + E8AC8C7505ABC218008C206D, + E8AC8C7605ABC218008C206D, + E8AC8C7705ABC218008C206D, + E8AC8C7805ABC218008C206D, + E8AC8C7905ABC218008C206D, + E8AC8C7A05ABC218008C206D, + E8AC8C7B05ABC218008C206D, + E8AC8C7C05ABC218008C206D, + E8AC8C7D05ABC218008C206D, + E8AC8C7E05ABC218008C206D, + E8AC8C7F05ABC218008C206D, + E8AC8C8005ABC218008C206D, + E8AC8C8105ABC218008C206D, + E8AC8C8205ABC218008C206D, + E8AC8C8305ABC218008C206D, + E8AC8C8405ABC218008C206D, + E8AC8C8505ABC218008C206D, + E8AC8C8605ABC218008C206D, + E8AC8C8705ABC218008C206D, + E8AC8C8805ABC218008C206D, + E8AC8C8905ABC218008C206D, + E8AC8C8A05ABC218008C206D, + E8AC8C8B05ABC218008C206D, + E8AC8C8C05ABC218008C206D, + E8AC8C8D05ABC218008C206D, + ); + isa = PBXGroup; + name = Headers; + refType = 4; + sourceTree = ""; + }; + E8AC8BEC05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = ChangeLog; + path = GDLAccess/ChangeLog; + refType = 4; + sourceTree = ""; + }; + E8AC8BED05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = common.h; + path = GDLAccess/common.h; + refType = 4; + sourceTree = ""; + }; + E8AC8BEE05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "connect-EOAdaptor.m"; + path = "GDLAccess/connect-EOAdaptor.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8BEF05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = COPYING.LIB; + path = GDLAccess/COPYING.LIB; + refType = 4; + sourceTree = ""; + }; + E8AC8BF005ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = eoaccess.m; + path = GDLAccess/eoaccess.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BF105ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAdaptor.m; + path = GDLAccess/EOAdaptor.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BF205ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAdaptorChannel.m; + path = GDLAccess/EOAdaptorChannel.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BF305ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOAdaptorChannel+Attributes.m"; + path = "GDLAccess/EOAdaptorChannel+Attributes.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8BF405ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAdaptorContext.m; + path = GDLAccess/EOAdaptorContext.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BF505ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAdaptorDataSource.m; + path = GDLAccess/EOAdaptorDataSource.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BF605ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAdaptorGlobalID.m; + path = GDLAccess/EOAdaptorGlobalID.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BF705ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAdaptorOperation.m; + path = GDLAccess/EOAdaptorOperation.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BF805ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOAndQualifier+SQL.m"; + path = "GDLAccess/EOAndQualifier+SQL.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8BF905ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOArrayProxy.m; + path = GDLAccess/EOArrayProxy.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BFA05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAttribute.m; + path = GDLAccess/EOAttribute.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BFB05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOAttributeOrdering.m; + path = GDLAccess/EOAttributeOrdering.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BFC05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOCustomValues.m; + path = GDLAccess/EOCustomValues.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BFD05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EODatabase.m; + path = GDLAccess/EODatabase.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BFE05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EODatabaseChannel.m; + path = GDLAccess/EODatabaseChannel.m; + refType = 4; + sourceTree = ""; + }; + E8AC8BFF05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EODatabaseContext.m; + path = GDLAccess/EODatabaseContext.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0005ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EODatabaseFault.m; + path = GDLAccess/EODatabaseFault.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0105ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EODatabaseFaultResolver.m; + path = GDLAccess/EODatabaseFaultResolver.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0205ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOEntity.m; + path = GDLAccess/EOEntity.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0305ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOEntity+Factory.m"; + path = "GDLAccess/EOEntity+Factory.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C0405ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOEntityClassDescription.m; + path = GDLAccess/EOEntityClassDescription.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0505ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOExpressionArray.m; + path = GDLAccess/EOExpressionArray.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0605ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOFault.m; + path = GDLAccess/EOFault.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0705ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOFaultHandler.m; + path = GDLAccess/EOFaultHandler.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0805ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOFExceptions.m; + path = GDLAccess/EOFExceptions.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0905ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOGenericRecord.m; + path = GDLAccess/EOGenericRecord.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0A05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOKeyComparisonQualifier+SQL.m"; + path = "GDLAccess/EOKeyComparisonQualifier+SQL.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C0B05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOKeySortOrdering.m; + path = GDLAccess/EOKeySortOrdering.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0C05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOKeyValueQualifier+SQL.m"; + path = "GDLAccess/EOKeyValueQualifier+SQL.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C0D05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOModel.m; + path = GDLAccess/EOModel.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0E05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOModelGroup.m; + path = GDLAccess/EOModelGroup.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C0F05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EONotQualifier+SQL.m"; + path = "GDLAccess/EONotQualifier+SQL.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C1005ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOObjectUniquer.m; + path = GDLAccess/EOObjectUniquer.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1105ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOOrQualifier+SQL.m"; + path = "GDLAccess/EOOrQualifier+SQL.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C1205ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOPrimaryKeyDictionary.m; + path = GDLAccess/EOPrimaryKeyDictionary.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1305ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOQualifier+SQL.m"; + path = "GDLAccess/EOQualifier+SQL.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C1405ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOQualifierScanner.m; + path = GDLAccess/EOQualifierScanner.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1505ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOQuotedExpression.m; + path = GDLAccess/EOQuotedExpression.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1605ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EORecordDictionary.m; + path = GDLAccess/EORecordDictionary.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1705ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EORelationship.m; + path = GDLAccess/EORelationship.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1805ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOSQLExpression.m; + path = GDLAccess/EOSQLExpression.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1905ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOSQLQualifier.m; + path = GDLAccess/EOSQLQualifier.m; + refType = 4; + sourceTree = ""; + }; + E8AC8C1A05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = GNUmakefile; + path = GDLAccess/GNUmakefile; + refType = 4; + sourceTree = ""; + }; + E8AC8C1B05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = GNUmakefile.postamble; + path = GDLAccess/GNUmakefile.postamble; + refType = 4; + sourceTree = ""; + }; + E8AC8C1C05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = GNUmakefile.preamble; + path = GDLAccess/GNUmakefile.preamble; + refType = 4; + sourceTree = ""; + }; + E8AC8C1D05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = libGDLAccess.def; + path = GDLAccess/libGDLAccess.def; + refType = 4; + sourceTree = ""; + }; + E8AC8C1E05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "load-EOAdaptor.m"; + path = "GDLAccess/load-EOAdaptor.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C1F05ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "NSObject+EONullInit.m"; + path = "GDLAccess/NSObject+EONullInit.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8C2005ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = README; + path = GDLAccess/README; + refType = 4; + sourceTree = ""; + }; + E8AC8C2105ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text.script.python; + name = test.py; + path = GDLAccess/test.py; + refType = 4; + sourceTree = ""; + }; + E8AC8C2205ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = TODO; + path = GDLAccess/TODO; + refType = 4; + sourceTree = ""; + }; + E8AC8C2305ABC13E008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = Version; + path = GDLAccess/Version; + refType = 4; + sourceTree = ""; + }; + E8AC8C2405ABC13E008C206D = { + fileRef = E8AC8BEC05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2505ABC13E008C206D = { + fileRef = E8AC8BED05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Private, + ); + }; + }; + E8AC8C2705ABC13E008C206D = { + fileRef = E8AC8BEF05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2805ABC13E008C206D = { + fileRef = E8AC8BF005ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2905ABC13E008C206D = { + fileRef = E8AC8BF105ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2A05ABC13E008C206D = { + fileRef = E8AC8BF205ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2B05ABC13E008C206D = { + fileRef = E8AC8BF305ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2C05ABC13E008C206D = { + fileRef = E8AC8BF405ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2D05ABC13E008C206D = { + fileRef = E8AC8BF505ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2E05ABC13E008C206D = { + fileRef = E8AC8BF605ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C2F05ABC13E008C206D = { + fileRef = E8AC8BF705ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3005ABC13E008C206D = { + fileRef = E8AC8BF805ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3105ABC13E008C206D = { + fileRef = E8AC8BF905ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3205ABC13E008C206D = { + fileRef = E8AC8BFA05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3305ABC13E008C206D = { + fileRef = E8AC8BFB05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3405ABC13E008C206D = { + fileRef = E8AC8BFC05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3505ABC13E008C206D = { + fileRef = E8AC8BFD05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3605ABC13E008C206D = { + fileRef = E8AC8BFE05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3705ABC13E008C206D = { + fileRef = E8AC8BFF05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3805ABC13E008C206D = { + fileRef = E8AC8C0005ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3905ABC13E008C206D = { + fileRef = E8AC8C0105ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3A05ABC13E008C206D = { + fileRef = E8AC8C0205ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3B05ABC13E008C206D = { + fileRef = E8AC8C0305ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3C05ABC13E008C206D = { + fileRef = E8AC8C0405ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3D05ABC13E008C206D = { + fileRef = E8AC8C0505ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3E05ABC13E008C206D = { + fileRef = E8AC8C0605ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C3F05ABC13E008C206D = { + fileRef = E8AC8C0705ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4005ABC13E008C206D = { + fileRef = E8AC8C0805ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4105ABC13E008C206D = { + fileRef = E8AC8C0905ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4205ABC13E008C206D = { + fileRef = E8AC8C0A05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4305ABC13E008C206D = { + fileRef = E8AC8C0B05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4405ABC13E008C206D = { + fileRef = E8AC8C0C05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4505ABC13E008C206D = { + fileRef = E8AC8C0D05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4605ABC13E008C206D = { + fileRef = E8AC8C0E05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4705ABC13E008C206D = { + fileRef = E8AC8C0F05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4805ABC13E008C206D = { + fileRef = E8AC8C1005ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4905ABC13E008C206D = { + fileRef = E8AC8C1105ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4A05ABC13E008C206D = { + fileRef = E8AC8C1205ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4B05ABC13E008C206D = { + fileRef = E8AC8C1305ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4C05ABC13E008C206D = { + fileRef = E8AC8C1405ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4D05ABC13E008C206D = { + fileRef = E8AC8C1505ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4E05ABC13E008C206D = { + fileRef = E8AC8C1605ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C4F05ABC13E008C206D = { + fileRef = E8AC8C1705ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5005ABC13E008C206D = { + fileRef = E8AC8C1805ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5105ABC13E008C206D = { + fileRef = E8AC8C1905ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5205ABC13E008C206D = { + fileRef = E8AC8C1A05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5305ABC13E008C206D = { + fileRef = E8AC8C1B05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5405ABC13E008C206D = { + fileRef = E8AC8C1C05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5505ABC13E008C206D = { + fileRef = E8AC8C1D05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5605ABC13E008C206D = { + fileRef = E8AC8C1E05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5705ABC13E008C206D = { + fileRef = E8AC8C1F05ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5805ABC13E008C206D = { + fileRef = E8AC8C2005ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5905ABC13E008C206D = { + fileRef = E8AC8C2105ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5A05ABC13E008C206D = { + fileRef = E8AC8C2205ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5B05ABC13E008C206D = { + fileRef = E8AC8C2305ABC13E008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8C5F05ABC179008C206D = { + children = ( + E8AC8C1A05ABC13E008C206D, + E8AC8C1B05ABC13E008C206D, + E8AC8C1C05ABC13E008C206D, + E8AC8C1D05ABC13E008C206D, + ); + isa = PBXGroup; + name = Makefiles; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8C6005ABC18A008C206D = { + children = ( + E8AC8C2105ABC13E008C206D, + E8AC8BEE05ABC13E008C206D, + E8AC8C1E05ABC13E008C206D, + ); + isa = PBXGroup; + name = Tools; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8C6205ABC19C008C206D = { + children = ( + E8AC8BF105ABC13E008C206D, + E8AC8BF205ABC13E008C206D, + E8AC8BF305ABC13E008C206D, + E8AC8BF405ABC13E008C206D, + E8AC8BF505ABC13E008C206D, + E8AC8BF605ABC13E008C206D, + E8AC8BF705ABC13E008C206D, + ); + isa = PBXGroup; + name = Adaptor; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8C6305ABC1B2008C206D = { + children = ( + E8AC8BF805ABC13E008C206D, + E8AC8C0A05ABC13E008C206D, + E8AC8C0C05ABC13E008C206D, + E8AC8C0F05ABC13E008C206D, + E8AC8C1105ABC13E008C206D, + E8AC8C1305ABC13E008C206D, + E8AC8C1405ABC13E008C206D, + E8AC8C1505ABC13E008C206D, + E8AC8C1805ABC13E008C206D, + E8D0A07D0605B8D10084DA47, + E8AC8C1905ABC13E008C206D, + ); + isa = PBXGroup; + name = Qualifier; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8C6405ABC1CB008C206D = { + children = ( + E8AC8BFA05ABC13E008C206D, + E8AC8BFB05ABC13E008C206D, + E8AC8C0205ABC13E008C206D, + E8AC8C0305ABC13E008C206D, + E8AC8C0405ABC13E008C206D, + E8AC8C0D05ABC13E008C206D, + E8AC8C0E05ABC13E008C206D, + E8AC8C1705ABC13E008C206D, + ); + isa = PBXGroup; + name = Model; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8C6505ABC1DB008C206D = { + children = ( + E8AC8BFD05ABC13E008C206D, + E8AC8BFE05ABC13E008C206D, + E8AC8BFF05ABC13E008C206D, + E8AC8C0005ABC13E008C206D, + E8AC8C0105ABC13E008C206D, + ); + isa = PBXGroup; + name = Database; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8C6605ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAccess.h; + path = GDLAccess/EOAccess/EOAccess.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6705ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAdaptor.h; + path = GDLAccess/EOAccess/EOAdaptor.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6805ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAdaptorChannel.h; + path = GDLAccess/EOAccess/EOAdaptorChannel.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6905ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "EOAdaptorChannel+Attributes.h"; + path = "GDLAccess/EOAccess/EOAdaptorChannel+Attributes.h"; + refType = 4; + sourceTree = ""; + }; + E8AC8C6A05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAdaptorContext.h; + path = GDLAccess/EOAccess/EOAdaptorContext.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6B05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAdaptorDataSource.h; + path = GDLAccess/EOAccess/EOAdaptorDataSource.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6C05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAdaptorGlobalID.h; + path = GDLAccess/EOAccess/EOAdaptorGlobalID.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6D05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAdaptorOperation.h; + path = GDLAccess/EOAccess/EOAdaptorOperation.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6E05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOArrayProxy.h; + path = GDLAccess/EOAccess/EOArrayProxy.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C6F05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAttribute.h; + path = GDLAccess/EOAccess/EOAttribute.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7005ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOAttributeOrdering.h; + path = GDLAccess/EOAccess/EOAttributeOrdering.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7105ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOCustomValues.h; + path = GDLAccess/EOAccess/EOCustomValues.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7205ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EODatabase.h; + path = GDLAccess/EOAccess/EODatabase.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7305ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EODatabaseChannel.h; + path = GDLAccess/EOAccess/EODatabaseChannel.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7405ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EODatabaseContext.h; + path = GDLAccess/EOAccess/EODatabaseContext.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7505ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EODatabaseFault.h; + path = GDLAccess/EOAccess/EODatabaseFault.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7605ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EODatabaseFaultResolver.h; + path = GDLAccess/EOAccess/EODatabaseFaultResolver.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7705ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EODelegateResponse.h; + path = GDLAccess/EOAccess/EODelegateResponse.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7805ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOEntity.h; + path = GDLAccess/EOAccess/EOEntity.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7905ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "EOEntity+Factory.h"; + path = "GDLAccess/EOAccess/EOEntity+Factory.h"; + refType = 4; + sourceTree = ""; + }; + E8AC8C7A05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOExpressionArray.h; + path = GDLAccess/EOAccess/EOExpressionArray.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7B05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOFault.h; + path = GDLAccess/EOAccess/EOFault.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7C05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOFaultHandler.h; + path = GDLAccess/EOAccess/EOFaultHandler.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7D05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOFExceptions.h; + path = GDLAccess/EOAccess/EOFExceptions.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7E05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOGenericRecord.h; + path = GDLAccess/EOAccess/EOGenericRecord.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C7F05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOJoinTypes.h; + path = GDLAccess/EOAccess/EOJoinTypes.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8005ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOKeySortOrdering.h; + path = GDLAccess/EOAccess/EOKeySortOrdering.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8105ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOModel.h; + path = GDLAccess/EOAccess/EOModel.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8205ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOModelGroup.h; + path = GDLAccess/EOAccess/EOModelGroup.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8305ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EONull.h; + path = GDLAccess/EOAccess/EONull.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8405ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOObjectUniquer.h; + path = GDLAccess/EOAccess/EOObjectUniquer.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8505ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOPrimaryKeyDictionary.h; + path = GDLAccess/EOAccess/EOPrimaryKeyDictionary.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8605ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOQualifierScanner.h; + path = GDLAccess/EOAccess/EOQualifierScanner.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8705ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOQuotedExpression.h; + path = GDLAccess/EOAccess/EOQuotedExpression.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8805ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EORecordDictionary.h; + path = GDLAccess/EOAccess/EORecordDictionary.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8905ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EORelationship.h; + path = GDLAccess/EOAccess/EORelationship.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8A05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOSQLExpression.h; + path = GDLAccess/EOAccess/EOSQLExpression.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8B05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = EOSQLQualifier.h; + path = GDLAccess/EOAccess/EOSQLQualifier.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8C05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = GDLAccess.h; + path = GDLAccess/EOAccess/GDLAccess.h; + refType = 4; + sourceTree = ""; + }; + E8AC8C8D05ABC218008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "NSObject+EONullInit.h"; + path = "GDLAccess/EOAccess/NSObject+EONullInit.h"; + refType = 4; + sourceTree = ""; + }; + E8AC8C8E05ABC218008C206D = { + fileRef = E8AC8C6605ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C8F05ABC218008C206D = { + fileRef = E8AC8C6705ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9005ABC218008C206D = { + fileRef = E8AC8C6805ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9105ABC218008C206D = { + fileRef = E8AC8C6905ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9205ABC218008C206D = { + fileRef = E8AC8C6A05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9305ABC218008C206D = { + fileRef = E8AC8C6B05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9405ABC218008C206D = { + fileRef = E8AC8C6C05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9505ABC218008C206D = { + fileRef = E8AC8C6D05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9605ABC218008C206D = { + fileRef = E8AC8C6E05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9705ABC218008C206D = { + fileRef = E8AC8C6F05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9805ABC218008C206D = { + fileRef = E8AC8C7005ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9905ABC218008C206D = { + fileRef = E8AC8C7105ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9A05ABC218008C206D = { + fileRef = E8AC8C7205ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9B05ABC218008C206D = { + fileRef = E8AC8C7305ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9C05ABC218008C206D = { + fileRef = E8AC8C7405ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9D05ABC218008C206D = { + fileRef = E8AC8C7505ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9E05ABC218008C206D = { + fileRef = E8AC8C7605ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8C9F05ABC218008C206D = { + fileRef = E8AC8C7705ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA005ABC218008C206D = { + fileRef = E8AC8C7805ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA105ABC218008C206D = { + fileRef = E8AC8C7905ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA205ABC218008C206D = { + fileRef = E8AC8C7A05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA305ABC218008C206D = { + fileRef = E8AC8C7B05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA405ABC218008C206D = { + fileRef = E8AC8C7C05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA505ABC218008C206D = { + fileRef = E8AC8C7D05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA605ABC218008C206D = { + fileRef = E8AC8C7E05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA705ABC218008C206D = { + fileRef = E8AC8C7F05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA805ABC218008C206D = { + fileRef = E8AC8C8005ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CA905ABC218008C206D = { + fileRef = E8AC8C8105ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CAA05ABC218008C206D = { + fileRef = E8AC8C8205ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CAB05ABC218008C206D = { + fileRef = E8AC8C8305ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CAC05ABC218008C206D = { + fileRef = E8AC8C8405ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CAD05ABC218008C206D = { + fileRef = E8AC8C8505ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CAE05ABC218008C206D = { + fileRef = E8AC8C8605ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CAF05ABC218008C206D = { + fileRef = E8AC8C8705ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CB005ABC218008C206D = { + fileRef = E8AC8C8805ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CB105ABC218008C206D = { + fileRef = E8AC8C8905ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CB205ABC218008C206D = { + fileRef = E8AC8C8A05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CB305ABC218008C206D = { + fileRef = E8AC8C8B05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CB405ABC218008C206D = { + fileRef = E8AC8C8C05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CB505ABC218008C206D = { + fileRef = E8AC8C8D05ABC218008C206D; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + Public, + ); + }; + }; + E8AC8CF405ABC67E008C206D = { + children = ( + E8AC8CF505ABC6AE008C206D, + E8AC8CF605ABC6AE008C206D, + E8AC8CFB05ABC6AE008C206D, + E8AC8CFC05ABC6AE008C206D, + E8AC8CF705ABC6AE008C206D, + E8AC8CF805ABC6AE008C206D, + E8AC8CF905ABC6AE008C206D, + E8AC8CFA05ABC6AE008C206D, + E8AC8CFD05ABC6AE008C206D, + E8AC8CFE05ABC6AE008C206D, + ); + isa = PBXGroup; + name = FoundationExt; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8CF505ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = COPYING; + path = GDLAccess/FoundationExt/COPYING; + refType = 4; + sourceTree = ""; + }; + E8AC8CF605ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = COPYRIGHT; + path = GDLAccess/FoundationExt/COPYRIGHT; + refType = 4; + sourceTree = ""; + }; + E8AC8CF705ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = DefaultScannerHandler.h; + path = GDLAccess/FoundationExt/DefaultScannerHandler.h; + refType = 4; + sourceTree = ""; + }; + E8AC8CF805ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = DefaultScannerHandler.m; + path = GDLAccess/FoundationExt/DefaultScannerHandler.m; + refType = 4; + sourceTree = ""; + }; + E8AC8CF905ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = FormatScanner.h; + path = GDLAccess/FoundationExt/FormatScanner.h; + refType = 4; + sourceTree = ""; + }; + E8AC8CFA05ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = FormatScanner.m; + path = GDLAccess/FoundationExt/FormatScanner.m; + refType = 4; + sourceTree = ""; + }; + E8AC8CFB05ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = GNUmakefile; + path = GDLAccess/FoundationExt/GNUmakefile; + refType = 4; + sourceTree = ""; + }; + E8AC8CFC05ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = LICENSE; + path = GDLAccess/FoundationExt/LICENSE; + refType = 4; + sourceTree = ""; + }; + E8AC8CFD05ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = PrintfFormatScanner.h; + path = GDLAccess/FoundationExt/PrintfFormatScanner.h; + refType = 4; + sourceTree = ""; + }; + E8AC8CFE05ABC6AE008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = PrintfFormatScanner.m; + path = GDLAccess/FoundationExt/PrintfFormatScanner.m; + refType = 4; + sourceTree = ""; + }; + E8AC8CFF05ABC6AE008C206D = { + fileRef = E8AC8CF505ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0005ABC6AE008C206D = { + fileRef = E8AC8CF605ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0105ABC6AE008C206D = { + fileRef = E8AC8CF705ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0205ABC6AE008C206D = { + fileRef = E8AC8CF805ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0305ABC6AE008C206D = { + fileRef = E8AC8CF905ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0405ABC6AE008C206D = { + fileRef = E8AC8CFA05ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0505ABC6AE008C206D = { + fileRef = E8AC8CFB05ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0605ABC6AE008C206D = { + fileRef = E8AC8CFC05ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0705ABC6AE008C206D = { + fileRef = E8AC8CFD05ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0805ABC6AE008C206D = { + fileRef = E8AC8CFE05ABC6AE008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D0905ABCA5E008C206D = { + children = ( + E8AC8D0A05ABCA7A008C206D, + ); + isa = PBXGroup; + name = "Linked Frameworks"; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8D0A05ABCA7A008C206D = { + isa = PBXFileReference; + lastKnownFileType = file; + name = EOControl.framework; + path = /Users/helge/Library/Frameworks/EOControl.framework; + refType = 0; + sourceTree = ""; + }; + E8AC8D0B05ABCA7A008C206D = { + fileRef = E8AC8D0A05ABCA7A008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8D1F05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = ChangeLog; + path = PostgreSQL72/ChangeLog; + refType = 4; + sourceTree = ""; + }; + E8AC8D2005ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = common.h; + path = PostgreSQL72/common.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D2105ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text.plist; + name = condict.plist; + path = PostgreSQL72/condict.plist; + refType = 4; + sourceTree = ""; + }; + E8AC8D2205ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = COPYING; + path = PostgreSQL72/COPYING; + refType = 4; + sourceTree = ""; + }; + E8AC8D2305ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = COPYING.LIB; + path = PostgreSQL72/COPYING.LIB; + refType = 4; + sourceTree = ""; + }; + E8AC8D2405ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "EOAttribute+PostgreSQL72.h"; + path = "PostgreSQL72/EOAttribute+PostgreSQL72.h"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2505ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "EOAttribute+PostgreSQL72.m"; + path = "PostgreSQL72/EOAttribute+PostgreSQL72.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2605ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = gdltest.m; + path = PostgreSQL72/gdltest.m; + refType = 4; + sourceTree = ""; + }; + E8AC8D2705ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = GNUmakefile; + path = PostgreSQL72/GNUmakefile; + refType = 4; + sourceTree = ""; + }; + E8AC8D2805ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = GNUmakefile.preamble; + path = PostgreSQL72/GNUmakefile.preamble; + refType = 4; + sourceTree = ""; + }; + E8AC8D2905ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "NSCalendarDate+PGVal.m"; + path = "PostgreSQL72/NSCalendarDate+PGVal.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2A05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "NSData+PGVal.m"; + path = "PostgreSQL72/NSData+PGVal.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2B05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "NSNumber+PGVal.m"; + path = "PostgreSQL72/NSNumber+PGVal.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2C05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "NSString+PGVal.m"; + path = "PostgreSQL72/NSString+PGVal.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2D05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "NSString+PostgreSQL72.h"; + path = "PostgreSQL72/NSString+PostgreSQL72.h"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2E05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "NSString+PostgreSQL72.m"; + path = "PostgreSQL72/NSString+PostgreSQL72.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8D2F05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = postgres_types.h; + path = PostgreSQL72/postgres_types.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D3005ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = PostgreSQL72Adaptor.h; + path = PostgreSQL72/PostgreSQL72Adaptor.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D3105ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = PostgreSQL72Adaptor.m; + path = PostgreSQL72/PostgreSQL72Adaptor.m; + refType = 4; + sourceTree = ""; + }; + E8AC8D3205ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = PostgreSQL72Channel.h; + path = PostgreSQL72/PostgreSQL72Channel.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D3305ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = PostgreSQL72Channel.m; + path = PostgreSQL72/PostgreSQL72Channel.m; + refType = 4; + sourceTree = ""; + }; + E8AC8D3405ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = "PostgreSQL72Channel+Model.h"; + path = "PostgreSQL72/PostgreSQL72Channel+Model.h"; + refType = 4; + sourceTree = ""; + }; + E8AC8D3505ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = "PostgreSQL72Channel+Model.m"; + path = "PostgreSQL72/PostgreSQL72Channel+Model.m"; + refType = 4; + sourceTree = ""; + }; + E8AC8D3605ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = PostgreSQL72Context.h; + path = PostgreSQL72/PostgreSQL72Context.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D3705ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = PostgreSQL72Context.m; + path = PostgreSQL72/PostgreSQL72Context.m; + refType = 4; + sourceTree = ""; + }; + E8AC8D3805ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = PostgreSQL72Exception.h; + path = PostgreSQL72/PostgreSQL72Exception.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D3905ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = PostgreSQL72Exception.m; + path = PostgreSQL72/PostgreSQL72Exception.m; + refType = 4; + sourceTree = ""; + }; + E8AC8D3A05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = PostgreSQL72Expression.h; + path = PostgreSQL72/PostgreSQL72Expression.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D3B05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = PostgreSQL72Expression.m; + path = PostgreSQL72/PostgreSQL72Expression.m; + refType = 4; + sourceTree = ""; + }; + E8AC8D3C05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = PostgreSQL72Values.h; + path = PostgreSQL72/PostgreSQL72Values.h; + refType = 4; + sourceTree = ""; + }; + E8AC8D3D05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = PostgreSQL72Values.m; + path = PostgreSQL72/PostgreSQL72Values.m; + refType = 4; + sourceTree = ""; + }; + E8AC8D3E05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = README; + path = PostgreSQL72/README; + refType = 4; + sourceTree = ""; + }; + E8AC8D3F05ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = test.eomodel; + path = PostgreSQL72/test.eomodel; + refType = 4; + sourceTree = ""; + }; + E8AC8D4005ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = TODO; + path = PostgreSQL72/TODO; + refType = 4; + sourceTree = ""; + }; + E8AC8D4105ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = types.psql; + path = PostgreSQL72/types.psql; + refType = 4; + sourceTree = ""; + }; + E8AC8D4205ABCAB9008C206D = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text; + name = Version; + path = PostgreSQL72/Version; + refType = 4; + sourceTree = ""; + }; + E8AC8D4305ABCACA008C206D = { + children = ( + E8AC8D3205ABCAB9008C206D, + E8AC8D3305ABCAB9008C206D, + E8AC8D3405ABCAB9008C206D, + E8AC8D3505ABCAB9008C206D, + ); + isa = PBXGroup; + name = Channel; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8D4405ABCADA008C206D = { + children = ( + E8AC8D3C05ABCAB9008C206D, + E8AC8D3D05ABCAB9008C206D, + E8AC8D2905ABCAB9008C206D, + E8AC8D2A05ABCAB9008C206D, + E8AC8D2B05ABCAB9008C206D, + E8AC8D2C05ABCAB9008C206D, + ); + isa = PBXGroup; + name = Values; + path = ""; + refType = 4; + sourceTree = ""; + }; + E8AC8D4505ABCAEA008C206D = { + children = ( + E8AC8D2705ABCAB9008C206D, + E8AC8D2805ABCAB9008C206D, + ); + isa = PBXGroup; + name = Makefiles; + refType = 4; + sourceTree = ""; + }; + E8AC8D4605ABCAFF008C206D = { + children = ( + E8AC8D2105ABCAB9008C206D, + E8AC8D2605ABCAB9008C206D, + E8AC8D3F05ABCAB9008C206D, + E8AC8D4105ABCAB9008C206D, + ); + isa = PBXGroup; + name = Misc; + refType = 4; + sourceTree = ""; + }; + E8AC8D4705ABCB1B008C206D = { + children = ( + E8AC8D2005ABCAB9008C206D, + E8AC8D4405ABCADA008C206D, + E8AC8D4305ABCACA008C206D, + E8AC8D2405ABCAB9008C206D, + E8AC8D2505ABCAB9008C206D, + E8AC8D2D05ABCAB9008C206D, + E8AC8D2E05ABCAB9008C206D, + E8AC8D2F05ABCAB9008C206D, + E8AC8D3005ABCAB9008C206D, + E8AC8D3105ABCAB9008C206D, + E8AC8D3605ABCAB9008C206D, + E8AC8D3705ABCAB9008C206D, + E8AC8D3805ABCAB9008C206D, + E8AC8D3905ABCAB9008C206D, + E8AC8D3A05ABCAB9008C206D, + E8AC8D3B05ABCAB9008C206D, + ); + isa = PBXGroup; + name = Classes; + refType = 4; + sourceTree = ""; + }; + E8AC8D4805ABCB39008C206D = { + buildActionMask = 2147483647; + files = ( + E8AC8DC005ABCB8D008C206D, + E8AC8DC205ABCB91008C206D, + E8AC8DC805ABCB99008C206D, + E8AC8DCA05ABCB9C008C206D, + E8AC8DCB05ABCB9C008C206D, + E8AC8DCD05ABCB9E008C206D, + E8AC8DCF05ABCB9F008C206D, + E8AC8DD105ABCBA0008C206D, + E8AC8DD305ABCBA3008C206D, + E8AC8DD505ABCBA4008C206D, + E8AC8DD705ABCBA6008C206D, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E8AC8D4905ABCB39008C206D = { + buildActionMask = 2147483647; + files = ( + E8AC8DBF05ABCB8C008C206D, + E8AC8DC105ABCB90008C206D, + E8AC8DD905ABCBA7008C206D, + E8AC8DDA05ABCBAB008C206D, + E8AC8DDB05ABCBAC008C206D, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E8AC8D4A05ABCB39008C206D = { + buildActionMask = 2147483647; + files = ( + E8AC8DC305ABCB92008C206D, + E8AC8DC405ABCB95008C206D, + E8AC8DC505ABCB97008C206D, + E8AC8DC605ABCB97008C206D, + E8AC8DC705ABCB98008C206D, + E8AC8DC905ABCB99008C206D, + E8AC8DCC05ABCB9D008C206D, + E8AC8DCE05ABCB9E008C206D, + E8AC8DD005ABCB9F008C206D, + E8AC8DD205ABCBA2008C206D, + E8AC8DD405ABCBA4008C206D, + E8AC8DD605ABCBA5008C206D, + E8AC8DD805ABCBA6008C206D, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E8AC8D4B05ABCB39008C206D = { + buildActionMask = 2147483647; + files = ( + E8F046BF067385960069C17E, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + E8AC8D4C05ABCB39008C206D = { + buildPhases = ( + E8AC8D4805ABCB39008C206D, + E8AC8D4905ABCB39008C206D, + E8AC8D4A05ABCB39008C206D, + E8AC8D4B05ABCB39008C206D, + ); + buildRules = ( + ); + buildSettings = { + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Foundation.framework/Headers/Foundation.h"; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + HEADER_SEARCH_PATHS = /usr/local/pgsql/include; + INFOPLIST_FILE = "PostgreSQL72/PostgreSQL72-Info.plist"; + INSTALL_PATH = "$(USER_LIBRARY_DIR)/GDLAdaptors/"; + OTHER_CFLAGS = "-DAPPLE_RUNTIME=1 -DNeXT_RUNTIME=1 -DCOCOA_Foundation_LIBRARY=1 -DNeXT_Foundation_LIBRARY=1"; + OTHER_LDFLAGS = "-framework Foundation -L/usr/local/pgsql/lib -lpq -lssl -lcrypto"; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = PostgreSQL72; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost"; + WRAPPER_EXTENSION = gdladaptor; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = PostgreSQL72; + productName = PostgreSQL72; + productReference = E8AC8D4D05ABCB39008C206D; + productSettingsXML = " + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + PostgreSQL72 + CFBundleGetInfoString + + CFBundleIconFile + + CFBundleIdentifier + com.MySoftwareCompany.PostgreSQL72 + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + + CFBundleSignature + ???? + CFBundleVersion + 1.0.0d1 + + +"; + productType = "com.apple.product-type.bundle"; + }; + E8AC8D4D05ABCB39008C206D = { + explicitFileType = wrapper.cfbundle; + includeInIndex = 0; + isa = PBXFileReference; + path = PostgreSQL72.gdladaptor; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E8AC8D4E05ABCB39008C206D = { + isa = PBXFileReference; + lastKnownFileType = text.plist.xml; + name = "PostgreSQL72-Info.plist"; + path = "PostgreSQL72/PostgreSQL72-Info.plist"; + refType = 2; + sourceTree = SOURCE_ROOT; + }; + E8AC8DBF05ABCB8C008C206D = { + fileRef = E8AC8D1F05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC005ABCB8D008C206D = { + fileRef = E8AC8D2005ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC105ABCB90008C206D = { + fileRef = E8AC8D2305ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC205ABCB91008C206D = { + fileRef = E8AC8D2405ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC305ABCB92008C206D = { + fileRef = E8AC8D2505ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC405ABCB95008C206D = { + fileRef = E8AC8D2905ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC505ABCB97008C206D = { + fileRef = E8AC8D2A05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC605ABCB97008C206D = { + fileRef = E8AC8D2B05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC705ABCB98008C206D = { + fileRef = E8AC8D2C05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC805ABCB99008C206D = { + fileRef = E8AC8D2D05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DC905ABCB99008C206D = { + fileRef = E8AC8D2E05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DCA05ABCB9C008C206D = { + fileRef = E8AC8D2F05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DCB05ABCB9C008C206D = { + fileRef = E8AC8D3005ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DCC05ABCB9D008C206D = { + fileRef = E8AC8D3105ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DCD05ABCB9E008C206D = { + fileRef = E8AC8D3405ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DCE05ABCB9E008C206D = { + fileRef = E8AC8D3505ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DCF05ABCB9F008C206D = { + fileRef = E8AC8D3205ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD005ABCB9F008C206D = { + fileRef = E8AC8D3305ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD105ABCBA0008C206D = { + fileRef = E8AC8D3605ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD205ABCBA2008C206D = { + fileRef = E8AC8D3705ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD305ABCBA3008C206D = { + fileRef = E8AC8D3805ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD405ABCBA4008C206D = { + fileRef = E8AC8D3905ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD505ABCBA4008C206D = { + fileRef = E8AC8D3A05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD605ABCBA5008C206D = { + fileRef = E8AC8D3B05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD705ABCBA6008C206D = { + fileRef = E8AC8D3C05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD805ABCBA6008C206D = { + fileRef = E8AC8D3D05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DD905ABCBA7008C206D = { + fileRef = E8AC8D3E05ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DDA05ABCBAB008C206D = { + fileRef = E8AC8D4205ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DDB05ABCBAC008C206D = { + fileRef = E8AC8D4005ABCAB9008C206D; + isa = PBXBuildFile; + settings = { + }; + }; + E8AC8DDC05ABCBC9008C206D = { + buildPhases = ( + ); + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = all; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + }; + dependencies = ( + E8AC8DDE05ABCBD0008C206D, + E8AC8DE005ABCBD0008C206D, + ); + isa = PBXAggregateTarget; + name = all; + productName = all; + }; + E8AC8DDD05ABCBD0008C206D = { + containerPortal = E890B012055AB18B004301A0; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = E890B026055AB1B8004301A0; + remoteInfo = GDLAccess; + }; + E8AC8DDE05ABCBD0008C206D = { + isa = PBXTargetDependency; + target = E890B026055AB1B8004301A0; + targetProxy = E8AC8DDD05ABCBD0008C206D; + }; + E8AC8DDF05ABCBD0008C206D = { + containerPortal = E890B012055AB18B004301A0; + isa = PBXContainerItemProxy; + proxyType = 1; + remoteGlobalIDString = E8AC8D4C05ABCB39008C206D; + remoteInfo = PostgreSQL72; + }; + E8AC8DE005ABCBD0008C206D = { + isa = PBXTargetDependency; + target = E8AC8D4C05ABCB39008C206D; + targetProxy = E8AC8DDF05ABCBD0008C206D; + }; + E8D0A07D0605B8D10084DA47 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.objc; + name = EOSelectSQLExpression.m; + path = GDLAccess/EOSelectSQLExpression.m; + refType = 4; + sourceTree = ""; + }; + E8D0A07E0605B8D10084DA47 = { + fileRef = E8D0A07D0605B8D10084DA47; + isa = PBXBuildFile; + settings = { + }; + }; + E8F046BF067385960069C17E = { + fileRef = E890B027055AB1B8004301A0; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = E890B012055AB18B004301A0; +} diff --git a/sope-ical/GNUmakefile b/sope-ical/GNUmakefile new file mode 100644 index 00000000..20989aaa --- /dev/null +++ b/sope-ical/GNUmakefile @@ -0,0 +1,10 @@ +include $(GNUSTEP_MAKEFILES)/common.make + +PACKAGE_NAME=sope-ical +VERSION=4.3.0 + +SUBPROJECTS = \ + iCalSaxDriver \ + NGiCal + +include $(GNUSTEP_MAKEFILES)/aggregate.make diff --git a/sope-core/NGMime/NGMail/COPYING b/sope-ical/NGiCal/COPYING similarity index 100% rename from sope-core/NGMime/NGMail/COPYING rename to sope-ical/NGiCal/COPYING diff --git a/sope-core/NGLdap/COPYRIGHT b/sope-ical/NGiCal/COPYRIGHT similarity index 100% rename from sope-core/NGLdap/COPYRIGHT rename to sope-ical/NGiCal/COPYRIGHT diff --git a/sope-core/NGiCal/ChangeLog b/sope-ical/NGiCal/ChangeLog similarity index 99% rename from sope-core/NGiCal/ChangeLog rename to sope-ical/NGiCal/ChangeLog index 5027024c..2ab2fee7 100644 --- a/sope-core/NGiCal/ChangeLog +++ b/sope-ical/NGiCal/ChangeLog @@ -1,5 +1,7 @@ 2004-08-20 Helge Hess + * moved to sope-ical + * moved to SOPE 4.3 (v4.3.25) 2004-08-14 Helge Hess diff --git a/sope-core/NGiCal/GNUmakefile b/sope-ical/NGiCal/GNUmakefile similarity index 100% rename from sope-core/NGiCal/GNUmakefile rename to sope-ical/NGiCal/GNUmakefile diff --git a/sope-core/NGiCal/GNUmakefile.postamble b/sope-ical/NGiCal/GNUmakefile.postamble similarity index 100% rename from sope-core/NGiCal/GNUmakefile.postamble rename to sope-ical/NGiCal/GNUmakefile.postamble diff --git a/sope-core/NGiCal/GNUmakefile.preamble b/sope-ical/NGiCal/GNUmakefile.preamble similarity index 100% rename from sope-core/NGiCal/GNUmakefile.preamble rename to sope-ical/NGiCal/GNUmakefile.preamble diff --git a/sope-core/NGiCal/IcalElements.m b/sope-ical/NGiCal/IcalElements.m similarity index 100% rename from sope-core/NGiCal/IcalElements.m rename to sope-ical/NGiCal/IcalElements.m diff --git a/sope-core/NGiCal/IcalResponse.h b/sope-ical/NGiCal/IcalResponse.h similarity index 100% rename from sope-core/NGiCal/IcalResponse.h rename to sope-ical/NGiCal/IcalResponse.h diff --git a/sope-core/NGiCal/IcalResponse.m b/sope-ical/NGiCal/IcalResponse.m similarity index 100% rename from sope-core/NGiCal/IcalResponse.m rename to sope-ical/NGiCal/IcalResponse.m diff --git a/sope-core/NGiCal/NGiCal-Info.plist b/sope-ical/NGiCal/NGiCal-Info.plist similarity index 100% rename from sope-core/NGiCal/NGiCal-Info.plist rename to sope-ical/NGiCal/NGiCal-Info.plist diff --git a/sope-core/NGiCal/NGiCal.h b/sope-ical/NGiCal/NGiCal.h similarity index 100% rename from sope-core/NGiCal/NGiCal.h rename to sope-ical/NGiCal/NGiCal.h diff --git a/sope-core/NGiCal/NGiCal.xmap b/sope-ical/NGiCal/NGiCal.xmap similarity index 100% rename from sope-core/NGiCal/NGiCal.xmap rename to sope-ical/NGiCal/NGiCal.xmap diff --git a/sope-core/NGiCal/NSCalendarDate+ICal.h b/sope-ical/NGiCal/NSCalendarDate+ICal.h similarity index 100% rename from sope-core/NGiCal/NSCalendarDate+ICal.h rename to sope-ical/NGiCal/NSCalendarDate+ICal.h diff --git a/sope-core/NGiCal/NSCalendarDate+ICal.m b/sope-ical/NGiCal/NSCalendarDate+ICal.m similarity index 100% rename from sope-core/NGiCal/NSCalendarDate+ICal.m rename to sope-ical/NGiCal/NSCalendarDate+ICal.m diff --git a/sope-core/NGiCal/NSString+ICal.h b/sope-ical/NGiCal/NSString+ICal.h similarity index 100% rename from sope-core/NGiCal/NSString+ICal.h rename to sope-ical/NGiCal/NSString+ICal.h diff --git a/sope-core/NGiCal/NSString+ICal.m b/sope-ical/NGiCal/NSString+ICal.m similarity index 100% rename from sope-core/NGiCal/NSString+ICal.m rename to sope-ical/NGiCal/NSString+ICal.m diff --git a/sope-core/NGiCal/README b/sope-ical/NGiCal/README similarity index 100% rename from sope-core/NGiCal/README rename to sope-ical/NGiCal/README diff --git a/sope-core/NGiCal/Version b/sope-ical/NGiCal/Version similarity index 100% rename from sope-core/NGiCal/Version rename to sope-ical/NGiCal/Version diff --git a/sope-core/NGiCal/common.h b/sope-ical/NGiCal/common.h similarity index 100% rename from sope-core/NGiCal/common.h rename to sope-ical/NGiCal/common.h diff --git a/sope-core/NGiCal/iCalAlarm.h b/sope-ical/NGiCal/iCalAlarm.h similarity index 100% rename from sope-core/NGiCal/iCalAlarm.h rename to sope-ical/NGiCal/iCalAlarm.h diff --git a/sope-core/NGiCal/iCalAlarm.m b/sope-ical/NGiCal/iCalAlarm.m similarity index 100% rename from sope-core/NGiCal/iCalAlarm.m rename to sope-ical/NGiCal/iCalAlarm.m diff --git a/sope-core/NGiCal/iCalAttachment.h b/sope-ical/NGiCal/iCalAttachment.h similarity index 100% rename from sope-core/NGiCal/iCalAttachment.h rename to sope-ical/NGiCal/iCalAttachment.h diff --git a/sope-core/NGiCal/iCalAttachment.m b/sope-ical/NGiCal/iCalAttachment.m similarity index 100% rename from sope-core/NGiCal/iCalAttachment.m rename to sope-ical/NGiCal/iCalAttachment.m diff --git a/sope-core/NGiCal/iCalCalendar.h b/sope-ical/NGiCal/iCalCalendar.h similarity index 100% rename from sope-core/NGiCal/iCalCalendar.h rename to sope-ical/NGiCal/iCalCalendar.h diff --git a/sope-core/NGiCal/iCalCalendar.m b/sope-ical/NGiCal/iCalCalendar.m similarity index 100% rename from sope-core/NGiCal/iCalCalendar.m rename to sope-ical/NGiCal/iCalCalendar.m diff --git a/sope-core/NGiCal/iCalDataSource.h b/sope-ical/NGiCal/iCalDataSource.h similarity index 100% rename from sope-core/NGiCal/iCalDataSource.h rename to sope-ical/NGiCal/iCalDataSource.h diff --git a/sope-core/NGiCal/iCalDataSource.m b/sope-ical/NGiCal/iCalDataSource.m similarity index 100% rename from sope-core/NGiCal/iCalDataSource.m rename to sope-ical/NGiCal/iCalDataSource.m diff --git a/sope-core/NGiCal/iCalDateHolder.h b/sope-ical/NGiCal/iCalDateHolder.h similarity index 100% rename from sope-core/NGiCal/iCalDateHolder.h rename to sope-ical/NGiCal/iCalDateHolder.h diff --git a/sope-core/NGiCal/iCalDateHolder.m b/sope-ical/NGiCal/iCalDateHolder.m similarity index 100% rename from sope-core/NGiCal/iCalDateHolder.m rename to sope-ical/NGiCal/iCalDateHolder.m diff --git a/sope-core/NGiCal/iCalDuration.h b/sope-ical/NGiCal/iCalDuration.h similarity index 100% rename from sope-core/NGiCal/iCalDuration.h rename to sope-ical/NGiCal/iCalDuration.h diff --git a/sope-core/NGiCal/iCalDuration.m b/sope-ical/NGiCal/iCalDuration.m similarity index 100% rename from sope-core/NGiCal/iCalDuration.m rename to sope-ical/NGiCal/iCalDuration.m diff --git a/sope-core/NGiCal/iCalEntityObject.h b/sope-ical/NGiCal/iCalEntityObject.h similarity index 100% rename from sope-core/NGiCal/iCalEntityObject.h rename to sope-ical/NGiCal/iCalEntityObject.h diff --git a/sope-core/NGiCal/iCalEntityObject.m b/sope-ical/NGiCal/iCalEntityObject.m similarity index 100% rename from sope-core/NGiCal/iCalEntityObject.m rename to sope-ical/NGiCal/iCalEntityObject.m diff --git a/sope-core/NGiCal/iCalEvent.h b/sope-ical/NGiCal/iCalEvent.h similarity index 100% rename from sope-core/NGiCal/iCalEvent.h rename to sope-ical/NGiCal/iCalEvent.h diff --git a/sope-core/NGiCal/iCalEvent.m b/sope-ical/NGiCal/iCalEvent.m similarity index 100% rename from sope-core/NGiCal/iCalEvent.m rename to sope-ical/NGiCal/iCalEvent.m diff --git a/sope-core/NGiCal/iCalFreeBusy.h b/sope-ical/NGiCal/iCalFreeBusy.h similarity index 100% rename from sope-core/NGiCal/iCalFreeBusy.h rename to sope-ical/NGiCal/iCalFreeBusy.h diff --git a/sope-core/NGiCal/iCalFreeBusy.m b/sope-ical/NGiCal/iCalFreeBusy.m similarity index 100% rename from sope-core/NGiCal/iCalFreeBusy.m rename to sope-ical/NGiCal/iCalFreeBusy.m diff --git a/sope-core/NGiCal/iCalJournal.h b/sope-ical/NGiCal/iCalJournal.h similarity index 100% rename from sope-core/NGiCal/iCalJournal.h rename to sope-ical/NGiCal/iCalJournal.h diff --git a/sope-core/NGiCal/iCalJournal.m b/sope-ical/NGiCal/iCalJournal.m similarity index 100% rename from sope-core/NGiCal/iCalJournal.m rename to sope-ical/NGiCal/iCalJournal.m diff --git a/sope-core/NGiCal/iCalObject.h b/sope-ical/NGiCal/iCalObject.h similarity index 100% rename from sope-core/NGiCal/iCalObject.h rename to sope-ical/NGiCal/iCalObject.h diff --git a/sope-core/NGiCal/iCalObject.m b/sope-ical/NGiCal/iCalObject.m similarity index 100% rename from sope-core/NGiCal/iCalObject.m rename to sope-ical/NGiCal/iCalObject.m diff --git a/sope-core/NGiCal/iCalPerson.h b/sope-ical/NGiCal/iCalPerson.h similarity index 100% rename from sope-core/NGiCal/iCalPerson.h rename to sope-ical/NGiCal/iCalPerson.h diff --git a/sope-core/NGiCal/iCalPerson.m b/sope-ical/NGiCal/iCalPerson.m similarity index 100% rename from sope-core/NGiCal/iCalPerson.m rename to sope-ical/NGiCal/iCalPerson.m diff --git a/sope-core/NGiCal/iCalToDo.h b/sope-ical/NGiCal/iCalToDo.h similarity index 100% rename from sope-core/NGiCal/iCalToDo.h rename to sope-ical/NGiCal/iCalToDo.h diff --git a/sope-core/NGiCal/iCalToDo.m b/sope-ical/NGiCal/iCalToDo.m similarity index 100% rename from sope-core/NGiCal/iCalToDo.m rename to sope-ical/NGiCal/iCalToDo.m diff --git a/sope-core/NGiCal/iCalTrigger.h b/sope-ical/NGiCal/iCalTrigger.h similarity index 100% rename from sope-core/NGiCal/iCalTrigger.h rename to sope-ical/NGiCal/iCalTrigger.h diff --git a/sope-core/NGiCal/iCalTrigger.m b/sope-ical/NGiCal/iCalTrigger.m similarity index 100% rename from sope-core/NGiCal/iCalTrigger.m rename to sope-ical/NGiCal/iCalTrigger.m diff --git a/sope-core/NGiCal/COPYING b/sope-ical/iCalSaxDriver/COPYING similarity index 100% rename from sope-core/NGiCal/COPYING rename to sope-ical/iCalSaxDriver/COPYING diff --git a/sope-core/NGiCal/COPYRIGHT b/sope-ical/iCalSaxDriver/COPYRIGHT similarity index 100% rename from sope-core/NGiCal/COPYRIGHT rename to sope-ical/iCalSaxDriver/COPYRIGHT diff --git a/sope-xml/iCalSaxDriver/ChangeLog b/sope-ical/iCalSaxDriver/ChangeLog similarity index 93% rename from sope-xml/iCalSaxDriver/ChangeLog rename to sope-ical/iCalSaxDriver/ChangeLog index b936876d..e476b6ec 100644 --- a/sope-xml/iCalSaxDriver/ChangeLog +++ b/sope-ical/iCalSaxDriver/ChangeLog @@ -1,3 +1,7 @@ +2004-08-20 Helge Hess + + * moved from sope-xml to sope-ical (v4.3.9) + 2004-07-02 Helge Hess * ICalSaxParser.m: added default 'iCalSaxDriverDebugEnabled' to enable diff --git a/sope-xml/iCalSaxDriver/GNUmakefile b/sope-ical/iCalSaxDriver/GNUmakefile similarity index 100% rename from sope-xml/iCalSaxDriver/GNUmakefile rename to sope-ical/iCalSaxDriver/GNUmakefile diff --git a/sope-xml/iCalSaxDriver/GNUmakefile.postamble b/sope-ical/iCalSaxDriver/GNUmakefile.postamble similarity index 100% rename from sope-xml/iCalSaxDriver/GNUmakefile.postamble rename to sope-ical/iCalSaxDriver/GNUmakefile.postamble diff --git a/sope-xml/iCalSaxDriver/GNUmakefile.preamble b/sope-ical/iCalSaxDriver/GNUmakefile.preamble similarity index 100% rename from sope-xml/iCalSaxDriver/GNUmakefile.preamble rename to sope-ical/iCalSaxDriver/GNUmakefile.preamble diff --git a/sope-xml/iCalSaxDriver/ICalSaxParser.h b/sope-ical/iCalSaxDriver/ICalSaxParser.h similarity index 100% rename from sope-xml/iCalSaxDriver/ICalSaxParser.h rename to sope-ical/iCalSaxDriver/ICalSaxParser.h diff --git a/sope-xml/iCalSaxDriver/ICalSaxParser.m b/sope-ical/iCalSaxDriver/ICalSaxParser.m similarity index 100% rename from sope-xml/iCalSaxDriver/ICalSaxParser.m rename to sope-ical/iCalSaxDriver/ICalSaxParser.m diff --git a/sope-xml/iCalSaxDriver/NSCalendarDate+ICal.h b/sope-ical/iCalSaxDriver/NSCalendarDate+ICal.h similarity index 100% rename from sope-xml/iCalSaxDriver/NSCalendarDate+ICal.h rename to sope-ical/iCalSaxDriver/NSCalendarDate+ICal.h diff --git a/sope-xml/iCalSaxDriver/NSCalendarDate+ICal.m b/sope-ical/iCalSaxDriver/NSCalendarDate+ICal.m similarity index 100% rename from sope-xml/iCalSaxDriver/NSCalendarDate+ICal.m rename to sope-ical/iCalSaxDriver/NSCalendarDate+ICal.m diff --git a/sope-xml/iCalSaxDriver/NSString+ICal.h b/sope-ical/iCalSaxDriver/NSString+ICal.h similarity index 100% rename from sope-xml/iCalSaxDriver/NSString+ICal.h rename to sope-ical/iCalSaxDriver/NSString+ICal.h diff --git a/sope-xml/iCalSaxDriver/NSString+ICal.m b/sope-ical/iCalSaxDriver/NSString+ICal.m similarity index 100% rename from sope-xml/iCalSaxDriver/NSString+ICal.m rename to sope-ical/iCalSaxDriver/NSString+ICal.m diff --git a/sope-xml/iCalSaxDriver/README b/sope-ical/iCalSaxDriver/README similarity index 100% rename from sope-xml/iCalSaxDriver/README rename to sope-ical/iCalSaxDriver/README diff --git a/sope-xml/iCalSaxDriver/TODO b/sope-ical/iCalSaxDriver/TODO similarity index 100% rename from sope-xml/iCalSaxDriver/TODO rename to sope-ical/iCalSaxDriver/TODO diff --git a/sope-ical/iCalSaxDriver/Version b/sope-ical/iCalSaxDriver/Version new file mode 100644 index 00000000..81be7eb6 --- /dev/null +++ b/sope-ical/iCalSaxDriver/Version @@ -0,0 +1,3 @@ +# $Id$ + +SUBMINOR_VERSION:=9 diff --git a/sope-xml/iCalSaxDriver/bundle-info.plist b/sope-ical/iCalSaxDriver/bundle-info.plist similarity index 100% rename from sope-xml/iCalSaxDriver/bundle-info.plist rename to sope-ical/iCalSaxDriver/bundle-info.plist diff --git a/sope-xml/iCalSaxDriver/common.h b/sope-ical/iCalSaxDriver/common.h similarity index 100% rename from sope-xml/iCalSaxDriver/common.h rename to sope-ical/iCalSaxDriver/common.h diff --git a/sope-xml/iCalSaxDriver/iCalSaxDriver-Info.plist b/sope-ical/iCalSaxDriver/iCalSaxDriver-Info.plist similarity index 100% rename from sope-xml/iCalSaxDriver/iCalSaxDriver-Info.plist rename to sope-ical/iCalSaxDriver/iCalSaxDriver-Info.plist diff --git a/sope-xml/iCalSaxDriver/test1.ics b/sope-ical/iCalSaxDriver/test1.ics similarity index 100% rename from sope-xml/iCalSaxDriver/test1.ics rename to sope-ical/iCalSaxDriver/test1.ics diff --git a/sope-xml/iCalSaxDriver/test2.vfb b/sope-ical/iCalSaxDriver/test2.vfb similarity index 100% rename from sope-xml/iCalSaxDriver/test2.vfb rename to sope-ical/iCalSaxDriver/test2.vfb diff --git a/sope-xml/iCalSaxDriver/test3.ics b/sope-ical/iCalSaxDriver/test3.ics similarity index 100% rename from sope-xml/iCalSaxDriver/test3.ics rename to sope-ical/iCalSaxDriver/test3.ics diff --git a/sope-xml/iCalSaxDriver/test4.ics b/sope-ical/iCalSaxDriver/test4.ics similarity index 100% rename from sope-xml/iCalSaxDriver/test4.ics rename to sope-ical/iCalSaxDriver/test4.ics diff --git a/sope-xml/iCalSaxDriver/test5-entourage.ics b/sope-ical/iCalSaxDriver/test5-entourage.ics similarity index 100% rename from sope-xml/iCalSaxDriver/test5-entourage.ics rename to sope-ical/iCalSaxDriver/test5-entourage.ics diff --git a/sope-xml/iCalSaxDriver/test6-appleical.ics b/sope-ical/iCalSaxDriver/test6-appleical.ics similarity index 100% rename from sope-xml/iCalSaxDriver/test6-appleical.ics rename to sope-ical/iCalSaxDriver/test6-appleical.ics diff --git a/sope-xml/iCalSaxDriver/unicode.h b/sope-ical/iCalSaxDriver/unicode.h similarity index 100% rename from sope-xml/iCalSaxDriver/unicode.h rename to sope-ical/iCalSaxDriver/unicode.h diff --git a/sope-ldap/GNUmakefile b/sope-ldap/GNUmakefile new file mode 100644 index 00000000..8b94c1fe --- /dev/null +++ b/sope-ldap/GNUmakefile @@ -0,0 +1,9 @@ +include $(GNUSTEP_MAKEFILES)/common.make + +PACKAGE_NAME=sope-ldap +VERSION=4.3.0 + +SUBPROJECTS = \ + NGLdap \ + +include $(GNUSTEP_MAKEFILES)/aggregate.make diff --git a/sope-xml/CFXMLSaxDriver/COPYING b/sope-ldap/NGLdap/COPYING similarity index 100% rename from sope-xml/CFXMLSaxDriver/COPYING rename to sope-ldap/NGLdap/COPYING diff --git a/sope-xml/iCalSaxDriver/COPYRIGHT b/sope-ldap/NGLdap/COPYRIGHT similarity index 100% rename from sope-xml/iCalSaxDriver/COPYRIGHT rename to sope-ldap/NGLdap/COPYRIGHT diff --git a/sope-core/NGLdap/ChangeLog b/sope-ldap/NGLdap/ChangeLog similarity index 99% rename from sope-core/NGLdap/ChangeLog rename to sope-ldap/NGLdap/ChangeLog index a2387e45..87217d57 100644 --- a/sope-core/NGLdap/ChangeLog +++ b/sope-ldap/NGLdap/ChangeLog @@ -1,5 +1,7 @@ 2004-08-20 Helge Hess + * moved to sope-ldap + * moved to SOPE 4.3 (v4.3.18) 2004-06-20 Florian G. Pflug diff --git a/sope-core/NGLdap/EOQualifier+LDAP.h b/sope-ldap/NGLdap/EOQualifier+LDAP.h similarity index 100% rename from sope-core/NGLdap/EOQualifier+LDAP.h rename to sope-ldap/NGLdap/EOQualifier+LDAP.h diff --git a/sope-core/NGLdap/EOQualifier+LDAP.m b/sope-ldap/NGLdap/EOQualifier+LDAP.m similarity index 100% rename from sope-core/NGLdap/EOQualifier+LDAP.m rename to sope-ldap/NGLdap/EOQualifier+LDAP.m diff --git a/sope-core/NGLdap/GNUmakefile b/sope-ldap/NGLdap/GNUmakefile similarity index 100% rename from sope-core/NGLdap/GNUmakefile rename to sope-ldap/NGLdap/GNUmakefile diff --git a/sope-core/NGLdap/GNUmakefile.postamble b/sope-ldap/NGLdap/GNUmakefile.postamble similarity index 100% rename from sope-core/NGLdap/GNUmakefile.postamble rename to sope-ldap/NGLdap/GNUmakefile.postamble diff --git a/sope-core/NGLdap/GNUmakefile.preamble b/sope-ldap/NGLdap/GNUmakefile.preamble similarity index 100% rename from sope-core/NGLdap/GNUmakefile.preamble rename to sope-ldap/NGLdap/GNUmakefile.preamble diff --git a/sope-core/NGLdap/NGLdap-Info.plist b/sope-ldap/NGLdap/NGLdap-Info.plist similarity index 100% rename from sope-core/NGLdap/NGLdap-Info.plist rename to sope-ldap/NGLdap/NGLdap-Info.plist diff --git a/sope-core/NGLdap/NGLdap.h b/sope-ldap/NGLdap/NGLdap.h similarity index 100% rename from sope-core/NGLdap/NGLdap.h rename to sope-ldap/NGLdap/NGLdap.h diff --git a/sope-core/NGLdap/NGLdapAttribute.h b/sope-ldap/NGLdap/NGLdapAttribute.h similarity index 100% rename from sope-core/NGLdap/NGLdapAttribute.h rename to sope-ldap/NGLdap/NGLdapAttribute.h diff --git a/sope-core/NGLdap/NGLdapAttribute.m b/sope-ldap/NGLdap/NGLdapAttribute.m similarity index 100% rename from sope-core/NGLdap/NGLdapAttribute.m rename to sope-ldap/NGLdap/NGLdapAttribute.m diff --git a/sope-core/NGLdap/NGLdapConnection+Private.h b/sope-ldap/NGLdap/NGLdapConnection+Private.h similarity index 100% rename from sope-core/NGLdap/NGLdapConnection+Private.h rename to sope-ldap/NGLdap/NGLdapConnection+Private.h diff --git a/sope-core/NGLdap/NGLdapConnection.h b/sope-ldap/NGLdap/NGLdapConnection.h similarity index 100% rename from sope-core/NGLdap/NGLdapConnection.h rename to sope-ldap/NGLdap/NGLdapConnection.h diff --git a/sope-core/NGLdap/NGLdapConnection.m b/sope-ldap/NGLdap/NGLdapConnection.m similarity index 100% rename from sope-core/NGLdap/NGLdapConnection.m rename to sope-ldap/NGLdap/NGLdapConnection.m diff --git a/sope-core/NGLdap/NGLdapDataSource.h b/sope-ldap/NGLdap/NGLdapDataSource.h similarity index 100% rename from sope-core/NGLdap/NGLdapDataSource.h rename to sope-ldap/NGLdap/NGLdapDataSource.h diff --git a/sope-core/NGLdap/NGLdapDataSource.m b/sope-ldap/NGLdap/NGLdapDataSource.m similarity index 100% rename from sope-core/NGLdap/NGLdapDataSource.m rename to sope-ldap/NGLdap/NGLdapDataSource.m diff --git a/sope-core/NGLdap/NGLdapEntry.h b/sope-ldap/NGLdap/NGLdapEntry.h similarity index 100% rename from sope-core/NGLdap/NGLdapEntry.h rename to sope-ldap/NGLdap/NGLdapEntry.h diff --git a/sope-core/NGLdap/NGLdapEntry.m b/sope-ldap/NGLdap/NGLdapEntry.m similarity index 100% rename from sope-core/NGLdap/NGLdapEntry.m rename to sope-ldap/NGLdap/NGLdapEntry.m diff --git a/sope-core/NGLdap/NGLdapFileManager.h b/sope-ldap/NGLdap/NGLdapFileManager.h similarity index 100% rename from sope-core/NGLdap/NGLdapFileManager.h rename to sope-ldap/NGLdap/NGLdapFileManager.h diff --git a/sope-core/NGLdap/NGLdapFileManager.m b/sope-ldap/NGLdap/NGLdapFileManager.m similarity index 100% rename from sope-core/NGLdap/NGLdapFileManager.m rename to sope-ldap/NGLdap/NGLdapFileManager.m diff --git a/sope-core/NGLdap/NGLdapGlobalID.h b/sope-ldap/NGLdap/NGLdapGlobalID.h similarity index 100% rename from sope-core/NGLdap/NGLdapGlobalID.h rename to sope-ldap/NGLdap/NGLdapGlobalID.h diff --git a/sope-core/NGLdap/NGLdapGlobalID.m b/sope-ldap/NGLdap/NGLdapGlobalID.m similarity index 100% rename from sope-core/NGLdap/NGLdapGlobalID.m rename to sope-ldap/NGLdap/NGLdapGlobalID.m diff --git a/sope-core/NGLdap/NGLdapModification.h b/sope-ldap/NGLdap/NGLdapModification.h similarity index 100% rename from sope-core/NGLdap/NGLdapModification.h rename to sope-ldap/NGLdap/NGLdapModification.h diff --git a/sope-core/NGLdap/NGLdapModification.m b/sope-ldap/NGLdap/NGLdapModification.m similarity index 100% rename from sope-core/NGLdap/NGLdapModification.m rename to sope-ldap/NGLdap/NGLdapModification.m diff --git a/sope-core/NGLdap/NGLdapSearchResultEnumerator.h b/sope-ldap/NGLdap/NGLdapSearchResultEnumerator.h similarity index 100% rename from sope-core/NGLdap/NGLdapSearchResultEnumerator.h rename to sope-ldap/NGLdap/NGLdapSearchResultEnumerator.h diff --git a/sope-core/NGLdap/NGLdapSearchResultEnumerator.m b/sope-ldap/NGLdap/NGLdapSearchResultEnumerator.m similarity index 100% rename from sope-core/NGLdap/NGLdapSearchResultEnumerator.m rename to sope-ldap/NGLdap/NGLdapSearchResultEnumerator.m diff --git a/sope-core/NGLdap/NGLdapURL.h b/sope-ldap/NGLdap/NGLdapURL.h similarity index 100% rename from sope-core/NGLdap/NGLdapURL.h rename to sope-ldap/NGLdap/NGLdapURL.h diff --git a/sope-core/NGLdap/NGLdapURL.m b/sope-ldap/NGLdap/NGLdapURL.m similarity index 100% rename from sope-core/NGLdap/NGLdapURL.m rename to sope-ldap/NGLdap/NGLdapURL.m diff --git a/sope-core/NGLdap/NSString+DN.h b/sope-ldap/NGLdap/NSString+DN.h similarity index 100% rename from sope-core/NGLdap/NSString+DN.h rename to sope-ldap/NGLdap/NSString+DN.h diff --git a/sope-core/NGLdap/NSString+DN.m b/sope-ldap/NGLdap/NSString+DN.m similarity index 100% rename from sope-core/NGLdap/NSString+DN.m rename to sope-ldap/NGLdap/NSString+DN.m diff --git a/sope-core/NGLdap/README b/sope-ldap/NGLdap/README similarity index 100% rename from sope-core/NGLdap/README rename to sope-ldap/NGLdap/README diff --git a/sope-core/NGLdap/README.macosx b/sope-ldap/NGLdap/README.macosx similarity index 100% rename from sope-core/NGLdap/README.macosx rename to sope-ldap/NGLdap/README.macosx diff --git a/sope-core/NGLdap/Version b/sope-ldap/NGLdap/Version similarity index 100% rename from sope-core/NGLdap/Version rename to sope-ldap/NGLdap/Version diff --git a/sope-core/NGLdap/common.h b/sope-ldap/NGLdap/common.h similarity index 100% rename from sope-core/NGLdap/common.h rename to sope-ldap/NGLdap/common.h diff --git a/sope-mime/GNUmakefile b/sope-mime/GNUmakefile new file mode 100644 index 00000000..8d203624 --- /dev/null +++ b/sope-mime/GNUmakefile @@ -0,0 +1,9 @@ +include $(GNUSTEP_MAKEFILES)/common.make + +PACKAGE_NAME=sope-mime +VERSION=4.3.0 + +SUBPROJECTS = \ + NGMime + +include $(GNUSTEP_MAKEFILES)/aggregate.make diff --git a/sope-xml/ExpatSaxDriver/COPYING b/sope-mime/NGMime/COPYING similarity index 100% rename from sope-xml/ExpatSaxDriver/COPYING rename to sope-mime/NGMime/COPYING diff --git a/sope-core/NGMime/COPYRIGHT b/sope-mime/NGMime/COPYRIGHT similarity index 100% rename from sope-core/NGMime/COPYRIGHT rename to sope-mime/NGMime/COPYRIGHT diff --git a/sope-core/NGMime/ChangeLog b/sope-mime/NGMime/ChangeLog similarity index 99% rename from sope-core/NGMime/ChangeLog rename to sope-mime/NGMime/ChangeLog index 126d6e73..38c65c54 100644 --- a/sope-core/NGMime/ChangeLog +++ b/sope-mime/NGMime/ChangeLog @@ -1,5 +1,7 @@ 2004-08-20 Helge Hess + * moved to sope-mime top + * moved to SOPE 4.3 (v4.3.172) 2004-08-02 Frank Reppin diff --git a/sope-core/NGMime/GNUmakefile b/sope-mime/NGMime/GNUmakefile similarity index 100% rename from sope-core/NGMime/GNUmakefile rename to sope-mime/NGMime/GNUmakefile diff --git a/sope-core/NGMime/GNUmakefile.preamble b/sope-mime/NGMime/GNUmakefile.preamble similarity index 100% rename from sope-core/NGMime/GNUmakefile.preamble rename to sope-mime/NGMime/GNUmakefile.preamble diff --git a/sope-core/NGMime/NGConcreteMimeType.h b/sope-mime/NGMime/NGConcreteMimeType.h similarity index 100% rename from sope-core/NGMime/NGConcreteMimeType.h rename to sope-mime/NGMime/NGConcreteMimeType.h diff --git a/sope-core/NGMime/NGConcreteMimeType.m b/sope-mime/NGMime/NGConcreteMimeType.m similarity index 100% rename from sope-core/NGMime/NGConcreteMimeType.m rename to sope-mime/NGMime/NGConcreteMimeType.m diff --git a/sope-xml/iCalSaxDriver/COPYING b/sope-mime/NGMime/NGImap4/COPYING similarity index 100% rename from sope-xml/iCalSaxDriver/COPYING rename to sope-mime/NGMime/NGImap4/COPYING diff --git a/sope-core/NGMime/NGImap4/ChangeLog b/sope-mime/NGMime/NGImap4/ChangeLog similarity index 100% rename from sope-core/NGMime/NGImap4/ChangeLog rename to sope-mime/NGMime/NGImap4/ChangeLog diff --git a/sope-core/NGMime/NGImap4/EOQualifier+IMAPAdditions.m b/sope-mime/NGMime/NGImap4/EOQualifier+IMAPAdditions.m similarity index 100% rename from sope-core/NGMime/NGImap4/EOQualifier+IMAPAdditions.m rename to sope-mime/NGMime/NGImap4/EOQualifier+IMAPAdditions.m diff --git a/sope-core/NGMime/NGImap4/GNUmakefile b/sope-mime/NGMime/NGImap4/GNUmakefile similarity index 100% rename from sope-core/NGMime/NGImap4/GNUmakefile rename to sope-mime/NGMime/NGImap4/GNUmakefile diff --git a/sope-core/NGMime/NGImap4/NGImap4-Info.plist b/sope-mime/NGMime/NGImap4/NGImap4-Info.plist similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4-Info.plist rename to sope-mime/NGMime/NGImap4/NGImap4-Info.plist diff --git a/sope-core/NGMime/NGImap4/NGImap4.h b/sope-mime/NGMime/NGImap4/NGImap4.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4.h rename to sope-mime/NGMime/NGImap4/NGImap4.h diff --git a/sope-core/NGMime/NGImap4/NGImap4.m b/sope-mime/NGMime/NGImap4/NGImap4.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4.m rename to sope-mime/NGMime/NGImap4/NGImap4.m diff --git a/sope-core/NGMime/NGImap4/NGImap4Client.h b/sope-mime/NGMime/NGImap4/NGImap4Client.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Client.h rename to sope-mime/NGMime/NGImap4/NGImap4Client.h diff --git a/sope-core/NGMime/NGImap4/NGImap4Client.m b/sope-mime/NGMime/NGImap4/NGImap4Client.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Client.m rename to sope-mime/NGMime/NGImap4/NGImap4Client.m diff --git a/sope-core/NGMime/NGImap4/NGImap4Context.h b/sope-mime/NGMime/NGImap4/NGImap4Context.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Context.h rename to sope-mime/NGMime/NGImap4/NGImap4Context.h diff --git a/sope-core/NGMime/NGImap4/NGImap4Context.m b/sope-mime/NGMime/NGImap4/NGImap4Context.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Context.m rename to sope-mime/NGMime/NGImap4/NGImap4Context.m diff --git a/sope-core/NGMime/NGImap4/NGImap4DataSource.h b/sope-mime/NGMime/NGImap4/NGImap4DataSource.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4DataSource.h rename to sope-mime/NGMime/NGImap4/NGImap4DataSource.h diff --git a/sope-core/NGMime/NGImap4/NGImap4DataSource.m b/sope-mime/NGMime/NGImap4/NGImap4DataSource.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4DataSource.m rename to sope-mime/NGMime/NGImap4/NGImap4DataSource.m diff --git a/sope-core/NGMime/NGImap4/NGImap4FileManager.h b/sope-mime/NGMime/NGImap4/NGImap4FileManager.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FileManager.h rename to sope-mime/NGMime/NGImap4/NGImap4FileManager.h diff --git a/sope-core/NGMime/NGImap4/NGImap4FileManager.m b/sope-mime/NGMime/NGImap4/NGImap4FileManager.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FileManager.m rename to sope-mime/NGMime/NGImap4/NGImap4FileManager.m diff --git a/sope-core/NGMime/NGImap4/NGImap4Folder.h b/sope-mime/NGMime/NGImap4/NGImap4Folder.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Folder.h rename to sope-mime/NGMime/NGImap4/NGImap4Folder.h diff --git a/sope-core/NGMime/NGImap4/NGImap4Folder.m b/sope-mime/NGMime/NGImap4/NGImap4Folder.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Folder.m rename to sope-mime/NGMime/NGImap4/NGImap4Folder.m diff --git a/sope-core/NGMime/NGImap4/NGImap4FolderFlags.h b/sope-mime/NGMime/NGImap4/NGImap4FolderFlags.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FolderFlags.h rename to sope-mime/NGMime/NGImap4/NGImap4FolderFlags.h diff --git a/sope-core/NGMime/NGImap4/NGImap4FolderFlags.m b/sope-mime/NGMime/NGImap4/NGImap4FolderFlags.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FolderFlags.m rename to sope-mime/NGMime/NGImap4/NGImap4FolderFlags.m diff --git a/sope-core/NGMime/NGImap4/NGImap4FolderGlobalID.h b/sope-mime/NGMime/NGImap4/NGImap4FolderGlobalID.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FolderGlobalID.h rename to sope-mime/NGMime/NGImap4/NGImap4FolderGlobalID.h diff --git a/sope-core/NGMime/NGImap4/NGImap4FolderGlobalID.m b/sope-mime/NGMime/NGImap4/NGImap4FolderGlobalID.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FolderGlobalID.m rename to sope-mime/NGMime/NGImap4/NGImap4FolderGlobalID.m diff --git a/sope-core/NGMime/NGImap4/NGImap4FolderMailRegistry.h b/sope-mime/NGMime/NGImap4/NGImap4FolderMailRegistry.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FolderMailRegistry.h rename to sope-mime/NGMime/NGImap4/NGImap4FolderMailRegistry.h diff --git a/sope-core/NGMime/NGImap4/NGImap4FolderMailRegistry.m b/sope-mime/NGMime/NGImap4/NGImap4FolderMailRegistry.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4FolderMailRegistry.m rename to sope-mime/NGMime/NGImap4/NGImap4FolderMailRegistry.m diff --git a/sope-core/NGMime/NGImap4/NGImap4Functions.h b/sope-mime/NGMime/NGImap4/NGImap4Functions.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Functions.h rename to sope-mime/NGMime/NGImap4/NGImap4Functions.h diff --git a/sope-core/NGMime/NGImap4/NGImap4Functions.m b/sope-mime/NGMime/NGImap4/NGImap4Functions.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Functions.m rename to sope-mime/NGMime/NGImap4/NGImap4Functions.m diff --git a/sope-core/NGMime/NGImap4/NGImap4Message+BodyStructure.h b/sope-mime/NGMime/NGImap4/NGImap4Message+BodyStructure.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Message+BodyStructure.h rename to sope-mime/NGMime/NGImap4/NGImap4Message+BodyStructure.h diff --git a/sope-core/NGMime/NGImap4/NGImap4Message.h b/sope-mime/NGMime/NGImap4/NGImap4Message.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Message.h rename to sope-mime/NGMime/NGImap4/NGImap4Message.h diff --git a/sope-core/NGMime/NGImap4/NGImap4Message.m b/sope-mime/NGMime/NGImap4/NGImap4Message.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Message.m rename to sope-mime/NGMime/NGImap4/NGImap4Message.m diff --git a/sope-core/NGMime/NGImap4/NGImap4MessageGlobalID.h b/sope-mime/NGMime/NGImap4/NGImap4MessageGlobalID.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4MessageGlobalID.h rename to sope-mime/NGMime/NGImap4/NGImap4MessageGlobalID.h diff --git a/sope-core/NGMime/NGImap4/NGImap4MessageGlobalID.m b/sope-mime/NGMime/NGImap4/NGImap4MessageGlobalID.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4MessageGlobalID.m rename to sope-mime/NGMime/NGImap4/NGImap4MessageGlobalID.m diff --git a/sope-core/NGMime/NGImap4/NGImap4ResponseNormalizer.h b/sope-mime/NGMime/NGImap4/NGImap4ResponseNormalizer.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ResponseNormalizer.h rename to sope-mime/NGMime/NGImap4/NGImap4ResponseNormalizer.h diff --git a/sope-core/NGMime/NGImap4/NGImap4ResponseNormalizer.m b/sope-mime/NGMime/NGImap4/NGImap4ResponseNormalizer.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ResponseNormalizer.m rename to sope-mime/NGMime/NGImap4/NGImap4ResponseNormalizer.m diff --git a/sope-core/NGMime/NGImap4/NGImap4ResponseParser.h b/sope-mime/NGMime/NGImap4/NGImap4ResponseParser.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ResponseParser.h rename to sope-mime/NGMime/NGImap4/NGImap4ResponseParser.h diff --git a/sope-core/NGMime/NGImap4/NGImap4ResponseParser.m b/sope-mime/NGMime/NGImap4/NGImap4ResponseParser.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ResponseParser.m rename to sope-mime/NGMime/NGImap4/NGImap4ResponseParser.m diff --git a/sope-core/NGMime/NGImap4/NGImap4ServerGlobalID.h b/sope-mime/NGMime/NGImap4/NGImap4ServerGlobalID.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ServerGlobalID.h rename to sope-mime/NGMime/NGImap4/NGImap4ServerGlobalID.h diff --git a/sope-core/NGMime/NGImap4/NGImap4ServerGlobalID.m b/sope-mime/NGMime/NGImap4/NGImap4ServerGlobalID.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ServerGlobalID.m rename to sope-mime/NGMime/NGImap4/NGImap4ServerGlobalID.m diff --git a/sope-core/NGMime/NGImap4/NGImap4ServerRoot.h b/sope-mime/NGMime/NGImap4/NGImap4ServerRoot.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ServerRoot.h rename to sope-mime/NGMime/NGImap4/NGImap4ServerRoot.h diff --git a/sope-core/NGMime/NGImap4/NGImap4ServerRoot.m b/sope-mime/NGMime/NGImap4/NGImap4ServerRoot.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4ServerRoot.m rename to sope-mime/NGMime/NGImap4/NGImap4ServerRoot.m diff --git a/sope-core/NGMime/NGImap4/NGImap4Support.h b/sope-mime/NGMime/NGImap4/NGImap4Support.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Support.h rename to sope-mime/NGMime/NGImap4/NGImap4Support.h diff --git a/sope-core/NGMime/NGImap4/NGImap4Support.m b/sope-mime/NGMime/NGImap4/NGImap4Support.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGImap4Support.m rename to sope-mime/NGMime/NGImap4/NGImap4Support.m diff --git a/sope-core/NGMime/NGImap4/NGSieveClient.h b/sope-mime/NGMime/NGImap4/NGSieveClient.h similarity index 100% rename from sope-core/NGMime/NGImap4/NGSieveClient.h rename to sope-mime/NGMime/NGImap4/NGSieveClient.h diff --git a/sope-core/NGMime/NGImap4/NGSieveClient.m b/sope-mime/NGMime/NGImap4/NGSieveClient.m similarity index 100% rename from sope-core/NGMime/NGImap4/NGSieveClient.m rename to sope-mime/NGMime/NGImap4/NGSieveClient.m diff --git a/sope-core/NGMime/NGImap4/NSString+Imap4.h b/sope-mime/NGMime/NGImap4/NSString+Imap4.h similarity index 100% rename from sope-core/NGMime/NGImap4/NSString+Imap4.h rename to sope-mime/NGMime/NGImap4/NSString+Imap4.h diff --git a/sope-core/NGMime/NGImap4/NSString+Imap4.m b/sope-mime/NGMime/NGImap4/NSString+Imap4.m similarity index 100% rename from sope-core/NGMime/NGImap4/NSString+Imap4.m rename to sope-mime/NGMime/NGImap4/NSString+Imap4.m diff --git a/sope-core/NGMime/NGImap4/README b/sope-mime/NGMime/NGImap4/README similarity index 100% rename from sope-core/NGMime/NGImap4/README rename to sope-mime/NGMime/NGImap4/README diff --git a/sope-core/NGMime/NGImap4/SxCore-NGImap4Flow.graffle b/sope-mime/NGMime/NGImap4/SxCore-NGImap4Flow.graffle similarity index 100% rename from sope-core/NGMime/NGImap4/SxCore-NGImap4Flow.graffle rename to sope-mime/NGMime/NGImap4/SxCore-NGImap4Flow.graffle diff --git a/sope-core/NGMime/NGImap4/TODO b/sope-mime/NGMime/NGImap4/TODO similarity index 100% rename from sope-core/NGMime/NGImap4/TODO rename to sope-mime/NGMime/NGImap4/TODO diff --git a/sope-core/NGMime/NGImap4/imCommon.h b/sope-mime/NGMime/NGImap4/imCommon.h similarity index 100% rename from sope-core/NGMime/NGImap4/imCommon.h rename to sope-mime/NGMime/NGImap4/imCommon.h diff --git a/sope-core/NGMime/NGImap4/imTimeMacros.h b/sope-mime/NGMime/NGImap4/imTimeMacros.h similarity index 100% rename from sope-core/NGMime/NGImap4/imTimeMacros.h rename to sope-mime/NGMime/NGImap4/imTimeMacros.h diff --git a/sope-mime/NGMime/NGMail/COPYING b/sope-mime/NGMime/NGMail/COPYING new file mode 100644 index 00000000..161a3d1d --- /dev/null +++ b/sope-mime/NGMime/NGMail/COPYING @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/sope-core/NGMime/NGMail/ChangeLog b/sope-mime/NGMime/NGMail/ChangeLog similarity index 100% rename from sope-core/NGMime/NGMail/ChangeLog rename to sope-mime/NGMime/NGMail/ChangeLog diff --git a/sope-core/NGMime/NGMail/GNUmakefile b/sope-mime/NGMime/NGMail/GNUmakefile similarity index 100% rename from sope-core/NGMime/NGMail/GNUmakefile rename to sope-mime/NGMime/NGMail/GNUmakefile diff --git a/sope-core/NGMime/NGMail/NGMBoxReader.h b/sope-mime/NGMime/NGMail/NGMBoxReader.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMBoxReader.h rename to sope-mime/NGMime/NGMail/NGMBoxReader.h diff --git a/sope-core/NGMime/NGMail/NGMBoxReader.m b/sope-mime/NGMime/NGMail/NGMBoxReader.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMBoxReader.m rename to sope-mime/NGMime/NGMail/NGMBoxReader.m diff --git a/sope-core/NGMime/NGMail/NGMail-Info.plist b/sope-mime/NGMime/NGMail/NGMail-Info.plist similarity index 100% rename from sope-core/NGMime/NGMail/NGMail-Info.plist rename to sope-mime/NGMime/NGMail/NGMail-Info.plist diff --git a/sope-core/NGMime/NGMail/NGMail.h b/sope-mime/NGMime/NGMail/NGMail.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMail.h rename to sope-mime/NGMime/NGMail/NGMail.h diff --git a/sope-core/NGMime/NGMail/NGMail.m b/sope-mime/NGMime/NGMail/NGMail.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMail.m rename to sope-mime/NGMime/NGMail/NGMail.m diff --git a/sope-core/NGMime/NGMail/NGMailAddress.h b/sope-mime/NGMime/NGMail/NGMailAddress.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMailAddress.h rename to sope-mime/NGMime/NGMail/NGMailAddress.h diff --git a/sope-core/NGMime/NGMail/NGMailAddress.m b/sope-mime/NGMime/NGMail/NGMailAddress.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMailAddress.m rename to sope-mime/NGMime/NGMail/NGMailAddress.m diff --git a/sope-core/NGMime/NGMail/NGMailAddressList.h b/sope-mime/NGMime/NGMail/NGMailAddressList.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMailAddressList.h rename to sope-mime/NGMime/NGMail/NGMailAddressList.h diff --git a/sope-core/NGMime/NGMail/NGMailAddressList.m b/sope-mime/NGMime/NGMail/NGMailAddressList.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMailAddressList.m rename to sope-mime/NGMime/NGMail/NGMailAddressList.m diff --git a/sope-core/NGMime/NGMail/NGMailAddressParser.h b/sope-mime/NGMime/NGMail/NGMailAddressParser.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMailAddressParser.h rename to sope-mime/NGMime/NGMail/NGMailAddressParser.h diff --git a/sope-core/NGMime/NGMail/NGMailAddressParser.m b/sope-mime/NGMime/NGMail/NGMailAddressParser.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMailAddressParser.m rename to sope-mime/NGMime/NGMail/NGMailAddressParser.m diff --git a/sope-core/NGMime/NGMail/NGMailDecls.h b/sope-mime/NGMime/NGMail/NGMailDecls.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMailDecls.h rename to sope-mime/NGMime/NGMail/NGMailDecls.h diff --git a/sope-core/NGMime/NGMail/NGMimeMessage.h b/sope-mime/NGMime/NGMail/NGMimeMessage.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessage.h rename to sope-mime/NGMime/NGMail/NGMimeMessage.h diff --git a/sope-core/NGMime/NGMail/NGMimeMessage.m b/sope-mime/NGMime/NGMail/NGMimeMessage.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessage.m rename to sope-mime/NGMime/NGMail/NGMimeMessage.m diff --git a/sope-core/NGMime/NGMail/NGMimeMessageBodyGenerator.m b/sope-mime/NGMime/NGMail/NGMimeMessageBodyGenerator.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageBodyGenerator.m rename to sope-mime/NGMime/NGMail/NGMimeMessageBodyGenerator.m diff --git a/sope-core/NGMime/NGMail/NGMimeMessageGenerator.h b/sope-mime/NGMime/NGMail/NGMimeMessageGenerator.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageGenerator.h rename to sope-mime/NGMime/NGMail/NGMimeMessageGenerator.h diff --git a/sope-core/NGMime/NGMail/NGMimeMessageGenerator.m b/sope-mime/NGMime/NGMail/NGMimeMessageGenerator.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageGenerator.m rename to sope-mime/NGMime/NGMail/NGMimeMessageGenerator.m diff --git a/sope-core/NGMime/NGMail/NGMimeMessageMultipartBodyGenerator.m b/sope-mime/NGMime/NGMail/NGMimeMessageMultipartBodyGenerator.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageMultipartBodyGenerator.m rename to sope-mime/NGMime/NGMail/NGMimeMessageMultipartBodyGenerator.m diff --git a/sope-core/NGMime/NGMail/NGMimeMessageParser.h b/sope-mime/NGMime/NGMail/NGMimeMessageParser.h similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageParser.h rename to sope-mime/NGMime/NGMail/NGMimeMessageParser.h diff --git a/sope-core/NGMime/NGMail/NGMimeMessageParser.m b/sope-mime/NGMime/NGMail/NGMimeMessageParser.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageParser.m rename to sope-mime/NGMime/NGMail/NGMimeMessageParser.m diff --git a/sope-core/NGMime/NGMail/NGMimeMessageRfc822BodyGenerator.m b/sope-mime/NGMime/NGMail/NGMimeMessageRfc822BodyGenerator.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageRfc822BodyGenerator.m rename to sope-mime/NGMime/NGMail/NGMimeMessageRfc822BodyGenerator.m diff --git a/sope-core/NGMime/NGMail/NGMimeMessageTextBodyGenerator.m b/sope-mime/NGMime/NGMail/NGMimeMessageTextBodyGenerator.m similarity index 100% rename from sope-core/NGMime/NGMail/NGMimeMessageTextBodyGenerator.m rename to sope-mime/NGMime/NGMail/NGMimeMessageTextBodyGenerator.m diff --git a/sope-core/NGMime/NGMail/NGPop3Client.h b/sope-mime/NGMime/NGMail/NGPop3Client.h similarity index 100% rename from sope-core/NGMime/NGMail/NGPop3Client.h rename to sope-mime/NGMime/NGMail/NGPop3Client.h diff --git a/sope-core/NGMime/NGMail/NGPop3Client.m b/sope-mime/NGMime/NGMail/NGPop3Client.m similarity index 100% rename from sope-core/NGMime/NGMail/NGPop3Client.m rename to sope-mime/NGMime/NGMail/NGPop3Client.m diff --git a/sope-core/NGMime/NGMail/NGPop3Support.h b/sope-mime/NGMime/NGMail/NGPop3Support.h similarity index 100% rename from sope-core/NGMime/NGMail/NGPop3Support.h rename to sope-mime/NGMime/NGMail/NGPop3Support.h diff --git a/sope-core/NGMime/NGMail/NGPop3Support.m b/sope-mime/NGMime/NGMail/NGPop3Support.m similarity index 100% rename from sope-core/NGMime/NGMail/NGPop3Support.m rename to sope-mime/NGMime/NGMail/NGPop3Support.m diff --git a/sope-core/NGMime/NGMail/NGSmtpClient.h b/sope-mime/NGMime/NGMail/NGSmtpClient.h similarity index 100% rename from sope-core/NGMime/NGMail/NGSmtpClient.h rename to sope-mime/NGMime/NGMail/NGSmtpClient.h diff --git a/sope-core/NGMime/NGMail/NGSmtpClient.m b/sope-mime/NGMime/NGMail/NGSmtpClient.m similarity index 100% rename from sope-core/NGMime/NGMail/NGSmtpClient.m rename to sope-mime/NGMime/NGMail/NGSmtpClient.m diff --git a/sope-core/NGMime/NGMail/NGSmtpReplyCodes.h b/sope-mime/NGMime/NGMail/NGSmtpReplyCodes.h similarity index 100% rename from sope-core/NGMime/NGMail/NGSmtpReplyCodes.h rename to sope-mime/NGMime/NGMail/NGSmtpReplyCodes.h diff --git a/sope-core/NGMime/NGMail/NGSmtpSupport.h b/sope-mime/NGMime/NGMail/NGSmtpSupport.h similarity index 100% rename from sope-core/NGMime/NGMail/NGSmtpSupport.h rename to sope-mime/NGMime/NGMail/NGSmtpSupport.h diff --git a/sope-core/NGMime/NGMail/NGSmtpSupport.m b/sope-mime/NGMime/NGMail/NGSmtpSupport.m similarity index 100% rename from sope-core/NGMime/NGMail/NGSmtpSupport.m rename to sope-mime/NGMime/NGMail/NGSmtpSupport.m diff --git a/sope-core/NGMime/NGMail/README b/sope-mime/NGMime/NGMail/README similarity index 100% rename from sope-core/NGMime/NGMail/README rename to sope-mime/NGMime/NGMail/README diff --git a/sope-core/NGMime/NGMail/common.h b/sope-mime/NGMime/NGMail/common.h similarity index 100% rename from sope-core/NGMime/NGMail/common.h rename to sope-mime/NGMime/NGMail/common.h diff --git a/sope-core/NGMime/NGMail/libNGMail.def b/sope-mime/NGMime/NGMail/libNGMail.def similarity index 100% rename from sope-core/NGMime/NGMail/libNGMail.def rename to sope-mime/NGMime/NGMail/libNGMail.def diff --git a/sope-core/NGMime/NGMime-Info.plist b/sope-mime/NGMime/NGMime-Info.plist similarity index 100% rename from sope-core/NGMime/NGMime-Info.plist rename to sope-mime/NGMime/NGMime-Info.plist diff --git a/sope-core/NGMime/NGMime.h b/sope-mime/NGMime/NGMime.h similarity index 100% rename from sope-core/NGMime/NGMime.h rename to sope-mime/NGMime/NGMime.h diff --git a/sope-core/NGMime/NGMime.m b/sope-mime/NGMime/NGMime.m similarity index 100% rename from sope-core/NGMime/NGMime.m rename to sope-mime/NGMime/NGMime.m diff --git a/sope-core/NGMime/NGMimeAddressHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeAddressHeaderFieldGenerator.m rename to sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m diff --git a/sope-core/NGMime/NGMimeBodyGenerator.h b/sope-mime/NGMime/NGMimeBodyGenerator.h similarity index 100% rename from sope-core/NGMime/NGMimeBodyGenerator.h rename to sope-mime/NGMime/NGMimeBodyGenerator.h diff --git a/sope-core/NGMime/NGMimeBodyGenerator.m b/sope-mime/NGMime/NGMimeBodyGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeBodyGenerator.m rename to sope-mime/NGMime/NGMimeBodyGenerator.m diff --git a/sope-core/NGMime/NGMimeBodyParser.h b/sope-mime/NGMime/NGMimeBodyParser.h similarity index 100% rename from sope-core/NGMime/NGMimeBodyParser.h rename to sope-mime/NGMime/NGMimeBodyParser.h diff --git a/sope-core/NGMime/NGMimeBodyParser.m b/sope-mime/NGMime/NGMimeBodyParser.m similarity index 100% rename from sope-core/NGMime/NGMimeBodyParser.m rename to sope-mime/NGMime/NGMimeBodyParser.m diff --git a/sope-core/NGMime/NGMimeBodyPart.h b/sope-mime/NGMime/NGMimeBodyPart.h similarity index 100% rename from sope-core/NGMime/NGMimeBodyPart.h rename to sope-mime/NGMime/NGMimeBodyPart.h diff --git a/sope-core/NGMime/NGMimeBodyPart.m b/sope-mime/NGMime/NGMimeBodyPart.m similarity index 100% rename from sope-core/NGMime/NGMimeBodyPart.m rename to sope-mime/NGMime/NGMimeBodyPart.m diff --git a/sope-core/NGMime/NGMimeBodyPartParser.h b/sope-mime/NGMime/NGMimeBodyPartParser.h similarity index 100% rename from sope-core/NGMime/NGMimeBodyPartParser.h rename to sope-mime/NGMime/NGMimeBodyPartParser.h diff --git a/sope-core/NGMime/NGMimeBodyPartParser.m b/sope-mime/NGMime/NGMimeBodyPartParser.m similarity index 100% rename from sope-core/NGMime/NGMimeBodyPartParser.m rename to sope-mime/NGMime/NGMimeBodyPartParser.m diff --git a/sope-core/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m rename to sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m diff --git a/sope-core/NGMime/NGMimeContentDispositionHeaderFieldParser.m b/sope-mime/NGMime/NGMimeContentDispositionHeaderFieldParser.m similarity index 100% rename from sope-core/NGMime/NGMimeContentDispositionHeaderFieldParser.m rename to sope-mime/NGMime/NGMimeContentDispositionHeaderFieldParser.m diff --git a/sope-core/NGMime/NGMimeContentLengthHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeContentLengthHeaderFieldGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeContentLengthHeaderFieldGenerator.m rename to sope-mime/NGMime/NGMimeContentLengthHeaderFieldGenerator.m diff --git a/sope-core/NGMime/NGMimeContentLengthHeaderFieldParser.m b/sope-mime/NGMime/NGMimeContentLengthHeaderFieldParser.m similarity index 100% rename from sope-core/NGMime/NGMimeContentLengthHeaderFieldParser.m rename to sope-mime/NGMime/NGMimeContentLengthHeaderFieldParser.m diff --git a/sope-core/NGMime/NGMimeContentTypeHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeContentTypeHeaderFieldGenerator.m rename to sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m diff --git a/sope-core/NGMime/NGMimeContentTypeHeaderFieldParser.m b/sope-mime/NGMime/NGMimeContentTypeHeaderFieldParser.m similarity index 100% rename from sope-core/NGMime/NGMimeContentTypeHeaderFieldParser.m rename to sope-mime/NGMime/NGMimeContentTypeHeaderFieldParser.m diff --git a/sope-core/NGMime/NGMimeDecls.h b/sope-mime/NGMime/NGMimeDecls.h similarity index 100% rename from sope-core/NGMime/NGMimeDecls.h rename to sope-mime/NGMime/NGMimeDecls.h diff --git a/sope-core/NGMime/NGMimeExceptions.h b/sope-mime/NGMime/NGMimeExceptions.h similarity index 100% rename from sope-core/NGMime/NGMimeExceptions.h rename to sope-mime/NGMime/NGMimeExceptions.h diff --git a/sope-core/NGMime/NGMimeExceptions.m b/sope-mime/NGMime/NGMimeExceptions.m similarity index 100% rename from sope-core/NGMime/NGMimeExceptions.m rename to sope-mime/NGMime/NGMimeExceptions.m diff --git a/sope-core/NGMime/NGMimeFileData.h b/sope-mime/NGMime/NGMimeFileData.h similarity index 100% rename from sope-core/NGMime/NGMimeFileData.h rename to sope-mime/NGMime/NGMimeFileData.h diff --git a/sope-core/NGMime/NGMimeFileData.m b/sope-mime/NGMime/NGMimeFileData.m similarity index 100% rename from sope-core/NGMime/NGMimeFileData.m rename to sope-mime/NGMime/NGMimeFileData.m diff --git a/sope-core/NGMime/NGMimeGeneratorProtocols.h b/sope-mime/NGMime/NGMimeGeneratorProtocols.h similarity index 100% rename from sope-core/NGMime/NGMimeGeneratorProtocols.h rename to sope-mime/NGMime/NGMimeGeneratorProtocols.h diff --git a/sope-core/NGMime/NGMimeHeaderFieldGenerator.h b/sope-mime/NGMime/NGMimeHeaderFieldGenerator.h similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFieldGenerator.h rename to sope-mime/NGMime/NGMimeHeaderFieldGenerator.h diff --git a/sope-core/NGMime/NGMimeHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeHeaderFieldGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFieldGenerator.m rename to sope-mime/NGMime/NGMimeHeaderFieldGenerator.m diff --git a/sope-core/NGMime/NGMimeHeaderFieldGeneratorSet.m b/sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFieldGeneratorSet.m rename to sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m diff --git a/sope-core/NGMime/NGMimeHeaderFieldParser.h b/sope-mime/NGMime/NGMimeHeaderFieldParser.h similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFieldParser.h rename to sope-mime/NGMime/NGMimeHeaderFieldParser.h diff --git a/sope-core/NGMime/NGMimeHeaderFieldParser.m b/sope-mime/NGMime/NGMimeHeaderFieldParser.m similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFieldParser.m rename to sope-mime/NGMime/NGMimeHeaderFieldParser.m diff --git a/sope-core/NGMime/NGMimeHeaderFieldParserSet.m b/sope-mime/NGMime/NGMimeHeaderFieldParserSet.m similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFieldParserSet.m rename to sope-mime/NGMime/NGMimeHeaderFieldParserSet.m diff --git a/sope-core/NGMime/NGMimeHeaderFields.h b/sope-mime/NGMime/NGMimeHeaderFields.h similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFields.h rename to sope-mime/NGMime/NGMimeHeaderFields.h diff --git a/sope-core/NGMime/NGMimeHeaderFields.m b/sope-mime/NGMime/NGMimeHeaderFields.m similarity index 100% rename from sope-core/NGMime/NGMimeHeaderFields.m rename to sope-mime/NGMime/NGMimeHeaderFields.m diff --git a/sope-core/NGMime/NGMimeJoinedData.h b/sope-mime/NGMime/NGMimeJoinedData.h similarity index 100% rename from sope-core/NGMime/NGMimeJoinedData.h rename to sope-mime/NGMime/NGMimeJoinedData.h diff --git a/sope-core/NGMime/NGMimeJoinedData.m b/sope-mime/NGMime/NGMimeJoinedData.m similarity index 100% rename from sope-core/NGMime/NGMimeJoinedData.m rename to sope-mime/NGMime/NGMimeJoinedData.m diff --git a/sope-core/NGMime/NGMimeMultipartBody.h b/sope-mime/NGMime/NGMimeMultipartBody.h similarity index 100% rename from sope-core/NGMime/NGMimeMultipartBody.h rename to sope-mime/NGMime/NGMimeMultipartBody.h diff --git a/sope-core/NGMime/NGMimeMultipartBody.m b/sope-mime/NGMime/NGMimeMultipartBody.m similarity index 100% rename from sope-core/NGMime/NGMimeMultipartBody.m rename to sope-mime/NGMime/NGMimeMultipartBody.m diff --git a/sope-core/NGMime/NGMimeMultipartBodyParser.m b/sope-mime/NGMime/NGMimeMultipartBodyParser.m similarity index 100% rename from sope-core/NGMime/NGMimeMultipartBodyParser.m rename to sope-mime/NGMime/NGMimeMultipartBodyParser.m diff --git a/sope-core/NGMime/NGMimePartGenerator.h b/sope-mime/NGMime/NGMimePartGenerator.h similarity index 100% rename from sope-core/NGMime/NGMimePartGenerator.h rename to sope-mime/NGMime/NGMimePartGenerator.h diff --git a/sope-core/NGMime/NGMimePartGenerator.m b/sope-mime/NGMime/NGMimePartGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimePartGenerator.m rename to sope-mime/NGMime/NGMimePartGenerator.m diff --git a/sope-core/NGMime/NGMimePartParser.h b/sope-mime/NGMime/NGMimePartParser.h similarity index 100% rename from sope-core/NGMime/NGMimePartParser.h rename to sope-mime/NGMime/NGMimePartParser.h diff --git a/sope-core/NGMime/NGMimePartParser.m b/sope-mime/NGMime/NGMimePartParser.m similarity index 100% rename from sope-core/NGMime/NGMimePartParser.m rename to sope-mime/NGMime/NGMimePartParser.m diff --git a/sope-core/NGMime/NGMimeRFC822DateHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeRFC822DateHeaderFieldGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeRFC822DateHeaderFieldGenerator.m rename to sope-mime/NGMime/NGMimeRFC822DateHeaderFieldGenerator.m diff --git a/sope-core/NGMime/NGMimeRFC822DateHeaderFieldParser.m b/sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m similarity index 100% rename from sope-core/NGMime/NGMimeRFC822DateHeaderFieldParser.m rename to sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m diff --git a/sope-core/NGMime/NGMimeStringHeaderFieldGenerator.m b/sope-mime/NGMime/NGMimeStringHeaderFieldGenerator.m similarity index 100% rename from sope-core/NGMime/NGMimeStringHeaderFieldGenerator.m rename to sope-mime/NGMime/NGMimeStringHeaderFieldGenerator.m diff --git a/sope-core/NGMime/NGMimeStringHeaderFieldParser.m b/sope-mime/NGMime/NGMimeStringHeaderFieldParser.m similarity index 100% rename from sope-core/NGMime/NGMimeStringHeaderFieldParser.m rename to sope-mime/NGMime/NGMimeStringHeaderFieldParser.m diff --git a/sope-core/NGMime/NGMimeType.h b/sope-mime/NGMime/NGMimeType.h similarity index 100% rename from sope-core/NGMime/NGMimeType.h rename to sope-mime/NGMime/NGMimeType.h diff --git a/sope-core/NGMime/NGMimeType.m b/sope-mime/NGMime/NGMimeType.m similarity index 100% rename from sope-core/NGMime/NGMimeType.m rename to sope-mime/NGMime/NGMimeType.m diff --git a/sope-core/NGMime/NGMimeUtilities.h b/sope-mime/NGMime/NGMimeUtilities.h similarity index 100% rename from sope-core/NGMime/NGMimeUtilities.h rename to sope-mime/NGMime/NGMimeUtilities.h diff --git a/sope-core/NGMime/NGMimeUtilities.m b/sope-mime/NGMime/NGMimeUtilities.m similarity index 100% rename from sope-core/NGMime/NGMimeUtilities.m rename to sope-mime/NGMime/NGMimeUtilities.m diff --git a/sope-core/NGMime/NGPart.h b/sope-mime/NGMime/NGPart.h similarity index 100% rename from sope-core/NGMime/NGPart.h rename to sope-mime/NGMime/NGPart.h diff --git a/sope-core/NGMime/NGPart.m b/sope-mime/NGMime/NGPart.m similarity index 100% rename from sope-core/NGMime/NGPart.m rename to sope-mime/NGMime/NGPart.m diff --git a/sope-core/NGMime/NSCalendarDate+RFC822.m b/sope-mime/NGMime/NSCalendarDate+RFC822.m similarity index 100% rename from sope-core/NGMime/NSCalendarDate+RFC822.m rename to sope-mime/NGMime/NSCalendarDate+RFC822.m diff --git a/sope-core/NGMime/README b/sope-mime/NGMime/README similarity index 100% rename from sope-core/NGMime/README rename to sope-mime/NGMime/README diff --git a/sope-core/NGMime/SxCore-NGMime.graffle b/sope-mime/NGMime/SxCore-NGMime.graffle similarity index 100% rename from sope-core/NGMime/SxCore-NGMime.graffle rename to sope-mime/NGMime/SxCore-NGMime.graffle diff --git a/sope-core/NGMime/TODO b/sope-mime/NGMime/TODO similarity index 100% rename from sope-core/NGMime/TODO rename to sope-mime/NGMime/TODO diff --git a/sope-core/NGMime/Version b/sope-mime/NGMime/Version similarity index 100% rename from sope-core/NGMime/Version rename to sope-mime/NGMime/Version diff --git a/sope-core/NGMime/common.h b/sope-mime/NGMime/common.h similarity index 100% rename from sope-core/NGMime/common.h rename to sope-mime/NGMime/common.h diff --git a/sope-core/NGMime/libNGMime.def b/sope-mime/NGMime/libNGMime.def similarity index 100% rename from sope-core/NGMime/libNGMime.def rename to sope-mime/NGMime/libNGMime.def diff --git a/sope-core/NGMime/timeMacros.h b/sope-mime/NGMime/timeMacros.h similarity index 100% rename from sope-core/NGMime/timeMacros.h rename to sope-mime/NGMime/timeMacros.h diff --git a/sope-xml/ChangeLog b/sope-xml/ChangeLog index aa020643..98c92171 100644 --- a/sope-xml/ChangeLog +++ b/sope-xml/ChangeLog @@ -1,8 +1,16 @@ +2004-08-20 Helge Hess + + * moved iCalSaxDriver to sope-ical + + * moved ExpatSaxDriver, CFXMLSaxDriver to Recycler + + * moved PlistSaxDriver to samples + 2004-08-03 Marcus Mueller - * SxXML.xcode: fixed missing SaxObjC build dependency. libxmlSAXDriver is - now built before SaxObjC, so copying it in the framework's wrapper will - succeed. + * SxXML.xcode: fixed missing SaxObjC build dependency. libxmlSAXDriver + is now built before SaxObjC, so copying it in the framework's + wrapper will succeed. 2004-07-21 Marcus Mueller diff --git a/sope-xml/GNUmakefile b/sope-xml/GNUmakefile index b17f4e23..61134514 100644 --- a/sope-xml/GNUmakefile +++ b/sope-xml/GNUmakefile @@ -2,8 +2,8 @@ include $(GNUSTEP_MAKEFILES)/common.make -PACKAGE_NAME=skyrix-xml -VERSION=4.2.0 +PACKAGE_NAME=sope-xml +VERSION=4.3.0 SUBPROJECTS = \ SaxObjC \ @@ -13,8 +13,4 @@ SUBPROJECTS = \ XmlRpc \ samples \ -ifeq ($(FOUNDATION_LIB), apple) -# no makefile yet: SUBPROJECTS += CFXMLSaxDriver -endif - include $(GNUSTEP_MAKEFILES)/aggregate.make diff --git a/sope-xml/iCalSaxDriver/Version b/sope-xml/iCalSaxDriver/Version deleted file mode 100644 index 28292b54..00000000 --- a/sope-xml/iCalSaxDriver/Version +++ /dev/null @@ -1,3 +0,0 @@ -# $Id$ - -SUBMINOR_VERSION:=8 diff --git a/sope-xml/PlistSaxDriver/GNUmakefile b/sope-xml/samples/PlistSaxDriver/GNUmakefile similarity index 100% rename from sope-xml/PlistSaxDriver/GNUmakefile rename to sope-xml/samples/PlistSaxDriver/GNUmakefile diff --git a/sope-xml/PlistSaxDriver/PlistSaxDriver.m b/sope-xml/samples/PlistSaxDriver/PlistSaxDriver.m similarity index 100% rename from sope-xml/PlistSaxDriver/PlistSaxDriver.m rename to sope-xml/samples/PlistSaxDriver/PlistSaxDriver.m diff --git a/sope-xml/PlistSaxDriver/README b/sope-xml/samples/PlistSaxDriver/README similarity index 100% rename from sope-xml/PlistSaxDriver/README rename to sope-xml/samples/PlistSaxDriver/README diff --git a/sope-xml/PlistSaxDriver/bundle-info.plist b/sope-xml/samples/PlistSaxDriver/bundle-info.plist similarity index 100% rename from sope-xml/PlistSaxDriver/bundle-info.plist rename to sope-xml/samples/PlistSaxDriver/bundle-info.plist