]> err.no Git - sope/commitdiff
more directory hierarchy reorganisations,
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Fri, 20 Aug 2004 17:27:20 +0000 (17:27 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Fri, 20 Aug 2004 17:27:20 +0000 (17:27 +0000)
moved in our GDL fork

git-svn-id: http://svn.opengroupware.org/SOPE/trunk@5 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

685 files changed:
GNUmakefile
Recycler/CFXMLSaxDriver/CFXMLSaxDriver-Info.plist [moved from sope-xml/CFXMLSaxDriver/CFXMLSaxDriver-Info.plist with 100% similarity]
Recycler/CFXMLSaxDriver/CFXMLSaxDriver.h [moved from sope-xml/CFXMLSaxDriver/CFXMLSaxDriver.h with 100% similarity]
Recycler/CFXMLSaxDriver/CFXMLSaxDriver.m [moved from sope-xml/CFXMLSaxDriver/CFXMLSaxDriver.m with 100% similarity]
Recycler/CFXMLSaxDriver/COPYING [moved from sope-appserver/NGJavaScript/COPYING with 100% similarity]
Recycler/CFXMLSaxDriver/ChangeLog [moved from sope-xml/CFXMLSaxDriver/ChangeLog with 100% similarity]
Recycler/CFXMLSaxDriver/README [moved from sope-xml/CFXMLSaxDriver/README with 100% similarity]
Recycler/CFXMLSaxDriver/bundle-info.plist [moved from sope-xml/CFXMLSaxDriver/bundle-info.plist with 100% similarity]
Recycler/ExpatSaxDriver/COPYING [moved from sope-appserver/NGObjDOM/COPYING with 100% similarity]
Recycler/ExpatSaxDriver/ExpatSaxDriver.m [moved from sope-xml/ExpatSaxDriver/ExpatSaxDriver.m with 100% similarity]
Recycler/ExpatSaxDriver/GNUmakefile [moved from sope-xml/ExpatSaxDriver/GNUmakefile with 100% similarity]
Recycler/ExpatSaxDriver/README [moved from sope-xml/ExpatSaxDriver/README with 100% similarity]
Recycler/ExpatSaxDriver/bundle-info.plist [moved from sope-xml/ExpatSaxDriver/bundle-info.plist with 100% similarity]
Recycler/ExpatSaxDriver/common.h [moved from sope-xml/ExpatSaxDriver/common.h with 100% similarity]
Recycler/ExpatSaxDriver/unicode.h [moved from sope-xml/ExpatSaxDriver/unicode.h with 100% similarity]
Recycler/NGJavaScript/COPYING [moved from sope-appserver/NGObjDOM/Dynamic.subproj/COPYING with 100% similarity]
Recycler/NGJavaScript/ChangeLog [moved from sope-appserver/NGJavaScript/ChangeLog with 99% similarity]
Recycler/NGJavaScript/Core+JS.subproj/EODataSource+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/EODataSource+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.h [moved from sope-appserver/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.h with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/EOJavaScriptGrouping.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/EONull+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/EONull+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/GNUmakefile [moved from sope-appserver/NGJavaScript/Core+JS.subproj/GNUmakefile with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/GNUmakefile.preamble [moved from sope-appserver/NGJavaScript/Core+JS.subproj/GNUmakefile.preamble with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NGFileManager+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NGFileManager+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSArray+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSArray+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSDate+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSDate+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSDictionary+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSDictionary+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSNumber+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSNumber+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSObject+JS.h [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSObject+JS.h with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSObject+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSObject+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSString+JS.h [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSString+JS.h with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSString+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSString+JS.m with 100% similarity]
Recycler/NGJavaScript/Core+JS.subproj/NSUserDefaults+JS.m [moved from sope-appserver/NGJavaScript/Core+JS.subproj/NSUserDefaults+JS.m with 100% similarity]
Recycler/NGJavaScript/GNUmakefile [moved from sope-appserver/NGJavaScript/GNUmakefile with 100% similarity]
Recycler/NGJavaScript/GNUmakefile.preamble [moved from sope-appserver/NGJavaScript/GNUmakefile.preamble with 100% similarity]
Recycler/NGJavaScript/JSObjectOps.m [moved from sope-appserver/NGJavaScript/JSObjectOps.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScript-Info.plist [moved from sope-appserver/NGJavaScript/NGJavaScript-Info.plist with 100% similarity]
Recycler/NGJavaScript/NGJavaScript.h [moved from sope-appserver/NGJavaScript/NGJavaScript.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptArray.m [moved from sope-appserver/NGJavaScript/NGJavaScriptArray.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptCallable.h [moved from sope-appserver/NGJavaScript/NGJavaScriptCallable.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptCallable.m [moved from sope-appserver/NGJavaScript/NGJavaScriptCallable.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptContext.h [moved from sope-appserver/NGJavaScript/NGJavaScriptContext.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptContext.m [moved from sope-appserver/NGJavaScript/NGJavaScriptContext.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptDecls.h [moved from sope-appserver/NGJavaScript/NGJavaScriptDecls.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptError.h [moved from sope-appserver/NGJavaScript/NGJavaScriptError.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptError.m [moved from sope-appserver/NGJavaScript/NGJavaScriptError.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptFunction.h [moved from sope-appserver/NGJavaScript/NGJavaScriptFunction.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptFunction.m [moved from sope-appserver/NGJavaScript/NGJavaScriptFunction.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptLanguage.m [moved from sope-appserver/NGJavaScript/NGJavaScriptLanguage.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObjCClassInfo.h [moved from sope-appserver/NGJavaScript/NGJavaScriptObjCClassInfo.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObjCClassInfo.m [moved from sope-appserver/NGJavaScript/NGJavaScriptObjCClassInfo.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObject.h [moved from sope-appserver/NGJavaScript/NGJavaScriptObject.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObject.m [moved from sope-appserver/NGJavaScript/NGJavaScriptObject.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObjectHandler.h [moved from sope-appserver/NGJavaScript/NGJavaScriptObjectHandler.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObjectHandler.m [moved from sope-appserver/NGJavaScript/NGJavaScriptObjectHandler.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObjectMappingContext.h [moved from sope-appserver/NGJavaScript/NGJavaScriptObjectMappingContext.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptObjectMappingContext.m [moved from sope-appserver/NGJavaScript/NGJavaScriptObjectMappingContext.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptRuntime.h [moved from sope-appserver/NGJavaScript/NGJavaScriptRuntime.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptRuntime.m [moved from sope-appserver/NGJavaScript/NGJavaScriptRuntime.m with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptShadow.h [moved from sope-appserver/NGJavaScript/NGJavaScriptShadow.h with 100% similarity]
Recycler/NGJavaScript/NGJavaScriptShadow.m [moved from sope-appserver/NGJavaScript/NGJavaScriptShadow.m with 100% similarity]
Recycler/NGJavaScript/README [moved from sope-appserver/NGJavaScript/README with 100% similarity]
Recycler/NGJavaScript/ScriptLanguages.plist [moved from sope-appserver/NGJavaScript/ScriptLanguages.plist with 100% similarity]
Recycler/NGJavaScript/TODO [moved from sope-appserver/NGJavaScript/TODO with 100% similarity]
Recycler/NGJavaScript/Version [moved from sope-appserver/NGJavaScript/Version with 100% similarity]
Recycler/NGJavaScript/common.h [moved from sope-appserver/NGJavaScript/common.h with 100% similarity]
Recycler/NGJavaScript/dummy.m [moved from sope-appserver/NGJavaScript/dummy.m with 100% similarity]
Recycler/NGJavaScript/globals.h [moved from sope-appserver/NGJavaScript/globals.h with 100% similarity]
Recycler/NGJavaScript/globals.m [moved from sope-appserver/NGJavaScript/globals.m with 100% similarity]
Recycler/NGJavaScript/jsobjops.m [moved from sope-appserver/NGJavaScript/jsobjops.m with 100% similarity]
Recycler/NGJavaScript/testjs.m [moved from sope-appserver/NGJavaScript/testjs.m with 100% similarity]
Recycler/NGJavaScript/tests/Blah.h [moved from sope-appserver/NGJavaScript/tests/Blah.h with 100% similarity]
Recycler/NGJavaScript/tests/Blah.m [moved from sope-appserver/NGJavaScript/tests/Blah.m with 100% similarity]
Recycler/NGJavaScript/tests/Combined.h [moved from sope-appserver/NGJavaScript/tests/Combined.h with 100% similarity]
Recycler/NGJavaScript/tests/Combined.m [moved from sope-appserver/NGJavaScript/tests/Combined.m with 100% similarity]
Recycler/NGJavaScript/tests/GNUmakefile [moved from sope-appserver/NGJavaScript/tests/GNUmakefile with 100% similarity]
Recycler/NGJavaScript/tests/JSArchivingTests.h [moved from sope-appserver/NGJavaScript/tests/JSArchivingTests.h with 100% similarity]
Recycler/NGJavaScript/tests/JSArchivingTests.m [moved from sope-appserver/NGJavaScript/tests/JSArchivingTests.m with 100% similarity]
Recycler/NGJavaScript/tests/JSBridgeTests.h [moved from sope-appserver/NGJavaScript/tests/JSBridgeTests.h with 100% similarity]
Recycler/NGJavaScript/tests/JSBridgeTests.m [moved from sope-appserver/NGJavaScript/tests/JSBridgeTests.m with 100% similarity]
Recycler/NGJavaScript/tests/JSTest.h [moved from sope-appserver/NGJavaScript/tests/JSTest.h with 100% similarity]
Recycler/NGJavaScript/tests/JSTest.m [moved from sope-appserver/NGJavaScript/tests/JSTest.m with 100% similarity]
Recycler/NGJavaScript/tests/MyNum.h [moved from sope-appserver/NGJavaScript/tests/MyNum.h with 100% similarity]
Recycler/NGJavaScript/tests/MyNum.m [moved from sope-appserver/NGJavaScript/tests/MyNum.m with 100% similarity]
Recycler/NGObjDOM/COPYING [moved from sope-appserver/NGObjDOM/XHTML.subproj/COPYING with 100% similarity]
Recycler/NGObjDOM/COPYRIGHT [moved from mod_ngobjweb/COPYRIGHT with 100% similarity]
Recycler/NGObjDOM/ChangeLog [moved from sope-appserver/NGObjDOM/ChangeLog with 99% similarity]
Recycler/NGObjDOM/Dynamic.subproj/COPYING [moved from sope-appserver/NGObjDOM/XUL.subproj/COPYING with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ChangeLog [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ChangeLog with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/GNUmakefile [moved from sope-appserver/NGObjDOM/Dynamic.subproj/GNUmakefile with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.h [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.h with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODBindNodeRenderFactory.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_checkbox.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_checkbox.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_collapsible.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_collapsible.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_datefield.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_datefield.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_fieldset.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_fieldset.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_foreach.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_foreach.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_form.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_form.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.h [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.h with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_groupings.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_if.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_if.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_multiselection.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_multiselection.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_nbsp.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_nbsp.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_popupbutton.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_popupbutton.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_radiobutton.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_radiobutton.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.h [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.h with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_sortorderings.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_string.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_string.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_switch.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_switch.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.h [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.h with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tablecell.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tabledata.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tabledata.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableheader.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableheader.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.h [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.h with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview+Private.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tableview.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tableview.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_tabview.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_tabview.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_viewertitle.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_viewertitle.m with 100% similarity]
Recycler/NGObjDOM/Dynamic.subproj/ODR_bind_with.m [moved from sope-appserver/NGObjDOM/Dynamic.subproj/ODR_bind_with.m with 100% similarity]
Recycler/NGObjDOM/GNUmakefile [moved from sope-appserver/NGObjDOM/GNUmakefile with 100% similarity]
Recycler/NGObjDOM/GNUmakefile.postamble [moved from sope-appserver/NGObjDOM/GNUmakefile.postamble with 100% similarity]
Recycler/NGObjDOM/GNUmakefile.preamble [moved from sope-appserver/NGObjDOM/GNUmakefile.preamble with 100% similarity]
Recycler/NGObjDOM/NGObjDOM-Info.plist [moved from sope-appserver/NGObjDOM/NGObjDOM-Info.plist with 100% similarity]
Recycler/NGObjDOM/NGObjDOM.h [moved from sope-appserver/NGObjDOM/NGObjDOM.h with 100% similarity]
Recycler/NGObjDOM/NGObjDOMModule.m [moved from sope-appserver/NGObjDOM/NGObjDOMModule.m with 100% similarity]
Recycler/NGObjDOM/ODNamespaces.h [moved from sope-appserver/NGObjDOM/ODNamespaces.h with 100% similarity]
Recycler/NGObjDOM/ODNodeRenderer+attributes.h [moved from sope-appserver/NGObjDOM/ODNodeRenderer+attributes.h with 100% similarity]
Recycler/NGObjDOM/ODNodeRenderer+attributes.m [moved from sope-appserver/NGObjDOM/ODNodeRenderer+attributes.m with 100% similarity]
Recycler/NGObjDOM/ODNodeRenderer.h [moved from sope-appserver/NGObjDOM/ODNodeRenderer.h with 100% similarity]
Recycler/NGObjDOM/ODNodeRenderer.m [moved from sope-appserver/NGObjDOM/ODNodeRenderer.m with 100% similarity]
Recycler/NGObjDOM/ODNodeRendererFactory.h [moved from sope-appserver/NGObjDOM/ODNodeRendererFactory.h with 100% similarity]
Recycler/NGObjDOM/ODNodeRendererFactory.m [moved from sope-appserver/NGObjDOM/ODNodeRendererFactory.m with 100% similarity]
Recycler/NGObjDOM/ODNodeRendererFactorySet.h [moved from sope-appserver/NGObjDOM/ODNodeRendererFactorySet.h with 100% similarity]
Recycler/NGObjDOM/ODNodeRendererFactorySet.m [moved from sope-appserver/NGObjDOM/ODNodeRendererFactorySet.m with 100% similarity]
Recycler/NGObjDOM/ODREmbedComponent.h [moved from sope-appserver/NGObjDOM/ODREmbedComponent.h with 100% similarity]
Recycler/NGObjDOM/ODREmbedComponent.m [moved from sope-appserver/NGObjDOM/ODREmbedComponent.m with 100% similarity]
Recycler/NGObjDOM/ODRGenericTag.h [moved from sope-appserver/NGObjDOM/ODRGenericTag.h with 100% similarity]
Recycler/NGObjDOM/ODRGenericTag.m [moved from sope-appserver/NGObjDOM/ODRGenericTag.m with 100% similarity]
Recycler/NGObjDOM/ODRNodeText.h [moved from sope-appserver/NGObjDOM/ODRNodeText.h with 100% similarity]
Recycler/NGObjDOM/ODRNodeText.m [moved from sope-appserver/NGObjDOM/ODRNodeText.m with 100% similarity]
Recycler/NGObjDOM/ODRWebObject.h [moved from sope-appserver/NGObjDOM/ODRWebObject.h with 100% similarity]
Recycler/NGObjDOM/ODRWebObject.m [moved from sope-appserver/NGObjDOM/ODRWebObject.m with 100% similarity]
Recycler/NGObjDOM/ODR_bind_collapsible.h [moved from sope-appserver/NGObjDOM/ODR_bind_collapsible.h with 100% similarity]
Recycler/NGObjDOM/ODR_bind_fieldset.h [moved from sope-appserver/NGObjDOM/ODR_bind_fieldset.h with 100% similarity]
Recycler/NGObjDOM/ODR_bind_tableview.h [moved from sope-appserver/NGObjDOM/ODR_bind_tableview.h with 100% similarity]
Recycler/NGObjDOM/ODR_bind_tabview.h [moved from sope-appserver/NGObjDOM/ODR_bind_tabview.h with 100% similarity]
Recycler/NGObjDOM/ODR_bind_viewertitle.h [moved from sope-appserver/NGObjDOM/ODR_bind_viewertitle.h with 100% similarity]
Recycler/NGObjDOM/ODResourceManager.h [moved from sope-appserver/NGObjDOM/ODResourceManager.h with 100% similarity]
Recycler/NGObjDOM/ODResourceManager.m [moved from sope-appserver/NGObjDOM/ODResourceManager.m with 100% similarity]
Recycler/NGObjDOM/ODWONodeRenderFactory.m [moved from sope-appserver/NGObjDOM/ODWONodeRenderFactory.m with 100% similarity]
Recycler/NGObjDOM/README [moved from sope-appserver/NGObjDOM/README with 100% similarity]
Recycler/NGObjDOM/Version [moved from sope-appserver/NGObjDOM/Version with 100% similarity]
Recycler/NGObjDOM/WOContext+Cursor.h [moved from sope-appserver/NGObjDOM/WOContext+Cursor.h with 100% similarity]
Recycler/NGObjDOM/WORenderDOM.h [moved from sope-appserver/NGObjDOM/WORenderDOM.h with 100% similarity]
Recycler/NGObjDOM/WORenderDOM.m [moved from sope-appserver/NGObjDOM/WORenderDOM.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/COPYING [moved from sope-core/NGLdap/COPYING with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ChangeLog [moved from sope-appserver/NGObjDOM/XHTML.subproj/ChangeLog with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/GNUmakefile [moved from sope-appserver/NGObjDOM/XHTML.subproj/GNUmakefile with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/GNUmakefile.preamble [moved from sope-appserver/NGObjDOM/XHTML.subproj/GNUmakefile.preamble with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.h [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.h with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODRDynamicXHTMLTag.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_a.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_a.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_button.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_button.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_form.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_form.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_img.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_img.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_input.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_input.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_option.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_option.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_select.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_select.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODR_XHTML_textarea.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODR_XHTML_textarea.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.h [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.h with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.m [moved from sope-appserver/NGObjDOM/XHTML.subproj/ODXHTMLNodeRenderFactory.m with 100% similarity]
Recycler/NGObjDOM/XHTML.subproj/bundle-info.plist [moved from sope-appserver/NGObjDOM/XHTML.subproj/bundle-info.plist with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/COPYING [moved from sope-core/NGMime/COPYING with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/GNUmakefile [moved from sope-appserver/NGObjDOM/XUL.subproj/GNUmakefile with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/GNUmakefile.preamble [moved from sope-appserver/NGObjDOM/XUL.subproj/GNUmakefile.preamble with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODRDynamicXULTag.h [moved from sope-appserver/NGObjDOM/XUL.subproj/ODRDynamicXULTag.h with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODRDynamicXULTag.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODRDynamicXULTag.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_box.h [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_box.h with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_box.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_box.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_button.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_button.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_column.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_column.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_columns.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_columns.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_grid.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_grid.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_image.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_image.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_spring.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_spring.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_tab.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_tab.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_text.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_text.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_textfield.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_textfield.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_title.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_title.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_titledbox.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_titledbox.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODR_XUL_window.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODR_XUL_window.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.h [moved from sope-appserver/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.h with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.m [moved from sope-appserver/NGObjDOM/XUL.subproj/ODXULNodeRenderFactory.m with 100% similarity]
Recycler/NGObjDOM/XUL.subproj/bundle-info.plist [moved from sope-appserver/NGObjDOM/XUL.subproj/bundle-info.plist with 100% similarity]
Recycler/NGObjDOM/bundle-info.plist [moved from sope-appserver/NGObjDOM/bundle-info.plist with 100% similarity]
Recycler/NGObjDOM/common.h [moved from sope-appserver/NGObjDOM/common.h with 100% similarity]
Recycler/NGObjDOM/dummy.m [moved from sope-appserver/NGObjDOM/dummy.m with 100% similarity]
Recycler/NGObjDOM/used_privates.h [moved from sope-appserver/NGObjDOM/used_privates.h with 100% similarity]
sope-appserver/mod_ngobjweb/CHANGES [moved from mod_ngobjweb/CHANGES with 100% similarity]
sope-appserver/mod_ngobjweb/COPYRIGHT [moved from sope-appserver/NGObjDOM/COPYRIGHT with 100% similarity]
sope-appserver/mod_ngobjweb/ChangeLog [moved from mod_ngobjweb/ChangeLog with 100% similarity]
sope-appserver/mod_ngobjweb/GNUmakefile [moved from mod_ngobjweb/GNUmakefile with 100% similarity]
sope-appserver/mod_ngobjweb/NGBufferedDescriptor.c [moved from mod_ngobjweb/NGBufferedDescriptor.c with 100% similarity]
sope-appserver/mod_ngobjweb/NGBufferedDescriptor.h [moved from mod_ngobjweb/NGBufferedDescriptor.h with 100% similarity]
sope-appserver/mod_ngobjweb/README [moved from mod_ngobjweb/README with 100% similarity]
sope-appserver/mod_ngobjweb/apversion.sh [moved from mod_ngobjweb/apversion.sh with 100% similarity]
sope-appserver/mod_ngobjweb/common.h [moved from mod_ngobjweb/common.h with 100% similarity]
sope-appserver/mod_ngobjweb/config.c [moved from mod_ngobjweb/config.c with 100% similarity]
sope-appserver/mod_ngobjweb/globals.c [moved from mod_ngobjweb/globals.c with 100% similarity]
sope-appserver/mod_ngobjweb/handler.c [moved from mod_ngobjweb/handler.c with 100% similarity]
sope-appserver/mod_ngobjweb/httpd.conf [moved from mod_ngobjweb/httpd.conf with 100% similarity]
sope-appserver/mod_ngobjweb/ngobjweb_module.c [moved from mod_ngobjweb/ngobjweb_module.c with 100% similarity]
sope-appserver/mod_ngobjweb/scanhttp.c [moved from mod_ngobjweb/scanhttp.c with 100% similarity]
sope-appserver/mod_ngobjweb/skyrix.conf [moved from mod_ngobjweb/skyrix.conf with 100% similarity]
sope-appserver/mod_ngobjweb/sns.c [moved from mod_ngobjweb/sns.c with 100% similarity]
sope-appserver/samples/WOxExtTest/WOxExtTest.pbproj/project.pbxproj [deleted file]
sope-core/GNUmakefile
sope-core/README-OSX.txt
sope-gdl1/COPYING.LIB [moved from sope-core/NGMime/NGImap4/COPYING with 100% similarity]
sope-gdl1/FrontBase2/COPYING.LIB [new file with mode: 0644]
sope-gdl1/FrontBase2/ChangeLog [new file with mode: 0644]
sope-gdl1/FrontBase2/EOAttribute+FB.h [new file with mode: 0644]
sope-gdl1/FrontBase2/EOAttribute+FB.m [new file with mode: 0644]
sope-gdl1/FrontBase2/English.lproj/InfoPlist.strings [new file with mode: 0644]
sope-gdl1/FrontBase2/FBAdaptor+Types.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FBBlobHandle.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBBlobHandle.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FBChannel+Model.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBChannel+Model.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FBChannel.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBChannel.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FBContext.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBContext.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FBException.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBException.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FBHeaders.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBSQLExpression.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBSQLExpression.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FBValues.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FBValues.m [new file with mode: 0644]
sope-gdl1/FrontBase2/FrontBase2Adaptor.h [new file with mode: 0644]
sope-gdl1/FrontBase2/FrontBase2Adaptor.m [new file with mode: 0644]
sope-gdl1/FrontBase2/GNUmakefile [new file with mode: 0644]
sope-gdl1/FrontBase2/GNUmakefile.preamble [new file with mode: 0644]
sope-gdl1/FrontBase2/Info.plist [new file with mode: 0644]
sope-gdl1/FrontBase2/NSString+FB.h [new file with mode: 0644]
sope-gdl1/FrontBase2/NSString+FB.m [new file with mode: 0644]
sope-gdl1/FrontBase2/README [new file with mode: 0644]
sope-gdl1/FrontBase2/Version [new file with mode: 0644]
sope-gdl1/FrontBase2/cancompile.sh [new file with mode: 0755]
sope-gdl1/FrontBase2/common.h [new file with mode: 0644]
sope-gdl1/FrontBase2/condict.plist [new file with mode: 0644]
sope-gdl1/FrontBase2/fbtest.m [new file with mode: 0644]
sope-gdl1/FrontBase2/fbtest.py [new file with mode: 0755]
sope-gdl1/FrontBase2/test.eomodel [new file with mode: 0644]
sope-gdl1/GDLAccess/COPYING.LIB [new file with mode: 0644]
sope-gdl1/GDLAccess/ChangeLog [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAccess.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAdaptor.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel+Attributes.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAdaptorChannel.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAdaptorContext.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAdaptorDataSource.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAdaptorGlobalID.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAdaptorOperation.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOArrayProxy.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAttribute.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOAttributeOrdering.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOCustomValues.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EODatabase.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EODatabaseChannel.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EODatabaseContext.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EODatabaseFault.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EODatabaseFaultResolver.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EODelegateResponse.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOEntity+Factory.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOEntity.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOExpressionArray.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOFExceptions.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOFault.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOFaultHandler.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOGenericRecord.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOJoinTypes.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOKeySortOrdering.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOModel.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOModelGroup.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EONull.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOObjectUniquer.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOPrimaryKeyDictionary.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOQualifierScanner.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOQuotedExpression.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EORecordDictionary.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EORelationship.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOSQLExpression.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/EOSQLQualifier.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/GDLAccess.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAccess/NSObject+EONullInit.h [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAdaptor.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAdaptorChannel+Attributes.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAdaptorChannel.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAdaptorContext.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAdaptorDataSource.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAdaptorGlobalID.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAdaptorOperation.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAndQualifier+SQL.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOArrayProxy.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAttribute.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOAttributeOrdering.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOCustomValues.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EODatabase.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EODatabaseChannel.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EODatabaseContext.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EODatabaseFault.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EODatabaseFaultResolver.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOEntity+Factory.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOEntity.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOEntityClassDescription.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOExpressionArray.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOFExceptions.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOFault.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOFaultHandler.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOGenericRecord.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOKeyComparisonQualifier+SQL.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOKeySortOrdering.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOKeyValueQualifier+SQL.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOModel.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOModelGroup.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EONotQualifier+SQL.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOObjectUniquer.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOOrQualifier+SQL.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOPrimaryKeyDictionary.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOQualifier+SQL.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOQualifierScanner.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOQuotedExpression.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EORecordDictionary.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EORelationship.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOSQLExpression.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOSQLQualifier.m [new file with mode: 0644]
sope-gdl1/GDLAccess/EOSelectSQLExpression.m [new file with mode: 0644]
sope-gdl1/GDLAccess/English.lproj/InfoPlist.strings [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/COPYING [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/COPYRIGHT [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.h [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.m [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/FormatScanner.h [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/FormatScanner.m [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/GNUmakefile [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/LICENSE [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.h [new file with mode: 0644]
sope-gdl1/GDLAccess/FoundationExt/PrintfFormatScanner.m [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLAccess-Info.plist [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/ChangeLog [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/EOEntity+Factory.h [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.h [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/GDLExtensions.m [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/GNUmakefile.preamble [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/NSObject+EONullInit.h [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/common.h [new file with mode: 0644]
sope-gdl1/GDLAccess/GDLExtensions/libGDLExtensions.def [new file with mode: 0644]
sope-gdl1/GDLAccess/GNUmakefile [new file with mode: 0644]
sope-gdl1/GDLAccess/GNUmakefile.postamble [new file with mode: 0644]
sope-gdl1/GDLAccess/GNUmakefile.preamble [new file with mode: 0644]
sope-gdl1/GDLAccess/NSObject+EONullInit.m [new file with mode: 0644]
sope-gdl1/GDLAccess/README [new file with mode: 0644]
sope-gdl1/GDLAccess/TODO [new file with mode: 0644]
sope-gdl1/GDLAccess/Version [new file with mode: 0644]
sope-gdl1/GDLAccess/common.h [new file with mode: 0644]
sope-gdl1/GDLAccess/connect-EOAdaptor.m [new file with mode: 0644]
sope-gdl1/GDLAccess/eoaccess.m [new file with mode: 0644]
sope-gdl1/GDLAccess/libGDLAccess.def [new file with mode: 0644]
sope-gdl1/GDLAccess/load-EOAdaptor.m [new file with mode: 0644]
sope-gdl1/GDLAccess/test.py [new file with mode: 0755]
sope-gdl1/GNUmakefile [new file with mode: 0644]
sope-gdl1/PostgreSQL72/COPYING [new file with mode: 0644]
sope-gdl1/PostgreSQL72/COPYING.LIB [new file with mode: 0644]
sope-gdl1/PostgreSQL72/ChangeLog [new file with mode: 0644]
sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/GNUmakefile [new file with mode: 0644]
sope-gdl1/PostgreSQL72/GNUmakefile.preamble [new file with mode: 0644]
sope-gdl1/PostgreSQL72/NSCalendarDate+PGVal.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/NSData+PGVal.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/NSNumber+PGVal.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/NSString+PGVal.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/NSString+PostgreSQL72.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PGConnection.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PGConnection.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72-Info.plist [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Channel+Model.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Channel.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Channel.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Context.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Context.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Exception.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Exception.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Expression.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Expression.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Values.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/PostgreSQL72Values.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/README [new file with mode: 0644]
sope-gdl1/PostgreSQL72/TODO [new file with mode: 0644]
sope-gdl1/PostgreSQL72/Version [new file with mode: 0644]
sope-gdl1/PostgreSQL72/common.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/condict.plist [new file with mode: 0644]
sope-gdl1/PostgreSQL72/gdltest.m [new file with mode: 0644]
sope-gdl1/PostgreSQL72/postgres_types.h [new file with mode: 0644]
sope-gdl1/PostgreSQL72/test.eomodel [new file with mode: 0644]
sope-gdl1/PostgreSQL72/types.psql [new file with mode: 0644]
sope-gdl1/Version [new file with mode: 0644]
sope-gdl1/common.make [new file with mode: 0644]
sope-gdl1/gnustep-db.xcode/project.pbxproj [new file with mode: 0644]
sope-ical/GNUmakefile [new file with mode: 0644]
sope-ical/NGiCal/COPYING [moved from sope-core/NGMime/NGMail/COPYING with 100% similarity]
sope-ical/NGiCal/COPYRIGHT [moved from sope-core/NGLdap/COPYRIGHT with 100% similarity]
sope-ical/NGiCal/ChangeLog [moved from sope-core/NGiCal/ChangeLog with 99% similarity]
sope-ical/NGiCal/GNUmakefile [moved from sope-core/NGiCal/GNUmakefile with 100% similarity]
sope-ical/NGiCal/GNUmakefile.postamble [moved from sope-core/NGiCal/GNUmakefile.postamble with 100% similarity]
sope-ical/NGiCal/GNUmakefile.preamble [moved from sope-core/NGiCal/GNUmakefile.preamble with 100% similarity]
sope-ical/NGiCal/IcalElements.m [moved from sope-core/NGiCal/IcalElements.m with 100% similarity]
sope-ical/NGiCal/IcalResponse.h [moved from sope-core/NGiCal/IcalResponse.h with 100% similarity]
sope-ical/NGiCal/IcalResponse.m [moved from sope-core/NGiCal/IcalResponse.m with 100% similarity]
sope-ical/NGiCal/NGiCal-Info.plist [moved from sope-core/NGiCal/NGiCal-Info.plist with 100% similarity]
sope-ical/NGiCal/NGiCal.h [moved from sope-core/NGiCal/NGiCal.h with 100% similarity]
sope-ical/NGiCal/NGiCal.xmap [moved from sope-core/NGiCal/NGiCal.xmap with 100% similarity]
sope-ical/NGiCal/NSCalendarDate+ICal.h [moved from sope-core/NGiCal/NSCalendarDate+ICal.h with 100% similarity]
sope-ical/NGiCal/NSCalendarDate+ICal.m [moved from sope-core/NGiCal/NSCalendarDate+ICal.m with 100% similarity]
sope-ical/NGiCal/NSString+ICal.h [moved from sope-core/NGiCal/NSString+ICal.h with 100% similarity]
sope-ical/NGiCal/NSString+ICal.m [moved from sope-core/NGiCal/NSString+ICal.m with 100% similarity]
sope-ical/NGiCal/README [moved from sope-core/NGiCal/README with 100% similarity]
sope-ical/NGiCal/Version [moved from sope-core/NGiCal/Version with 100% similarity]
sope-ical/NGiCal/common.h [moved from sope-core/NGiCal/common.h with 100% similarity]
sope-ical/NGiCal/iCalAlarm.h [moved from sope-core/NGiCal/iCalAlarm.h with 100% similarity]
sope-ical/NGiCal/iCalAlarm.m [moved from sope-core/NGiCal/iCalAlarm.m with 100% similarity]
sope-ical/NGiCal/iCalAttachment.h [moved from sope-core/NGiCal/iCalAttachment.h with 100% similarity]
sope-ical/NGiCal/iCalAttachment.m [moved from sope-core/NGiCal/iCalAttachment.m with 100% similarity]
sope-ical/NGiCal/iCalCalendar.h [moved from sope-core/NGiCal/iCalCalendar.h with 100% similarity]
sope-ical/NGiCal/iCalCalendar.m [moved from sope-core/NGiCal/iCalCalendar.m with 100% similarity]
sope-ical/NGiCal/iCalDataSource.h [moved from sope-core/NGiCal/iCalDataSource.h with 100% similarity]
sope-ical/NGiCal/iCalDataSource.m [moved from sope-core/NGiCal/iCalDataSource.m with 100% similarity]
sope-ical/NGiCal/iCalDateHolder.h [moved from sope-core/NGiCal/iCalDateHolder.h with 100% similarity]
sope-ical/NGiCal/iCalDateHolder.m [moved from sope-core/NGiCal/iCalDateHolder.m with 100% similarity]
sope-ical/NGiCal/iCalDuration.h [moved from sope-core/NGiCal/iCalDuration.h with 100% similarity]
sope-ical/NGiCal/iCalDuration.m [moved from sope-core/NGiCal/iCalDuration.m with 100% similarity]
sope-ical/NGiCal/iCalEntityObject.h [moved from sope-core/NGiCal/iCalEntityObject.h with 100% similarity]
sope-ical/NGiCal/iCalEntityObject.m [moved from sope-core/NGiCal/iCalEntityObject.m with 100% similarity]
sope-ical/NGiCal/iCalEvent.h [moved from sope-core/NGiCal/iCalEvent.h with 100% similarity]
sope-ical/NGiCal/iCalEvent.m [moved from sope-core/NGiCal/iCalEvent.m with 100% similarity]
sope-ical/NGiCal/iCalFreeBusy.h [moved from sope-core/NGiCal/iCalFreeBusy.h with 100% similarity]
sope-ical/NGiCal/iCalFreeBusy.m [moved from sope-core/NGiCal/iCalFreeBusy.m with 100% similarity]
sope-ical/NGiCal/iCalJournal.h [moved from sope-core/NGiCal/iCalJournal.h with 100% similarity]
sope-ical/NGiCal/iCalJournal.m [moved from sope-core/NGiCal/iCalJournal.m with 100% similarity]
sope-ical/NGiCal/iCalObject.h [moved from sope-core/NGiCal/iCalObject.h with 100% similarity]
sope-ical/NGiCal/iCalObject.m [moved from sope-core/NGiCal/iCalObject.m with 100% similarity]
sope-ical/NGiCal/iCalPerson.h [moved from sope-core/NGiCal/iCalPerson.h with 100% similarity]
sope-ical/NGiCal/iCalPerson.m [moved from sope-core/NGiCal/iCalPerson.m with 100% similarity]
sope-ical/NGiCal/iCalToDo.h [moved from sope-core/NGiCal/iCalToDo.h with 100% similarity]
sope-ical/NGiCal/iCalToDo.m [moved from sope-core/NGiCal/iCalToDo.m with 100% similarity]
sope-ical/NGiCal/iCalTrigger.h [moved from sope-core/NGiCal/iCalTrigger.h with 100% similarity]
sope-ical/NGiCal/iCalTrigger.m [moved from sope-core/NGiCal/iCalTrigger.m with 100% similarity]
sope-ical/iCalSaxDriver/COPYING [moved from sope-core/NGiCal/COPYING with 100% similarity]
sope-ical/iCalSaxDriver/COPYRIGHT [moved from sope-core/NGiCal/COPYRIGHT with 100% similarity]
sope-ical/iCalSaxDriver/ChangeLog [moved from sope-xml/iCalSaxDriver/ChangeLog with 93% similarity]
sope-ical/iCalSaxDriver/GNUmakefile [moved from sope-xml/iCalSaxDriver/GNUmakefile with 100% similarity]
sope-ical/iCalSaxDriver/GNUmakefile.postamble [moved from sope-xml/iCalSaxDriver/GNUmakefile.postamble with 100% similarity]
sope-ical/iCalSaxDriver/GNUmakefile.preamble [moved from sope-xml/iCalSaxDriver/GNUmakefile.preamble with 100% similarity]
sope-ical/iCalSaxDriver/ICalSaxParser.h [moved from sope-xml/iCalSaxDriver/ICalSaxParser.h with 100% similarity]
sope-ical/iCalSaxDriver/ICalSaxParser.m [moved from sope-xml/iCalSaxDriver/ICalSaxParser.m with 100% similarity]
sope-ical/iCalSaxDriver/NSCalendarDate+ICal.h [moved from sope-xml/iCalSaxDriver/NSCalendarDate+ICal.h with 100% similarity]
sope-ical/iCalSaxDriver/NSCalendarDate+ICal.m [moved from sope-xml/iCalSaxDriver/NSCalendarDate+ICal.m with 100% similarity]
sope-ical/iCalSaxDriver/NSString+ICal.h [moved from sope-xml/iCalSaxDriver/NSString+ICal.h with 100% similarity]
sope-ical/iCalSaxDriver/NSString+ICal.m [moved from sope-xml/iCalSaxDriver/NSString+ICal.m with 100% similarity]
sope-ical/iCalSaxDriver/README [moved from sope-xml/iCalSaxDriver/README with 100% similarity]
sope-ical/iCalSaxDriver/TODO [moved from sope-xml/iCalSaxDriver/TODO with 100% similarity]
sope-ical/iCalSaxDriver/Version [new file with mode: 0644]
sope-ical/iCalSaxDriver/bundle-info.plist [moved from sope-xml/iCalSaxDriver/bundle-info.plist with 100% similarity]
sope-ical/iCalSaxDriver/common.h [moved from sope-xml/iCalSaxDriver/common.h with 100% similarity]
sope-ical/iCalSaxDriver/iCalSaxDriver-Info.plist [moved from sope-xml/iCalSaxDriver/iCalSaxDriver-Info.plist with 100% similarity]
sope-ical/iCalSaxDriver/test1.ics [moved from sope-xml/iCalSaxDriver/test1.ics with 100% similarity]
sope-ical/iCalSaxDriver/test2.vfb [moved from sope-xml/iCalSaxDriver/test2.vfb with 100% similarity]
sope-ical/iCalSaxDriver/test3.ics [moved from sope-xml/iCalSaxDriver/test3.ics with 100% similarity]
sope-ical/iCalSaxDriver/test4.ics [moved from sope-xml/iCalSaxDriver/test4.ics with 100% similarity]
sope-ical/iCalSaxDriver/test5-entourage.ics [moved from sope-xml/iCalSaxDriver/test5-entourage.ics with 100% similarity]
sope-ical/iCalSaxDriver/test6-appleical.ics [moved from sope-xml/iCalSaxDriver/test6-appleical.ics with 100% similarity]
sope-ical/iCalSaxDriver/unicode.h [moved from sope-xml/iCalSaxDriver/unicode.h with 100% similarity]
sope-ldap/GNUmakefile [new file with mode: 0644]
sope-ldap/NGLdap/COPYING [moved from sope-xml/CFXMLSaxDriver/COPYING with 100% similarity]
sope-ldap/NGLdap/COPYRIGHT [moved from sope-xml/iCalSaxDriver/COPYRIGHT with 100% similarity]
sope-ldap/NGLdap/ChangeLog [moved from sope-core/NGLdap/ChangeLog with 99% similarity]
sope-ldap/NGLdap/EOQualifier+LDAP.h [moved from sope-core/NGLdap/EOQualifier+LDAP.h with 100% similarity]
sope-ldap/NGLdap/EOQualifier+LDAP.m [moved from sope-core/NGLdap/EOQualifier+LDAP.m with 100% similarity]
sope-ldap/NGLdap/GNUmakefile [moved from sope-core/NGLdap/GNUmakefile with 100% similarity]
sope-ldap/NGLdap/GNUmakefile.postamble [moved from sope-core/NGLdap/GNUmakefile.postamble with 100% similarity]
sope-ldap/NGLdap/GNUmakefile.preamble [moved from sope-core/NGLdap/GNUmakefile.preamble with 100% similarity]
sope-ldap/NGLdap/NGLdap-Info.plist [moved from sope-core/NGLdap/NGLdap-Info.plist with 100% similarity]
sope-ldap/NGLdap/NGLdap.h [moved from sope-core/NGLdap/NGLdap.h with 100% similarity]
sope-ldap/NGLdap/NGLdapAttribute.h [moved from sope-core/NGLdap/NGLdapAttribute.h with 100% similarity]
sope-ldap/NGLdap/NGLdapAttribute.m [moved from sope-core/NGLdap/NGLdapAttribute.m with 100% similarity]
sope-ldap/NGLdap/NGLdapConnection+Private.h [moved from sope-core/NGLdap/NGLdapConnection+Private.h with 100% similarity]
sope-ldap/NGLdap/NGLdapConnection.h [moved from sope-core/NGLdap/NGLdapConnection.h with 100% similarity]
sope-ldap/NGLdap/NGLdapConnection.m [moved from sope-core/NGLdap/NGLdapConnection.m with 100% similarity]
sope-ldap/NGLdap/NGLdapDataSource.h [moved from sope-core/NGLdap/NGLdapDataSource.h with 100% similarity]
sope-ldap/NGLdap/NGLdapDataSource.m [moved from sope-core/NGLdap/NGLdapDataSource.m with 100% similarity]
sope-ldap/NGLdap/NGLdapEntry.h [moved from sope-core/NGLdap/NGLdapEntry.h with 100% similarity]
sope-ldap/NGLdap/NGLdapEntry.m [moved from sope-core/NGLdap/NGLdapEntry.m with 100% similarity]
sope-ldap/NGLdap/NGLdapFileManager.h [moved from sope-core/NGLdap/NGLdapFileManager.h with 100% similarity]
sope-ldap/NGLdap/NGLdapFileManager.m [moved from sope-core/NGLdap/NGLdapFileManager.m with 100% similarity]
sope-ldap/NGLdap/NGLdapGlobalID.h [moved from sope-core/NGLdap/NGLdapGlobalID.h with 100% similarity]
sope-ldap/NGLdap/NGLdapGlobalID.m [moved from sope-core/NGLdap/NGLdapGlobalID.m with 100% similarity]
sope-ldap/NGLdap/NGLdapModification.h [moved from sope-core/NGLdap/NGLdapModification.h with 100% similarity]
sope-ldap/NGLdap/NGLdapModification.m [moved from sope-core/NGLdap/NGLdapModification.m with 100% similarity]
sope-ldap/NGLdap/NGLdapSearchResultEnumerator.h [moved from sope-core/NGLdap/NGLdapSearchResultEnumerator.h with 100% similarity]
sope-ldap/NGLdap/NGLdapSearchResultEnumerator.m [moved from sope-core/NGLdap/NGLdapSearchResultEnumerator.m with 100% similarity]
sope-ldap/NGLdap/NGLdapURL.h [moved from sope-core/NGLdap/NGLdapURL.h with 100% similarity]
sope-ldap/NGLdap/NGLdapURL.m [moved from sope-core/NGLdap/NGLdapURL.m with 100% similarity]
sope-ldap/NGLdap/NSString+DN.h [moved from sope-core/NGLdap/NSString+DN.h with 100% similarity]
sope-ldap/NGLdap/NSString+DN.m [moved from sope-core/NGLdap/NSString+DN.m with 100% similarity]
sope-ldap/NGLdap/README [moved from sope-core/NGLdap/README with 100% similarity]
sope-ldap/NGLdap/README.macosx [moved from sope-core/NGLdap/README.macosx with 100% similarity]
sope-ldap/NGLdap/Version [moved from sope-core/NGLdap/Version with 100% similarity]
sope-ldap/NGLdap/common.h [moved from sope-core/NGLdap/common.h with 100% similarity]
sope-mime/GNUmakefile [new file with mode: 0644]
sope-mime/NGMime/COPYING [moved from sope-xml/ExpatSaxDriver/COPYING with 100% similarity]
sope-mime/NGMime/COPYRIGHT [moved from sope-core/NGMime/COPYRIGHT with 100% similarity]
sope-mime/NGMime/ChangeLog [moved from sope-core/NGMime/ChangeLog with 99% similarity]
sope-mime/NGMime/GNUmakefile [moved from sope-core/NGMime/GNUmakefile with 100% similarity]
sope-mime/NGMime/GNUmakefile.preamble [moved from sope-core/NGMime/GNUmakefile.preamble with 100% similarity]
sope-mime/NGMime/NGConcreteMimeType.h [moved from sope-core/NGMime/NGConcreteMimeType.h with 100% similarity]
sope-mime/NGMime/NGConcreteMimeType.m [moved from sope-core/NGMime/NGConcreteMimeType.m with 100% similarity]
sope-mime/NGMime/NGImap4/COPYING [moved from sope-xml/iCalSaxDriver/COPYING with 100% similarity]
sope-mime/NGMime/NGImap4/ChangeLog [moved from sope-core/NGMime/NGImap4/ChangeLog with 100% similarity]
sope-mime/NGMime/NGImap4/EOQualifier+IMAPAdditions.m [moved from sope-core/NGMime/NGImap4/EOQualifier+IMAPAdditions.m with 100% similarity]
sope-mime/NGMime/NGImap4/GNUmakefile [moved from sope-core/NGMime/NGImap4/GNUmakefile with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4-Info.plist [moved from sope-core/NGMime/NGImap4/NGImap4-Info.plist with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4.h [moved from sope-core/NGMime/NGImap4/NGImap4.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4.m [moved from sope-core/NGMime/NGImap4/NGImap4.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Client.h [moved from sope-core/NGMime/NGImap4/NGImap4Client.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Client.m [moved from sope-core/NGMime/NGImap4/NGImap4Client.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Context.h [moved from sope-core/NGMime/NGImap4/NGImap4Context.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Context.m [moved from sope-core/NGMime/NGImap4/NGImap4Context.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4DataSource.h [moved from sope-core/NGMime/NGImap4/NGImap4DataSource.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4DataSource.m [moved from sope-core/NGMime/NGImap4/NGImap4DataSource.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FileManager.h [moved from sope-core/NGMime/NGImap4/NGImap4FileManager.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FileManager.m [moved from sope-core/NGMime/NGImap4/NGImap4FileManager.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Folder.h [moved from sope-core/NGMime/NGImap4/NGImap4Folder.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Folder.m [moved from sope-core/NGMime/NGImap4/NGImap4Folder.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FolderFlags.h [moved from sope-core/NGMime/NGImap4/NGImap4FolderFlags.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FolderFlags.m [moved from sope-core/NGMime/NGImap4/NGImap4FolderFlags.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FolderGlobalID.h [moved from sope-core/NGMime/NGImap4/NGImap4FolderGlobalID.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FolderGlobalID.m [moved from sope-core/NGMime/NGImap4/NGImap4FolderGlobalID.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FolderMailRegistry.h [moved from sope-core/NGMime/NGImap4/NGImap4FolderMailRegistry.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4FolderMailRegistry.m [moved from sope-core/NGMime/NGImap4/NGImap4FolderMailRegistry.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Functions.h [moved from sope-core/NGMime/NGImap4/NGImap4Functions.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Functions.m [moved from sope-core/NGMime/NGImap4/NGImap4Functions.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Message+BodyStructure.h [moved from sope-core/NGMime/NGImap4/NGImap4Message+BodyStructure.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Message.h [moved from sope-core/NGMime/NGImap4/NGImap4Message.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Message.m [moved from sope-core/NGMime/NGImap4/NGImap4Message.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4MessageGlobalID.h [moved from sope-core/NGMime/NGImap4/NGImap4MessageGlobalID.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4MessageGlobalID.m [moved from sope-core/NGMime/NGImap4/NGImap4MessageGlobalID.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ResponseNormalizer.h [moved from sope-core/NGMime/NGImap4/NGImap4ResponseNormalizer.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ResponseNormalizer.m [moved from sope-core/NGMime/NGImap4/NGImap4ResponseNormalizer.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ResponseParser.h [moved from sope-core/NGMime/NGImap4/NGImap4ResponseParser.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ResponseParser.m [moved from sope-core/NGMime/NGImap4/NGImap4ResponseParser.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ServerGlobalID.h [moved from sope-core/NGMime/NGImap4/NGImap4ServerGlobalID.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ServerGlobalID.m [moved from sope-core/NGMime/NGImap4/NGImap4ServerGlobalID.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ServerRoot.h [moved from sope-core/NGMime/NGImap4/NGImap4ServerRoot.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4ServerRoot.m [moved from sope-core/NGMime/NGImap4/NGImap4ServerRoot.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Support.h [moved from sope-core/NGMime/NGImap4/NGImap4Support.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGImap4Support.m [moved from sope-core/NGMime/NGImap4/NGImap4Support.m with 100% similarity]
sope-mime/NGMime/NGImap4/NGSieveClient.h [moved from sope-core/NGMime/NGImap4/NGSieveClient.h with 100% similarity]
sope-mime/NGMime/NGImap4/NGSieveClient.m [moved from sope-core/NGMime/NGImap4/NGSieveClient.m with 100% similarity]
sope-mime/NGMime/NGImap4/NSString+Imap4.h [moved from sope-core/NGMime/NGImap4/NSString+Imap4.h with 100% similarity]
sope-mime/NGMime/NGImap4/NSString+Imap4.m [moved from sope-core/NGMime/NGImap4/NSString+Imap4.m with 100% similarity]
sope-mime/NGMime/NGImap4/README [moved from sope-core/NGMime/NGImap4/README with 100% similarity]
sope-mime/NGMime/NGImap4/SxCore-NGImap4Flow.graffle [moved from sope-core/NGMime/NGImap4/SxCore-NGImap4Flow.graffle with 100% similarity]
sope-mime/NGMime/NGImap4/TODO [moved from sope-core/NGMime/NGImap4/TODO with 100% similarity]
sope-mime/NGMime/NGImap4/imCommon.h [moved from sope-core/NGMime/NGImap4/imCommon.h with 100% similarity]
sope-mime/NGMime/NGImap4/imTimeMacros.h [moved from sope-core/NGMime/NGImap4/imTimeMacros.h with 100% similarity]
sope-mime/NGMime/NGMail/COPYING [new file with mode: 0644]
sope-mime/NGMime/NGMail/ChangeLog [moved from sope-core/NGMime/NGMail/ChangeLog with 100% similarity]
sope-mime/NGMime/NGMail/GNUmakefile [moved from sope-core/NGMime/NGMail/GNUmakefile with 100% similarity]
sope-mime/NGMime/NGMail/NGMBoxReader.h [moved from sope-core/NGMime/NGMail/NGMBoxReader.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMBoxReader.m [moved from sope-core/NGMime/NGMail/NGMBoxReader.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMail-Info.plist [moved from sope-core/NGMime/NGMail/NGMail-Info.plist with 100% similarity]
sope-mime/NGMime/NGMail/NGMail.h [moved from sope-core/NGMime/NGMail/NGMail.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMail.m [moved from sope-core/NGMime/NGMail/NGMail.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMailAddress.h [moved from sope-core/NGMime/NGMail/NGMailAddress.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMailAddress.m [moved from sope-core/NGMime/NGMail/NGMailAddress.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMailAddressList.h [moved from sope-core/NGMime/NGMail/NGMailAddressList.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMailAddressList.m [moved from sope-core/NGMime/NGMail/NGMailAddressList.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMailAddressParser.h [moved from sope-core/NGMime/NGMail/NGMailAddressParser.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMailAddressParser.m [moved from sope-core/NGMime/NGMail/NGMailAddressParser.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMailDecls.h [moved from sope-core/NGMime/NGMail/NGMailDecls.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessage.h [moved from sope-core/NGMime/NGMail/NGMimeMessage.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessage.m [moved from sope-core/NGMime/NGMail/NGMimeMessage.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageBodyGenerator.m [moved from sope-core/NGMime/NGMail/NGMimeMessageBodyGenerator.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageGenerator.h [moved from sope-core/NGMime/NGMail/NGMimeMessageGenerator.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageGenerator.m [moved from sope-core/NGMime/NGMail/NGMimeMessageGenerator.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageMultipartBodyGenerator.m [moved from sope-core/NGMime/NGMail/NGMimeMessageMultipartBodyGenerator.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageParser.h [moved from sope-core/NGMime/NGMail/NGMimeMessageParser.h with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageParser.m [moved from sope-core/NGMime/NGMail/NGMimeMessageParser.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageRfc822BodyGenerator.m [moved from sope-core/NGMime/NGMail/NGMimeMessageRfc822BodyGenerator.m with 100% similarity]
sope-mime/NGMime/NGMail/NGMimeMessageTextBodyGenerator.m [moved from sope-core/NGMime/NGMail/NGMimeMessageTextBodyGenerator.m with 100% similarity]
sope-mime/NGMime/NGMail/NGPop3Client.h [moved from sope-core/NGMime/NGMail/NGPop3Client.h with 100% similarity]
sope-mime/NGMime/NGMail/NGPop3Client.m [moved from sope-core/NGMime/NGMail/NGPop3Client.m with 100% similarity]
sope-mime/NGMime/NGMail/NGPop3Support.h [moved from sope-core/NGMime/NGMail/NGPop3Support.h with 100% similarity]
sope-mime/NGMime/NGMail/NGPop3Support.m [moved from sope-core/NGMime/NGMail/NGPop3Support.m with 100% similarity]
sope-mime/NGMime/NGMail/NGSmtpClient.h [moved from sope-core/NGMime/NGMail/NGSmtpClient.h with 100% similarity]
sope-mime/NGMime/NGMail/NGSmtpClient.m [moved from sope-core/NGMime/NGMail/NGSmtpClient.m with 100% similarity]
sope-mime/NGMime/NGMail/NGSmtpReplyCodes.h [moved from sope-core/NGMime/NGMail/NGSmtpReplyCodes.h with 100% similarity]
sope-mime/NGMime/NGMail/NGSmtpSupport.h [moved from sope-core/NGMime/NGMail/NGSmtpSupport.h with 100% similarity]
sope-mime/NGMime/NGMail/NGSmtpSupport.m [moved from sope-core/NGMime/NGMail/NGSmtpSupport.m with 100% similarity]
sope-mime/NGMime/NGMail/README [moved from sope-core/NGMime/NGMail/README with 100% similarity]
sope-mime/NGMime/NGMail/common.h [moved from sope-core/NGMime/NGMail/common.h with 100% similarity]
sope-mime/NGMime/NGMail/libNGMail.def [moved from sope-core/NGMime/NGMail/libNGMail.def with 100% similarity]
sope-mime/NGMime/NGMime-Info.plist [moved from sope-core/NGMime/NGMime-Info.plist with 100% similarity]
sope-mime/NGMime/NGMime.h [moved from sope-core/NGMime/NGMime.h with 100% similarity]
sope-mime/NGMime/NGMime.m [moved from sope-core/NGMime/NGMime.m with 100% similarity]
sope-mime/NGMime/NGMimeAddressHeaderFieldGenerator.m [moved from sope-core/NGMime/NGMimeAddressHeaderFieldGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeBodyGenerator.h [moved from sope-core/NGMime/NGMimeBodyGenerator.h with 100% similarity]
sope-mime/NGMime/NGMimeBodyGenerator.m [moved from sope-core/NGMime/NGMimeBodyGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeBodyParser.h [moved from sope-core/NGMime/NGMimeBodyParser.h with 100% similarity]
sope-mime/NGMime/NGMimeBodyParser.m [moved from sope-core/NGMime/NGMimeBodyParser.m with 100% similarity]
sope-mime/NGMime/NGMimeBodyPart.h [moved from sope-core/NGMime/NGMimeBodyPart.h with 100% similarity]
sope-mime/NGMime/NGMimeBodyPart.m [moved from sope-core/NGMime/NGMimeBodyPart.m with 100% similarity]
sope-mime/NGMime/NGMimeBodyPartParser.h [moved from sope-core/NGMime/NGMimeBodyPartParser.h with 100% similarity]
sope-mime/NGMime/NGMimeBodyPartParser.m [moved from sope-core/NGMime/NGMimeBodyPartParser.m with 100% similarity]
sope-mime/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m [moved from sope-core/NGMime/NGMimeContentDispositionHeaderFieldGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeContentDispositionHeaderFieldParser.m [moved from sope-core/NGMime/NGMimeContentDispositionHeaderFieldParser.m with 100% similarity]
sope-mime/NGMime/NGMimeContentLengthHeaderFieldGenerator.m [moved from sope-core/NGMime/NGMimeContentLengthHeaderFieldGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeContentLengthHeaderFieldParser.m [moved from sope-core/NGMime/NGMimeContentLengthHeaderFieldParser.m with 100% similarity]
sope-mime/NGMime/NGMimeContentTypeHeaderFieldGenerator.m [moved from sope-core/NGMime/NGMimeContentTypeHeaderFieldGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeContentTypeHeaderFieldParser.m [moved from sope-core/NGMime/NGMimeContentTypeHeaderFieldParser.m with 100% similarity]
sope-mime/NGMime/NGMimeDecls.h [moved from sope-core/NGMime/NGMimeDecls.h with 100% similarity]
sope-mime/NGMime/NGMimeExceptions.h [moved from sope-core/NGMime/NGMimeExceptions.h with 100% similarity]
sope-mime/NGMime/NGMimeExceptions.m [moved from sope-core/NGMime/NGMimeExceptions.m with 100% similarity]
sope-mime/NGMime/NGMimeFileData.h [moved from sope-core/NGMime/NGMimeFileData.h with 100% similarity]
sope-mime/NGMime/NGMimeFileData.m [moved from sope-core/NGMime/NGMimeFileData.m with 100% similarity]
sope-mime/NGMime/NGMimeGeneratorProtocols.h [moved from sope-core/NGMime/NGMimeGeneratorProtocols.h with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFieldGenerator.h [moved from sope-core/NGMime/NGMimeHeaderFieldGenerator.h with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFieldGenerator.m [moved from sope-core/NGMime/NGMimeHeaderFieldGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFieldGeneratorSet.m [moved from sope-core/NGMime/NGMimeHeaderFieldGeneratorSet.m with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFieldParser.h [moved from sope-core/NGMime/NGMimeHeaderFieldParser.h with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFieldParser.m [moved from sope-core/NGMime/NGMimeHeaderFieldParser.m with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFieldParserSet.m [moved from sope-core/NGMime/NGMimeHeaderFieldParserSet.m with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFields.h [moved from sope-core/NGMime/NGMimeHeaderFields.h with 100% similarity]
sope-mime/NGMime/NGMimeHeaderFields.m [moved from sope-core/NGMime/NGMimeHeaderFields.m with 100% similarity]
sope-mime/NGMime/NGMimeJoinedData.h [moved from sope-core/NGMime/NGMimeJoinedData.h with 100% similarity]
sope-mime/NGMime/NGMimeJoinedData.m [moved from sope-core/NGMime/NGMimeJoinedData.m with 100% similarity]
sope-mime/NGMime/NGMimeMultipartBody.h [moved from sope-core/NGMime/NGMimeMultipartBody.h with 100% similarity]
sope-mime/NGMime/NGMimeMultipartBody.m [moved from sope-core/NGMime/NGMimeMultipartBody.m with 100% similarity]
sope-mime/NGMime/NGMimeMultipartBodyParser.m [moved from sope-core/NGMime/NGMimeMultipartBodyParser.m with 100% similarity]
sope-mime/NGMime/NGMimePartGenerator.h [moved from sope-core/NGMime/NGMimePartGenerator.h with 100% similarity]
sope-mime/NGMime/NGMimePartGenerator.m [moved from sope-core/NGMime/NGMimePartGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimePartParser.h [moved from sope-core/NGMime/NGMimePartParser.h with 100% similarity]
sope-mime/NGMime/NGMimePartParser.m [moved from sope-core/NGMime/NGMimePartParser.m with 100% similarity]
sope-mime/NGMime/NGMimeRFC822DateHeaderFieldGenerator.m [moved from sope-core/NGMime/NGMimeRFC822DateHeaderFieldGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeRFC822DateHeaderFieldParser.m [moved from sope-core/NGMime/NGMimeRFC822DateHeaderFieldParser.m with 100% similarity]
sope-mime/NGMime/NGMimeStringHeaderFieldGenerator.m [moved from sope-core/NGMime/NGMimeStringHeaderFieldGenerator.m with 100% similarity]
sope-mime/NGMime/NGMimeStringHeaderFieldParser.m [moved from sope-core/NGMime/NGMimeStringHeaderFieldParser.m with 100% similarity]
sope-mime/NGMime/NGMimeType.h [moved from sope-core/NGMime/NGMimeType.h with 100% similarity]
sope-mime/NGMime/NGMimeType.m [moved from sope-core/NGMime/NGMimeType.m with 100% similarity]
sope-mime/NGMime/NGMimeUtilities.h [moved from sope-core/NGMime/NGMimeUtilities.h with 100% similarity]
sope-mime/NGMime/NGMimeUtilities.m [moved from sope-core/NGMime/NGMimeUtilities.m with 100% similarity]
sope-mime/NGMime/NGPart.h [moved from sope-core/NGMime/NGPart.h with 100% similarity]
sope-mime/NGMime/NGPart.m [moved from sope-core/NGMime/NGPart.m with 100% similarity]
sope-mime/NGMime/NSCalendarDate+RFC822.m [moved from sope-core/NGMime/NSCalendarDate+RFC822.m with 100% similarity]
sope-mime/NGMime/README [moved from sope-core/NGMime/README with 100% similarity]
sope-mime/NGMime/SxCore-NGMime.graffle [moved from sope-core/NGMime/SxCore-NGMime.graffle with 100% similarity]
sope-mime/NGMime/TODO [moved from sope-core/NGMime/TODO with 100% similarity]
sope-mime/NGMime/Version [moved from sope-core/NGMime/Version with 100% similarity]
sope-mime/NGMime/common.h [moved from sope-core/NGMime/common.h with 100% similarity]
sope-mime/NGMime/libNGMime.def [moved from sope-core/NGMime/libNGMime.def with 100% similarity]
sope-mime/NGMime/timeMacros.h [moved from sope-core/NGMime/timeMacros.h with 100% similarity]
sope-xml/ChangeLog
sope-xml/GNUmakefile
sope-xml/iCalSaxDriver/Version [deleted file]
sope-xml/samples/PlistSaxDriver/GNUmakefile [moved from sope-xml/PlistSaxDriver/GNUmakefile with 100% similarity]
sope-xml/samples/PlistSaxDriver/PlistSaxDriver.m [moved from sope-xml/PlistSaxDriver/PlistSaxDriver.m with 100% similarity]
sope-xml/samples/PlistSaxDriver/README [moved from sope-xml/PlistSaxDriver/README with 100% similarity]
sope-xml/samples/PlistSaxDriver/bundle-info.plist [moved from sope-xml/PlistSaxDriver/bundle-info.plist with 100% similarity]

index 668c6bd5baef5587c7dce40c317e0441fba87a69..8244c86b7dccd439980d3a7e002103db63519f80 100644 (file)
@@ -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
similarity index 99%
rename from sope-appserver/NGJavaScript/ChangeLog
rename to Recycler/NGJavaScript/ChangeLog
index 9c262b86aa84e8ea76dbf7ec6c1742e4fe86a506..8323683c678ca52f6452be1f37c4baffd5863867 100644 (file)
@@ -1,5 +1,7 @@
 2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
 
+       * deprecated and moved to Recycler
+
        * moved to SOPE 4.3 (v4.3.31)
 
 2004-08-17  Helge Hess  <helge.hess@opengroupware.org>
similarity index 99%
rename from sope-appserver/NGObjDOM/ChangeLog
rename to Recycler/NGObjDOM/ChangeLog
index e11735c9ddb6798bfa9e672ee061b2fd98600935..1d96ab3625d5faea3fb4a93118c6915d1ee3bc9d 100644 (file)
@@ -1,5 +1,7 @@
 2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
 
+       * deprecated and moved to Recycler
+
        * moved to SOPE 4.3 (v4.3.25)
 
 2004-07-19  Helge Hess  <helge.hess@skyrix.com>
diff --git a/sope-appserver/samples/WOxExtTest/WOxExtTest.pbproj/project.pbxproj b/sope-appserver/samples/WOxExtTest/WOxExtTest.pbproj/project.pbxproj
deleted file mode 100644 (file)
index e274858..0000000
+++ /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 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
-<plist version=\"1.0\">
-<dict>
-       <key>CFBundleDevelopmentRegion</key>
-       <string>English</string>
-       <key>CFBundleExecutable</key>
-       <string></string>
-       <key>CFBundleGetInfoString</key>
-       <string></string>
-       <key>CFBundleIconFile</key>
-       <string></string>
-       <key>CFBundleIdentifier</key>
-       <string>com.skyrix.WOxExtTest</string>
-       <key>CFBundleInfoDictionaryVersion</key>
-       <string>6.0</string>
-       <key>CFBundleName</key>
-       <string></string>
-       <key>CFBundlePackageType</key>
-       <string>BDNL</string>
-       <key>CFBundleShortVersionString</key>
-       <string></string>
-       <key>CFBundleSignature</key>
-       <string>????</string>
-       <key>CFBundleVersion</key>
-       <string>4.2</string>
-</dict>
-</plist>
-";
-                       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;
-}
index 2de42883ddff10ef48abbe5b080c332b310efc2d..7f58da2c8fc3ebf09a19b71a0bc02b2c0ce58228 100644 (file)
@@ -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)
index c722ff369cd19757791a9fb97692d8fce83d0165..8119c4df1917bd08695090419b5bac7d13e2076d 100644 (file)
@@ -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-gdl1/FrontBase2/COPYING.LIB b/sope-gdl1/FrontBase2/COPYING.LIB
new file mode 100644 (file)
index 0000000..eb685a5
--- /dev/null
@@ -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.
+\f
+  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.
+\f
+                 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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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
+\f
+     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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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 (file)
index 0000000..61d528d
--- /dev/null
@@ -0,0 +1,109 @@
+2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
+
+       * moved from ThirdParty to SOPE/sope-gdl1 (v1.0.2)
+
+2003-05-07  Helge Hess  <helge.hess@skyrix.com>
+
+       * 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  <jan@skyrix.com>
+
+       * FBValues.m: code cleanups, fixed retain bug (NSData valueFromBytes)
+
+Wed Mar 26 10:23:53 2003  Jan Reichmann  <jan@skyrix.com>
+
+       * FBChannel.m: add debugging-logs if channel will be closed
+
+Mon Dec 23 18:22:18 2002  Helge Hess  <helge.hess@skyrix.com>
+
+       * FBChannel.m: fixed a gcc 3.2 warning
+
+Fri Nov 29 15:17:04 2002    <jan@skyrix.com>
+
+       * FBChannel.m: from 4.1
+
+Tue Sep  3 15:32:24 2002  Jan Reichmann  <jan@skyrix.com>
+
+       * FBChannel.m: values comes now from self->selectedAttributes
+       * FBValues.m: add missing Frontbase type to NSNumber -valueFromBytes 
+       (FB_VCharacter)
+
+2002-08-30  Helge Hess  <helge.hess@skyrix.com>
+
+       * 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  <jan@skyrix.com>
+
+       * 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  <helge.hess@skyrix.com>
+
+       * FBChannel.m: close channel on -dealloc
+
+Wed Jan  3 19:15:59 2001  Jan Reichmann  <jan@skyrix.com>
+
+       * FBChannel.m, FBChannel+Model.m: cache table informations
+
+Wed Jan  3 18:51:28 2001  Jan Reichmann  <jan@skyrix.com>
+
+       * FBAdaptor+Types.m, EOAttribute+FB.m: INT -> INTEGER
+
+Tue Jan  2 14:42:20 2001  Jan Reichmann  <jan@skyrix.com>
+
+       * FBChannel.m: fixed core dump if password is wrong
+
+Wed Dec  6 12:48:58 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * renamed file FBAdaptor to FrontBase2Adaptor, renamed FrontBaseAdaptor
+         class to FrontBase2Adaptor
+
+Mon Dec  4 13:31:07 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * GNUmakefile: added cancompile.sh script and support
+
+Fri Nov 17 15:46:43 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * created FB2 adaptor out of FB1 adaptor ..
+
+Wed Aug 23 16:56:28 2000  Joerg Grimm  <joerg@trex2>
+
+       * FBAdaptor.m: formatting for text attributes added
+
+Mon May 29 15:56:58 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * FBChannel.m: automagically add sort-ordering attributes to query set
+
+Mon Apr 10 17:54:39 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * FBValues.m ([NSCalendarDate -stringValueForFrontBaseType:attribute:]):
+         removed a NSLog
+
+Mon Apr 10 12:25:38 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * FBChannel.m: fixed memory free bug
+
+Tue Feb 29 19:30:46 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * MOF3 import
+
+Fri Nov 12 14:35:05 1999  Helge Hess  <helge.hess@mdlink.de>
+
+       * added support for user and database authentication
+
+Tue Nov  2 16:52:47 1999  Helge Hess  <helge.hess@mdlink.de>
+
+       * FBAdaptor.m: fixed -charConvertExpression..
+
+Thu Oct  7 13:50:48 1999  Helge Hess  <helge.hess@mdlink.de>
+
+       * 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 (file)
index 0000000..7594bcd
--- /dev/null
@@ -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 <GDLAccess/EOAttribute.h>
+
+@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 (file)
index 0000000..8f9ef96
--- /dev/null
@@ -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 <FBCAccess/FBCAccess.h>
+
+// 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 (file)
index 0000000..97e0935
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 (file)
index 0000000..5ffb21d
--- /dev/null
@@ -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 (file)
index 0000000..f182da1
--- /dev/null
@@ -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 <Foundation/NSObject.h>
+#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 (file)
index 0000000..e6e7dce
--- /dev/null
@@ -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 (file)
index 0000000..eb138f7
--- /dev/null
@@ -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 (file)
index 0000000..98c8c40
--- /dev/null
@@ -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 <GDLAccess/EOAccess.h>
+
+@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 (file)
index 0000000..c7463bb
--- /dev/null
@@ -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 <GDLAccess/EOAdaptorChannel.h>
+#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 (file)
index 0000000..f1f5461
--- /dev/null
@@ -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 <ctype.h>
+#include <string.h>
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#import "common.h"
+#include "FBBlobHandle.h"
+#include <NGExtensions/NSString+misc.h>
+
+#include <FBCAccess/FBCDigestPassword.h>
+#include <GDLAccess/EORecordDictionary.h>
+#import <EOControl/EOSortOrdering.h>
+
+//#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 (file)
index 0000000..08ebd1f
--- /dev/null
@@ -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 <GDLAccess/EOAdaptorContext.h>
+#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 (file)
index 0000000..2a18f0e
--- /dev/null
@@ -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 (file)
index 0000000..9acb576
--- /dev/null
@@ -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 <Foundation/NSException.h>
+#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 (file)
index 0000000..43a556d
--- /dev/null
@@ -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 <Foundation/Foundation.h>
+#import <GDLAccess/EOAccess.h>
+#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 (file)
index 0000000..cb75727
--- /dev/null
@@ -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 <FBCAccess/FBCAccess.h>
+
+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 (file)
index 0000000..4ce24d5
--- /dev/null
@@ -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 <GDLAccess/EOSQLExpression.h>
+
+@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 (file)
index 0000000..917801f
--- /dev/null
@@ -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 <Foundation/Foundation.h>
+#include <GDLAccess/EOAccess.h>
+#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 (file)
index 0000000..6e4eb4f
--- /dev/null
@@ -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 <Foundation/NSObject.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSDate.h>
+#import <Foundation/NSValue.h>
+#import <GDLAccess/EONull.h>
+#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 (file)
index 0000000..af8d424
--- /dev/null
@@ -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 <string.h>
+#if HAVE_STRINGS_H
+#  include <strings.h>
+#endif
+#include <stdlib.h>
+#import "common.h"
+#include "FBException.h"
+#import <Foundation/NSDate.h>
+
+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 %@<Class:%@> 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 (file)
index 0000000..580aec0
--- /dev/null
@@ -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 <Foundation/NSMapTable.h>
+#import <GDLAccess/EOAdaptor.h>
+#import <GDLAccess/EOAttribute.h>
+#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 (file)
index 0000000..a9f4de3
--- /dev/null
@@ -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 (file)
index 0000000..a5d9aa1
--- /dev/null
@@ -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 (file)
index 0000000..49aea87
--- /dev/null
@@ -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 (file)
index 0000000..fbdf36d
--- /dev/null
@@ -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 (file)
index 0000000..027ea83
--- /dev/null
@@ -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 <Foundation/NSString.h>
+
+@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 (file)
index 0000000..3604325
--- /dev/null
@@ -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 <objc/gc.h>
+#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 (file)
index 0000000..375e6f0
--- /dev/null
@@ -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 (file)
index 0000000..947c5a9
--- /dev/null
@@ -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 (executable)
index 0000000..c3463eb
--- /dev/null
@@ -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 (file)
index 0000000..70d7d94
--- /dev/null
@@ -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 <objc/objc-api.h>
+
+#if LIB_FOUNDATION_BOEHM_GC
+#  include <objc/gc.h>
+#  include <objc/gc_typed.h>
+#  include <extensions/GarbageCollector.h>
+#endif
+
+#import <Foundation/Foundation.h>
+
+
+#if !LIB_FOUNDATION_LIBRARY
+#  import <FoundationExt/NSObjectMacros.h>
+#  import <FoundationExt/FoundationException.h>
+#  import <FoundationExt/NSCoderExceptions.h>
+#  import <FoundationExt/NSException.h>
+#  import <FoundationExt/GeneralExceptions.h>
+#  import <FoundationExt/objc-api.h>
+#  import <FoundationExt/objc-runtime.h>
+#else
+#  import <Foundation/exceptions/GeneralExceptions.h>
+#endif
+
+#import <GDLAccess/EOAccess.h>
+
+#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 (file)
index 0000000..668a9c8
--- /dev/null
@@ -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 (file)
index 0000000..dd2df1b
--- /dev/null
@@ -0,0 +1,302 @@
+// $Id: fbtest.m 1 2004-08-20 10:38:46Z znek $
+
+#import <Foundation/Foundation.h>
+#import <NGExtensions/NGExtensions.h>
+#import <GDLAccess/EOAccess.h>
+//#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 (executable)
index 0000000..4ef645e
--- /dev/null
@@ -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 (file)
index 0000000..725348d
--- /dev/null
@@ -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 (file)
index 0000000..eb685a5
--- /dev/null
@@ -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.
+\f
+  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.
+\f
+                 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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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
+\f
+     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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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 (file)
index 0000000..4adfba7
--- /dev/null
@@ -0,0 +1,146 @@
+2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
+
+       * moved from ThirdParty to SOPE/sope-gdl1 (v1.0.32)
+
+2004-06-29  Helge Hess  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * EOModel.m: minor code cleanups (v1.0.27)
+
+2004-06-21  Helge Hess  <helge.hess@opengroupware.org>
+
+       * EOModel.m: some code cleanups, improved description (v1.0.26)
+
+2004-06-06  Helge Hess  <helge.hess@opengroupware.org>
+
+       * fixed Xcode compilation with embedded FoundationExt classes (v1.0.25)
+
+2004-05-14  Helge Hess  <helge@developer.opengroupware.org>
+
+       * EOAdaptorDataSource.m: removed some ==YES comparisons, minor cleanups
+         (v1.0.24)
+
+2004-03-14  Helge Hess  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * EODatabaseChannel.m: only check for GC objects on libFoundation
+         (v1.0.21)
+
+2004-01-29  Helge Hess  <helge.hess@skyrix.com>
+
+       * EORecordDictionary.m: disabled a profiling log (v1.0.20)
+
+2004-01-07  Helge Hess  <helge@groove.local>
+
+       * some tweaks for Xcode compilation (v1.0.19)
+
+2004-01-04  Helge Hess  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@skyrix.com>
+
+       * 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  <jr@skyrix.com>
+
+       * 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  <znek@mulle-kybernetik.com>
+
+       * GNUmakefile: reordered autodoc target
+
+Mon Jul 14 14:07:22 2003  Jan Reichmann  <jr@skyrix.com>
+
+       *  fixed license entries (v1.0.13)
+
+Fri Jul  4 19:15:35 2003  Helge Hess  <helge.hess@skyrix.com>
+
+       * 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 (file)
index 0000000..70d10c0
--- /dev/null
@@ -0,0 +1,43 @@
+// $Id: EOAccess.h 1 2004-08-20 10:38:46Z znek $
+
+#ifndef __GDLAccess_H__
+#define __GDLAccess_H__
+
+#import <GDLAccess/EODatabase.h>
+#import <GDLAccess/EODatabaseChannel.h>
+#import <GDLAccess/EODatabaseContext.h>
+
+#import <GDLAccess/EOAdaptor.h>
+#import <GDLAccess/EOAdaptorChannel.h>
+#import <GDLAccess/EOAdaptorContext.h>
+#import <GDLAccess/EOAttribute.h>
+#import <GDLAccess/EOAttributeOrdering.h>
+#import <GDLAccess/EOCustomValues.h>
+#import <GDLAccess/EODatabase.h>
+#import <GDLAccess/EODatabaseChannel.h>
+#import <GDLAccess/EODatabaseContext.h>
+#import <GDLAccess/EOEntity.h>
+#import <GDLAccess/EOExpressionArray.h>
+#import <GDLAccess/EOFExceptions.h>
+#import <GDLAccess/EOGenericRecord.h>
+#import <GDLAccess/EOKeySortOrdering.h>
+#import <GDLAccess/EOModel.h>
+#import <GDLAccess/EOObjectUniquer.h>
+#import <GDLAccess/EOPrimaryKeyDictionary.h>
+#import <GDLAccess/EOQuotedExpression.h>
+#import <GDLAccess/EORelationship.h>
+#import <GDLAccess/EOSQLExpression.h>
+#import <GDLAccess/EOSQLQualifier.h>
+#import <GDLAccess/EOAdaptorChannel+Attributes.h>
+#import <GDLAccess/EOAdaptorDataSource.h>
+#import <GDLAccess/EOAdaptorGlobalID.h>
+
+#import <EOControl/EOGenericRecord.h>
+#import <EOControl/EOKeyValueCoding.h>
+
+// 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 (file)
index 0000000..a4e2718
--- /dev/null
@@ -0,0 +1,136 @@
+/* 
+   EOAdaptor.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..1131816
--- /dev/null
@@ -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 <GDLAccess/EOAdaptorChannel.h>
+
+@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 (file)
index 0000000..751b1b8
--- /dev/null
@@ -0,0 +1,202 @@
+/* 
+   EOAdaptorChannel.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSObject.h>
+
+@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 <GDLAccess/EODelegateResponse.h>
+
+@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 (file)
index 0000000..d7b3291
--- /dev/null
@@ -0,0 +1,123 @@
+/* 
+   EOAdaptorContext.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSObject.h>
+
+@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 <GDLAccess/EODelegateResponse.h>
+
+@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 (file)
index 0000000..6e1fdb4
--- /dev/null
@@ -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 <EOControl/EODataSource.h>
+
+@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 (file)
index 0000000..49d9011
--- /dev/null
@@ -0,0 +1,28 @@
+// $Id: EOAdaptorGlobalID.h 1 2004-08-20 10:38:46Z znek $
+
+#ifndef __EOAdaptorGlobalID_H__
+#define __EOAdaptorGlobalID_H__
+
+#include <EOControl/EOGlobalID.h>
+
+@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 (file)
index 0000000..5f74c27
--- /dev/null
@@ -0,0 +1,11 @@
+// $If$
+
+#ifndef __EOAdaptorOperation_H__
+#define __EOAdaptorOperation_H__
+
+#import <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..bdcfb8b
--- /dev/null
@@ -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 <Foundation/NSArray.h>
+
+/*
+ * 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 (file)
index 0000000..86feb5c
--- /dev/null
@@ -0,0 +1,188 @@
+/* 
+   EOAttribute.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSString.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSDate.h>
+
+@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 (file)
index 0000000..f62d7fc
--- /dev/null
@@ -0,0 +1,65 @@
+/* 
+   EOAttributeOrdering.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..0e331e3
--- /dev/null
@@ -0,0 +1,84 @@
+/* 
+   EOCustomValues.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSString.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSValue.h>
+
+/*
+ * 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 (file)
index 0000000..d900527
--- /dev/null
@@ -0,0 +1,169 @@
+/* 
+   EODatabase.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSObject.h>
+#import <Foundation/NSDate.h>
+
+@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 (file)
index 0000000..e6ac207
--- /dev/null
@@ -0,0 +1,213 @@
+/* 
+   EODatabaseChannel.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..f6994bc
--- /dev/null
@@ -0,0 +1,190 @@
+/* 
+   EODatabaseContext.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSObject.h>
+#import <GDLAccess/EODatabase.h>
+
+@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 (file)
index 0000000..63e78c7
--- /dev/null
@@ -0,0 +1,77 @@
+/* 
+   EODatabaseFault.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <GDLAccess/EOFault.h>
+
+@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 (file)
index 0000000..4a76ffe
--- /dev/null
@@ -0,0 +1,93 @@
+/* 
+   EODatabaseFaultResolver.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   Date: 1996
+
+   Author: Helge Hess <helge.hess@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.
+*/
+
+#ifndef __EODatabaseFaultResolver_h__
+#define __EODatabaseFaultResolver_h__
+
+#import <GDLAccess/EOFault.h>
+
+@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 (file)
index 0000000..863fe62
--- /dev/null
@@ -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 (file)
index 0000000..4063b83
--- /dev/null
@@ -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 <GDLAccess/EOEntity.h>
+
+@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 (file)
index 0000000..414206b
--- /dev/null
@@ -0,0 +1,219 @@
+/* 
+   EOEntity.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSString.h>
+
+@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 <EOControl/EOClassDescription.h>
+
+@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 (file)
index 0000000..08f887f
--- /dev/null
@@ -0,0 +1,106 @@
+/* 
+   EOExpressionArray.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSString.h>
+
+@class EOAttribute, EOEntity, EOExpressionArray;
+
+@protocol EOExpressionContext <NSObject>
+
+- (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<EOExpressionContext>)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<EOExpressionContext>)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 (file)
index 0000000..7f1045c
--- /dev/null
@@ -0,0 +1,117 @@
+/* 
+   EOFExceptions.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSException.h>
+
+@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 (file)
index 0000000..21e8c81
--- /dev/null
@@ -0,0 +1,59 @@
+// $Id: EOFault.h 1 2004-08-20 10:38:46Z znek $
+
+#ifndef __EOFault_h__
+#define __EOFault_h__
+
+#import <Foundation/NSObject.h>
+
+@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 <GDLAccess/EOFaultHandler.h>
+
+#endif  /* __EOFault_h__ */
diff --git a/sope-gdl1/GDLAccess/EOAccess/EOFaultHandler.h b/sope-gdl1/GDLAccess/EOAccess/EOFaultHandler.h
new file mode 100644 (file)
index 0000000..300272f
--- /dev/null
@@ -0,0 +1,47 @@
+// $Id: EOFaultHandler.h 1 2004-08-20 10:38:46Z znek $
+
+#ifndef __EOFaultHandler_h__
+#define __EOFaultHandler_h__
+
+#import <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..ec4b89b
--- /dev/null
@@ -0,0 +1,54 @@
+// $Id: EOGenericRecord.h 1 2004-08-20 10:38:46Z znek $
+
+#ifndef __eoaccess_EOGenericRecord_H__
+#define __eoaccess_EOGenericRecord_H__
+
+#import <EOControl/EOGenericRecord.h>
+
+@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 (file)
index 0000000..9010e78
--- /dev/null
@@ -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 (file)
index 0000000..c8b9399
--- /dev/null
@@ -0,0 +1,55 @@
+/* 
+   EOKeySortOrdering.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSObject.h>
+#import <Foundation/NSArray.h>
+
+@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 (file)
index 0000000..7582365
--- /dev/null
@@ -0,0 +1,124 @@
+/* 
+   EOModel.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSString.h>
+
+@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 (file)
index 0000000..95e0d8e
--- /dev/null
@@ -0,0 +1,88 @@
+// $Id: EOModelGroup.h 1 2004-08-20 10:38:46Z znek $
+
+#ifndef __EOAccess_EOModelGroup_H__
+#define __EOAccess_EOModelGroup_H__
+
+#import <Foundation/NSObject.h>
+
+@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<EOModelGroupDelegation> delegate; /* non-retained */
+}
+
++ (void)setDefaultGroup:(EOModelGroup *)_group;
++ (EOModelGroup *)defaultGroup;
+
++ (EOModelGroup *)globalModelGroup;
+
+/* class delegate */
+
++ (void)setClassDelegate:(id<EOModelGroupClassDelegation>)_delegate;
++ (id<EOModelGroupClassDelegation>)classDelegate;
+
+/* instance delegate */
+
+- (void)setDelegate:(id<EOModelGroupDelegation>)_delegate;
+- (id<EOModelGroupDelegation>)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 (file)
index 0000000..64b561f
--- /dev/null
@@ -0,0 +1,8 @@
+// $Id: EONull.h 1 2004-08-20 10:38:46Z znek $
+
+#ifndef __eoaccess_EONull_H__
+#define __eoaccess_EONull_H__
+
+#import <EOControl/EONull.h>
+
+#endif /* __eoaccess_EONull_H__ */
diff --git a/sope-gdl1/GDLAccess/EOAccess/EOObjectUniquer.h b/sope-gdl1/GDLAccess/EOAccess/EOObjectUniquer.h
new file mode 100644 (file)
index 0000000..17d99fd
--- /dev/null
@@ -0,0 +1,84 @@
+/* 
+   EOObjectUniquer.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSObject.h>
+#import <Foundation/NSMapTable.h>
+
+@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 (file)
index 0000000..b53536a
--- /dev/null
@@ -0,0 +1,52 @@
+/* 
+   EOPrimaryKeyDictionary.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSDictionary.h>
+
+@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 (file)
index 0000000..a6c7a7d
--- /dev/null
@@ -0,0 +1,59 @@
+/* 
+   EOQualifierScanner.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+           Helge Hess <helge.hess@mdlink.de>
+   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 <extensions/DefaultScannerHandler.h>
+#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 (file)
index 0000000..ef0e4b7
--- /dev/null
@@ -0,0 +1,49 @@
+/* 
+   EOQuotedExpression.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <GDLAccess/EOExpressionArray.h>
+
+@class NSString;
+
+@interface EOQuotedExpression : NSObject <NSCopying>
+{
+    id       expression;
+    NSString *quote;
+    NSString *escape;
+}
+
+- (id)expressionValueForContext:(id<EOExpressionContext>)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 (file)
index 0000000..ac51a19
--- /dev/null
@@ -0,0 +1,50 @@
+/* 
+*/
+
+#ifndef __EORecordDictionary_h__
+#define __EORecordDictionary_h__
+
+#import <Foundation/NSDictionary.h>
+
+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 <Foundation/NSEnumerator.h>
+
+@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 (file)
index 0000000..ab7f9f2
--- /dev/null
@@ -0,0 +1,162 @@
+/* 
+   EORelationship.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSString.h>
+#import <GDLAccess/EOJoinTypes.h>
+
+@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 (file)
index 0000000..5c91e2d
--- /dev/null
@@ -0,0 +1,268 @@
+/* 
+   EOSQLExpression.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSDictionary.h>
+#import <Foundation/NSArray.h>
+
+#import <GDLAccess/EOExpressionArray.h>
+#import <GDLAccess/EOJoinTypes.h>
+
+@class EOAdaptor;
+@class EOAdaptorChannel;
+@class EOEntity;
+@class EOSQLQualifier;
+
+extern NSString *EOBindVariableNameKey;
+extern NSString *EOBindVariablePlaceHolderKey;
+extern NSString *EOBindVariableAttributeKey;
+extern NSString *EOBindVariableValueKey;
+
+@interface EOSQLExpression : NSObject <EOExpressionContext>
+{
+    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 (file)
index 0000000..8528f65
--- /dev/null
@@ -0,0 +1,140 @@
+/* 
+   EOSQLQualifier.h
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+           Helge Hess <helge.hess@mdlink.de>
+   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 <EOControl/EOQualifier.h>
+
+#import <GDLAccess/EOExpressionArray.h>
+
+@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<EOExpressionContext>)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 (file)
index 0000000..8ac7eba
--- /dev/null
@@ -0,0 +1,3 @@
+// $Id: GDLAccess.h 1 2004-08-20 10:38:46Z znek $
+
+#import <GDLAccess/EOAccess.h>
diff --git a/sope-gdl1/GDLAccess/EOAccess/NSObject+EONullInit.h b/sope-gdl1/GDLAccess/EOAccess/NSObject+EONullInit.h
new file mode 100644 (file)
index 0000000..569d607
--- /dev/null
@@ -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 <Foundation/NSObject.h>
+#import <GDLAccess/EONull.h>
+
+@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 (file)
index 0000000..366329e
--- /dev/null
@@ -0,0 +1,342 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..0f198fb
--- /dev/null
@@ -0,0 +1,78 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..e8af497
--- /dev/null
@@ -0,0 +1,621 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <EOControl/EOFetchSpecification.h>
+
+@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 (file)
index 0000000..82026ee
--- /dev/null
@@ -0,0 +1,257 @@
+/* 
+   EOAdaptorContext.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSUtilities.h>
+#import <Foundation/NSValue.h>
+#import <Foundation/NSArray.h>
+
+#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 (file)
index 0000000..38ca909
--- /dev/null
@@ -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 <NGExtensions/NGExtensions.h>
+#include <GDLAccess/GDLAccess.h>
+#include <EOControl/EOControl.h>
+#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 (file)
index 0000000..8682a6d
--- /dev/null
@@ -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 <GDLAccess/EOAdaptorGlobalID.h>
+#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 (file)
index 0000000..7d68565
--- /dev/null
@@ -0,0 +1,32 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <GDLAccess/EOAdaptorOperation.h>
+#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 (file)
index 0000000..3df7e9d
--- /dev/null
@@ -0,0 +1,72 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..2a5eca9
--- /dev/null
@@ -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 (file)
index 0000000..59a72be
--- /dev/null
@@ -0,0 +1,729 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <EOControl/EONull.h>
+#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<EOExpressionContext>)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 (file)
index 0000000..bf1408f
--- /dev/null
@@ -0,0 +1,53 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <GDLAccess/EOAttribute.h>
+#import <GDLAccess/EOAttributeOrdering.h>
+#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 (file)
index 0000000..d63d9f4
--- /dev/null
@@ -0,0 +1,171 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..8f5ef43
--- /dev/null
@@ -0,0 +1,523 @@
+/* 
+   EODatabase.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 (file)
index 0000000..2853305
--- /dev/null
@@ -0,0 +1,1469 @@
+/* 
+   EODatabaseChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <EOControl/EONull.h>
+#import <EOControl/EOFetchSpecification.h>
+#import <EOControl/EOKeyValueCoding.h>
+
+@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 (file)
index 0000000..9934699
--- /dev/null
@@ -0,0 +1,870 @@
+/* 
+   EODatabaseContext.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   Date: 1996
+   
+   Author: Helge Hess <helge.hess@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.
+*/
+
+#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 <EOControl/EOFetchSpecification.h>
+#include <EOControl/EOKeyGlobalID.h>
+
+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 (file)
index 0000000..ce6895a
--- /dev/null
@@ -0,0 +1,246 @@
+/* 
+   EODatabaseFault.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   Date: 1996
+
+   Author: Helge Hess <helge.hess@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.
+*/
+
+#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 <objc/objc-class.h>
+#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 (file)
index 0000000..e0e1940
--- /dev/null
@@ -0,0 +1,314 @@
+/* 
+   EODatabaseFaultResolver.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   Date: 1996
+
+   Author: Helge Hess <helge.hess@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.
+*/
+
+#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:
+                   @"<Array fault 0x%x (qualifier=%@, order=%@, channel=%@)>",
+                   _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:
+                     @"<Object fault 0x%X "
+                     @"(class=%@, entity=%@, key=%@, channel=%@)>",
+                     _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 (file)
index 0000000..ce83d1c
--- /dev/null
@@ -0,0 +1,123 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <GDLAccess/EOEntity+Factory.h>
+#include <GDLAccess/EOAttribute.h>
+#include <EOControl/EONull.h>
+#include <EOControl/EOKeyValueCoding.h>
+#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 (file)
index 0000000..e3989dd
--- /dev/null
@@ -0,0 +1,1143 @@
+/* 
+   EOEntity.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   Date: August 1996
+
+   Author: Helge Hess <helge.hess@mdlink.de>
+   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 <EOControl/EOKeyValueCoding.h>
+#import <EOControl/EOKeyGlobalID.h>
+
+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 (file)
index 0000000..e113f14
--- /dev/null
@@ -0,0 +1,237 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <EOControl/EOKeyValueCoding.h>
+#import <EOControl/EOKeyGlobalID.h>
+
+@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 (file)
index 0000000..cdd014b
--- /dev/null
@@ -0,0 +1,318 @@
+/* 
+   EOExpressionArray.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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<EOExpressionContext>)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<EOExpressionContext>)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<EOExpressionContext>)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 (file)
index 0000000..48bd267
--- /dev/null
@@ -0,0 +1,171 @@
+/* 
+   EOFExceptions.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..c15e077
--- /dev/null
@@ -0,0 +1,376 @@
+/* 
+   EOAttributeOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <objc/objc-class.h>
+#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 (file)
index 0000000..a52a9c6
--- /dev/null
@@ -0,0 +1,206 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..79856f4
--- /dev/null
@@ -0,0 +1,84 @@
+/* 
+   EOGenericRecord.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <stdio.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSMapTable.h>
+#import <Foundation/NSArray.h>
+#import "common.h"
+#import "EOEntity.h"
+#import "EOGenericRecord.h"
+#import "EODatabase.h"
+#import <GDLAccess/EOFault.h>
+#import <EOControl/EOClassDescription.h>
+
+@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 <nil> 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 (file)
index 0000000..8b56c89
--- /dev/null
@@ -0,0 +1,70 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..dc2296f
--- /dev/null
@@ -0,0 +1,144 @@
+/* 
+   EOKeySortOrdering.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <Foundation/NSAutoreleasePool.h>
+#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+#import "common.h"
+#import "EOKeySortOrdering.h"
+#import <EOControl/EOKeyValueCoding.h>
+
+@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 (file)
index 0000000..e4e098f
--- /dev/null
@@ -0,0 +1,64 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..917c9ad
--- /dev/null
@@ -0,0 +1,462 @@
+/* 
+   EOModel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..64839b8
--- /dev/null
@@ -0,0 +1,242 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <EOControl/EOClassDescription.h>
+#include "common.h"
+
+@implementation EOModelGroup
+
+static EOModelGroup *defaultGroup = nil;
+static id<EOModelGroupClassDelegation> 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<EOModelGroupClassDelegation>)_delegate {
+  ASSIGN(classDelegate, _delegate);
+}
++ (id<EOModelGroupClassDelegation>)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<EOModelGroupDelegation>)_delegate {
+  self->delegate = _delegate;
+}
+- (id<EOModelGroupDelegation>)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 (file)
index 0000000..18ecb41
--- /dev/null
@@ -0,0 +1,43 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..e6057f6
--- /dev/null
@@ -0,0 +1,369 @@
+/* 
+   EOObjectUniquer.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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:
+                     @"<<pkey:%08x entity:%08x object:%08x snapshot:%08x>>",
+                     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 (file)
index 0000000..a2ced42
--- /dev/null
@@ -0,0 +1,69 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..6d4fb36
--- /dev/null
@@ -0,0 +1,403 @@
+/* 
+   EOPrimaryKeyDictionary.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Mircea Oancea <mircea@jupiter.elcom.pub.ro>
+   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 <EOControl/EONull.h>
+
+/*
+ * 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 (file)
index 0000000..30c0f4e
--- /dev/null
@@ -0,0 +1,141 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <EOControl/EOQualifier.h>
+#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<EOQualifierSQLGeneration>)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 (file)
index 0000000..0286f31
--- /dev/null
@@ -0,0 +1,194 @@
+/* 
+   EOQualifierScanner.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+           Helge Hess <helge.hess@mdlink.de>
+   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 <EOControl/EONull.h>
+
+#if LIB_FOUNDATION_LIBRARY
+#  import <extensions/DefaultScannerHandler.h>
+#  import <extensions/PrintfFormatScanner.h>
+#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 (file)
index 0000000..7a00128
--- /dev/null
@@ -0,0 +1,81 @@
+/* 
+   EOQuotedExpression.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/NSString.h>
+#import <Foundation/NSArray.h>
+#import "common.h"
+#import "EOQuotedExpression.h"
+
+@implementation EOQuotedExpression
+
+- (id)expressionValueForContext:(id<EOExpressionContext>)_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 (file)
index 0000000..b839b11
--- /dev/null
@@ -0,0 +1,231 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <stdarg.h>
+#include <math.h>
+
+#import <Foundation/NSObject.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSArray.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSException.h>
+
+#if LIB_FOUNDATION_LIBRARY
+#  include <Foundation/exceptions/GeneralExceptions.h>
+#  include <extensions/objc-runtime.h>
+#else
+#  include <NGExtensions/NGObjectMacros.h>
+#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 (file)
index 0000000..8918554
--- /dev/null
@@ -0,0 +1,567 @@
+/* 
+   EORelationship.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <EOControl/EONull.h>
+
+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<EOExpressionContext>)_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 (file)
index 0000000..d273de6
--- /dev/null
@@ -0,0 +1,1446 @@
+/* 
+   EOSQLExpression.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <EOControl/EOFetchSpecification.h>
+#import <EOControl/EONull.h>
+#import <EOControl/EOQualifier.h>
+#import <EOControl/EOSortOrdering.h>
+
+#if LIB_FOUNDATION_LIBRARY
+#  include <extensions/DefaultScannerHandler.h>
+#  include <extensions/PrintfFormatScanner.h>
+#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<EOExpressionContext>)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<EOQualifierSQLGeneration>)_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<EOQualifierSQLGeneration> 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<EOQualifierSQLGeneration> 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<EOQualifierSQLGeneration>)_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<EOQualifierSQLGeneration>)_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 (file)
index 0000000..50425bb
--- /dev/null
@@ -0,0 +1,592 @@
+/* 
+   EOSQLQualifier.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@apache.org>
+           Helge Hess <helge.hess@opengroupware.org>
+   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 <stdio.h>
+#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 <EOControl/EOKeyValueCoding.h>
+#include <EOControl/EONull.h>
+#import "EOQualifierScanner.h"
+
+#if LIB_FOUNDATION_LIBRARY
+#  include <extensions/DefaultScannerHandler.h>
+#  include <extensions/PrintfFormatScanner.h>
+#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<EOExpressionContext>)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 (file)
index 0000000..2c750a3
--- /dev/null
@@ -0,0 +1,147 @@
+/* 
+   EOSQLExpression.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <extensions/DefaultScannerHandler.h>
+#  include <extensions/PrintfFormatScanner.h>
+#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 (file)
index 0000000..38e0c36
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 (file)
index 0000000..ea95187
--- /dev/null
@@ -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 (file)
index 0000000..60438d5
--- /dev/null
@@ -0,0 +1,5 @@
+   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
+   All rights reserved.
+
+   Author: Ovidiu Predescu <ovidiu@apache.org>
+           Helge Hess <helge.hess@opengroupware.org>
diff --git a/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.h b/sope-gdl1/GDLAccess/FoundationExt/DefaultScannerHandler.h
new file mode 100644 (file)
index 0000000..a634668
--- /dev/null
@@ -0,0 +1,62 @@
+/* 
+   DefaultScannerHandler.h
+
+   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
+   All rights reserved.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+
+   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 <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..dad679f
--- /dev/null
@@ -0,0 +1,90 @@
+/* 
+   DefaultScannerHandler.m
+
+   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
+   All rights reserved.
+
+   Author: Ovidiu Predescu <ovidiu@apache.org>
+           Helge Hess <helge.hess@opengroupware.org>
+
+   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 <Foundation/NSString.h>
+#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 (file)
index 0000000..efa75ed
--- /dev/null
@@ -0,0 +1,127 @@
+/* 
+   FormatScanner.h
+
+   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
+   All rights reserved.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+
+   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 <stdarg.h>
+#include <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..5f2026e
--- /dev/null
@@ -0,0 +1,341 @@
+/* 
+   FormatScanner.m
+
+   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
+   All rights reserved.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+
+   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 <ctype.h>
+
+#include "common.h"
+
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSValue.h>
+#import <Foundation/NSCharacterSet.h>
+
+//#include <extensions/support.h>
+#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 (file)
index 0000000..ca095b5
--- /dev/null
@@ -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 (file)
index 0000000..dcdb6da
--- /dev/null
@@ -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 (file)
index 0000000..cc373f2
--- /dev/null
@@ -0,0 +1,52 @@
+/* 
+   PrintfFormatScanner.h
+
+   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
+   All rights reserved.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+
+   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 <FoundationExt/FormatScanner.h>
+#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 (file)
index 0000000..fe7c7e8
--- /dev/null
@@ -0,0 +1,55 @@
+/* 
+   PrintfFormatScanner.m
+
+   Copyright (C) 1995, 1996 Ovidiu Predescu and Mircea Oancea.
+   All rights reserved.
+
+   Author: Ovidiu Predescu <ovidiu@apache.org>
+
+   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 <Foundation/NSString.h>
+#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 (file)
index 0000000..8484355
--- /dev/null
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>GDLAccess</string>
+       <key>CFBundleGetInfoString</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.opengroupware.gnustep-db</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleShortVersionString</key>
+       <string></string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+</dict>
+</plist>
diff --git a/sope-gdl1/GDLAccess/GDLExtensions/ChangeLog b/sope-gdl1/GDLAccess/GDLExtensions/ChangeLog
new file mode 100644 (file)
index 0000000..05bae17
--- /dev/null
@@ -0,0 +1,44 @@
+2004-06-28  Helge Hess  <helge.hess@opengroupware.org>
+
+       * GNUmakefile.preamble: fixed link pathes (v4.2.28)
+
+2002-08-15  Helge Hess  <helge.hess@skyrix.com>
+
+       * GNUmakefile: fixed Version imports (now v4.2.3)
+
+Mon Apr  2 22:02:05 2001  Helge Hess  <helge.hess@skyrix.com>
+
+       * GDLExtensions.m: fixed linking problem
+
+Tue Feb 29 19:06:44 2000  Helge Hess  <helge.hess@mdlink.de>
+
+       * MOF3 import
+
+Mon Apr 26 14:00:01 1999  Helge Hess  <helge@trex.mdlink.de>
+
+       * added kit class GDLExtensions
+
+       * use #include instead of #import
+
+Mon Dec 21 19:02:16 1998  Helge Hess  <helge@trex.mdlink.de>
+
+       * NSObject+EONullInit.m: added -stringValue to EONull
+
+Mon Dec 21 16:19:18 1998  Helge Hess  <helge@trex.mdlink.de>
+
+       * EOGenericRecord+KeyValueCoding2.m: updated for new EOGenericRecord
+         classes (which uses NSMapTable instead of a dictionary).
+
+Fri Dec 11 16:48:10 1998  Helge Hess  <helge@trex.mdlink.de>
+
+       * NSObject+EONullInit.m: added method '-isNull' to EONull, NSObject
+
+Fri Nov 27 19:55:21 1998  Helge Hess  <helge@trex.mdlink.de>
+
+       * added PB.project
+
+Fri Nov 27 19:55:12 1998  Helge Hess  <helge@trex.mdlink.de>
+
+       * created ChangeLog
+       
+
diff --git a/sope-gdl1/GDLAccess/GDLExtensions/EOEntity+Factory.h b/sope-gdl1/GDLAccess/GDLExtensions/EOEntity+Factory.h
new file mode 100644 (file)
index 0000000..193faa6
--- /dev/null
@@ -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 <EOAccess/EOEntity+Factory.h>
+
+#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 (file)
index 0000000..63eb7aa
--- /dev/null
@@ -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 <GDLAccess/EOEntity+Factory.h>
+#  include <GDLAccess/NSObject+EONullInit.h>
+#else
+#  include <GDLExtensions/EOEntity+Factory.h>
+#  include <GDLExtensions/NSObject+EONullInit.h>
+#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 (file)
index 0000000..c40ff42
--- /dev/null
@@ -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 (file)
index 0000000..c025379
--- /dev/null
@@ -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 (file)
index 0000000..e1f7543
--- /dev/null
@@ -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 (file)
index 0000000..894e6be
--- /dev/null
@@ -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 <EOAccess/NSObject+EONullInit.h>
+
+#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 (file)
index 0000000..0938f70
--- /dev/null
@@ -0,0 +1,10 @@
+// $Id: common.h 1 2004-08-20 10:38:46Z znek $
+
+// common include files
+
+#import <Foundation/Foundation.h>
+#import <EOAccess/EOAccess.h>
+
+#if NeXT_Foundation_LIBRARY
+#  import <extensions/NSObjectMacros.h>
+#endif
diff --git a/sope-gdl1/GDLAccess/GDLExtensions/libGDLExtensions.def b/sope-gdl1/GDLAccess/GDLExtensions/libGDLExtensions.def
new file mode 100644 (file)
index 0000000..875da0a
--- /dev/null
@@ -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 (file)
index 0000000..6363319
--- /dev/null
@@ -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 (file)
index 0000000..70457d3
--- /dev/null
@@ -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 (file)
index 0000000..4440793
--- /dev/null
@@ -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 (file)
index 0000000..72cf5e2
--- /dev/null
@@ -0,0 +1,48 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <GDLAccess/NSObject+EONullInit.h>
+#include <GDLAccess/EOEntity+Factory.h>
+#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 (file)
index 0000000..9e54000
--- /dev/null
@@ -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 (file)
index 0000000..fb5aa76
--- /dev/null
@@ -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 (file)
index 0000000..92391da
--- /dev/null
@@ -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 (file)
index 0000000..e9274af
--- /dev/null
@@ -0,0 +1,246 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <string.h>
+#include <stdlib.h>
+
+#ifndef __WIN32__
+#  include <unistd.h>
+#  include <pwd.h>
+#endif
+
+#include <sys/types.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#import <Foundation/NSZone.h>
+#import <Foundation/Foundation.h>
+#import <Foundation/NSUtilities.h>
+#import <Foundation/NSObjCRuntime.h>
+
+#if NeXT_RUNTIME || APPLE_RUNTIME
+#  define sel_eq(sela,selb) (sela==selb?YES:NO)
+#endif
+
+#if LIB_FOUNDATION_LIBRARY
+#  import <Foundation/exceptions/GeneralExceptions.h>
+#  import <extensions/objc-runtime.h>
+#else
+#  include <NGExtensions/NGObjectMacros.h>
+#  include <NGExtensions/NSString+Ext.h>
+#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 <objc/objc.h>
+#    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 (file)
index 0000000..c52b987
--- /dev/null
@@ -0,0 +1,125 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/Foundation.h>
+#include <GDLAccess/EOAdaptor.h>
+#include <GDLAccess/EOAdaptorContext.h>
+#include <GDLAccess/EOAdaptorChannel.h>
+#include <stdio.h>
+
+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 (file)
index 0000000..b6a9bfe
--- /dev/null
@@ -0,0 +1,85 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 (file)
index 0000000..74854c4
--- /dev/null
@@ -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 (file)
index 0000000..4fa4f4f
--- /dev/null
@@ -0,0 +1,72 @@
+/* 
+   EOAdaptorChannel.m
+
+   Copyright (C) 1996 Free Software Foundation, Inc.
+
+   Author: Ovidiu Predescu <ovidiu@bx.logicnet.ro>
+   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 <Foundation/Foundation.h>
+#include <GDLAccess/EOAdaptor.h>
+#include <stdio.h>
+
+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 (executable)
index 0000000..c8ab2c3
--- /dev/null
@@ -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 (file)
index 0000000..ff278d2
--- /dev/null
@@ -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 (file)
index 0000000..a43ea21
--- /dev/null
@@ -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.
+\f
+                   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.)
+\f
+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.
+\f
+  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.
+\f
+  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
+\f
+       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.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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 (file)
index 0000000..eb685a5
--- /dev/null
@@ -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.
+\f
+  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.
+\f
+                 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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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
+\f
+     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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 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 (file)
index 0000000..f4488af
--- /dev/null
@@ -0,0 +1,250 @@
+2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
+
+       * moved from ThirdParty to SOPE/sope-gdl1 (v1.0.33)
+
+2004-07-06  Helge Hess  <helge.hess@opengroupware.org>
+
+       * PostgreSQL72Channel.m: ensure that the port is passed to the 
+         connection as a string object (v1.0.32)
+
+2004-06-29  Helge Hess  <helge.hess@opengroupware.org>
+
+       * GNUmakefile.preamble: added include path to SOPE/skyrix-core for
+         "inline" compilation (v1.0.31)
+
+2004-06-28  Helge Hess  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@skyrix.com>
+
+       * NSString+PGVal.m, PGConnection.m: fixed some gcc 3.4 warnings 
+         (v1.0.25)
+
+2004-06-16  Helge Hess  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * fixed some MacOSX compilation warnings (v1.0.21)
+
+2004-05-04  Helge Hess  <helge.hess@opengroupware.org>
+
+       * GNUmakefile.preamble (PostgreSQL72_BUNDLE_LIBS): added missing libs
+         for current Panther PostgreSQL compilation (v1.0.20)
+
+2004-03-01  Helge Hess  <helge.hess@skyrix.com>
+
+       * GNUmakefile.preamble: fixed makefile for "inline" compilation
+         (v1.0.19)
+
+2004-02-12  Helge Hess  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@skyrix.com>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * PostgreSQL72Channel.m: explicitly set connection encoding to Latin1
+         to avoid problems with databases created as Unicode (v1.0.16)
+
+2004-01-07  Helge Hess  <helge.hess@opengroupware.org>
+
+       * PostgreSQL72Exception.m: minor cleanup, include stdarg.h for varargs
+         processing (might fix compilation on Solaris) (v1.0.15)
+
+2004-01-07  Helge Hess  <helge.hess@skyrix.com>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * 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  <helge.hess@opengroupware.org>
+
+       * GNUmakefile.preamble: fixed include flags, so that GDLAccess must not
+         be installed prior compiling the adaptor (v1.0.11)
+
+2003-12-11  Helge Hess  <helge.hess@skyrix.com>
+
+       * GNUmakefile (BUNDLE_INSTALL_DIR): install into 
+         GNUSTEP_INSTALLATION_DIR instead of GNUSTEP_SYSTEM_ROOT (v1.0.10)
+
+2003-09-03  Helge Hess  <helge.hess@skyrix.com>
+
+       * 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  <helge.hess@skyrix.com>
+
+       * 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  <helge.hess@skyrix.com>
+
+       * NSCalendarDate+PGVal.m: fixed two more bugs introduced in 1.0.5 ...
+         (v1.0.7)
+
+2003-07-28  Bjoern Stierand  <bjoern@opengroupware.org>
+       
+       * 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  <helge.hess@skyrix.com>
+       
+       * PostgreSQL72Values.m: split up into separate files, added several
+         performance optimizations to base value creation code (v1.0.5)
+
+2003-07-23  Helge Hess  <helge.hess@skyrix.com>
+
+       * more fixes to the include pathes, do not include using <pgsql/xxx.h>
+         but always using <xxx.h> (v1.0.4)
+
+2003-07-21  Helge Hess  <helge.hess@skyrix.com>
+
+       * some include cleanups for FreeBSD (reported by Mirko Viviani),
+         fixed some warnings (v1.0.3)
+
+Wed May 14 11:27:21 2003  Jan Reichmann  <jan@skyrix.com>
+
+       * PostgreSQL72Values.m: use lowercase type to determine sql type 
+         (bug 126) (v1.0.2)
+
+2003-05-07  Helge Hess  <helge.hess@skyrix.com>
+
+       * 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  <jan@skyrix.com>
+
+       * PostgreSQL72Values.m: implement valueFromCString, valueFromBytes, 
+         stringValueForPostgreSQLType for NSData+PostgreSQL72Values (bug 126)
+
+Mon Dec 23 18:20:13 2002  Helge Hess  <helge.hess@skyrix.com>
+
+       * ported to MacOSX 10.2.3 (do not use <EOAccess, include common.h)
+
+Tue Nov 26 12:01:49 2002  Jan Reichmann  <jan@skyrix.com>
+
+       * EOAttribute+PostgreSQL72.m: add timestamptz type
+
+Tue Nov  5 10:02:45 2002  Jan Reichmann  <jan@skyrix.com>
+
+       * PostgreSQLChannel.m: add PGMaxOpenConnectionCount - Default to
+       set the max number of open postgres connections
+
+Fri Oct 18 19:15:15 2002  Jan Reichmann  <jan@skyrix.com>
+
+       * EOAttribute+PostgreSQL72.m: add postgres types
+
+Thu Aug 22 11:08:35 2002  Jan Reichmann  <jan@skyrix.com>
+
+       * 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  <jan@skyrix.com>
+
+       * PostgreSQL72Values.m: remove Logs
+
+Tue Jun 11 14:43:14 2002  Jan41 Reichmann  <jan@skyrix.com>
+
+       * PostgreSQL72Context.m: remove abort() :(
+
+Mon Mar 18 12:53:42 CET 2002 Jan41 Reichmann  <jan@skyrix.com>
+
+       * PostgreSQLValues.m, *Channel.*: add caches for attributes/ 
+       add get primary key infos
+
+Mon Mar 11 12:02:24 2002  Jan41 Reichmann  <jan@skyrix.com>
+
+       * PostgreSQLValues.m: fixed CAL-FORMAT Entry
+
+Thu Aug 16 14:13:10 2001  Martin Hoerning  <mh@skyrix.com>
+
+       * PostgreSQLChannel.m: fixed RETAIN-BUGS, removed LOGS
+
+Fri Jul 27 17:32:17 2001  Jan Reichmann  <jan@skyrix.com>
+
+       * EOAttribute+PostgreSQL.m: fixed timezone bugs
+
+Thu Jul  5 14:08:11 2001  Helge Hess  <helge.hess@skyrix.com>
+
+       * reactivated for SkyDev41
+
+Tue Feb  2 09:01:10 1999  Helge Hess  <helge@trex.mdlink.de>
+
+       * created ChangeLog
diff --git a/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.h b/sope-gdl1/PostgreSQL72/EOAttribute+PostgreSQL72.h
new file mode 100644 (file)
index 0000000..07ca689
--- /dev/null
@@ -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 <GDLAccess/EOAttribute.h>
+#include <libpq-fe.h>
+
+@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 (file)
index 0000000..0a68fb3
--- /dev/null
@@ -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 <pg_type.h>
+#else
+#include <postgres_types.h>
+#endif
+#include <sql3types.h>
+
+// 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 (file)
index 0000000..f73bb89
--- /dev/null
@@ -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 (file)
index 0000000..6607d48
--- /dev/null
@@ -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 (file)
index 0000000..0774841
--- /dev/null
@@ -0,0 +1,179 @@
+// $Id: NSCalendarDate+PGVal.m 1 2004-08-20 10:38:46Z znek $
+
+#import <Foundation/NSString.h>
+#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 (file)
index 0000000..a0095f4
--- /dev/null
@@ -0,0 +1,97 @@
+// $Id: NSData+PGVal.m 1 2004-08-20 10:38:46Z znek $
+
+#import <Foundation/NSData.h>
+#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 (file)
index 0000000..4972818
--- /dev/null
@@ -0,0 +1,156 @@
+// $Id: NSNumber+PGVal.m 1 2004-08-20 10:38:46Z znek $
+
+#import <Foundation/NSString.h>
+#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 (file)
index 0000000..2883999
--- /dev/null
@@ -0,0 +1,88 @@
+// $Id: NSString+PGVal.m 1 2004-08-20 10:38:46Z znek $
+
+#import <Foundation/NSString.h>
+#include "PostgreSQL72Channel.h"
+#include <NGExtensions/NSString+Ext.h>
+#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 (file)
index 0000000..ae5ed90
--- /dev/null
@@ -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 <Foundation/NSString.h>
+
+@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 (file)
index 0000000..dfcbb51
--- /dev/null
@@ -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 <objc/gc.h>
+#endif
+
+#import <objc/objc-api.h>
+#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 (file)
index 0000000..ebc8156
--- /dev/null
@@ -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 <Foundation/NSObject.h>
+
+@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 (file)
index 0000000..7881260
--- /dev/null
@@ -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 <libpq-fe.h>
+
+#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 (file)
index 0000000..792cb7a
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>PostgreSQL72</string>
+       <key>CFBundleGetInfoString</key>
+       <string></string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.opengroupware.gnustep-db.PostgreSQL72</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string></string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0</string>
+</dict>
+</plist>
diff --git a/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.h b/sope-gdl1/PostgreSQL72/PostgreSQL72Adaptor.h
new file mode 100644 (file)
index 0000000..e028936
--- /dev/null
@@ -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 <Foundation/NSMapTable.h>
+#import <GDLAccess/EOAdaptor.h>
+#import <GDLAccess/EOAttribute.h>
+
+@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 (file)
index 0000000..18fd8f8
--- /dev/null
@@ -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 (file)
index 0000000..9f44474
--- /dev/null
@@ -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 (file)
index 0000000..80d974d
--- /dev/null
@@ -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 (file)
index 0000000..06598fb
--- /dev/null
@@ -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 <GDLAccess/EOAdaptorChannel.h>
+#include <libpq-fe.h>
+
+@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 (file)
index 0000000..fc7dbc5
--- /dev/null
@@ -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 <ctype.h>
+#include <string.h>
+#include <strings.h>
+#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 (file)
index 0000000..d3c794d
--- /dev/null
@@ -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 <GDLAccess/EOAdaptorContext.h>
+
+@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 (file)
index 0000000..551e505
--- /dev/null
@@ -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 (file)
index 0000000..e062c7e
--- /dev/null
@@ -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 <Foundation/NSException.h>
+
+@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 (file)
index 0000000..dd39f0b
--- /dev/null
@@ -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 <GDLAccess/GDLAccess.h>
+#include "PostgreSQL72Exception.h"
+#include "common.h"
+#include <stdarg.h>
+
+@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 (file)
index 0000000..94785ec
--- /dev/null
@@ -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 <GDLAccess/EOSQLExpression.h>
+
+@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 (file)
index 0000000..9eade07
--- /dev/null
@@ -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 <Foundation/Foundation.h>
+#include <GDLAccess/EOAccess.h>
+#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 (file)
index 0000000..4396b82
--- /dev/null
@@ -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 <Foundation/NSObject.h>
+#import <Foundation/NSString.h>
+#import <Foundation/NSData.h>
+#import <Foundation/NSDate.h>
+#import <GDLAccess/EONull.h>
+#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 (file)
index 0000000..8ee3ce7
--- /dev/null
@@ -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 %@<Class:%@> 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 (file)
index 0000000..33367bf
--- /dev/null
@@ -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 (file)
index 0000000..5d265ce
--- /dev/null
@@ -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 (file)
index 0000000..2544f20
--- /dev/null
@@ -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 (file)
index 0000000..0b8abb0
--- /dev/null
@@ -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 <objc/objc-api.h>
+
+#if LIB_FOUNDATION_BOEHM_GC
+#  include <objc/gc.h>
+#  include <objc/gc_typed.h>
+#  include <extensions/GarbageCollector.h>
+#endif
+
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+
+#import <Foundation/Foundation.h>
+
+#if LIB_FOUNDATION_LIBRARY
+#  import <Foundation/exceptions/GeneralExceptions.h>
+#else
+#  include <NGExtensions/NGObjectMacros.h>
+#endif
+
+#import <GDLAccess/EOAccess.h>
+
+#endif /* ___PostgreSQL_common_H___ */
diff --git a/sope-gdl1/PostgreSQL72/condict.plist b/sope-gdl1/PostgreSQL72/condict.plist
new file mode 100644 (file)
index 0000000..1e9d44a
--- /dev/null
@@ -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 (file)
index 0000000..dc95aeb
--- /dev/null
@@ -0,0 +1,165 @@
+// $Id: gdltest.m 1 2004-08-20 10:38:46Z znek $
+
+#import <Foundation/Foundation.h>
+#import <EOAccess/EOAccess.h>
+#include <NGExtensions/NGExtensions.h>
+
+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 (file)
index 0000000..76c1727
--- /dev/null
@@ -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 (file)
index 0000000..f17df57
--- /dev/null
@@ -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 (file)
index 0000000..0f70ce4
--- /dev/null
@@ -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 (file)
index 0000000..eef107a
--- /dev/null
@@ -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 (file)
index 0000000..5e17e3a
--- /dev/null
@@ -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 (file)
index 0000000..c726e0a
--- /dev/null
@@ -0,0 +1,3002 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 39;
+       objects = {
+               E890B00E055AB18B004301A0 = {
+                       children = (
+                               E890B01B055AB194004301A0,
+                               E890B01D055AB1A0004301A0,
+                               E890B01C055AB19B004301A0,
+                               E8AC8D0905ABCA5E008C206D,
+                               E890B028055AB1B8004301A0,
+                               E8AC8D4E05ABCB39008C206D,
+                       );
+                       isa = PBXGroup;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               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 = "<group>";
+               };
+               E890B01C055AB19B004301A0 = {
+                       children = (
+                       );
+                       isa = PBXGroup;
+                       name = FrontBase2;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E890B01D055AB1A0004301A0 = {
+                       children = (
+                               E8AC8D1F05ABCAB9008C206D,
+                               E8AC8D2205ABCAB9008C206D,
+                               E8AC8D2305ABCAB9008C206D,
+                               E8AC8D3E05ABCAB9008C206D,
+                               E8AC8D4005ABCAB9008C206D,
+                               E8AC8D4205ABCAB9008C206D,
+                               E8AC8D4505ABCAEA008C206D,
+                               E8AC8D4605ABCAFF008C206D,
+                               E8AC8D4705ABCB1B008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = PostgreSQL;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               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 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>GDLAccess</string>
+       <key>CFBundleGetInfoString</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.MySoftwareCompany.GDLAccess</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+       <key>CFBundleShortVersionString</key>
+       <string></string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0.0d1</string>
+</dict>
+</plist>
+";
+                       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 = "<group>";
+               };
+               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 = "<group>";
+               };
+               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 = "<group>";
+               };
+               E8AC8BEC05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = ChangeLog;
+                       path = GDLAccess/ChangeLog;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BED05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = common.h;
+                       path = GDLAccess/common.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BEE05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "connect-EOAdaptor.m";
+                       path = "GDLAccess/connect-EOAdaptor.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BEF05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = COPYING.LIB;
+                       path = GDLAccess/COPYING.LIB;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF005ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = eoaccess.m;
+                       path = GDLAccess/eoaccess.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF105ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAdaptor.m;
+                       path = GDLAccess/EOAdaptor.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF205ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAdaptorChannel.m;
+                       path = GDLAccess/EOAdaptorChannel.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF305ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOAdaptorChannel+Attributes.m";
+                       path = "GDLAccess/EOAdaptorChannel+Attributes.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF405ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAdaptorContext.m;
+                       path = GDLAccess/EOAdaptorContext.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF505ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAdaptorDataSource.m;
+                       path = GDLAccess/EOAdaptorDataSource.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF605ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAdaptorGlobalID.m;
+                       path = GDLAccess/EOAdaptorGlobalID.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF705ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAdaptorOperation.m;
+                       path = GDLAccess/EOAdaptorOperation.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF805ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOAndQualifier+SQL.m";
+                       path = "GDLAccess/EOAndQualifier+SQL.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BF905ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOArrayProxy.m;
+                       path = GDLAccess/EOArrayProxy.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BFA05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAttribute.m;
+                       path = GDLAccess/EOAttribute.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BFB05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOAttributeOrdering.m;
+                       path = GDLAccess/EOAttributeOrdering.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BFC05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOCustomValues.m;
+                       path = GDLAccess/EOCustomValues.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BFD05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EODatabase.m;
+                       path = GDLAccess/EODatabase.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BFE05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EODatabaseChannel.m;
+                       path = GDLAccess/EODatabaseChannel.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8BFF05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EODatabaseContext.m;
+                       path = GDLAccess/EODatabaseContext.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0005ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EODatabaseFault.m;
+                       path = GDLAccess/EODatabaseFault.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0105ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EODatabaseFaultResolver.m;
+                       path = GDLAccess/EODatabaseFaultResolver.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0205ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOEntity.m;
+                       path = GDLAccess/EOEntity.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0305ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOEntity+Factory.m";
+                       path = "GDLAccess/EOEntity+Factory.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0405ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOEntityClassDescription.m;
+                       path = GDLAccess/EOEntityClassDescription.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0505ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOExpressionArray.m;
+                       path = GDLAccess/EOExpressionArray.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0605ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOFault.m;
+                       path = GDLAccess/EOFault.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0705ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOFaultHandler.m;
+                       path = GDLAccess/EOFaultHandler.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0805ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOFExceptions.m;
+                       path = GDLAccess/EOFExceptions.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0905ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOGenericRecord.m;
+                       path = GDLAccess/EOGenericRecord.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0A05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOKeyComparisonQualifier+SQL.m";
+                       path = "GDLAccess/EOKeyComparisonQualifier+SQL.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0B05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOKeySortOrdering.m;
+                       path = GDLAccess/EOKeySortOrdering.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0C05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOKeyValueQualifier+SQL.m";
+                       path = "GDLAccess/EOKeyValueQualifier+SQL.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0D05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOModel.m;
+                       path = GDLAccess/EOModel.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0E05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOModelGroup.m;
+                       path = GDLAccess/EOModelGroup.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C0F05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EONotQualifier+SQL.m";
+                       path = "GDLAccess/EONotQualifier+SQL.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1005ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOObjectUniquer.m;
+                       path = GDLAccess/EOObjectUniquer.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1105ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOOrQualifier+SQL.m";
+                       path = "GDLAccess/EOOrQualifier+SQL.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1205ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOPrimaryKeyDictionary.m;
+                       path = GDLAccess/EOPrimaryKeyDictionary.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1305ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOQualifier+SQL.m";
+                       path = "GDLAccess/EOQualifier+SQL.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1405ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOQualifierScanner.m;
+                       path = GDLAccess/EOQualifierScanner.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1505ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOQuotedExpression.m;
+                       path = GDLAccess/EOQuotedExpression.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1605ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EORecordDictionary.m;
+                       path = GDLAccess/EORecordDictionary.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1705ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EORelationship.m;
+                       path = GDLAccess/EORelationship.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1805ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOSQLExpression.m;
+                       path = GDLAccess/EOSQLExpression.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1905ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = EOSQLQualifier.m;
+                       path = GDLAccess/EOSQLQualifier.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1A05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = GNUmakefile;
+                       path = GDLAccess/GNUmakefile;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1B05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = GNUmakefile.postamble;
+                       path = GDLAccess/GNUmakefile.postamble;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1C05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = GNUmakefile.preamble;
+                       path = GDLAccess/GNUmakefile.preamble;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1D05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = libGDLAccess.def;
+                       path = GDLAccess/libGDLAccess.def;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1E05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "load-EOAdaptor.m";
+                       path = "GDLAccess/load-EOAdaptor.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C1F05ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "NSObject+EONullInit.m";
+                       path = "GDLAccess/NSObject+EONullInit.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C2005ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = README;
+                       path = GDLAccess/README;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C2105ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.script.python;
+                       name = test.py;
+                       path = GDLAccess/test.py;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C2205ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = TODO;
+                       path = GDLAccess/TODO;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C2305ABC13E008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = Version;
+                       path = GDLAccess/Version;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               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 = "<group>";
+               };
+               E8AC8C6005ABC18A008C206D = {
+                       children = (
+                               E8AC8C2105ABC13E008C206D,
+                               E8AC8BEE05ABC13E008C206D,
+                               E8AC8C1E05ABC13E008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Tools;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6205ABC19C008C206D = {
+                       children = (
+                               E8AC8BF105ABC13E008C206D,
+                               E8AC8BF205ABC13E008C206D,
+                               E8AC8BF305ABC13E008C206D,
+                               E8AC8BF405ABC13E008C206D,
+                               E8AC8BF505ABC13E008C206D,
+                               E8AC8BF605ABC13E008C206D,
+                               E8AC8BF705ABC13E008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Adaptor;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6305ABC1B2008C206D = {
+                       children = (
+                               E8AC8BF805ABC13E008C206D,
+                               E8AC8C0A05ABC13E008C206D,
+                               E8AC8C0C05ABC13E008C206D,
+                               E8AC8C0F05ABC13E008C206D,
+                               E8AC8C1105ABC13E008C206D,
+                               E8AC8C1305ABC13E008C206D,
+                               E8AC8C1405ABC13E008C206D,
+                               E8AC8C1505ABC13E008C206D,
+                               E8AC8C1805ABC13E008C206D,
+                               E8D0A07D0605B8D10084DA47,
+                               E8AC8C1905ABC13E008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Qualifier;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6405ABC1CB008C206D = {
+                       children = (
+                               E8AC8BFA05ABC13E008C206D,
+                               E8AC8BFB05ABC13E008C206D,
+                               E8AC8C0205ABC13E008C206D,
+                               E8AC8C0305ABC13E008C206D,
+                               E8AC8C0405ABC13E008C206D,
+                               E8AC8C0D05ABC13E008C206D,
+                               E8AC8C0E05ABC13E008C206D,
+                               E8AC8C1705ABC13E008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Model;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6505ABC1DB008C206D = {
+                       children = (
+                               E8AC8BFD05ABC13E008C206D,
+                               E8AC8BFE05ABC13E008C206D,
+                               E8AC8BFF05ABC13E008C206D,
+                               E8AC8C0005ABC13E008C206D,
+                               E8AC8C0105ABC13E008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Database;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6605ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAccess.h;
+                       path = GDLAccess/EOAccess/EOAccess.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6705ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAdaptor.h;
+                       path = GDLAccess/EOAccess/EOAdaptor.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6805ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAdaptorChannel.h;
+                       path = GDLAccess/EOAccess/EOAdaptorChannel.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6905ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = "EOAdaptorChannel+Attributes.h";
+                       path = "GDLAccess/EOAccess/EOAdaptorChannel+Attributes.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6A05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAdaptorContext.h;
+                       path = GDLAccess/EOAccess/EOAdaptorContext.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6B05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAdaptorDataSource.h;
+                       path = GDLAccess/EOAccess/EOAdaptorDataSource.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6C05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAdaptorGlobalID.h;
+                       path = GDLAccess/EOAccess/EOAdaptorGlobalID.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6D05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAdaptorOperation.h;
+                       path = GDLAccess/EOAccess/EOAdaptorOperation.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6E05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOArrayProxy.h;
+                       path = GDLAccess/EOAccess/EOArrayProxy.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C6F05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAttribute.h;
+                       path = GDLAccess/EOAccess/EOAttribute.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7005ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOAttributeOrdering.h;
+                       path = GDLAccess/EOAccess/EOAttributeOrdering.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7105ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOCustomValues.h;
+                       path = GDLAccess/EOAccess/EOCustomValues.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7205ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EODatabase.h;
+                       path = GDLAccess/EOAccess/EODatabase.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7305ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EODatabaseChannel.h;
+                       path = GDLAccess/EOAccess/EODatabaseChannel.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7405ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EODatabaseContext.h;
+                       path = GDLAccess/EOAccess/EODatabaseContext.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7505ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EODatabaseFault.h;
+                       path = GDLAccess/EOAccess/EODatabaseFault.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7605ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EODatabaseFaultResolver.h;
+                       path = GDLAccess/EOAccess/EODatabaseFaultResolver.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7705ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EODelegateResponse.h;
+                       path = GDLAccess/EOAccess/EODelegateResponse.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7805ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOEntity.h;
+                       path = GDLAccess/EOAccess/EOEntity.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7905ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = "EOEntity+Factory.h";
+                       path = "GDLAccess/EOAccess/EOEntity+Factory.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7A05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOExpressionArray.h;
+                       path = GDLAccess/EOAccess/EOExpressionArray.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7B05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOFault.h;
+                       path = GDLAccess/EOAccess/EOFault.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7C05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOFaultHandler.h;
+                       path = GDLAccess/EOAccess/EOFaultHandler.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7D05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOFExceptions.h;
+                       path = GDLAccess/EOAccess/EOFExceptions.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7E05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOGenericRecord.h;
+                       path = GDLAccess/EOAccess/EOGenericRecord.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C7F05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOJoinTypes.h;
+                       path = GDLAccess/EOAccess/EOJoinTypes.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8005ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOKeySortOrdering.h;
+                       path = GDLAccess/EOAccess/EOKeySortOrdering.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8105ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOModel.h;
+                       path = GDLAccess/EOAccess/EOModel.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8205ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOModelGroup.h;
+                       path = GDLAccess/EOAccess/EOModelGroup.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8305ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EONull.h;
+                       path = GDLAccess/EOAccess/EONull.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8405ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOObjectUniquer.h;
+                       path = GDLAccess/EOAccess/EOObjectUniquer.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8505ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOPrimaryKeyDictionary.h;
+                       path = GDLAccess/EOAccess/EOPrimaryKeyDictionary.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8605ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOQualifierScanner.h;
+                       path = GDLAccess/EOAccess/EOQualifierScanner.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8705ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOQuotedExpression.h;
+                       path = GDLAccess/EOAccess/EOQuotedExpression.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8805ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EORecordDictionary.h;
+                       path = GDLAccess/EOAccess/EORecordDictionary.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8905ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EORelationship.h;
+                       path = GDLAccess/EOAccess/EORelationship.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8A05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOSQLExpression.h;
+                       path = GDLAccess/EOAccess/EOSQLExpression.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8B05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = EOSQLQualifier.h;
+                       path = GDLAccess/EOAccess/EOSQLQualifier.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8C05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = GDLAccess.h;
+                       path = GDLAccess/EOAccess/GDLAccess.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8C8D05ABC218008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = "NSObject+EONullInit.h";
+                       path = "GDLAccess/EOAccess/NSObject+EONullInit.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               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 = "<group>";
+               };
+               E8AC8CF505ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = COPYING;
+                       path = GDLAccess/FoundationExt/COPYING;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CF605ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = COPYRIGHT;
+                       path = GDLAccess/FoundationExt/COPYRIGHT;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CF705ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = DefaultScannerHandler.h;
+                       path = GDLAccess/FoundationExt/DefaultScannerHandler.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CF805ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = DefaultScannerHandler.m;
+                       path = GDLAccess/FoundationExt/DefaultScannerHandler.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CF905ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = FormatScanner.h;
+                       path = GDLAccess/FoundationExt/FormatScanner.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CFA05ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = FormatScanner.m;
+                       path = GDLAccess/FoundationExt/FormatScanner.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CFB05ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = GNUmakefile;
+                       path = GDLAccess/FoundationExt/GNUmakefile;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CFC05ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = LICENSE;
+                       path = GDLAccess/FoundationExt/LICENSE;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CFD05ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = PrintfFormatScanner.h;
+                       path = GDLAccess/FoundationExt/PrintfFormatScanner.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8CFE05ABC6AE008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = PrintfFormatScanner.m;
+                       path = GDLAccess/FoundationExt/PrintfFormatScanner.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               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 = "<group>";
+               };
+               E8AC8D0A05ABCA7A008C206D = {
+                       isa = PBXFileReference;
+                       lastKnownFileType = file;
+                       name = EOControl.framework;
+                       path = /Users/helge/Library/Frameworks/EOControl.framework;
+                       refType = 0;
+                       sourceTree = "<absolute>";
+               };
+               E8AC8D0B05ABCA7A008C206D = {
+                       fileRef = E8AC8D0A05ABCA7A008C206D;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               E8AC8D1F05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = ChangeLog;
+                       path = PostgreSQL72/ChangeLog;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2005ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = common.h;
+                       path = PostgreSQL72/common.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2105ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.plist;
+                       name = condict.plist;
+                       path = PostgreSQL72/condict.plist;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2205ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = COPYING;
+                       path = PostgreSQL72/COPYING;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2305ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = COPYING.LIB;
+                       path = PostgreSQL72/COPYING.LIB;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2405ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = "EOAttribute+PostgreSQL72.h";
+                       path = "PostgreSQL72/EOAttribute+PostgreSQL72.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2505ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "EOAttribute+PostgreSQL72.m";
+                       path = "PostgreSQL72/EOAttribute+PostgreSQL72.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2605ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = gdltest.m;
+                       path = PostgreSQL72/gdltest.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2705ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = GNUmakefile;
+                       path = PostgreSQL72/GNUmakefile;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2805ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = GNUmakefile.preamble;
+                       path = PostgreSQL72/GNUmakefile.preamble;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2905ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "NSCalendarDate+PGVal.m";
+                       path = "PostgreSQL72/NSCalendarDate+PGVal.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2A05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "NSData+PGVal.m";
+                       path = "PostgreSQL72/NSData+PGVal.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2B05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "NSNumber+PGVal.m";
+                       path = "PostgreSQL72/NSNumber+PGVal.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2C05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "NSString+PGVal.m";
+                       path = "PostgreSQL72/NSString+PGVal.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2D05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = "NSString+PostgreSQL72.h";
+                       path = "PostgreSQL72/NSString+PostgreSQL72.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2E05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "NSString+PostgreSQL72.m";
+                       path = "PostgreSQL72/NSString+PostgreSQL72.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D2F05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = postgres_types.h;
+                       path = PostgreSQL72/postgres_types.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3005ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = PostgreSQL72Adaptor.h;
+                       path = PostgreSQL72/PostgreSQL72Adaptor.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3105ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = PostgreSQL72Adaptor.m;
+                       path = PostgreSQL72/PostgreSQL72Adaptor.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3205ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = PostgreSQL72Channel.h;
+                       path = PostgreSQL72/PostgreSQL72Channel.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3305ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = PostgreSQL72Channel.m;
+                       path = PostgreSQL72/PostgreSQL72Channel.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3405ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = "PostgreSQL72Channel+Model.h";
+                       path = "PostgreSQL72/PostgreSQL72Channel+Model.h";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3505ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = "PostgreSQL72Channel+Model.m";
+                       path = "PostgreSQL72/PostgreSQL72Channel+Model.m";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3605ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = PostgreSQL72Context.h;
+                       path = PostgreSQL72/PostgreSQL72Context.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3705ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = PostgreSQL72Context.m;
+                       path = PostgreSQL72/PostgreSQL72Context.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3805ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = PostgreSQL72Exception.h;
+                       path = PostgreSQL72/PostgreSQL72Exception.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3905ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = PostgreSQL72Exception.m;
+                       path = PostgreSQL72/PostgreSQL72Exception.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3A05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = PostgreSQL72Expression.h;
+                       path = PostgreSQL72/PostgreSQL72Expression.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3B05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = PostgreSQL72Expression.m;
+                       path = PostgreSQL72/PostgreSQL72Expression.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3C05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.h;
+                       name = PostgreSQL72Values.h;
+                       path = PostgreSQL72/PostgreSQL72Values.h;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3D05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       name = PostgreSQL72Values.m;
+                       path = PostgreSQL72/PostgreSQL72Values.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3E05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = README;
+                       path = PostgreSQL72/README;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D3F05ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = test.eomodel;
+                       path = PostgreSQL72/test.eomodel;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D4005ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = TODO;
+                       path = PostgreSQL72/TODO;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D4105ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = types.psql;
+                       path = PostgreSQL72/types.psql;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D4205ABCAB9008C206D = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text;
+                       name = Version;
+                       path = PostgreSQL72/Version;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D4305ABCACA008C206D = {
+                       children = (
+                               E8AC8D3205ABCAB9008C206D,
+                               E8AC8D3305ABCAB9008C206D,
+                               E8AC8D3405ABCAB9008C206D,
+                               E8AC8D3505ABCAB9008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Channel;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D4405ABCADA008C206D = {
+                       children = (
+                               E8AC8D3C05ABCAB9008C206D,
+                               E8AC8D3D05ABCAB9008C206D,
+                               E8AC8D2905ABCAB9008C206D,
+                               E8AC8D2A05ABCAB9008C206D,
+                               E8AC8D2B05ABCAB9008C206D,
+                               E8AC8D2C05ABCAB9008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Values;
+                       path = "";
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D4505ABCAEA008C206D = {
+                       children = (
+                               E8AC8D2705ABCAB9008C206D,
+                               E8AC8D2805ABCAB9008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Makefiles;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               E8AC8D4605ABCAFF008C206D = {
+                       children = (
+                               E8AC8D2105ABCAB9008C206D,
+                               E8AC8D2605ABCAB9008C206D,
+                               E8AC8D3F05ABCAB9008C206D,
+                               E8AC8D4105ABCAB9008C206D,
+                       );
+                       isa = PBXGroup;
+                       name = Misc;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               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 = "<group>";
+               };
+               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 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>English</string>
+       <key>CFBundleExecutable</key>
+       <string>PostgreSQL72</string>
+       <key>CFBundleGetInfoString</key>
+       <string></string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>com.MySoftwareCompany.PostgreSQL72</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string></string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1.0.0d1</string>
+</dict>
+</plist>
+";
+                       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 = "<group>";
+               };
+               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 (file)
index 0000000..20989aa
--- /dev/null
@@ -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
similarity index 99%
rename from sope-core/NGiCal/ChangeLog
rename to sope-ical/NGiCal/ChangeLog
index 5027024c0583127d4913e10707b91868e8eb6900..2ab2fee77528d8db0813bdde222a5248997275b8 100644 (file)
@@ -1,5 +1,7 @@
 2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
 
+       * moved to sope-ical
+
        * moved to SOPE 4.3 (v4.3.25)
 
 2004-08-14  Helge Hess  <helge.hess@opengroupware.org>
similarity index 93%
rename from sope-xml/iCalSaxDriver/ChangeLog
rename to sope-ical/iCalSaxDriver/ChangeLog
index b936876d97ac1df0cc1194b27008ca9e54cabb25..e476b6ec89dfa9fc004f426df7843ba59d058254 100644 (file)
@@ -1,3 +1,7 @@
+2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
+
+       * moved from sope-xml to sope-ical (v4.3.9)
+
 2004-07-02  Helge Hess  <helge.hess@opengroupware.org>
 
        * ICalSaxParser.m: added default 'iCalSaxDriverDebugEnabled' to enable
diff --git a/sope-ical/iCalSaxDriver/Version b/sope-ical/iCalSaxDriver/Version
new file mode 100644 (file)
index 0000000..81be7eb
--- /dev/null
@@ -0,0 +1,3 @@
+# $Id$
+
+SUBMINOR_VERSION:=9
diff --git a/sope-ldap/GNUmakefile b/sope-ldap/GNUmakefile
new file mode 100644 (file)
index 0000000..8b94c1f
--- /dev/null
@@ -0,0 +1,9 @@
+include $(GNUSTEP_MAKEFILES)/common.make
+
+PACKAGE_NAME=sope-ldap
+VERSION=4.3.0
+
+SUBPROJECTS = \
+       NGLdap          \
+
+include $(GNUSTEP_MAKEFILES)/aggregate.make
similarity index 99%
rename from sope-core/NGLdap/ChangeLog
rename to sope-ldap/NGLdap/ChangeLog
index a2387e45e421be655ac34a421f32b2230cf76649..87217d570d6539b53cef80f3455f49f3e2263769 100644 (file)
@@ -1,5 +1,7 @@
 2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
 
+       * moved to sope-ldap
+
        * moved to SOPE 4.3 (v4.3.18)
 
 2004-06-20  Florian G. Pflug  <fgp@phlo.org>
diff --git a/sope-mime/GNUmakefile b/sope-mime/GNUmakefile
new file mode 100644 (file)
index 0000000..8d20362
--- /dev/null
@@ -0,0 +1,9 @@
+include $(GNUSTEP_MAKEFILES)/common.make
+
+PACKAGE_NAME=sope-mime
+VERSION=4.3.0
+
+SUBPROJECTS = \
+       NGMime
+
+include $(GNUSTEP_MAKEFILES)/aggregate.make
similarity index 99%
rename from sope-core/NGMime/ChangeLog
rename to sope-mime/NGMime/ChangeLog
index 126d6e730beaf7ef9384eb777f845254ba08bec2..38c65c548bfcb46caca6d738fd2be73e6bf622c6 100644 (file)
@@ -1,5 +1,7 @@
 2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
 
+       * moved to sope-mime top
+
        * moved to SOPE 4.3 (v4.3.172)
 
 2004-08-02  Frank Reppin  <frank@opengroupware.org>
diff --git a/sope-mime/NGMime/NGMail/COPYING b/sope-mime/NGMime/NGMail/COPYING
new file mode 100644 (file)
index 0000000..161a3d1
--- /dev/null
@@ -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.
+\f
+  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.
+\f
+                 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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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.
+\f
+  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
+\f
+     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.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
similarity index 100%
rename from sope-core/NGMime/TODO
rename to sope-mime/NGMime/TODO
index aa0206431ec46d526267e783c85f1a844465cf2f..98c9217101abc5449f15f200852fc76462c0cd2d 100644 (file)
@@ -1,8 +1,16 @@
+2004-08-20  Helge Hess  <helge.hess@opengroupware.org>
+
+       * moved iCalSaxDriver to sope-ical
+
+       * moved ExpatSaxDriver, CFXMLSaxDriver to Recycler
+
+       * moved PlistSaxDriver to samples
+
 2004-08-03  Marcus Mueller  <znek@mulle-kybernetik.com>
 
-       * 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  <znek@mulle-kybernetik.com>
 
index b17f4e2339bb0e575e31d3ebc9f194d1deae84a9..61134514ce89f3b2ceadeaf6d19d71285215ba6a 100644 (file)
@@ -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 (file)
index 28292b5..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# $Id$
-
-SUBMINOR_VERSION:=8